Make SPL_BLOBLIST_PASS_REGS also pass the bloblist to BL33, which is normally U-Boot proper, when SPL starts it through BL31. Set the BL33 entry point arguments that SPL gives to BL31 to the register values in struct spl_image_info instead of the primary CPU MPID. BL31 passes these on to BL33 unchanged.
This is done after bl2_plat_get_bl31_params() or bl2_plat_get_bl31_params_v2() returns, so it also works with boards that provide their own. Without this, the only way for BL33 to find the SPL bloblist is a fixed address in memory. Signed-off-by: David Lechner <[email protected]> --- common/Kconfig | 4 ++++ common/spl/spl_atf.c | 48 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/common/Kconfig b/common/Kconfig index 4180755525d..5b728cfe324 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -1243,6 +1243,10 @@ config SPL_BLOBLIST_PASS_REGS specification. The next phase then finds the bloblist without relying on a fixed address in memory. + When SPL starts BL31 (SPL_ATF), the registers are passed to BL33 + through its entry point arguments instead of the primary CPU MPID, + and BL31 must pass them on unchanged. + SPL works out the register values in struct spl_image_info. The default jump_to_image() uses them, other implementations need to do the same. diff --git a/common/spl/spl_atf.c b/common/spl/spl_atf.c index c1233b54cf5..00346779713 100644 --- a/common/spl/spl_atf.c +++ b/common/spl/spl_atf.c @@ -181,6 +181,39 @@ __weak struct bl_params *bl2_plat_get_bl31_params_v2(ulong bl32_entry, fdt_addr); } +/* + * Pass the bloblist to BL33 in its entry point arguments, which BL31 passes on + * to BL33 unchanged, instead of the primary CPU MPID. + */ +static void bl31_params_set_bl33_args(void *bl31_params, const ulong *args) +{ + struct entry_point_info *ep_info = NULL; + + if (CONFIG_IS_ENABLED(ATF_LOAD_IMAGE_V2)) { + struct bl_params_node *node; + + for (node = ((struct bl_params *)bl31_params)->head; node; + node = node->next_params_info) { + if (node->image_id == ATF_BL33_IMAGE_ID) { + ep_info = node->ep_info; + break; + } + } + } else { + ep_info = ((struct bl31_params *)bl31_params)->bl33_ep_info; + } + + if (!ep_info) { + printf("Warning: Failed to pass bloblist to BL33\n"); + return; + } + + ep_info->args.arg0 = args[0]; + ep_info->args.arg1 = args[1]; + ep_info->args.arg2 = args[2]; + ep_info->args.arg3 = args[3]; +} + static inline void raw_write_daif(unsigned int daif) { __asm__ __volatile__("msr DAIF, %x0\n\t" : : "r" (daif) : "memory"); @@ -188,10 +221,11 @@ static inline void raw_write_daif(unsigned int daif) typedef void __noreturn (*atf_entry_t)(struct bl31_params *params, void *plat_params); -static void __noreturn bl31_entry(ulong bl31_entry, ulong bl32_entry, - ulong bl33_entry, ulong fdt_addr) +static void __noreturn bl31_entry(struct spl_image_info *spl_image, + ulong bl32_entry, ulong bl33_entry, + ulong fdt_addr) { - atf_entry_t atf_entry = (atf_entry_t)bl31_entry; + atf_entry_t atf_entry = (atf_entry_t)spl_image->entry_point; void *bl31_params; if (CONFIG_IS_ENABLED(ATF_LOAD_IMAGE_V2)) @@ -202,6 +236,11 @@ static void __noreturn bl31_entry(ulong bl31_entry, ulong bl32_entry, bl31_params = bl2_plat_get_bl31_params(bl32_entry, bl33_entry, fdt_addr); + if (CONFIG_IS_ENABLED(BLOBLIST_PASS_REGS) && + spl_image->bloblist_args_valid) + bl31_params_set_bl33_args(bl31_params, + spl_image->bloblist_args); + raw_write_daif(SPSR_EXCEPTION_MASK); if (!CONFIG_IS_ENABLED(SYS_DCACHE_OFF)) dcache_disable(); @@ -309,6 +348,5 @@ void __noreturn spl_invoke_atf(struct spl_image_info *spl_image) * We don't provide a BL3-2 entry yet, but this will be possible * using similar logic. */ - bl31_entry(spl_image->entry_point, bl32_entry, - bl33_entry, platform_param); + bl31_entry(spl_image, bl32_entry, bl33_entry, platform_param); } -- 2.53.0
