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 /* Check whether Video memory resize is enabled */ 56 if (mmio_read_32(TEGRA_MC_BASE + MC_VIDEO_PROTECT_REG_CTRL) 57 != MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED) { 58 ERROR("Video Memory Resize isn't enabled! \n"); 59 SMC_RET1(handle, (uint64_t)-ENOTSUP); 60 } 61 62 /* 63 * Check if Video Memory overlaps TZDRAM (contains bl31/bl32) 64 * or falls outside of the valid DRAM range 65 */ 66 err = bl31_check_ns_address(x1, local_x2_32); 67 if (err != 0) { 68 SMC_RET1(handle, (uint64_t)err); 69 } 70 71 /* 72 * Check if Video Memory is aligned to 1MB. 73 */ 74 if (((x1 & 0xFFFFFU) != 0U) || ((local_x2_32 & 0xFFFFFU) != 0U)) { 75 ERROR("Unaligned Video Memory base address!\n"); 76 SMC_RET1(handle, (uint64_t)-ENOTSUP); 77 } 78 79 /* 80 * The GPU is the user of the Video Memory region. In order to 81 * transition to the new memory region smoothly, we program the 82 * new base/size ONLY if the GPU is in reset mode. 83 */ 84 regval = mmio_read_32(TEGRA_CAR_RESET_BASE + 85 TEGRA_GPU_RESET_REG_OFFSET); 86 if ((regval & GPU_RESET_BIT) == 0U) { 87 ERROR("GPU not in reset! Video Memory setup failed\n"); 88 SMC_RET1(handle, (uint64_t)-ENOTSUP); 89 } 90 91 /* new video memory carveout settings */ 92 tegra_memctrl_videomem_setup(x1, local_x2_32); 93 94 /* 95 * Ensure again that GPU is still in reset after VPR resize 96 */ 97 regval = mmio_read_32(TEGRA_CAR_RESET_BASE + 98 TEGRA_GPU_RESET_REG_OFFSET); 99 if ((regval & GPU_RESET_BIT) == 0U) { 100 mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_GPU_RESET_GPU_SET_OFFSET, 101 GPU_SET_BIT); 102 } 103 104 SMC_RET1(handle, 0); 105 106 /* 107 * The NS world registers the address of its handler to be 108 * used for processing the FIQ. This is normally used by the 109 * NS FIQ debugger driver to detect system hangs by programming 110 * a watchdog timer to fire a FIQ interrupt. 111 */ 112 case TEGRA_SIP_FIQ_NS_ENTRYPOINT: 113 114 if (x1 == 0U) { 115 SMC_RET1(handle, SMC_UNK); 116 } 117 118 /* 119 * TODO: Check if x1 contains a valid DRAM address 120 */ 121 122 /* store the NS world's entrypoint */ 123 tegra_fiq_set_ns_entrypoint(x1); 124 125 SMC_RET1(handle, 0); 126 127 /* 128 * The NS world's FIQ handler issues this SMC to get the NS EL1/EL0 129 * CPU context when the FIQ interrupt was triggered. This allows the 130 * NS world to understand the CPU state when the watchdog interrupt 131 * triggered. 132 */ 133 case TEGRA_SIP_FIQ_NS_GET_CONTEXT: 134 135 /* retrieve context registers when FIQ triggered */ 136 (void)tegra_fiq_get_intr_context(); 137 138 SMC_RET0(handle); 139 140 default: 141 ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); 142 break; 143 } 144 } 145 146 SMC_RET1(handle, SMC_UNK); 147 } 148 149 /* Define a runtime service descriptor for fast SMC calls */ 150 DECLARE_RT_SVC( 151 tegra_sip_fast, 152 153 (OEN_SIP_START), 154 (OEN_SIP_END), 155 (SMC_TYPE_FAST), 156 (NULL), 157 (tegra_sip_handler) 158 ); 159