[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