[PATCH v5 2/3] sunxi: Support SPL in both eGON and TOC0 images
Andre Przywara
andre.przywara at arm.com
Mon Apr 4 19:23:48 CEST 2022
On Fri, 18 Mar 2022 00:00:44 -0500
Samuel Holland <samuel at 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 <samuel at 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
More information about the U-Boot
mailing list