summaryrefslogtreecommitdiff
path: root/boot/bootmeth_efi.c
diff options
context:
space:
mode:
Diffstat (limited to 'boot/bootmeth_efi.c')
-rw-r--r--boot/bootmeth_efi.c49
1 files changed, 31 insertions, 18 deletions
diff --git a/boot/bootmeth_efi.c b/boot/bootmeth_efi.c
index 6a97ac02ff5..6f70f2229b9 100644
--- a/boot/bootmeth_efi.c
+++ b/boot/bootmeth_efi.c
@@ -94,7 +94,7 @@ static int get_efi_pxe_vci(char *str, int max_len)
return 0;
}
-static int efiload_read_file(struct blk_desc *desc, struct bootflow *bflow)
+static void set_efi_bootdev(struct blk_desc *desc, struct bootflow *bflow)
{
const struct udevice *media_dev;
int size = bflow->size;
@@ -102,11 +102,6 @@ static int efiload_read_file(struct blk_desc *desc, struct bootflow *bflow)
char devnum_str[9];
char dirname[200];
char *last_slash;
- int ret;
-
- ret = bootmeth_alloc_file(bflow, 0x2000000, 0x10000);
- if (ret)
- return log_msg_ret("read", ret);
/*
* This is a horrible hack to tell EFI about this boot device. Once we
@@ -117,7 +112,9 @@ static int efiload_read_file(struct blk_desc *desc, struct bootflow *bflow)
* this can go away.
*/
media_dev = dev_get_parent(bflow->dev);
- snprintf(devnum_str, sizeof(devnum_str), "%x", dev_seq(media_dev));
+ snprintf(devnum_str, sizeof(devnum_str), "%x:%x",
+ desc ? desc->devnum : dev_seq(media_dev),
+ bflow->part);
strlcpy(dirname, bflow->fname, sizeof(dirname));
last_slash = strrchr(dirname, '/');
@@ -130,6 +127,15 @@ static int efiload_read_file(struct blk_desc *desc, struct bootflow *bflow)
dev_name = device_get_uclass_id(media_dev) == UCLASS_MASS_STORAGE ?
"usb" : dev_get_uclass_name(media_dev);
efi_set_bootdev(dev_name, devnum_str, bflow->fname, bflow->buf, size);
+}
+
+static int efiload_read_file(struct blk_desc *desc, struct bootflow *bflow)
+{
+ int ret;
+
+ ret = bootmeth_alloc_file(bflow, 0x2000000, 0x10000);
+ if (ret)
+ return log_msg_ret("read", ret);
return 0;
}
@@ -235,21 +241,21 @@ static int distro_efi_read_bootflow_file(struct udevice *dev,
/* try the various available names */
ret = -ENOENT;
- for (seq = 0; ret; seq++) {
+ *fname = '\0';
+ for (seq = 0; ret == -ENOENT; seq++) {
ret = distro_efi_get_fdt_name(fname, sizeof(fname), seq);
- if (ret == -EALREADY) {
+ if (ret == -EALREADY)
bflow->flags = BOOTFLOWF_USE_PRIOR_FDT;
- break;
- }
- if (ret)
- return log_msg_ret("nam", ret);
- ret = bootmeth_common_read_file(dev, bflow, fname, fdt_addr,
- &size);
+ if (!ret)
+ ret = bootmeth_common_read_file(dev, bflow, fname,
+ fdt_addr, &size);
}
- bflow->fdt_fname = strdup(fname);
- if (!bflow->fdt_fname)
- return log_msg_ret("fil", -ENOMEM);
+ if (*fname) {
+ bflow->fdt_fname = strdup(fname);
+ if (!bflow->fdt_fname)
+ return log_msg_ret("fil", -ENOMEM);
+ }
if (!ret) {
bflow->fdt_size = size;
@@ -373,6 +379,13 @@ int distro_efi_boot(struct udevice *dev, struct bootflow *bflow)
/* A non-zero buffer indicates the kernel is there */
if (bflow->buf) {
+ /* Set the EFI bootdev again, since reading an FDT loses it! */
+ if (bflow->blk) {
+ struct blk_desc *desc = dev_get_uclass_plat(bflow->blk);
+
+ set_efi_bootdev(desc, bflow);
+ }
+
kernel = (ulong)map_to_sysmem(bflow->buf);
/*