Where the bloblist is located in internal memory and TF-A's BL31 blob
removes access to this memory, the best option seems to be to relocate
the bloblist just before running TF-A.

Add an option to select this behaviour and provide a relocation address.

Signed-off-by: Simon Glass <s...@chromium.org>
---

 common/Kconfig    | 20 ++++++++++++++++++++
 common/bloblist.c | 15 ++++++++++++++-
 common/spl/spl.c  |  9 +++++++++
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/common/Kconfig b/common/Kconfig
index 0e8c44f3f74..962e7fd76eb 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -1125,6 +1125,26 @@ config SPL_BLOBLIST_ALLOC
 
 endchoice
 
+config SPL_BLOBLIST_RELOC
+       bool "Relocate the bloblist before existing SPL"
+       depends on BLOBLIST_FIXED
+       help
+         Some platforms locate the bloblist in SRAM in SPL. In some cases,
+         the TF-A BL31 blob removes access to SRAM, e.g. with Rockchip RK3399.
+
+         Enable this option to make U-Boot copy the bloblist from SRAM to SDRAM
+         before leaving SPL.
+
+config SPL_BLOBLIST_RELOC_ADDR
+       hex "Relocate the bloblist before existing SPL"
+       depends on SPL_BLOBLIST_RELOC
+       default BLOBLIST_ADDR
+       help
+         Sets the address to which the bloblist is relocated at the end of SPL.
+         U-Boot proper uses this address when it starts up. Note that U-Boot
+         always relocates the bloblist again as part of its own relocation
+         process.
+
 endif # SPL_BLOBLIST
 
 if TPL_BLOBLIST
diff --git a/common/bloblist.c b/common/bloblist.c
index 7eda94ecdf9..60c23d604b6 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -503,9 +503,22 @@ int bloblist_init(void)
        expected = fixed && !xpl_is_first_phase();
        if (xpl_prev_phase() == PHASE_TPL && !IS_ENABLED(CONFIG_TPL_BLOBLIST))
                expected = false;
-       if (fixed)
+       if (fixed) {
                addr = IF_ENABLED_INT(CONFIG_BLOBLIST_FIXED,
                                      CONFIG_BLOBLIST_ADDR);
+
+               if (xpl_phase() == PHASE_BOARD_F &&
+                   IS_ENABLED(CONFIG_SPL_BLOBLIST_RELOC)) {
+                       ulong addr = IF_ENABLED_INT(CONFIG_SPL_BLOBLIST_RELOC,
+                                           CONFIG_SPL_BLOBLIST_RELOC_ADDR);
+
+                       log_debug("Using bloblist at %lx\n", addr);
+                       bloblist_reloc(map_sysmem(addr, 0),
+                                      bloblist_get_total_size());
+               }
+               log_debug("bloblist addr=%lx\n", addr);
+       }
+
        size = CONFIG_BLOBLIST_SIZE;
        if (expected) {
                ret = bloblist_check(addr, size);
diff --git a/common/spl/spl.c b/common/spl/spl.c
index e7157df1ff9..84543691cde 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -841,6 +841,15 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
                               ret);
        }
 
+       if (xpl_phase() == PHASE_SPL && CONFIG_IS_ENABLED(BLOBLIST_RELOC)) {
+               ulong addr = CONFIG_IF_ENABLED_INT(BLOBLIST_RELOC,
+                                                  BLOBLIST_RELOC_ADDR);
+
+               log_debug("Relocating bloblist %p to %lx\n", gd_bloblist(),
+                         addr);
+               bloblist_reloc(map_sysmem(addr, 0), bloblist_get_total_size());
+       }
+
        spl_board_prepare_for_boot();
 
        if (CONFIG_IS_ENABLED(RELOC_LOADER)) {
-- 
2.43.0

Reply via email to