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