Re: [PATCH v4 3/4] sunxi: Support SPL in both eGON and TOC0 images

Andre Przywara
2021-10-20T23:50:32Z

On Tue, 19 Oct 2021 21:44:53 -0500
Samuel Holland <samuel@sholland.org> wrote:

> 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@sholland.org>

Many thanks for fixing the issues, actually in a more elegant way than
I did here internally.
Tested for regressions on A20, H3, A64, H616, all non-secure (those
were the ones broken in v2).

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre

> ---
>
> (no changes since v3)
>
> 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 | 2 --
> arch/arm/mach-sunxi/board.c | 34 ++++++++++++++++++++++-----
> 2 files changed, 28 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h
> index 58cdf806d9..157b11e489 100644
> --- a/arch/arm/include/asm/arch-sunxi/spl.h
> +++ b/arch/arm/include/asm/arch-sunxi/spl.h
> @@ -19,8 +19,6 @@
> #define SUNXI_BOOTED_FROM_MMC0_HIGH 0x10
> #define SUNXI_BOOTED_FROM_MMC2_HIGH 0x12
>
> -#define is_boot0_magic(addr) (memcmp((void *)(addr), BOOT0_MAGIC, 8) == 0)
> -
> uint32_t sunxi_get_boot_device(void);
>
> #endif
> diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
> index b4ba2a72c4..b2cd64bb3f 100644
> --- a/arch/arm/mach-sunxi/board.c
> +++ b/arch/arm/mach-sunxi/board.c
> @@ -243,12 +243,28 @@ void s_init(void)
>
> #define SUNXI_INVALID_BOOT_SOURCE -1
>
> +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)
> {
> - if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */
> - return SUNXI_INVALID_BOOT_SOURCE;
> + 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 readb(&egon_head->boot_media);
> + if (sunxi_toc0_valid(toc0_info))
> + return readb(&toc0_info->platform[0]);
>
> - return readb(SPL_ADDR + 0x28);
> + /* 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
> @@ -296,10 +312,16 @@ uint32_t sunxi_get_boot_device(void)
> #ifdef CONFIG_SPL_BUILD
> static u32 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;
> }
>
> /*