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

Reply via email to