diff options
Diffstat (limited to 'boot/bootmeth_efi.c')
-rw-r--r-- | boot/bootmeth_efi.c | 49 |
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); /* |