Booting into SPL using ramboot can take several seconds on some SoCs due
to the large size of the usb472 payload sent over USB to BootROM.

A large chunk of the usb472 payload, around 1-2 MiB, is padding used to
avoid overlapping when loading e.g. TF-A to 0x40000.

BootROM is likely wasting unnecessary time crc16 validating the padding
of the payload.

Place the FIT payload directly after SPL and memmove it to the expected
memory location, SPL_LOAD_FIT_ADDRESS, to avoid excessive padding and
help speed up ramboot.

Binman symbols are used to get the position and size of the FIT payload
that is initially loaded into DRAM by the BootROM.

Signed-off-by: Jonas Karlman <[email protected]>
---
 arch/arm/dts/rockchip-u-boot.dtsi |  7 +++--
 arch/arm/mach-rockchip/spl.c      | 51 +++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/arch/arm/dts/rockchip-u-boot.dtsi 
b/arch/arm/dts/rockchip-u-boot.dtsi
index 71d7623fe2ca..9fb1abd27fa0 100644
--- a/arch/arm/dts/rockchip-u-boot.dtsi
+++ b/arch/arm/dts/rockchip-u-boot.dtsi
@@ -244,18 +244,21 @@
        simple-bin-usb472 {
                filename = "u-boot-rockchip-usb472.bin";
                pad-byte = <0x00>;
+               skip-at-start = <CFG_SYS_SDRAM_BASE>;
 
                u-boot-spl {
-                       no-write-symbols;
                };
 
+               payload {
+                       type = "section";
+                       align = <CONFIG_SYS_CACHELINE_SIZE>;
 #ifdef HAS_FIT
                fit {
                        insert-template = <&fit_template>;
 #else
                u-boot-img {
 #endif
-                       offset = <(CONFIG_SPL_LOAD_FIT_ADDRESS - 
CFG_SYS_SDRAM_BASE)>;
+               };
                };
        };
 #endif /* CONFIG_ROCKCHIP_MASKROM_IMAGE */
diff --git a/arch/arm/mach-rockchip/spl.c b/arch/arm/mach-rockchip/spl.c
index 1ce3a3b05547..a9155dceedb4 100644
--- a/arch/arm/mach-rockchip/spl.c
+++ b/arch/arm/mach-rockchip/spl.c
@@ -3,6 +3,7 @@
  * (C) Copyright 2019 Rockchip Electronics Co., Ltd
  */
 
+#include <binman_sym.h>
 #include <cpu_func.h>
 #include <debug_uart.h>
 #include <dm.h>
@@ -10,6 +11,7 @@
 #include <image.h>
 #include <init.h>
 #include <log.h>
+#include <mapmem.h>
 #include <ram.h>
 #include <spl.h>
 #include <asm/arch-rockchip/bootrom.h>
@@ -140,3 +142,52 @@ void spl_board_prepare_for_boot(void)
 
        cleanup_before_linux();
 }
+
+#if CONFIG_IS_ENABLED(RAM_DEVICE) && IS_ENABLED(CONFIG_SPL_LOAD_FIT)
+binman_sym_declare_optional(ulong, payload, image_pos);
+binman_sym_declare_optional(ulong, payload, size);
+
+static ulong ramboot_load_read(struct spl_load_info *load, ulong sector,
+                              ulong count, void *buf)
+{
+       ulong addr = IF_ENABLED_INT(CONFIG_SPL_LOAD_FIT,
+                                   CONFIG_SPL_LOAD_FIT_ADDRESS);
+
+       memcpy(buf, map_sysmem(addr + sector, 0), count);
+       return count;
+}
+
+static int ramboot_load_image(struct spl_image_info *spl_image,
+                             struct spl_boot_device *bootdev)
+{
+       struct legacy_img_hdr *header;
+       ulong addr = IF_ENABLED_INT(CONFIG_SPL_LOAD_FIT,
+                                   CONFIG_SPL_LOAD_FIT_ADDRESS);
+       ulong image_pos = binman_sym(ulong, payload, image_pos);
+       ulong size = binman_sym(ulong, payload, size);
+
+       if (addr == CFG_SYS_SDRAM_BASE || addr == CONFIG_SPL_TEXT_BASE)
+               return -ENODEV;
+
+       if (image_pos != BINMAN_SYM_MISSING && size != BINMAN_SYM_MISSING) {
+               header = map_sysmem(image_pos, 0);
+               if (image_get_magic(header) == FDT_MAGIC) {
+                       memmove(map_sysmem(addr, 0), header, size);
+                       memset(header, 0, sizeof(*header));
+               }
+       }
+
+       header = map_sysmem(addr, 0);
+       if (image_get_magic(header) == FDT_MAGIC) {
+               struct spl_load_info load;
+
+               spl_load_init(&load, ramboot_load_read, NULL, 1);
+               return spl_load_simple_fit(spl_image, &load, 0, header);
+       }
+
+       return -ENODEV;
+}
+
+/* Use priority and method name that sort before default spl_ram_load_image */
+SPL_LOAD_IMAGE_METHOD("RAM", 0, BOOT_DEVICE_RAM, ramboot_load_image);
+#endif
-- 
2.52.0

Reply via email to