On Fri, 18 Mar 2022 00:00:44 -0500 Samuel Holland <sam...@sholland.org> wrote:
Hi, > SPL uses the image header to detect the boot device and to find the > offset of the next U-Boot stage. Since this information is stored > differently in the eGON and TOC0 image headers, add code to find the > correct value based on the image type currently in use. > > Signed-off-by: Samuel Holland <sam...@sholland.org> > --- > > Changes in v5: > - Rebased on top of suniv platform additions > - Took care of additional hardcoded offset in SPL SPI code > > Changes in v3: > - Fixed offset of magic passed to memcmp > - Refactored functions to not return pointers (fixes ambiguous NULL) > > Changes in v2: > - Moved SPL header signature checks out of sunxi_image.h > - Refactored SPL header signature checks to use fewer casts > > arch/arm/include/asm/arch-sunxi/spl.h | 3 +-- > arch/arm/mach-sunxi/board.c | 39 ++++++++++++++++++++------- > arch/arm/mach-sunxi/spl_spi_sunxi.c | 2 +- > 3 files changed, 32 insertions(+), 12 deletions(-) > > 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 0071de19ff..1872dbc24d 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; > + > + if (sunxi_egon_valid(egon_head)) > + return readl(&egon_head->length); > + if (sunxi_toc0_valid(toc0_info)) > + return readl(&toc0_info->length); > > - return readl(SPL_ADDR + 0x10); > + /* 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..0a2671e17c 100644 > --- a/arch/arm/mach-sunxi/spl_spi_sunxi.c > +++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c > @@ -337,7 +337,7 @@ 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(); So this seemingly innocent change breaks the compilation for 32-bit targets, at least with my Ubuntu GCC 9.4.0 armhf toolchain: ---------------- arch/arm/mach-sunxi/spl_spi_sunxi.c: In function ‘spl_spi_load_image’: include/linux/kernel.h:190:17: warning: comparison of distinct pointer types lacks a cast 190 | (void) (&_max1 == &_max2); \ | ^~ arch/arm/mach-sunxi/spl_spi_sunxi.c:342:16: note: in expansion of macro ‘max’ 342 | load_offset = max(load_offset, CONFIG_SYS_SPI_U_BOOT_OFFS); | ^~~ ---------------- Just not sure why this is fine with the AArch64 builds, but changing this below to: - 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); fixes this. Unless someone has a better idea, I will merge this series (plus Icenowy's RISC-V series) with this fix. Cheers, Andre