1 /* 2 * Copyright (c) 2015-2017, 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 <assert.h> 9 #include <errno.h> 10 11 #include <arch.h> 12 #include <arch_helpers.h> 13 #include <common/bl_common.h> 14 #include <common/debug.h> 15 #include <common/runtime_svc.h> 16 #include <lib/mmio.h> 17 18 #include <memctrl.h> 19 #include <tegra_platform.h> 20 #include <tegra_private.h> 21 22 /******************************************************************************* 23 * Common Tegra SiP SMCs 24 ******************************************************************************/ 25 #define TEGRA_SIP_NEW_VIDEOMEM_REGION 0x82000003 26 #define TEGRA_SIP_FIQ_NS_ENTRYPOINT 0x82000005 27 #define TEGRA_SIP_FIQ_NS_GET_CONTEXT 0x82000006 28 29 /******************************************************************************* 30 * This function is responsible for handling all SiP calls 31 ******************************************************************************/ 32 uintptr_t tegra_sip_handler(uint32_t smc_fid, 33 u_register_t x1, 34 u_register_t x2, 35 u_register_t x3, 36 u_register_t x4, 37 void *cookie, 38 void *handle, 39 u_register_t flags) 40 { 41 uint32_t regval, local_x2_32 = (uint32_t)x2; 42 int32_t err; 43 44 /* Check if this is a SoC specific SiP */ 45 err = plat_sip_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags); 46 if (err == 0) { 47 48 SMC_RET1(handle, (uint64_t)err); 49 50 } else { 51 52 switch (smc_fid) { 53 54 case TEGRA_SIP_NEW_VIDEOMEM_REGION: 55 56 /* 57 * Check if Video Memory overlaps TZDRAM (contains bl31/bl32) 58 * or falls outside of the valid DRAM range 59 */ 60 err = bl31_check_ns_address(x1, local_x2_32); 61 if (err != 0) { 62 SMC_RET1(handle, (uint64_t)err); 63 } 64 65 /* 66 * Check if Video Memory is aligned to 1MB. 67 */ 68 if (((x1 & 0xFFFFFU) != 0U) || ((local_x2_32 & 0xFFFFFU) != 0U)) { 69 ERROR("Unaligned Video Memory base address!\n"); 70 SMC_RET1(handle, (uint64_t)-ENOTSUP); 71 } 72 73 /* 74 * The GPU is the user of the Video Memory region. In order to 75 * transition to the new memory region smoothly, we program the 76 * new base/size ONLY if the GPU is in reset mode. 77 */ 78 regval = mmio_read_32(TEGRA_CAR_RESET_BASE + 79 TEGRA_GPU_RESET_REG_OFFSET); 80 if ((regval & GPU_RESET_BIT) == 0U) { 81 ERROR("GPU not in reset! Video Memory setup failed\n"); 82 SMC_RET1(handle, (uint64_t)-ENOTSUP); 83 } 84 85 /* new video memory carveout settings */ 86 tegra_memctrl_videomem_setup(x1, local_x2_32); 87 88 /* 89 * Ensure again that GPU is still in reset after VPR resize 90 */ 91 regval = mmio_read_32(TEGRA_CAR_RESET_BASE + 92 TEGRA_GPU_RESET_REG_OFFSET); 93 if ((regval & GPU_RESET_BIT) == 0U) { 94 mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_GPU_RESET_GPU_SET_OFFSET, 95 GPU_SET_BIT); 96 } 97 98 SMC_RET1(handle, 0); 99 100 /* 101 * The NS world registers the address of its handler to be 102 * used for processing the FIQ. This is normally used by the 103 * NS FIQ debugger driver to detect system hangs by programming 104 * a watchdog timer to fire a FIQ interrupt. 105 */ 106 case TEGRA_SIP_FIQ_NS_ENTRYPOINT: 107 108 if (x1 == 0U) { 109 SMC_RET1(handle, SMC_UNK); 110 } 111 112 /* 113 * TODO: Check if x1 contains a valid DRAM address 114 */ 115 116 /* store the NS world's entrypoint */ 117 tegra_fiq_set_ns_entrypoint(x1); 118 119 SMC_RET1(handle, 0); 120 121 /* 122 * The NS world's FIQ handler issues this SMC to get the NS EL1/EL0 123 * CPU context when the FIQ interrupt was triggered. This allows the 124 * NS world to understand the CPU state when the watchdog interrupt 125 * triggered. 126 */ 127 case TEGRA_SIP_FIQ_NS_GET_CONTEXT: 128 129 /* retrieve context registers when FIQ triggered */ 130 (void)tegra_fiq_get_intr_context(); 131 132 SMC_RET0(handle); 133 134 default: 135 ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); 136 break; 137 } 138 } 139 140 SMC_RET1(handle, SMC_UNK); 141 } 142 143 /* Define a runtime service descriptor for fast SMC calls */ 144 DECLARE_RT_SVC( 145 tegra_sip_fast, 146 147 (OEN_SIP_START), 148 (OEN_SIP_END), 149 (SMC_TYPE_FAST), 150 (NULL), 151 (tegra_sip_handler) 152 ); 153