[PATCH v2 03/14] spl: ufs: add partition-based U-Boot loading support
Balaji Selvanathan
balaji.selvanathan at oss.qualcomm.com
Sat Jun 6 12:18:34 CEST 2026
Refactor spl_ufs.c to support loading U-Boot either from a raw
sector offset or from a named/numbered partition, controlled by
the Kconfig choice introduced in the previous commit.
The monolithic spl_ufs_load_image() is split into helper functions:
ufs_load_image_raw_sector() handles sector-based loading, and
ufs_load_image_raw_partition() resolves the target sector by looking
up a partition name first, falling back to partition number. A new
exported spl_ufs_load() function drives the boot-mode switch and
can be reused by other callers. A weak spl_ufs_boot_mode() hook
allows board code to override the default raw boot mode.
Signed-off-by: Balaji Selvanathan <balaji.selvanathan at oss.qualcomm.com>
---
Changes in v2:
- Refactored the codes in common/spl/spl_ufs.c to use helper functions
to make the codes readable and clear
---
---
common/spl/spl_ufs.c | 153 ++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 134 insertions(+), 19 deletions(-)
diff --git a/common/spl/spl_ufs.c b/common/spl/spl_ufs.c
index cef1843f40f..0590b796267 100644
--- a/common/spl/spl_ufs.c
+++ b/common/spl/spl_ufs.c
@@ -3,15 +3,19 @@
* (C) Copyright 2025 Alexey Charkov <alchark at gmail.com>
*/
+#include <dm.h>
+#include <log.h>
#include <spl.h>
#include <spl_load.h>
#include <scsi.h>
-#include <errno.h>
-#include <image.h>
+#include <part.h>
+#include <blk.h>
#include <linux/compiler.h>
-#include <log.h>
+#include <errno.h>
-static ulong spl_ufs_load_read(struct spl_load_info *load, ulong off, ulong size, void *buf)
+/* Block read callback for spl_load framework */
+static ulong h_spl_load_read(struct spl_load_info *load, ulong off,
+ ulong size, void *buf)
{
struct blk_desc *bd = load->priv;
lbaint_t sector = off >> bd->log2blksz;
@@ -20,30 +24,141 @@ static ulong spl_ufs_load_read(struct spl_load_info *load, ulong off, ulong size
return blk_dread(bd, sector, count, buf) << bd->log2blksz;
}
-static int spl_ufs_load_image(struct spl_image_info *spl_image,
- struct spl_boot_device *bootdev)
+/* Load image from raw sector */
+static int ufs_load_image_raw_sector(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev,
+ struct blk_desc *bd,
+ unsigned long sector)
{
- unsigned long sector = CONFIG_SPL_UFS_RAW_U_BOOT_SECTOR;
- int devnum = CONFIG_SPL_UFS_RAW_U_BOOT_DEVNUM;
struct spl_load_info load;
+ int ret;
+
+ debug("spl: ufs: loading from sector 0x%lx\n", sector);
+
+ spl_load_init(&load, h_spl_load_read, bd, bd->blksz);
+ ret = spl_load(spl_image, bootdev, &load, 0, sector << bd->log2blksz);
+
+ if (ret) {
+ printf("%s: ufs block read error\n", __func__);
+ log_debug("(error=%d)\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/* Find and load from partition */
+static int ufs_load_image_raw_partition(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev,
+ struct blk_desc *bd)
+{
+ struct disk_partition part_info;
+ int ret;
+
+ /* Try partition name first if configured */
+#ifdef CONFIG_SPL_UFS_RAW_U_BOOT_PARTITION_NAME
+ if (strlen(CONFIG_SPL_UFS_RAW_U_BOOT_PARTITION_NAME) > 0) {
+ debug("spl: ufs: trying partition name '%s'\n",
+ CONFIG_SPL_UFS_RAW_U_BOOT_PARTITION_NAME);
+
+ ret = part_get_info_by_name(bd,
+ CONFIG_SPL_UFS_RAW_U_BOOT_PARTITION_NAME,
+ &part_info);
+ if (ret >= 0) {
+ debug("spl: ufs: found partition '%s' at 0x%lx\n",
+ CONFIG_SPL_UFS_RAW_U_BOOT_PARTITION_NAME,
+ (ulong)part_info.start);
+ return ufs_load_image_raw_sector(spl_image, bootdev, bd,
+ part_info.start);
+ }
+ debug("spl: ufs: partition name not found: %d\n", ret);
+ }
+#endif
+
+ /* Try partition number if configured */
+ if (IS_ENABLED(CONFIG_SPL_UFS_RAW_U_BOOT_PARTITION_NUM)) {
+ debug("spl: ufs: trying partition number %d\n",
+ CONFIG_SPL_UFS_RAW_U_BOOT_PARTITION_NUM);
+
+ ret = part_get_info(bd, CONFIG_SPL_UFS_RAW_U_BOOT_PARTITION_NUM,
+ &part_info);
+ if (ret >= 0) {
+ debug("spl: ufs: found partition %d at 0x%lx\n",
+ CONFIG_SPL_UFS_RAW_U_BOOT_PARTITION_NUM,
+ (ulong)part_info.start);
+ return ufs_load_image_raw_sector(spl_image, bootdev, bd,
+ part_info.start);
+ }
+ debug("spl: ufs: partition number not found: %d\n", ret);
+ }
+
+ puts("spl: ufs: partition error\n");
+ return -ENOENT;
+}
+
+u32 __weak spl_ufs_boot_mode(const u32 boot_device)
+{
+ return UFS_MODE_RAW;
+}
+
+int spl_ufs_load(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev,
+ const char *filename)
+{
+ u32 boot_mode;
+ int ret = 0;
+ int devnum = CONFIG_SPL_UFS_RAW_U_BOOT_DEVNUM;
struct blk_desc *bd;
- int err;
- /* try to recognize storage devices immediately */
- scsi_scan(false);
+ log_debug("spl: ufs: devnum=%d\n", devnum);
+
+ ret = scsi_scan(false);
+ if (ret) {
+ printf("spl: ufs: scsi scan failed: %d\n", ret);
+ return ret;
+ }
+
bd = blk_get_devnum_by_uclass_id(UCLASS_SCSI, devnum);
- if (!bd)
+ if (!bd) {
+ printf("spl: ufs: could not get device %d\n", devnum);
return -ENODEV;
+ }
+
+ boot_mode = spl_ufs_boot_mode(bootdev->boot_device);
+ ret = -EINVAL;
- spl_load_init(&load, spl_ufs_load_read, bd, bd->blksz);
- err = spl_load(spl_image, bootdev, &load, 0, sector << bd->log2blksz);
- if (err) {
- puts("spl_ufs_load_image: ufs block read error\n");
- log_debug("(error=%d)\n", err);
- return err;
+ switch (boot_mode) {
+ case UFS_MODE_RAW:
+ debug("spl: ufs: boot mode: raw\n");
+
+#ifdef CONFIG_SPL_UFS_RAW_U_BOOT_USE_SECTOR
+ ret = ufs_load_image_raw_sector(spl_image, bootdev, bd,
+ CONFIG_SPL_UFS_RAW_U_BOOT_SECTOR);
+ if (!ret)
+ return 0;
+#elif defined(CONFIG_SPL_UFS_RAW_U_BOOT_USE_PARTITION)
+ ret = ufs_load_image_raw_partition(spl_image, bootdev, bd);
+ if (!ret)
+ return 0;
+#endif
+ break;
+ default:
+ puts("spl: ufs: wrong boot mode\n");
}
- return 0;
+ return ret;
+}
+
+/* SPL load image entry point */
+static int spl_ufs_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ return spl_ufs_load(spl_image, bootdev,
+#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
+ CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
+#else
+ NULL);
+#endif
}
SPL_LOAD_IMAGE_METHOD("UFS", 0, BOOT_DEVICE_UFS, spl_ufs_load_image);
--
2.34.1
More information about the U-Boot
mailing list