diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h index b543d24e5a..14944a20ea 100644 --- a/arch/arm/include/asm/arch-sunxi/spl.h +++ b/arch/arm/include/asm/arch-sunxi/spl.h @@ -28,8 +28,7 @@ #define SUNIV_BOOTED_FROM_SPI 0xffff4130 #define SUNIV_BOOTED_FROM_MMC1 0xffff4150 -#define is_boot0_magic(addr) (memcmp((void *)(addr), BOOT0_MAGIC, 8) == 0) - uint32_t sunxi_get_boot_device(void); +uint32_t sunxi_get_spl_size(void); #endif diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 9a7673d82d..ffe578d5c3 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -213,8 +213,21 @@ static int suniv_get_boot_source(void) return SUNXI_INVALID_BOOT_SOURCE; } +static int sunxi_egon_valid(struct boot_file_head *egon_head) +{ + return !memcmp(egon_head->magic, BOOT0_MAGIC, 8); /* eGON.BT0 */ +} + +static int sunxi_toc0_valid(struct toc0_main_info *toc0_info) +{ + return !memcmp(toc0_info->name, TOC0_MAIN_INFO_NAME, 8); /* TOC0.GLH */ +} + static int sunxi_get_boot_source(void) { + struct boot_file_head *egon_head = (void *)SPL_ADDR; + struct toc0_main_info *toc0_info = (void *)SPL_ADDR; + /* * On the ARMv5 SoCs, the SPL header in SRAM is overwritten by the * exception vectors in U-Boot proper, so we won't find any @@ -226,13 +239,15 @@ static int sunxi_get_boot_source(void) !IS_ENABLED(CONFIG_SPL_BUILD)) return SUNXI_BOOTED_FROM_MMC0; - if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */ - return SUNXI_INVALID_BOOT_SOURCE; - if (IS_ENABLED(CONFIG_MACH_SUNIV)) return suniv_get_boot_source(); - else - return readb(SPL_ADDR + 0x28); + if (sunxi_egon_valid(egon_head)) + return readb(&egon_head->boot_media); + if (sunxi_toc0_valid(toc0_info)) + return readb(&toc0_info->platform[0]); + + /* Not a valid image, so we must have been booted via FEL. */ + return SUNXI_INVALID_BOOT_SOURCE; } /* The sunxi internal brom will try to loader external bootloader @@ -278,12 +293,18 @@ uint32_t sunxi_get_boot_device(void) } #ifdef CONFIG_SPL_BUILD -static u32 sunxi_get_spl_size(void) +uint32_t sunxi_get_spl_size(void) { - if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */ - return 0; + struct boot_file_head *egon_head = (void *)SPL_ADDR; + struct toc0_main_info *toc0_info = (void *)SPL_ADDR; - return readl(SPL_ADDR + 0x10); + if (sunxi_egon_valid(egon_head)) + return readl(&egon_head->length); + if (sunxi_toc0_valid(toc0_info)) + return readl(&toc0_info->length); + + /* Not a valid image, so use the default U-Boot offset. */ + return 0; } /* diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c index 734c165e5d..de9aa68c4a 100644 --- a/arch/arm/mach-sunxi/spl_spi_sunxi.c +++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c @@ -337,9 +337,9 @@ static int spl_spi_load_image(struct spl_image_info *spl_image, int ret = 0; struct image_header *header; header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); - int load_offset = readl(SPL_ADDR + 0x10); + uint32_t load_offset = sunxi_get_spl_size(); - load_offset = max(load_offset, CONFIG_SYS_SPI_U_BOOT_OFFS); + load_offset = max_t(uint32_t, load_offset, CONFIG_SYS_SPI_U_BOOT_OFFS); spi0_init();