[PATCH v2 1/3] mach-sunxi: Add boot device detection for SUNIV/F1C100s

Jesse Taube mr.bossman075 at gmail.com
Sat Feb 12 01:36:18 CET 2022



On 2/11/22 19:32, Jesse Taube wrote:
> In contrast to other Allwinner SoCs the F1C100s BROM does not store a
> boot source indicator in the eGON header in SRAM. This leaves the SPL
> guessing where we were exactly booted from, and for instance trying
> the SD card first, even though we booted from SPI flash.
> 
> By inspecting the BROM code and by experimentation, Samuel found that the
> top of the BROM stack contains unique pointers for each of the boot
> sources, which we can use as a boot source indicator.
> 
> This patch removes the existing board_boot_order bodge and replace it
> with a proper boot source indication function.
> 
> Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
> Suggested-by: Samuel Holland <samuel at sholland.org>
> ---
> V1 -> V2:
> * Bail on NAND
> * Change commit description
> * Change sunxi_get_boot_source to u32
> * Fix FEL boot by next change
> * Move suniv_get_boot_device call into sunxi_get_boot_source
> * Rename suniv_get_boot_device
> * Remove redundant comments
> ---
>   arch/arm/include/asm/arch-sunxi/spl.h | 10 +++++
>   arch/arm/mach-sunxi/board.c           | 57 +++++++++++++--------------
>   2 files changed, 38 insertions(+), 29 deletions(-)
> 
> diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h
> index 58cdf806d9..9a6e8da8e1 100644
> --- a/arch/arm/include/asm/arch-sunxi/spl.h
> +++ b/arch/arm/include/asm/arch-sunxi/spl.h
> @@ -19,6 +19,16 @@
>   #define SUNXI_BOOTED_FROM_MMC0_HIGH	0x10
>   #define SUNXI_BOOTED_FROM_MMC2_HIGH	0x12
>   
> +/*
> + * Values taken from the Bootrom's stack used
> + * to determine where we booted from.
> + */
> +
> +#define SUNIV_BOOTED_FROM_MMC0	0xffff40f8
> +#define SUNIV_BOOTED_FROM_NAND	0xffff4114
> +#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);
> diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
> index 57078f7a7b..27aee1e445 100644
> --- a/arch/arm/mach-sunxi/board.c
> +++ b/arch/arm/mach-sunxi/board.c
> @@ -191,12 +191,37 @@ SPL_LOAD_IMAGE_METHOD("FEL", 0, BOOT_DEVICE_BOARD, spl_board_load_image);
>   
>   #define SUNXI_INVALID_BOOT_SOURCE	-1
>   
> -static int sunxi_get_boot_source(void)
Didn't like the implicit cast on the return statement.
> +static uint32_t suniv_get_boot_source(void)
> +{
> +	/* Get the last function call from BootRom's stack. */
> +	u32 brom_call = *(u32 *)(fel_stash.sp - 4);
> +
> +	/* translate SUNIV Bootrom stack to standard SUNXI boot sources */
> +	switch (brom_call) {
> +	case SUNIV_BOOTED_FROM_MMC0:
> +		return SUNXI_BOOTED_FROM_MMC0;
> +	case SUNIV_BOOTED_FROM_SPI:
> +		return SUNXI_BOOTED_FROM_SPI;
> +	case SUNIV_BOOTED_FROM_MMC1:
> +		return SUNXI_BOOTED_FROM_MMC2;
> +	/* SPI nand is invalid try to boot from FEL*/
> +	case SUNIV_BOOTED_FROM_NAND:
> +		return SUNXI_INVALID_BOOT_SOURCE;
> +	}
> +	/* If we get here something went wrong try to boot from FEL.*/
> +	printf("Unknown boot source from BROM: 0x%x\n", brom_call);
> +	return SUNXI_INVALID_BOOT_SOURCE;
This just trys to boot from FEL doesn't hang.
> +}
> +
> +static uint32_t sunxi_get_boot_source(void)
>   {
>   	if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */
>   		return SUNXI_INVALID_BOOT_SOURCE;
This will return when booting from FEL.
>   
> -	return readb(SPL_ADDR + 0x28);
> +	if (IS_ENABLED(CONFIG_MACH_SUNIV))
> +		return suniv_get_boot_source();
> +	else
> +		return readb(SPL_ADDR + 0x28);
>   }
>   
>   /* The sunxi internal brom will try to loader external bootloader
> @@ -204,7 +229,7 @@ static int sunxi_get_boot_source(void)
>    */
>   uint32_t sunxi_get_boot_device(void)
>   {
> -	int boot_source = sunxi_get_boot_source();
> +	uint32_t boot_source = sunxi_get_boot_source();
>   
>   	/*
>   	 * When booting from the SD card or NAND memory, the "eGON.BT0"
> @@ -276,36 +301,10 @@ unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc,
>   	return sector;
>   }
>   
> -#ifdef CONFIG_MACH_SUNIV
> -/*
> - * The suniv BROM does not pass the boot media type to SPL, so we try with the
> - * boot sequence in BROM: mmc0->spinor->fail.
> - * TODO: This has the slight chance of being wrong (invalid SPL signature,
> - * but valid U-Boot legacy image on the SD card), but this should be rare.
> - * It looks like we can deduce from some BROM state upon entering the SPL
> - * (registers, SP, or stack itself) where the BROM was coming from and use
> - * that here.
> - */
> -void board_boot_order(u32 *spl_boot_list)
> -{
> -	/*
> -	 * See the comments above in sunxi_get_boot_device() for information
> -	 * about FEL boot.
> -	 */
> -	if (!is_boot0_magic(SPL_ADDR + 4)) {
> -		spl_boot_list[0] = BOOT_DEVICE_BOARD;
> -		return;
> -	}
> -
> -	spl_boot_list[0] = BOOT_DEVICE_MMC1;
> -	spl_boot_list[1] = BOOT_DEVICE_SPI;
> -}
> -#else
>   u32 spl_boot_device(void)
>   {
>   	return sunxi_get_boot_device();
>   }
> -#endif
>   
>   __weak void sunxi_sram_init(void)
>   {


More information about the U-Boot mailing list