From ee91d465573637da5c386df3770a20cfb183d210 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Tue, 31 Aug 2021 13:20:48 -0500 Subject: [PATCH] arm: mach-k3: common: Make sure firmware sections are loaded prior to armv8 startup With Device Manager firmware in an elf file form, we cannot load the FIT image to the exact same address as any of the executable sections of the elf file itself is located. However, the device tree descriptions for the ARMV8 bootloader/OS includes DDR regions only the final sections in DDR where the Device Manager firmware is actually executing out of. As the R5 uC is usually operating at a slower rate than an ARMv8 MPU, by starting the Armv8 ahead of parsing the elf and copying the correct sections to the required memories creates a race condition where the ARMv8 could overwrite the elf image loaded from the FIT image prior to the R5 completing parsing and putting the correct sections of elf in the required memory locations. OR create rather obscure debug conditions where data in the section is being modified by ARMV8 OS while the elf copy is in progress. To prevent all these conditions, lets make sure that the elf parse and copy operations are completed ahead of ARMv8 being released to execute. We will pay a penalty of elf copy time, but that is a valid tradeoff in comparison to debug of alternate scenarios. Signed-off-by: Nishanth Menon --- arch/arm/mach-k3/common.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index 08b7344..2666cd2 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -203,7 +203,7 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) typedef void __noreturn (*image_entry_noargs_t)(void); struct ti_sci_handle *ti_sci = get_ti_sci_handle(); u32 loadaddr = 0; - int ret, size = 0; + int ret, size = 0, shut_cpu = 0; /* Release all the exclusive devices held by SPL before starting ATF */ ti_sci->ops.dev_ops.release_exclusive_devices(ti_sci); @@ -231,19 +231,10 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) if (ret) panic("%s: ATF failed to load on rproc (%d)\n", __func__, ret); - /* Add an extra newline to differentiate the ATF logs from SPL */ - printf("Starting ATF on ARM64 core...\n\n"); - - ret = rproc_start(1); - if (ret) - panic("%s: ATF failed to start on rproc (%d)\n", __func__, ret); if (!fit_image_info[IMAGE_ID_DM_FW].image_len && !(size > 0 && valid_elf_image(loadaddr))) { - debug("Shutting down...\n"); - release_resources_for_core_shutdown(); - - while (1) - asm volatile("wfe"); + shut_cpu = 1; + goto start_arm64; } if (!fit_image_info[IMAGE_ID_DM_FW].image_start) { @@ -256,6 +247,21 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) debug("%s: jumping to address %x\n", __func__, loadaddr); +start_arm64: + /* Add an extra newline to differentiate the ATF logs from SPL */ + printf("Starting ATF on ARM64 core...\n\n"); + + ret = rproc_start(1); + if (ret) + panic("%s: ATF failed to start on rproc (%d)\n", __func__, ret); + + if (shut_cpu) { + debug("Shutting down...\n"); + release_resources_for_core_shutdown(); + + while (1) + asm volatile("wfe"); + } image_entry_noargs_t image_entry = (image_entry_noargs_t)loadaddr; image_entry(); -- 2.7.4