diff --git a/plat/nvidia/tegra/common/tegra_sip_calls.c b/plat/nvidia/tegra/common/tegra_sip_calls.c index 2c3be60f7..e7acecea4 100644 --- a/plat/nvidia/tegra/common/tegra_sip_calls.c +++ b/plat/nvidia/tegra/common/tegra_sip_calls.c @@ -31,12 +31,11 @@ ******************************************************************************/ extern uint8_t tegra_fake_system_suspend; - /******************************************************************************* * SoC specific SiP handler ******************************************************************************/ #pragma weak plat_sip_handler -int plat_sip_handler(uint32_t smc_fid, +int32_t plat_sip_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, @@ -75,108 +74,111 @@ uintptr_t tegra_sip_handler(uint32_t smc_fid, /* Check if this is a SoC specific SiP */ err = plat_sip_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags); - if (err == 0) + if (err == 0) { + SMC_RET1(handle, (uint64_t)err); - switch (smc_fid) { + } else { - case TEGRA_SIP_NEW_VIDEOMEM_REGION: + switch (smc_fid) { - /* clean up the high bits */ - x2 = (uint32_t)x2; + case TEGRA_SIP_NEW_VIDEOMEM_REGION: - /* - * Check if Video Memory overlaps TZDRAM (contains bl31/bl32) - * or falls outside of the valid DRAM range - */ - err = bl31_check_ns_address(x1, x2); - if (err) - SMC_RET1(handle, err); + /* clean up the high bits */ + x2 = (uint32_t)x2; - /* - * Check if Video Memory is aligned to 1MB. - */ - if ((x1 & 0xFFFFF) || (x2 & 0xFFFFF)) { - ERROR("Unaligned Video Memory base address!\n"); - SMC_RET1(handle, -ENOTSUP); - } + /* + * Check if Video Memory overlaps TZDRAM (contains bl31/bl32) + * or falls outside of the valid DRAM range + */ + err = bl31_check_ns_address(x1, x2); + if (err != 0) { + SMC_RET1(handle, (uint64_t)err); + } - /* - * The GPU is the user of the Video Memory region. In order to - * transition to the new memory region smoothly, we program the - * new base/size ONLY if the GPU is in reset mode. - */ - regval = mmio_read_32(TEGRA_CAR_RESET_BASE + - TEGRA_GPU_RESET_REG_OFFSET); - if ((regval & GPU_RESET_BIT) == 0U) { - ERROR("GPU not in reset! Video Memory setup failed\n"); - SMC_RET1(handle, -ENOTSUP); - } + /* + * Check if Video Memory is aligned to 1MB. + */ + if (((x1 & 0xFFFFFU) != 0U) || ((x2 & 0xFFFFFU) != 0U)) { + ERROR("Unaligned Video Memory base address!\n"); + SMC_RET1(handle, -ENOTSUP); + } - /* new video memory carveout settings */ - tegra_memctrl_videomem_setup(x1, x2); + /* + * The GPU is the user of the Video Memory region. In order to + * transition to the new memory region smoothly, we program the + * new base/size ONLY if the GPU is in reset mode. + */ + regval = mmio_read_32(TEGRA_CAR_RESET_BASE + + TEGRA_GPU_RESET_REG_OFFSET); + if ((regval & GPU_RESET_BIT) == 0UL) { + ERROR("GPU not in reset! Video Memory setup failed\n"); + SMC_RET1(handle, -ENOTSUP); + } - SMC_RET1(handle, 0); - break; + /* new video memory carveout settings */ + tegra_memctrl_videomem_setup(x1, (uint32_t)x2); - /* - * The NS world registers the address of its handler to be - * used for processing the FIQ. This is normally used by the - * NS FIQ debugger driver to detect system hangs by programming - * a watchdog timer to fire a FIQ interrupt. - */ - case TEGRA_SIP_FIQ_NS_ENTRYPOINT: - - if (!x1) - SMC_RET1(handle, SMC_UNK); - - /* - * TODO: Check if x1 contains a valid DRAM address - */ - - /* store the NS world's entrypoint */ - tegra_fiq_set_ns_entrypoint(x1); - - SMC_RET1(handle, 0); - break; - - /* - * The NS world's FIQ handler issues this SMC to get the NS EL1/EL0 - * CPU context when the FIQ interrupt was triggered. This allows the - * NS world to understand the CPU state when the watchdog interrupt - * triggered. - */ - case TEGRA_SIP_FIQ_NS_GET_CONTEXT: - - /* retrieve context registers when FIQ triggered */ - tegra_fiq_get_intr_context(); - - SMC_RET0(handle); - break; - - case TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND: - /* - * System suspend fake mode is set if we are on VDK and we make - * a debug SIP call. This mode ensures that we excercise debug - * path instead of the regular code path to suit the pre-silicon - * platform needs. These include replacing the call to WFI by - * a warm reset request. - */ - if (tegra_platform_is_emulation() != 0U) { - - tegra_fake_system_suspend = 1; SMC_RET1(handle, 0); - } /* - * We return to the external world as if this SIP is not - * implemented in case, we are not running on VDK. + * The NS world registers the address of its handler to be + * used for processing the FIQ. This is normally used by the + * NS FIQ debugger driver to detect system hangs by programming + * a watchdog timer to fire a FIQ interrupt. */ - break; + case TEGRA_SIP_FIQ_NS_ENTRYPOINT: - default: - ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); - break; + if (x1 == 0U) { + SMC_RET1(handle, SMC_UNK); + } + + /* + * TODO: Check if x1 contains a valid DRAM address + */ + + /* store the NS world's entrypoint */ + tegra_fiq_set_ns_entrypoint(x1); + + SMC_RET1(handle, 0); + + /* + * The NS world's FIQ handler issues this SMC to get the NS EL1/EL0 + * CPU context when the FIQ interrupt was triggered. This allows the + * NS world to understand the CPU state when the watchdog interrupt + * triggered. + */ + case TEGRA_SIP_FIQ_NS_GET_CONTEXT: + + /* retrieve context registers when FIQ triggered */ + (void)tegra_fiq_get_intr_context(); + + SMC_RET0(handle); + + case TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND: + /* + * System suspend fake mode is set if we are on VDK and we make + * a debug SIP call. This mode ensures that we excercise debug + * path instead of the regular code path to suit the pre-silicon + * platform needs. These include replacing the call to WFI by + * a warm reset request. + */ + if (tegra_platform_is_virt_dev_kit() != false) { + + tegra_fake_system_suspend = 1; + SMC_RET1(handle, 0); + } + + /* + * We return to the external world as if this SIP is not + * implemented in case, we are not running on VDK. + */ + break; + + default: + ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); + break; + } } SMC_RET1(handle, SMC_UNK);