diff options
Diffstat (limited to 'boot')
-rw-r--r-- | boot/Kconfig | 22 | ||||
-rw-r--r-- | boot/Makefile | 5 | ||||
-rw-r--r-- | boot/bootdev-uclass.c | 16 | ||||
-rw-r--r-- | boot/bootflow.c | 23 | ||||
-rw-r--r-- | boot/bootmeth_efi.c | 70 | ||||
-rw-r--r-- | boot/vbe_request.c | 2 |
6 files changed, 107 insertions, 31 deletions
diff --git a/boot/Kconfig b/boot/Kconfig index ad035695a4a..d95a2a70266 100644 --- a/boot/Kconfig +++ b/boot/Kconfig @@ -411,7 +411,7 @@ config BOOTSTD_FULL as well as the "boot_targets" environment variable config SPL_BOOTSTD - bool "Standard boot support in VPL" + bool "Standard boot support in SPL" depends on SPL && SPL_DM && SPL_OF_CONTROL && SPL_BLK default y if VPL help @@ -537,6 +537,26 @@ config VPL_BOOTMETH_VBE if BOOTMETH_VBE +config BOOTMETH_VBE_REQUEST + bool "Support for serving VBE OS requests" + default y + help + Enables support for looking that the requests made by the + Operating System being booted. These requests result in additions to + the device tree /chosen node, added during the device tree fixup + phase. + +config SPL_BOOTMETH_VBE_REQUEST + bool "Support for serving VBE OS requests (SPL)" + depends on SPL + help + Enables support for looking that the requests made by the + Operating System being booted. These requests result in additions to + the device tree /chosen node, added during the device tree fixup + phase. + + This is only useful if you are booting an OS direct from SPL. + config BOOTMETH_VBE_SIMPLE bool "Bootdev support for VBE 'simple' method" default y diff --git a/boot/Makefile b/boot/Makefile index 5424b6fafcc..88193a1b60e 100644 --- a/boot/Makefile +++ b/boot/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_CMD_BOOTZ) += bootm.o bootm_os.o obj-$(CONFIG_CMD_BOOTI) += bootm.o bootm_os.o obj-$(CONFIG_PXE_UTILS) += pxe_utils.o +obj-$(CONFIG_QFW) += bootmeth_qfw.o endif @@ -26,7 +27,6 @@ obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += bootstd-uclass.o obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_DISTRO) += bootmeth_distro.o obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_DISTRO_PXE) += bootmeth_pxe.o obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_EFILOADER) += bootmeth_efi.o -obj-$(CONFIG_$(SPL_TPL_)QFW) += bootmeth_qfw.o obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_SANDBOX) += bootmeth_sandbox.o obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_SCRIPT) += bootmeth_script.o ifdef CONFIG_$(SPL_TPL_)BOOTSTD_FULL @@ -52,7 +52,8 @@ endif obj-$(CONFIG_$(SPL_TPL_)EXPO) += expo.o scene.o scene_menu.o -obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_VBE) += vbe.o vbe_request.o +obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_VBE) += vbe.o +obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_VBE_REQUEST) += vbe_request.o obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_VBE_SIMPLE) += vbe_simple.o obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_VBE_SIMPLE_FW) += vbe_simple_fw.o obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_VBE_SIMPLE_OS) += vbe_simple_os.o diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c index 8103a11d1bb..d34b7e37cf7 100644 --- a/boot/bootdev-uclass.c +++ b/boot/bootdev-uclass.c @@ -629,11 +629,11 @@ int bootdev_next_prio(struct bootflow_iter *iter, struct udevice **devp) if (++iter->cur_prio == BOOTDEVP_COUNT) return log_msg_ret("fin", -ENODEV); - if (iter->flags & BOOTFLOWF_HUNT) { + if (iter->flags & BOOTFLOWIF_HUNT) { /* hunt to find new bootdevs */ ret = bootdev_hunt_prio(iter->cur_prio, iter->flags & - BOOTFLOWF_SHOW); + BOOTFLOWIF_SHOW); log_debug("- hunt ret %d\n", ret); if (ret) return log_msg_ret("hun", ret); @@ -657,7 +657,7 @@ int bootdev_setup_iter(struct bootflow_iter *iter, const char *label, struct udevice **devp, int *method_flagsp) { struct udevice *bootstd, *dev = NULL; - bool show = iter->flags & BOOTFLOWF_SHOW; + bool show = iter->flags & BOOTFLOWIF_SHOW; int method_flags; int ret; @@ -668,7 +668,7 @@ int bootdev_setup_iter(struct bootflow_iter *iter, const char *label, } /* hunt for any pre-scan devices */ - if (iter->flags & BOOTFLOWF_HUNT) { + if (iter->flags & BOOTFLOWIF_HUNT) { ret = bootdev_hunt_prio(BOOTDEVP_1_PRE_SCAN, show); if (ret) return log_msg_ret("pre", ret); @@ -676,7 +676,7 @@ int bootdev_setup_iter(struct bootflow_iter *iter, const char *label, /* Handle scanning a single device */ if (IS_ENABLED(CONFIG_BOOTSTD_FULL) && label) { - if (iter->flags & BOOTFLOWF_HUNT) { + if (iter->flags & BOOTFLOWIF_HUNT) { ret = bootdev_hunt(label, show); if (ret) return log_msg_ret("hun", ret); @@ -687,11 +687,11 @@ int bootdev_setup_iter(struct bootflow_iter *iter, const char *label, log_debug("method_flags: %x\n", method_flags); if (method_flags & BOOTFLOW_METHF_SINGLE_UCLASS) - iter->flags |= BOOTFLOWF_SINGLE_UCLASS; + iter->flags |= BOOTFLOWIF_SINGLE_UCLASS; else if (method_flags & BOOTFLOW_METHF_SINGLE_DEV) - iter->flags |= BOOTFLOWF_SINGLE_DEV; + iter->flags |= BOOTFLOWIF_SINGLE_DEV; else - iter->flags |= BOOTFLOWF_SINGLE_MEDIA; + iter->flags |= BOOTFLOWIF_SINGLE_MEDIA; log_debug("Selected label: %s, flags %x\n", label, iter->flags); } else { bool ok; diff --git a/boot/bootflow.c b/boot/bootflow.c index 60791e681bd..8f2cb876bb4 100644 --- a/boot/bootflow.c +++ b/boot/bootflow.c @@ -139,8 +139,8 @@ static void bootflow_iter_set_dev(struct bootflow_iter *iter, if (dev && iter->num_devs < iter->max_devs) iter->dev_used[iter->num_devs++] = dev; - if ((iter->flags & (BOOTFLOWF_SHOW | BOOTFLOWF_SINGLE_DEV)) == - BOOTFLOWF_SHOW) { + if ((iter->flags & (BOOTFLOWIF_SHOW | BOOTFLOWIF_SINGLE_DEV)) == + BOOTFLOWIF_SHOW) { if (dev) printf("Scanning bootdev '%s':\n", dev->name); else if (IS_ENABLED(CONFIG_BOOTMETH_GLOBAL) && @@ -215,7 +215,7 @@ static int iter_incr(struct bootflow_iter *iter) iter->max_part = 0; /* ...select next bootdev */ - if (iter->flags & BOOTFLOWF_SINGLE_DEV) { + if (iter->flags & BOOTFLOWIF_SINGLE_DEV) { ret = -ENOENT; } else { int method_flags; @@ -227,7 +227,7 @@ static int iter_incr(struct bootflow_iter *iter) ret = bootdev_setup_iter(iter, NULL, &dev, &method_flags); } else if (IS_ENABLED(CONFIG_BOOTSTD_FULL) && - (iter->flags & BOOTFLOWF_SINGLE_UCLASS)) { + (iter->flags & BOOTFLOWIF_SINGLE_UCLASS)) { /* Move to the next bootdev in this uclass */ uclass_find_next_device(&dev); if (!dev) { @@ -236,7 +236,7 @@ static int iter_incr(struct bootflow_iter *iter) ret = -ENODEV; } } else if (IS_ENABLED(CONFIG_BOOTSTD_FULL) && - iter->flags & BOOTFLOWF_SINGLE_MEDIA) { + iter->flags & BOOTFLOWIF_SINGLE_MEDIA) { log_debug("next in single\n"); method_flags = 0; do { @@ -328,7 +328,7 @@ static int bootflow_check(struct bootflow_iter *iter, struct bootflow *bflow) * For 'all' we return all bootflows, even * those with errors */ - if (iter->flags & BOOTFLOWF_ALL) + if (iter->flags & BOOTFLOWIF_ALL) return log_msg_ret("all", ret); } if (ret) @@ -344,14 +344,14 @@ int bootflow_scan_first(struct udevice *dev, const char *label, int ret; if (dev || label) - flags |= BOOTFLOWF_SKIP_GLOBAL; + flags |= BOOTFLOWIF_SKIP_GLOBAL; bootflow_iter_init(iter, flags); /* * Set up the ordering of bootmeths. This sets iter->doing_global and * iter->first_glob_method if we are starting with the global bootmeths */ - ret = bootmeth_setup_iter_order(iter, !(flags & BOOTFLOWF_SKIP_GLOBAL)); + ret = bootmeth_setup_iter_order(iter, !(flags & BOOTFLOWIF_SKIP_GLOBAL)); if (ret) return log_msg_ret("obmeth", -ENODEV); @@ -373,7 +373,7 @@ int bootflow_scan_first(struct udevice *dev, const char *label, if (ret) { log_debug("check - ret=%d\n", ret); if (ret != BF_NO_MORE_PARTS && ret != -ENOSYS) { - if (iter->flags & BOOTFLOWF_ALL) + if (iter->flags & BOOTFLOWIF_ALL) return log_msg_ret("all", ret); } iter->err = ret; @@ -402,7 +402,7 @@ int bootflow_scan_next(struct bootflow_iter *iter, struct bootflow *bflow) return 0; iter->err = ret; if (ret != BF_NO_MORE_PARTS && ret != -ENOSYS) { - if (iter->flags & BOOTFLOWF_ALL) + if (iter->flags & BOOTFLOWIF_ALL) return log_msg_ret("all", ret); } } else { @@ -467,6 +467,9 @@ int bootflow_run_boot(struct bootflow_iter *iter, struct bootflow *bflow) printf("** Booting bootflow '%s' with %s\n", bflow->name, bflow->method->name); + if (IS_ENABLED(CONFIG_OF_HAS_PRIOR_STAGE) && + (bflow->flags & BOOTFLOWF_USE_PRIOR_FDT)) + printf("Using prior-stage device tree\n"); ret = bootflow_boot(bflow); if (!IS_ENABLED(CONFIG_BOOTSTD_FULL)) { printf("Boot failed (err=%d)\n", ret); diff --git a/boot/bootmeth_efi.c b/boot/bootmeth_efi.c index 67c972e3fe4..6a97ac02ff5 100644 --- a/boot/bootmeth_efi.c +++ b/boot/bootmeth_efi.c @@ -147,25 +147,60 @@ static int distro_efi_check(struct udevice *dev, struct bootflow_iter *iter) return 0; } -static void distro_efi_get_fdt_name(char *fname, int size) +/** + * distro_efi_get_fdt_name() - Get the filename for reading the .dtb file + * + * @fname: Place to put filename + * @size: Max size of filename + * @seq: Sequence number, to cycle through options (0=first) + * Returns: 0 on success, -ENOENT if the "fdtfile" env var does not exist, + * -EINVAL if there are no more options, -EALREADY if the control FDT should be + * used + */ +static int distro_efi_get_fdt_name(char *fname, int size, int seq) { const char *fdt_fname; + const char *prefix; + + /* select the prefix */ + switch (seq) { + case 0: + /* this is the default */ + prefix = "/dtb"; + break; + case 1: + prefix = ""; + break; + case 2: + prefix = "/dtb/current"; + break; + default: + return log_msg_ret("pref", -EINVAL); + } fdt_fname = env_get("fdtfile"); if (fdt_fname) { - snprintf(fname, size, "dtb/%s", fdt_fname); + snprintf(fname, size, "%s/%s", prefix, fdt_fname); log_debug("Using device tree: %s\n", fname); - } else { + } else if (IS_ENABLED(CONFIG_OF_HAS_PRIOR_STAGE)) { + strcpy(fname, "<prior>"); + return log_msg_ret("pref", -EALREADY); + /* Use this fallback only for 32-bit ARM */ + } else if (IS_ENABLED(CONFIG_ARM) && !IS_ENABLED(CONFIG_ARM64)) { const char *soc = env_get("soc"); const char *board = env_get("board"); const char *boardver = env_get("boardver"); /* cf the code in label_boot() which seems very complex */ - snprintf(fname, size, "dtb/%s%s%s%s.dtb", + snprintf(fname, size, "%s/%s%s%s%s.dtb", prefix, soc ? soc : "", soc ? "-" : "", board ? board : "", boardver ? boardver : ""); log_debug("Using default device tree: %s\n", fname); + } else { + return log_msg_ret("env", -ENOENT); } + + return 0; } static int distro_efi_read_bootflow_file(struct udevice *dev, @@ -174,7 +209,7 @@ static int distro_efi_read_bootflow_file(struct udevice *dev, struct blk_desc *desc = NULL; ulong fdt_addr, size; char fname[256]; - int ret; + int ret, seq; /* We require a partition table */ if (!bflow->part) @@ -196,13 +231,26 @@ static int distro_efi_read_bootflow_file(struct udevice *dev, if (ret) return log_msg_ret("read", -EINVAL); - distro_efi_get_fdt_name(fname, sizeof(fname)); + fdt_addr = env_get_hex("fdt_addr_r", 0); + + /* try the various available names */ + ret = -ENOENT; + for (seq = 0; ret; seq++) { + ret = distro_efi_get_fdt_name(fname, sizeof(fname), seq); + 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); + } + bflow->fdt_fname = strdup(fname); if (!bflow->fdt_fname) return log_msg_ret("fil", -ENOMEM); - fdt_addr = env_get_hex("fdt_addr_r", 0); - ret = bootmeth_common_read_file(dev, bflow, fname, fdt_addr, &size); if (!ret) { bflow->fdt_size = size; bflow->fdt_addr = fdt_addr; @@ -277,7 +325,11 @@ static int distro_efi_read_bootflow_net(struct bootflow *bflow) fdt_addr = hextoul(fdt_addr_str, NULL); sprintf(file_addr, "%lx", fdt_addr); - distro_efi_get_fdt_name(fname, sizeof(fname)); + /* We only allow the first prefix with PXE */ + ret = distro_efi_get_fdt_name(fname, sizeof(fname), 0); + if (ret) + return log_msg_ret("nam", ret); + bflow->fdt_fname = strdup(fname); if (!bflow->fdt_fname) return log_msg_ret("fil", -ENOMEM); diff --git a/boot/vbe_request.c b/boot/vbe_request.c index 45f1d2b7e17..312edfa2bdb 100644 --- a/boot/vbe_request.c +++ b/boot/vbe_request.c @@ -36,7 +36,7 @@ static int handle_random_req(ofnode node, int default_size, u32 size; int ret; - if (!CONFIG_IS_ENABLED(DM_RNG)) + if (!IS_ENABLED(CONFIG_DM_RNG)) return -ENOTSUPP; if (ofnode_read_u32(node, "vbe,size", &size)) { |