blob: 0e8900ef7792d64a0136ee0a43f99d5da1854cd5 [file] [log] [blame]
kalyani chidambarama1ad9b72018-03-06 16:36:57 -08001/*
2 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
8#include <arch_helpers.h>
9#include <assert.h>
10#include <common/bl_common.h>
11#include <common/debug.h>
12#include <common/runtime_svc.h>
13#include <errno.h>
14#include <mmio.h>
15#include <utils_def.h>
16
17#include <memctrl.h>
18#include <pmc.h>
19#include <tegra_private.h>
20#include <tegra_platform.h>
21#include <tegra_def.h>
22
23/*******************************************************************************
24 * PMC parameters
25 ******************************************************************************/
26#define PMC_READ U(0xaa)
27#define PMC_WRITE U(0xbb)
28
29/*******************************************************************************
30 * Tegra210 SiP SMCs
31 ******************************************************************************/
32#define TEGRA_SIP_PMC_COMMANDS U(0xC2FFFE00)
33
34/*******************************************************************************
35 * This function is responsible for handling all T210 SiP calls
36 ******************************************************************************/
37int plat_sip_handler(uint32_t smc_fid,
38 uint64_t x1,
39 uint64_t x2,
40 uint64_t x3,
41 uint64_t x4,
42 const void *cookie,
43 void *handle,
44 uint64_t flags)
45{
46 uint32_t val, ns;
47
48 /* Determine which security state this SMC originated from */
49 ns = is_caller_non_secure(flags);
50 if (!ns)
51 SMC_RET1(handle, SMC_UNK);
52
53 switch (smc_fid) {
54 case TEGRA_SIP_PMC_COMMANDS:
55
56 /* check the address is within PMC range and is 4byte aligned */
57 if ((x2 >= TEGRA_PMC_SIZE) || (x2 & 0x3))
58 return -EINVAL;
59
60 /* pmc_secure_scratch registers are not accessible */
61 if (((x2 >= PMC_SECURE_SCRATCH0) && (x2 <= PMC_SECURE_SCRATCH5)) ||
62 ((x2 >= PMC_SECURE_SCRATCH6) && (x2 <= PMC_SECURE_SCRATCH7)) ||
63 ((x2 >= PMC_SECURE_SCRATCH8) && (x2 <= PMC_SECURE_SCRATCH79)) ||
64 ((x2 >= PMC_SECURE_SCRATCH80) && (x2 <= PMC_SECURE_SCRATCH119)))
65 return -EFAULT;
66
67 /* PMC secure-only registers are not accessible */
68 if ((x2 == PMC_DPD_ENABLE_0) || (x2 == PMC_FUSE_CONTROL_0) ||
69 (x2 == PMC_CRYPTO_OP_0))
70 return -EFAULT;
71
72 /* Perform PMC read/write */
73 if (x1 == PMC_READ) {
74 val = mmio_read_32((uint32_t)(TEGRA_PMC_BASE + x2));
75 write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X1, val);
76 } else if (x1 == PMC_WRITE) {
77 mmio_write_32((uint32_t)(TEGRA_PMC_BASE + x2), (uint32_t)x3);
78 } else {
79 return -EINVAL;
80 }
81
82 break;
83
84 default:
85 ERROR("%s: unsupported function ID\n", __func__);
86 return -ENOTSUP;
87 }
88
89 return 0;
90}