[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