diff --git a/plat/nvidia/tegra/include/t194/tegra194_private.h b/plat/nvidia/tegra/include/t194/tegra194_private.h new file mode 100644 index 0000000..f5de017 --- /dev/null +++ b/plat/nvidia/tegra/include/t194/tegra194_private.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __TEGRA194_PRIVATE_H__ +#define __TEGRA194_PRIVATE_H__ + +void tegra194_cpu_reset_handler(void); +uint64_t tegra194_get_cpu_reset_handler_base(void); +uint64_t tegra194_get_cpu_reset_handler_size(void); +uint64_t tegra194_get_smmu_ctx_offset(void); + +#endif /* __TEGRA194_PRIVATE_H__ */ diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c index 4517ffe..c25897d 100644 --- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -134,9 +135,7 @@ /* save SMMU context */ smmu_ctx_base = params_from_bl2->tzdram_base + - ((uintptr_t)&__tegra194_cpu_reset_handler_data - - (uintptr_t)&tegra194_cpu_reset_handler) + - TEGRA194_SMMU_CTX_OFFSET; + tegra194_get_smmu_ctx_offset(); tegra_smmu_save_context((uintptr_t)smmu_ctx_base); /* @@ -261,8 +260,7 @@ * BL3-1 over to TZDRAM. */ val = params_from_bl2->tzdram_base + - ((uintptr_t)&__tegra194_cpu_reset_handler_end - - (uintptr_t)&tegra194_cpu_reset_handler); + tegra194_get_cpu_reset_handler_size(); memcpy((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE, (uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE); diff --git a/plat/nvidia/tegra/soc/t194/plat_secondary.c b/plat/nvidia/tegra/soc/t194/plat_secondary.c index 3905f8b..c397c91 100644 --- a/plat/nvidia/tegra/soc/t194/plat_secondary.c +++ b/plat/nvidia/tegra/soc/t194/plat_secondary.c @@ -9,18 +9,15 @@ #include #include #include +#include #include #include -#define MISCREG_CPU_RESET_VECTOR 0x2000U #define MISCREG_AA64_RST_LOW 0x2004U #define MISCREG_AA64_RST_HIGH 0x2008U #define CPU_RESET_MODE_AA64 1U -extern void tegra194_cpu_reset_handler(void); -extern uint64_t __tegra194_smmu_ctx_start; - /******************************************************************************* * Setup secondary CPU vectors ******************************************************************************/ @@ -28,17 +25,24 @@ { uint32_t addr_low, addr_high; plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); - uint64_t cpu_reset_handler_base = params_from_bl2->tzdram_base; + uint64_t cpu_reset_handler_base, cpu_reset_handler_size; INFO("Setting up secondary CPU boot\n"); - memcpy((void *)((uintptr_t)cpu_reset_handler_base), - (void *)(uintptr_t)tegra194_cpu_reset_handler, - (uintptr_t)&__tegra194_smmu_ctx_start - - (uintptr_t)&tegra194_cpu_reset_handler); + /* + * The BL31 code resides in the TZSRAM which loses state + * when we enter System Suspend. Copy the wakeup trampoline + * code to TZDRAM to help us exit from System Suspend. + */ + cpu_reset_handler_base = tegra194_get_cpu_reset_handler_base(); + cpu_reset_handler_size = tegra194_get_cpu_reset_handler_size(); + memcpy((void *)((uintptr_t)params_from_bl2->tzdram_base), + (void *)((uintptr_t)cpu_reset_handler_base), + cpu_reset_handler_size); - addr_low = (uint32_t)cpu_reset_handler_base | CPU_RESET_MODE_AA64; - addr_high = (uint32_t)((cpu_reset_handler_base >> 32U) & 0x7ffU); + /* TZDRAM base will be used as the "resume" address */ + addr_low = (uint32_t)params_from_bl2->tzdram_base | CPU_RESET_MODE_AA64; + addr_high = (uint32_t)((params_from_bl2->tzdram_base >> 32U) & 0x7ffU); /* write lower 32 bits first, then the upper 11 bits */ mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW, addr_low); diff --git a/plat/nvidia/tegra/soc/t194/plat_trampoline.S b/plat/nvidia/tegra/soc/t194/plat_trampoline.S index 111fc15..ea8cbef 100644 --- a/plat/nvidia/tegra/soc/t194/plat_trampoline.S +++ b/plat/nvidia/tegra/soc/t194/plat_trampoline.S @@ -70,8 +70,9 @@ __tegra194_cpu_reset_handler_data: .quad tegra_secure_entrypoint .quad __BL31_END__ - BL31_BASE - .globl __tegra194_smmu_ctx_start -__tegra194_smmu_ctx_start: + + .align 4 +__tegra194_smmu_context: .rept TEGRA194_SMMU_CTX_SIZE .quad 0 .endr @@ -81,3 +82,29 @@ .align 4 .globl __tegra194_cpu_reset_handler_end __tegra194_cpu_reset_handler_end: + + .globl tegra194_get_cpu_reset_handler_size + .globl tegra194_get_cpu_reset_handler_base + .globl tegra194_get_smmu_ctx_offset + +/* return size of the CPU reset handler */ +func tegra194_get_cpu_reset_handler_size + adr x0, __tegra194_cpu_reset_handler_end + adr x1, tegra194_cpu_reset_handler + sub x0, x0, x1 + ret +endfunc tegra194_get_cpu_reset_handler_size + +/* return the start address of the CPU reset handler */ +func tegra194_get_cpu_reset_handler_base + adr x0, tegra194_cpu_reset_handler + ret +endfunc tegra194_get_cpu_reset_handler_base + +/* return the size of the SMMU context */ +func tegra194_get_smmu_ctx_offset + adr x0, __tegra194_smmu_context + adr x1, tegra194_cpu_reset_handler + sub x0, x0, x1 + ret +endfunc tegra194_get_smmu_ctx_offset