Boards using boot metadata should not have to configure an unused fixed partition number. Make board-selected partitions an alternative to fixed numbers and partition types in the existing raw-location choice.
Keep the selection policies together so the MMC loader only has to select a partition and load it. Selection failures in dynamic mode must stop the MMC attempt instead of falling back to an unrelated filesystem partition. Existing fixed-number and partition-type fallback behavior is preserved. Distinguish shared partition-loading support from settings specific to partition-number modes. This keeps existing platform defaults and guards while allowing dynamic selection to use the same partition loader. The STM32 fixed override remains conditional on its static partition setting. Signed-off-by: Carlo Caione <[email protected]> --- arch/arm/mach-k3/r5/Kconfig | 4 +- arch/arm/mach-stm32mp/stm32mp1/spl.c | 2 +- common/spl/Kconfig | 13 +++++++ common/spl/spl_mmc.c | 73 +++++++++++++++++++++++++----------- include/part.h | 3 +- include/spl.h | 16 +++++--- 6 files changed, 80 insertions(+), 31 deletions(-) diff --git a/arch/arm/mach-k3/r5/Kconfig b/arch/arm/mach-k3/r5/Kconfig index 12335880e10..672c8a226df 100644 --- a/arch/arm/mach-k3/r5/Kconfig +++ b/arch/arm/mach-k3/r5/Kconfig @@ -35,7 +35,9 @@ config K3_SYSFW_IMAGE_MMCSD_RAW_MODE_SECT config K3_SYSFW_IMAGE_MMCSD_RAW_MODE_PART hex "MMC partition to load SYSFW firmware and configuration blob from" - depends on K3_LOAD_SYSFW && SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION + depends on K3_LOAD_SYSFW + depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION || \ + SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_DYNAMIC default 2 help Partition on the MMC to the combined System Firmware and configuration diff --git a/arch/arm/mach-stm32mp/stm32mp1/spl.c b/arch/arm/mach-stm32mp/stm32mp1/spl.c index 2229ebf5eeb..c1be468cb1d 100644 --- a/arch/arm/mach-stm32mp/stm32mp1/spl.c +++ b/arch/arm/mach-stm32mp/stm32mp1/spl.c @@ -61,7 +61,7 @@ u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device) return MMCSD_MODE_RAW; } -#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION +#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION int spl_mmc_boot_partition(struct mmc *mmc, const u32 boot_device) { switch (boot_device) { diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 0618f42c941..56375ef287d 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -574,8 +574,21 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE raw mode. U-Boot will be loaded from the first partition of this type to be found. +config SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_DYNAMIC + bool "MMC raw mode: by board-selected partition" + select SPL_LOAD_BLOCK + select SPL_PARTITIONS + help + Select the partition at runtime instead of using a fixed number. + The board must implement spl_mmc_boot_partition(). + endchoice +config SYS_MMCSD_RAW_MODE_U_BOOT_USE_ANY_PARTITION + def_bool SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION || \ + SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE || \ + SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_DYNAMIC + config SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR hex "Address on the MMC to load U-Boot from" depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index 3e637f5adbd..8f4df4104ca 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -106,18 +106,14 @@ static int spl_mmc_find_device(struct mmc **mmcp, int mmc_dev) return 0; } -#if defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION) || \ - defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE) -static int mmc_load_image_raw_partition(struct spl_image_info *spl_image, - struct spl_boot_device *bootdev, - struct mmc *mmc, int partition, - unsigned long sector) +#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_ANY_PARTITION +static int spl_mmc_select_partition(struct mmc *mmc, const u32 boot_device, + int *partition) { +#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE struct disk_partition info; - int ret; + int type_part, ret; -#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE - int type_part; /* Only support MBR so DOS_ENTRY_NUMBERS */ for (type_part = 1; type_part <= DOS_ENTRY_NUMBERS; type_part++) { ret = part_get_info(mmc_get_blk_desc(mmc), type_part, &info); @@ -125,11 +121,40 @@ static int mmc_load_image_raw_partition(struct spl_image_info *spl_image, continue; if (info.sys_ind == CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_TYPE) { - partition = type_part; + *partition = type_part; break; } } + + return 0; +#elif defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_DYNAMIC) + int ret; + + if (*partition != -1) + return 0; + + *partition = spl_mmc_boot_partition(mmc, boot_device); + if (*partition > 0) + return 0; + + ret = *partition < 0 ? *partition : -EINVAL; + printf("spl: partition selection failed: %d\n", ret); + return ret; +#else + if (*partition == -1) + *partition = spl_mmc_boot_partition(mmc, boot_device); + + return 0; #endif +} + +static int mmc_load_image_raw_partition(struct spl_image_info *spl_image, + struct spl_boot_device *bootdev, + struct mmc *mmc, int partition, + unsigned long sector) +{ + struct disk_partition info; + int ret; ret = part_get_info(mmc_get_blk_desc(mmc), partition, &info); if (ret) { @@ -300,10 +325,15 @@ u32 __weak spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device) return MMCSD_MODE_RAW; } -#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION +#if defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION) || \ + defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_DYNAMIC) int __weak spl_mmc_boot_partition(struct mmc *mmc, const u32 boot_device) { +#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION return CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION; +#else + return -ENOSYS; +#endif } #endif @@ -429,11 +459,10 @@ int spl_mmc_load(struct spl_image_info *spl_image, spl_mmc_raw_uboot_offset(part)); if (!ret) return 0; -#elif defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION) || \ - defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE) - if (IS_ENABLED(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION) && - raw_part == -1) - raw_part = spl_mmc_boot_partition(mmc, bootdev->boot_device); +#elif defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_ANY_PARTITION) + ret = spl_mmc_select_partition(mmc, bootdev->boot_device, &raw_part); + if (ret) + return ret; ret = mmc_load_image_raw_partition(spl_image, bootdev, mmc, raw_part, raw_sect); @@ -462,17 +491,19 @@ int spl_mmc_load(struct spl_image_info *spl_image, int spl_mmc_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { + int raw_part = 0; + + if (IS_ENABLED(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION) || + IS_ENABLED(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_DYNAMIC)) + raw_part = -1; + return spl_mmc_load(spl_image, bootdev, #ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME CONFIG_SPL_FS_LOAD_PAYLOAD_NAME, #else NULL, #endif -#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION - -1, -#else - 0, -#endif + raw_part, #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); #else diff --git a/include/part.h b/include/part.h index 15daacd7faa..5268216b46d 100644 --- a/include/part.h +++ b/include/part.h @@ -462,8 +462,7 @@ ulong disk_blk_erase(struct udevice *dev, lbaint_t start, lbaint_t blkcnt); # define part_print_ptr(x) NULL # if defined(CONFIG_SPL_FS_EXT4) || defined(CONFIG_SPL_FS_FAT) || \ defined(CONFIG_SPL_FS_SQUASHFS) || \ - defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION) || \ - defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE) + defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_ANY_PARTITION) # define part_get_info_ptr(x) x # else # define part_get_info_ptr(x) NULL diff --git a/include/spl.h b/include/spl.h index 08a84536f51..d05623caaf6 100644 --- a/include/spl.h +++ b/include/spl.h @@ -599,13 +599,17 @@ u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device); * @boot_device: ID of the device which the MMC driver wants to load * U-Boot from. * - * Called before loading U-Boot in raw partition mode, after any Falcon - * attempt. The hook may select the hardware area containing the image; - * it must leave that area selected. It may run for each MMC load attempt. + * Called in fixed-number or dynamic mode after any Falcon attempt. The + * incoming hardware area is not necessarily the user area. The hook must + * leave the image area selected for loading and any configured filesystem + * fallback; the loader does not restore it. It may run for each MMC attempt. * - * If not overridden, it is weakly defined in common/spl/spl_mmc.c. + * The default returns the configured partition, or -ENOSYS with + * CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_DYNAMIC. In dynamic mode, + * zero or a negative error aborts this MMC attempt without filesystem + * fallback; SPL may still try other boot devices. * - * Return: Partition number to load U-Boot from. + * Return: Partition number (positive in dynamic mode), or a negative error. */ int spl_mmc_boot_partition(struct mmc *mmc, const u32 boot_device); @@ -975,7 +979,7 @@ int spl_mmc_load_image(struct spl_image_info *spl_image, * @param bootdev Describes which device to load from * @param filename Name of file to load (in FS mode) * @param raw_part Partition to load from (in RAW mode), or -1 to call - * spl_mmc_boot_partition() in partition-number mode + * spl_mmc_boot_partition() in fixed-number or dynamic mode * @param raw_sect Sector to load from (in RAW mode) * * Return: 0 on success, otherwise error code -- 2.55.0
