1 /*
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 <lib/mmio.h>
15 #include <lib/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 ******************************************************************************/
plat_sip_handler(uint32_t smc_fid,uint64_t x1,uint64_t x2,uint64_t x3,uint64_t x4,const void * cookie,void * handle,uint64_t flags)37 int 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 }
91