@@ -1292,6 +1292,14 @@ config SPL_SATA_RAW_U_BOOT_SECTOR
Sector on the SATA disk to load U-Boot from, when the SATA disk is being
used in raw mode. Units: SATA disk sectors (1 sector = 512 bytes).
+config SPL_ESP_BOOT
+ bool "Load next stage boot image from the UEFI system partition"
+ default y if BOOT_DEFAULTS
+ select SPL_PARTITION_TYPE_GUID
+ help
+ When enabled, first try to boot from the UEFI system partition as
+ described in the Ch.4 of the EBBR specification.
+
config SPL_NVME
bool "NVM Express device support"
depends on BLK
@@ -10,12 +10,15 @@
#include <spl_load.h>
#include <image.h>
#include <fs.h>
+#include <part.h>
#include <asm/cache.h>
#include <asm/io.h>
struct blk_dev {
const char *ifname;
const char *filename;
+ int devnum;
+ int partnum;
char dev_part_str[8];
};
@@ -44,16 +47,37 @@ static ulong spl_fit_read(struct spl_load_info *load, ulong file_offset,
return actlen;
}
+static int spl_blk_file_size(struct blk_dev *dev, loff_t *filesize)
+{
+ int ret;
+
+ snprintf(dev->dev_part_str, sizeof(dev->dev_part_str) - 1, "%x:%x",
+ dev->devnum, dev->partnum);
+ debug("Loading file %s from %s %s\n", dev->filename, dev->ifname,
+ dev->dev_part_str);
+ ret = fs_set_blk_dev(dev->ifname, dev->dev_part_str, FS_TYPE_ANY);
+ if (ret) {
+ printf("spl: unable to set blk_dev %s %s. Err - %d\n",
+ dev->ifname, dev->dev_part_str, ret);
+ return ret;
+ }
+
+ ret = fs_size(dev->filename, filesize);
+ if (ret)
+ printf("spl: unable to get size, file: %s. Err - %d\n",
+ dev->filename, ret);
+ return ret;
+}
+
int spl_blk_load_image(struct spl_image_info *spl_image,
struct spl_boot_device *bootdev,
enum uclass_id uclass_id, int devnum, int partnum)
{
- const char *filename = CONFIG_SPL_FS_LOAD_PAYLOAD_NAME;
struct blk_desc *blk_desc;
loff_t filesize;
struct blk_dev dev;
struct spl_load_info load;
- int ret;
+ int ret, part;
blk_desc = blk_get_devnum_by_uclass_id(uclass_id, devnum);
if (!blk_desc) {
@@ -63,24 +87,28 @@ int spl_blk_load_image(struct spl_image_info *spl_image,
blk_show_device(uclass_id, devnum);
- dev.filename = filename;
+ dev.filename = CONFIG_SPL_FS_LOAD_PAYLOAD_NAME;
dev.ifname = blk_get_uclass_name(uclass_id);
- snprintf(dev.dev_part_str, sizeof(dev.dev_part_str) - 1, "%x:%x",
- devnum, partnum);
- ret = fs_set_blk_dev(dev.ifname, dev.dev_part_str, FS_TYPE_ANY);
- if (ret) {
- printf("spl: unable to set blk_dev %s %s. Err - %d\n",
- dev.ifname, dev.dev_part_str, ret);
- return ret;
+ dev.devnum = devnum;
+ /*
+ * First try to boot from EFI System partition. In case of failure,
+ * fall back to the configured partition.
+ */
+ if (IS_ENABLED(CONFIG_SPL_ESP_BOOT)) {
+ part = part_get_esp(blk_desc);
+ if (part) {
+ dev.partnum = part;
+ ret = spl_blk_file_size(&dev, &filesize);
+ if (!ret)
+ goto out;
+ }
}
- ret = fs_size(filename, &filesize);
- if (ret) {
- printf("spl: unable to get file size: %s. Err - %d\n",
- filename, ret);
+ dev.partnum = partnum;
+ ret = spl_blk_file_size(&dev, &filesize);
+ if (ret)
return ret;
- }
-
+out:
load.read = spl_fit_read;
if (IS_ENABLED(CONFIG_SPL_FS_FAT_DMA_ALIGN))
spl_set_bl_len(&load, ARCH_DMA_MINALIGN);
@@ -60,10 +60,10 @@ static ulong spl_fit_read(struct spl_load_info *load, ulong file_offset,
return actread;
}
-int spl_load_image_fat(struct spl_image_info *spl_image,
- struct spl_boot_device *bootdev,
- struct blk_desc *block_dev, int partition,
- const char *filename)
+int spl_load_image_fat_one(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev,
+ struct blk_desc *block_dev, int partition,
+ const char *filename)
{
int err;
loff_t size;
@@ -103,6 +103,32 @@ end:
return err;
}
+int spl_load_image_fat(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev,
+ struct blk_desc *block_dev, int partition,
+ const char *filename)
+{
+ int err, part;
+
+ /*
+ * First try to boot from EFI System partition. In case of failure,
+ * fall back to the configured partition.
+ */
+ if (IS_ENABLED(CONFIG_SPL_ESP_BOOT)) {
+ part = part_get_esp(block_dev);
+ if (part) {
+ err = spl_load_image_fat_one(spl_image, bootdev,
+ block_dev, part,
+ filename);
+ if (!err)
+ return err;
+ }
+ }
+
+ return spl_load_image_fat_one(spl_image, bootdev, block_dev,
+ partition, filename);
+}
+
#if CONFIG_IS_ENABLED(OS_BOOT)
int spl_load_image_fat_os(struct spl_image_info *spl_image,
struct spl_boot_device *bootdev,