[PATCH 00/13] bootstd: Update ARM QEMU for standard boot and environment

This series fixes a few reported problems with virtio block-device handling.
It also moves QEMU over to use standard boot on ARM, by adding a suitable bootdev and bootmeth for qfw.
Finally, it moves the boards to use a text-based environment. The only remaining item in the config.h header file is CFG_SYS_SDRAM_BASE so it would be nice to move that to Kconfig, if possible.
Simon Glass (13): log: Add a category for filesystems virtio: Add some debugging bootstd: Allow enabling BOOTSTD_FULL without needing EXPO bootstd: Probe the block device before use bootstd: Correct virtio block-device handling bootstd: Add some default filesystems and commands qemu: Update qfw command to use addresses qemu: Move qfw kernel setup into a common file qemu: Add a bootdev for qfw qemu: Add a bootmeth for qfw arm: qemu: Switch to standard boot arm: qemu: Switch to a text environment arm: qemu: Move GUIDs to the C file
board/emulation/qemu-arm/qemu-arm.c | 10 +++ board/emulation/qemu-arm/qemu-arm.env | 12 +++ boot/Kconfig | 28 +++++++ boot/Makefile | 5 +- boot/bootdev-uclass.c | 3 + boot/bootflow.c | 6 +- boot/bootmeth_qfw.c | 102 ++++++++++++++++++++++++++ cmd/bootflow.c | 21 ++++-- cmd/qfw.c | 89 +++------------------- common/log.c | 1 + common/qfw.c | 66 ++++++++++++++++- configs/qemu_arm64_defconfig | 5 +- configs/qemu_arm_defconfig | 5 +- configs/tools-only_defconfig | 1 + doc/develop/bootstd.rst | 4 + drivers/misc/qfw.c | 87 ++++++++++++++++++++++ drivers/virtio/virtio-uclass.c | 8 +- drivers/virtio/virtio_blk.c | 7 ++ fs/fat/fat_write.c | 2 + include/configs/qemu-arm.h | 75 ------------------- include/log.h | 2 + include/qfw.h | 13 ++++ test/boot/bootdev.c | 25 ++++--- test/boot/bootstd_common.h | 2 +- 24 files changed, 398 insertions(+), 181 deletions(-) create mode 100644 board/emulation/qemu-arm/qemu-arm.env create mode 100644 boot/bootmeth_qfw.c

Sometimes it is useful to log things related to filesystems. Add a new category and place it at the top of one of the FAT files.
Signed-off-by: Simon Glass sjg@chromium.org ---
common/log.c | 1 + fs/fat/fat_write.c | 2 ++ include/log.h | 2 ++ 3 files changed, 5 insertions(+)
diff --git a/common/log.c b/common/log.c index 57b71ed1b36..7cfc49bc28a 100644 --- a/common/log.c +++ b/common/log.c @@ -30,6 +30,7 @@ static const char *const log_cat_name[] = { "acpi", "boot", "event", + "fs", };
_Static_assert(ARRAY_SIZE(log_cat_name) == LOGC_COUNT - LOGC_NONE, diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c index 8ff2f6def08..00541ebc3a4 100644 --- a/fs/fat/fat_write.c +++ b/fs/fat/fat_write.c @@ -5,6 +5,8 @@ * R/W (V)FAT 12/16/32 filesystem implementation by Donggeun Kim */
+#define LOG_CATEGORY LOGC_FS + #include <common.h> #include <command.h> #include <config.h> diff --git a/include/log.h b/include/log.h index 8a7b961bbfb..3bab40b6171 100644 --- a/include/log.h +++ b/include/log.h @@ -100,6 +100,8 @@ enum log_category_t { LOGC_BOOT, /** @LOGC_EVENT: Related to event and event handling */ LOGC_EVENT, + /** @LOGC_FS: Related to filesystems */ + LOGC_FS, /** @LOGC_COUNT: Number of log categories */ LOGC_COUNT, /** @LOGC_END: Sentinel value for lists of log categories */

On Sat, Jan 28, 2023 at 03:00:16PM -0700, Simon Glass wrote:
Sometimes it is useful to log things related to filesystems. Add a new category and place it at the top of one of the FAT files.
Signed-off-by: Simon Glass sjg@chromium.org
Applied to u-boot/master, thanks!

When QEMU does not respond for some reason, it is helpful to have debugging info to show. Add some.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/virtio/virtio_blk.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/virtio/virtio_blk.c b/drivers/virtio/virtio_blk.c index 30cfc56725c..95810582867 100644 --- a/drivers/virtio/virtio_blk.c +++ b/drivers/virtio/virtio_blk.c @@ -4,6 +4,8 @@ * Copyright (C) 2018, Bin Meng bmeng.cn@gmail.com */
+#define LOG_CATEGORY UCLASS_VIRTIO + #include <common.h> #include <blk.h> #include <dm.h> @@ -42,6 +44,8 @@ static ulong virtio_blk_do_req(struct udevice *dev, u64 sector, sgs[num_out + num_in++] = &data_sg;
sgs[num_out + num_in++] = &status_sg; + log_debug("dev=%s, active=%d, priv=%p, priv->vq=%p\n", dev->name, + device_active(dev), priv, priv->vq);
ret = virtqueue_add(priv->vq, sgs, num_out, num_in); if (ret) @@ -49,8 +53,10 @@ static ulong virtio_blk_do_req(struct udevice *dev, u64 sector,
virtqueue_kick(priv->vq);
+ log_debug("wait..."); while (!virtqueue_get_buf(priv->vq, NULL)) ; + log_debug("done\n");
return status == VIRTIO_BLK_S_OK ? blkcnt : -EIO; } @@ -58,6 +64,7 @@ static ulong virtio_blk_do_req(struct udevice *dev, u64 sector, static ulong virtio_blk_read(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *buffer) { + log_debug("read %s\n", dev->name); return virtio_blk_do_req(dev, start, blkcnt, buffer, VIRTIO_BLK_T_IN); }

On Sat, Jan 28, 2023 at 03:00:17PM -0700, Simon Glass wrote:
When QEMU does not respond for some reason, it is helpful to have debugging info to show. Add some.
Signed-off-by: Simon Glass sjg@chromium.org
Applied to u-boot/master, thanks!

It is sometimes useful to have one without the other, e.g. on a device without a display, since at present the expo feature requires CONFIG_VIDEO to be enabled.
Update the Makefile and bootflow command to support this, as well as the EXPO dependency.
Signed-off-by: Simon Glass sjg@chromium.org ---
boot/Kconfig | 1 + boot/Makefile | 4 ++-- cmd/bootflow.c | 21 +++++++++++++-------- 3 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/boot/Kconfig b/boot/Kconfig index fdcfbae7b2c..98e194fc2b2 100644 --- a/boot/Kconfig +++ b/boot/Kconfig @@ -561,6 +561,7 @@ endif # BOOTMETH_VBE
config EXPO bool "Support for expos - groups of scenes displaying a UI" + depends on VIDEO default y if BOOTMETH_VBE help An expo is a way of presenting and collecting information from the diff --git a/boot/Makefile b/boot/Makefile index f990e66f522..43baf2b89b3 100644 --- a/boot/Makefile +++ b/boot/Makefile @@ -30,7 +30,7 @@ obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_SANDBOX) += bootmeth_sandbox.o obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_SCRIPT) += bootmeth_script.o ifdef CONFIG_$(SPL_TPL_)BOOTSTD_FULL obj-$(CONFIG_$(SPL_TPL_)CMD_BOOTEFI_BOOTMGR) += bootmeth_efi_mgr.o -obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += bootflow_menu.o +obj-$(CONFIG_$(SPL_TPL_)EXPO) += bootflow_menu.o endif
obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += image-fdt.o @@ -48,7 +48,7 @@ ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SPL_LOAD_FIT) += common_fit.o endif
-obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_VBE) += expo.o scene.o scene_menu.o +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_SIMPLE) += vbe_simple.o diff --git a/cmd/bootflow.c b/cmd/bootflow.c index 692bc6d117f..3548bbb6830 100644 --- a/cmd/bootflow.c +++ b/cmd/bootflow.c @@ -394,15 +394,20 @@ static int do_bootflow_menu(struct cmd_tbl *cmdtp, int flag, int argc, if (ret) return CMD_RET_FAILURE;
- ret = bootflow_menu_run(std, text_mode, &bflow); - if (ret) { - if (ret == -EAGAIN) - printf("Nothing chosen\n"); - else - printf("Menu failed (err=%d)\n", ret); - - return CMD_RET_FAILURE; + if (IS_ENABLED(CONFIG_EXPO)) { + ret = bootflow_menu_run(std, text_mode, &bflow); + if (ret) { + if (ret == -EAGAIN) + printf("Nothing chosen\n"); + else + printf("Menu failed (err=%d)\n", ret); + } + } else { + printf("Menu not supported\n"); + ret = -ENOSYS; } + if (ret) + return CMD_RET_FAILURE;
printf("Selected: %s\n", bflow->os_name ? bflow->os_name : bflow->name); std->cur_bootflow = bflow;

On Sat, Jan 28, 2023 at 03:00:18PM -0700, Simon Glass wrote:
It is sometimes useful to have one without the other, e.g. on a device without a display, since at present the expo feature requires CONFIG_VIDEO to be enabled.
Update the Makefile and bootflow command to support this, as well as the EXPO dependency.
Signed-off-by: Simon Glass sjg@chromium.org
Applied to u-boot/master, thanks!

In some cases the block device is obtained but is not probed, since it is a sibling of the bootdev. Make sure it is probed, so it can be used without any trouble.
This fixes a bug with virtio, where the device is accessed before it has been set up by the virtio uclass.
Signed-off-by: Simon Glass sjg@chromium.org Fixes: 201417d700a ("bootstd: Add the bootdev uclass") Reported-by: Ilias Apalodimas ilias.apalodimas@linaro.org ---
boot/bootdev-uclass.c | 3 +++ boot/bootflow.c | 4 ++++ 2 files changed, 7 insertions(+)
diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c index 99ee08e3353..8103a11d1bb 100644 --- a/boot/bootdev-uclass.c +++ b/boot/bootdev-uclass.c @@ -309,6 +309,9 @@ int bootdev_get_sibling_blk(struct udevice *dev, struct udevice **blkp) if (ret) return log_msg_ret("find", ret); } + ret = device_probe(blk); + if (ret) + return log_msg_ret("act", ret); *blkp = blk;
return 0; diff --git a/boot/bootflow.c b/boot/bootflow.c index dc3f1f0c731..b8fa37ee2a0 100644 --- a/boot/bootflow.c +++ b/boot/bootflow.c @@ -270,6 +270,10 @@ static int iter_incr(struct bootflow_iter *iter) if (ret) { bootflow_iter_set_dev(iter, NULL, 0); } else { + /* + * Probe the bootdev. This does not probe any attached + * block device, since they are siblings + */ ret = device_probe(dev); log_debug("probe %s %d\n", dev->name, ret); if (!log_msg_ret("probe", ret))

On Sat, Jan 28, 2023 at 03:00:19PM -0700, Simon Glass wrote:
In some cases the block device is obtained but is not probed, since it is a sibling of the bootdev. Make sure it is probed, so it can be used without any trouble.
This fixes a bug with virtio, where the device is accessed before it has been set up by the virtio uclass.
Signed-off-by: Simon Glass sjg@chromium.org Fixes: 201417d700a ("bootstd: Add the bootdev uclass") Reported-by: Ilias Apalodimas ilias.apalodimas@linaro.org
Applied to u-boot/master, thanks!

At present virtio tries to attach QEMU services to a bootdev device, which cannot work. Add a check for this.
Also use bootdev_setup_sibling_blk() to create the bootdev device, since it allows the correct name to be used and bootdev_get_sibling_blk() to work as expected.
The bootdev is not created on sandbox since it does have a real virtio device and it is not possible to read blocks.
Signed-off-by: Simon Glass sjg@chromium.org Fixes: a60f7a3e35b ("bootstd: Add a virtio bootdev") Reported-by: Ilias Apalodimas ilias.apalodimas@linaro.org ---
drivers/virtio/virtio-uclass.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/virtio/virtio-uclass.c b/drivers/virtio/virtio-uclass.c index 91af412ec1d..de9bc90359c 100644 --- a/drivers/virtio/virtio-uclass.c +++ b/drivers/virtio/virtio-uclass.c @@ -247,8 +247,8 @@ static int virtio_uclass_post_probe(struct udevice *udev) } device_set_name_alloced(vdev);
- if (uc_priv->device == VIRTIO_ID_BLOCK) { - ret = bootdev_setup_for_dev(udev, name); + if (uc_priv->device == VIRTIO_ID_BLOCK && !IS_ENABLED(CONFIG_SANDBOX)) { + ret = bootdev_setup_sibling_blk(vdev, "virtio_bootdev"); if (ret) return log_msg_ret("bootdev", ret); } @@ -275,6 +275,10 @@ static int virtio_uclass_child_pre_probe(struct udevice *vdev) int i; int ret;
+ /* bootdevs are not virtio devices */ + if (device_get_uclass_id(vdev) == UCLASS_BOOTDEV) + return 0; + /* * Save the real virtio device (eg: virtio-net, virtio-blk) to * the transport (parent) device's uclass priv for future use.

On Sat, Jan 28, 2023 at 03:00:20PM -0700, Simon Glass wrote:
At present virtio tries to attach QEMU services to a bootdev device, which cannot work. Add a check for this.
Also use bootdev_setup_sibling_blk() to create the bootdev device, since it allows the correct name to be used and bootdev_get_sibling_blk() to work as expected.
The bootdev is not created on sandbox since it does have a real virtio device and it is not possible to read blocks.
Signed-off-by: Simon Glass sjg@chromium.org Fixes: a60f7a3e35b ("bootstd: Add a virtio bootdev") Reported-by: Ilias Apalodimas ilias.apalodimas@linaro.org
Applied to u-boot/master, thanks!

We need to support a basic set of filesystems for booting to work in most cases. Add these in via a new option, letting the board disable them individually (for space reasons) if desired.
This enables the filesystem commands as well as the actual functionality, even though bootstd is quite happy to use ext4 without the ext4 command. Further work would be needed to disintangle this and reduce code size.
Add several other options as well, providing sensible defaults.
We cannot enable this by default, since it expands the size of many boards quite a lot.
Signed-off-by: Simon Glass sjg@chromium.org ---
boot/Kconfig | 27 +++++++++++++++++++++++++++ configs/tools-only_defconfig | 1 + doc/develop/bootstd.rst | 4 ++++ 3 files changed, 32 insertions(+)
diff --git a/boot/Kconfig b/boot/Kconfig index 98e194fc2b2..5f491625c82 100644 --- a/boot/Kconfig +++ b/boot/Kconfig @@ -406,6 +406,33 @@ config VPL_BOOTSTD
if BOOTSTD
+config BOOTSTD_DEFAULTS + bool "Select some common defaults for standard boot" + depends on BOOTSTD + imply USE_BOOTCOMMAND + # Bring in some defaults which are generally needed. Boards can drop + # these as needed to save code space. Bootstd does not generally require + # the commands themselves to be enabled, but this is how some of the + # functionality is controlled at present + imply CMD_EXT2 + imply CMD_EXT4 + imply CMD_FAT + imply CMD_FS_GENERIC + imply CMD_PART + imply CMD_DHCP if NET + imply CMD_MII if NET + imply CMD_PING if NET + imply CMD_PXE if NET + imply USB_STORAGE + imply SUPPORT_RAW_INITRD + imply ENV_VARS_UBOOT_CONFIG + imply EFI_PARTITION + imply ISO_PARTITION + help + These are not required but are commonly needed to support a good + selection of booting methods. Enable this to improve the capability + of U-Boot to boot various images. + config BOOTSTD_BOOTCOMMAND bool "Use bootstd to boot" default y if !DISTRO_DEFAULTS diff --git a/configs/tools-only_defconfig b/configs/tools-only_defconfig index 23e1f0e9dba..88a94ddd6b0 100644 --- a/configs/tools-only_defconfig +++ b/configs/tools-only_defconfig @@ -12,6 +12,7 @@ CONFIG_FIT_SIGNATURE=y # CONFIG_BOOTMETH_VBE is not set CONFIG_USE_BOOTCOMMAND=y CONFIG_BOOTCOMMAND="run distro_bootcmd" +# CONFIG_AVB_VERIFY is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_BOOTM is not set # CONFIG_CMD_ELF is not set diff --git a/doc/develop/bootstd.rst b/doc/develop/bootstd.rst index 281aabf74b2..dabe987c0dc 100644 --- a/doc/develop/bootstd.rst +++ b/doc/develop/bootstd.rst @@ -396,6 +396,10 @@ To enable all feature sof standard boot, use `CONFIG_BOOTSTD_FULL`. This includes the full set of commands, more error messages when things go wrong and bootmeth ordering with the bootmeths environment variable.
+You should probably also enable `CONFIG_BOOTSTD_DEFAULTS`, which provides +several filesystem and network features (if `CONFIG_NET` is enabled) so that +a good selection of boot options is available. +
Available bootmeth drivers --------------------------

On Sat, Jan 28, 2023 at 03:00:21PM -0700, Simon Glass wrote:
We need to support a basic set of filesystems for booting to work in most cases. Add these in via a new option, letting the board disable them individually (for space reasons) if desired.
This enables the filesystem commands as well as the actual functionality, even though bootstd is quite happy to use ext4 without the ext4 command. Further work would be needed to disintangle this and reduce code size.
Add several other options as well, providing sensible defaults.
We cannot enable this by default, since it expands the size of many boards quite a lot.
Signed-off-by: Simon Glass sjg@chromium.org
Applied to u-boot/master, thanks!

This uses casts all over the place. Use the correct type so that these can be avoided, as is done with other commands. Also simplify a few conditionals.
Signed-off-by: Simon Glass sjg@chromium.org ---
cmd/qfw.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-)
diff --git a/cmd/qfw.c b/cmd/qfw.c index 0c49c6074e1..8837911d99f 100644 --- a/cmd/qfw.c +++ b/cmd/qfw.c @@ -7,6 +7,7 @@ #include <command.h> #include <env.h> #include <errno.h> +#include <mapmem.h> #include <qfw.h> #include <dm.h>
@@ -17,7 +18,7 @@ static struct udevice *qfw_dev; * to 'load_addr', initrd to 'initrd_addr' and kernel command * line using qemu fw_cfg interface. */ -static int qemu_fwcfg_cmd_setup_kernel(void *load_addr, void *initrd_addr) +int qemu_fwcfg_cmd_setup_kernel(ulong load_addr, ulong initrd_addr) { char *data_addr; uint32_t setup_size, kernel_size, cmdline_size, initrd_size; @@ -25,13 +26,13 @@ static int qemu_fwcfg_cmd_setup_kernel(void *load_addr, void *initrd_addr) qfw_read_entry(qfw_dev, FW_CFG_SETUP_SIZE, 4, &setup_size); qfw_read_entry(qfw_dev, FW_CFG_KERNEL_SIZE, 4, &kernel_size);
- if (kernel_size == 0) { + if (!kernel_size) { printf("fatal: no kernel available\n"); - return CMD_RET_FAILURE; + return -ENOENT; }
- data_addr = load_addr; - if (setup_size != 0) { + data_addr = map_sysmem(load_addr, 0); + if (setup_size) { qfw_read_entry(qfw_dev, FW_CFG_SETUP_DATA, le32_to_cpu(setup_size), data_addr); data_addr += le32_to_cpu(setup_size); @@ -42,9 +43,9 @@ static int qemu_fwcfg_cmd_setup_kernel(void *load_addr, void *initrd_addr) data_addr += le32_to_cpu(kernel_size); env_set_hex("filesize", le32_to_cpu(kernel_size));
- data_addr = initrd_addr; + data_addr = map_sysmem(initrd_addr, 0); qfw_read_entry(qfw_dev, FW_CFG_INITRD_SIZE, 4, &initrd_size); - if (initrd_size == 0) { + if (!initrd_size) { printf("warning: no initrd available\n"); } else { qfw_read_entry(qfw_dev, FW_CFG_INITRD_DATA, @@ -61,17 +62,16 @@ static int qemu_fwcfg_cmd_setup_kernel(void *load_addr, void *initrd_addr) * if kernel cmdline only contains '\0', (e.g. no -append * when invoking qemu), do not update bootargs */ - if (*data_addr != '\0') { + if (*data_addr) { if (env_set("bootargs", data_addr) < 0) printf("warning: unable to change bootargs\n"); } }
- printf("loading kernel to address %p size %x", load_addr, + printf("loading kernel to address %lx size %x", load_addr, le32_to_cpu(kernel_size)); if (initrd_size) - printf(" initrd %p size %x\n", - initrd_addr, + printf(" initrd %lx size %x\n", initrd_addr, le32_to_cpu(initrd_size)); else printf("\n"); @@ -119,28 +119,28 @@ static int qemu_fwcfg_do_load(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { char *env; - void *load_addr; - void *initrd_addr; + ulong load_addr; + ulong initrd_addr;
env = env_get("loadaddr"); load_addr = env ? - (void *)hextoul(env, NULL) : - (void *)CONFIG_SYS_LOAD_ADDR; + hextoul(env, NULL) : + CONFIG_SYS_LOAD_ADDR;
env = env_get("ramdiskaddr"); initrd_addr = env ? - (void *)hextoul(env, NULL) : + hextoul(env, NULL) : #ifdef CFG_RAMDISK_ADDR - (void *)CFG_RAMDISK_ADDR; + CFG_RAMDISK_ADDR; #else - NULL; + 0; #endif
if (argc == 2) { - load_addr = (void *)hextoul(argv[0], NULL); - initrd_addr = (void *)hextoul(argv[1], NULL); + load_addr = hextoul(argv[0], NULL); + initrd_addr = hextoul(argv[1], NULL); } else if (argc == 1) { - load_addr = (void *)hextoul(argv[0], NULL); + load_addr = hextoul(argv[0], NULL); }
if (!load_addr || !initrd_addr) {

On Sat, Jan 28, 2023 at 03:00:22PM -0700, Simon Glass wrote:
This uses casts all over the place. Use the correct type so that these can be avoided, as is done with other commands. Also simplify a few conditionals.
Signed-off-by: Simon Glass sjg@chromium.org
Applied to u-boot/master, thanks!

This is currently in the cmd/ file but we want to call it from a driver. Move it into a common place. Tidy up the header-file order while we are here.
Signed-off-by: Simon Glass sjg@chromium.org ---
cmd/qfw.c | 69 +-------------------------------------------------- common/qfw.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++- include/qfw.h | 13 ++++++++++ 3 files changed, 79 insertions(+), 69 deletions(-)
diff --git a/cmd/qfw.c b/cmd/qfw.c index 8837911d99f..ae3c6a7a84e 100644 --- a/cmd/qfw.c +++ b/cmd/qfw.c @@ -7,78 +7,11 @@ #include <command.h> #include <env.h> #include <errno.h> -#include <mapmem.h> #include <qfw.h> #include <dm.h>
static struct udevice *qfw_dev;
-/* - * This function prepares kernel for zboot. It loads kernel data - * to 'load_addr', initrd to 'initrd_addr' and kernel command - * line using qemu fw_cfg interface. - */ -int qemu_fwcfg_cmd_setup_kernel(ulong load_addr, ulong initrd_addr) -{ - char *data_addr; - uint32_t setup_size, kernel_size, cmdline_size, initrd_size; - - qfw_read_entry(qfw_dev, FW_CFG_SETUP_SIZE, 4, &setup_size); - qfw_read_entry(qfw_dev, FW_CFG_KERNEL_SIZE, 4, &kernel_size); - - if (!kernel_size) { - printf("fatal: no kernel available\n"); - return -ENOENT; - } - - data_addr = map_sysmem(load_addr, 0); - if (setup_size) { - qfw_read_entry(qfw_dev, FW_CFG_SETUP_DATA, - le32_to_cpu(setup_size), data_addr); - data_addr += le32_to_cpu(setup_size); - } - - qfw_read_entry(qfw_dev, FW_CFG_KERNEL_DATA, - le32_to_cpu(kernel_size), data_addr); - data_addr += le32_to_cpu(kernel_size); - env_set_hex("filesize", le32_to_cpu(kernel_size)); - - data_addr = map_sysmem(initrd_addr, 0); - qfw_read_entry(qfw_dev, FW_CFG_INITRD_SIZE, 4, &initrd_size); - if (!initrd_size) { - printf("warning: no initrd available\n"); - } else { - qfw_read_entry(qfw_dev, FW_CFG_INITRD_DATA, - le32_to_cpu(initrd_size), data_addr); - data_addr += le32_to_cpu(initrd_size); - env_set_hex("filesize", le32_to_cpu(initrd_size)); - } - - qfw_read_entry(qfw_dev, FW_CFG_CMDLINE_SIZE, 4, &cmdline_size); - if (cmdline_size) { - qfw_read_entry(qfw_dev, FW_CFG_CMDLINE_DATA, - le32_to_cpu(cmdline_size), data_addr); - /* - * if kernel cmdline only contains '\0', (e.g. no -append - * when invoking qemu), do not update bootargs - */ - if (*data_addr) { - if (env_set("bootargs", data_addr) < 0) - printf("warning: unable to change bootargs\n"); - } - } - - printf("loading kernel to address %lx size %x", load_addr, - le32_to_cpu(kernel_size)); - if (initrd_size) - printf(" initrd %lx size %x\n", initrd_addr, - le32_to_cpu(initrd_size)); - else - printf("\n"); - - return 0; -} - static int qemu_fwcfg_cmd_list_firmware(void) { int ret; @@ -148,7 +81,7 @@ static int qemu_fwcfg_do_load(struct cmd_tbl *cmdtp, int flag, return CMD_RET_FAILURE; }
- return qemu_fwcfg_cmd_setup_kernel(load_addr, initrd_addr); + return qemu_fwcfg_setup_kernel(qfw_dev, load_addr, initrd_addr); }
static struct cmd_tbl fwcfg_commands[] = { diff --git a/common/qfw.c b/common/qfw.c index 90cbb8c5dd4..45e87d3ae28 100644 --- a/common/qfw.c +++ b/common/qfw.c @@ -5,9 +5,11 @@ */
#include <dm.h> -#include <dm/uclass.h> +#include <env.h> +#include <mapmem.h> #include <qfw.h> #include <stdlib.h> +#include <dm/uclass.h>
int qfw_get_dev(struct udevice **devp) { @@ -102,3 +104,65 @@ bool qfw_file_iter_end(struct fw_cfg_file_iter *iter) { return iter->entry == iter->end; } + +int qemu_fwcfg_setup_kernel(struct udevice *qfw_dev, ulong load_addr, + ulong initrd_addr) +{ + char *data_addr; + u32 setup_size, kernel_size, cmdline_size, initrd_size; + + qfw_read_entry(qfw_dev, FW_CFG_SETUP_SIZE, 4, &setup_size); + qfw_read_entry(qfw_dev, FW_CFG_KERNEL_SIZE, 4, &kernel_size); + + if (!kernel_size) { + printf("fatal: no kernel available\n"); + return -ENOENT; + } + + data_addr = map_sysmem(load_addr, 0); + if (setup_size) { + qfw_read_entry(qfw_dev, FW_CFG_SETUP_DATA, + le32_to_cpu(setup_size), data_addr); + data_addr += le32_to_cpu(setup_size); + } + + qfw_read_entry(qfw_dev, FW_CFG_KERNEL_DATA, + le32_to_cpu(kernel_size), data_addr); + data_addr += le32_to_cpu(kernel_size); + env_set_hex("filesize", le32_to_cpu(kernel_size)); + + data_addr = map_sysmem(initrd_addr, 0); + qfw_read_entry(qfw_dev, FW_CFG_INITRD_SIZE, 4, &initrd_size); + if (!initrd_size) { + printf("warning: no initrd available\n"); + } else { + qfw_read_entry(qfw_dev, FW_CFG_INITRD_DATA, + le32_to_cpu(initrd_size), data_addr); + data_addr += le32_to_cpu(initrd_size); + env_set_hex("filesize", le32_to_cpu(initrd_size)); + } + + qfw_read_entry(qfw_dev, FW_CFG_CMDLINE_SIZE, 4, &cmdline_size); + if (cmdline_size) { + qfw_read_entry(qfw_dev, FW_CFG_CMDLINE_DATA, + le32_to_cpu(cmdline_size), data_addr); + /* + * if kernel cmdline only contains '\0', (e.g. no -append + * when invoking qemu), do not update bootargs + */ + if (*data_addr) { + if (env_set("bootargs", data_addr) < 0) + printf("warning: unable to change bootargs\n"); + } + } + + printf("loading kernel to address %lx size %x", load_addr, + le32_to_cpu(kernel_size)); + if (initrd_size) + printf(" initrd %lx size %x\n", initrd_addr, + le32_to_cpu(initrd_size)); + else + printf("\n"); + + return 0; +} diff --git a/include/qfw.h b/include/qfw.h index 7ca132e66a2..42798fea7db 100644 --- a/include/qfw.h +++ b/include/qfw.h @@ -316,4 +316,17 @@ bool qfw_file_iter_end(struct fw_cfg_file_iter *iter); */ int qemu_cpu_fixup(void);
+/* + * qemu_fwcfg_setup_kernel() - Prepare the kernel for zboot + * + * Loads kernel data to 'load_addr', initrd to 'initrd_addr' and kernel command + * line using qemu fw_cfg interface + * + * @load_addr: Load address for kernel + * @initrd_addr: Load address for ramdisk + * @return 0 if OK, -ENOENT if no kernel + */ +int qemu_fwcfg_setup_kernel(struct udevice *qfw_dev, ulong load_addr, + ulong initrd_addr); + #endif

On Sat, Jan 28, 2023 at 03:00:23PM -0700, Simon Glass wrote:
This is currently in the cmd/ file but we want to call it from a driver. Move it into a common place. Tidy up the header-file order while we are here.
Signed-off-by: Simon Glass sjg@chromium.org
Applied to u-boot/master, thanks!

Add a bootdev device for qfw so that it can be used with standard boot. This simply checks for the correct method and then does the read. Most of the other logic is handed in a new bootmeth driver.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/misc/qfw.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+)
diff --git a/drivers/misc/qfw.c b/drivers/misc/qfw.c index 1d54b7542b8..9ef95caa895 100644 --- a/drivers/misc/qfw.c +++ b/drivers/misc/qfw.c @@ -7,6 +7,9 @@ #define LOG_CATEGORY UCLASS_QFW
#include <common.h> +#include <bootdev.h> +#include <bootflow.h> +#include <bootmeth.h> #include <command.h> #include <errno.h> #include <log.h> @@ -310,8 +313,92 @@ int qfw_register(struct udevice *dev) return 0; }
+static int qfw_post_bind(struct udevice *dev) +{ + int ret; + + ret = bootdev_setup_for_dev(dev, "qfw_bootdev"); + if (ret) + return log_msg_ret("dev", ret); + + return 0; +} + +static int qfw_get_bootflow(struct udevice *dev, struct bootflow_iter *iter, + struct bootflow *bflow) +{ + const struct udevice *media = dev_get_parent(dev); + int ret; + + if (!CONFIG_IS_ENABLED(BOOTSTD)) + return -ENOSYS; + + log_debug("media=%s\n", media->name); + ret = bootmeth_check(bflow->method, iter); + if (ret) + return log_msg_ret("check", ret); + + log_debug("iter->part=%d\n", iter->part); + + /* We only support the whole device, not partitions */ + if (iter->part) + return log_msg_ret("max", -ESHUTDOWN); + + log_debug("reading bootflow with method: %s\n", bflow->method->name); + ret = bootmeth_read_bootflow(bflow->method, bflow); + if (ret) + return log_msg_ret("method", ret); + + return 0; +} + +static int qfw_bootdev_bind(struct udevice *dev) +{ + struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev); + + ucp->prio = BOOTDEVP_4_SCAN_FAST; + + return 0; +} + +static int qfw_bootdev_hunt(struct bootdev_hunter *info, bool show) +{ + int ret; + + ret = uclass_probe_all(UCLASS_QFW); + if (ret && ret != -ENOENT) + return log_msg_ret("vir", ret); + + return 0; +} + UCLASS_DRIVER(qfw) = { .id = UCLASS_QFW, .name = "qfw", + .post_bind = qfw_post_bind, .per_device_auto = sizeof(struct qfw_dev), }; + +struct bootdev_ops qfw_bootdev_ops = { + .get_bootflow = qfw_get_bootflow, +}; + +static const struct udevice_id qfw_bootdev_ids[] = { + { .compatible = "u-boot,bootdev-qfw" }, + { } +}; + +U_BOOT_DRIVER(qfw_bootdev) = { + .name = "qfw_bootdev", + .id = UCLASS_BOOTDEV, + .ops = &qfw_bootdev_ops, + .bind = qfw_bootdev_bind, + .of_match = qfw_bootdev_ids, +}; + +BOOTDEV_HUNTER(qfw_bootdev_hunter) = { + .prio = BOOTDEVP_4_SCAN_FAST, + .uclass = UCLASS_QFW, + .hunt = qfw_bootdev_hunt, + .drv = DM_DRIVER_REF(qfw_bootdev), +};

On Sat, Jan 28, 2023 at 03:00:24PM -0700, Simon Glass wrote:
Add a bootdev device for qfw so that it can be used with standard boot. This simply checks for the correct method and then does the read. Most of the other logic is handed in a new bootmeth driver.
Signed-off-by: Simon Glass sjg@chromium.org
Applied to u-boot/master, thanks!

This supports reading a kernel and ramdisk from qfw, then loading it with either the booti or bootz commands.
For now this uses the existing booti and bootz commands, rather than trying to call that functionality directly (e.g. do_bootm_states()). It does not require the HUSH parser though, which helps a little with size.
Signed-off-by: Simon Glass sjg@chromium.org ---
boot/Makefile | 1 + boot/bootflow.c | 2 +- boot/bootmeth_qfw.c | 102 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 boot/bootmeth_qfw.c
diff --git a/boot/Makefile b/boot/Makefile index 43baf2b89b3..0db4672b050 100644 --- a/boot/Makefile +++ b/boot/Makefile @@ -26,6 +26,7 @@ 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 diff --git a/boot/bootflow.c b/boot/bootflow.c index b8fa37ee2a0..60791e681bd 100644 --- a/boot/bootflow.c +++ b/boot/bootflow.c @@ -508,7 +508,7 @@ int bootflow_iter_check_blk(const struct bootflow_iter *iter) enum uclass_id id = device_get_uclass_id(media);
log_debug("uclass %d: %s\n", id, uclass_get_name(id)); - if (id != UCLASS_ETH && id != UCLASS_BOOTSTD) + if (id != UCLASS_ETH && id != UCLASS_BOOTSTD && id != UCLASS_QFW) return 0;
return -ENOTSUPP; diff --git a/boot/bootmeth_qfw.c b/boot/bootmeth_qfw.c new file mode 100644 index 00000000000..a5f95d4d0c5 --- /dev/null +++ b/boot/bootmeth_qfw.c @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Bootmethod for QEMU qfw + * + * Copyright 2023 Google LLC + * Written by Simon Glass sjg@chromium.org + */ + +#define LOG_CATEGORY UCLASS_BOOTSTD + +#include <common.h> +#include <command.h> +#include <bootdev.h> +#include <bootflow.h> +#include <bootmeth.h> +#include <env.h> +#include <qfw.h> +#include <dm.h> + +static int qfw_check(struct udevice *dev, struct bootflow_iter *iter) +{ + const struct udevice *media = dev_get_parent(iter->dev); + enum uclass_id id = device_get_uclass_id(media); + + log_debug("media=%s\n", media->name); + if (id == UCLASS_QFW) + return 0; + + return -ENOTSUPP; +} + +static int qfw_read_bootflow(struct udevice *dev, struct bootflow *bflow) +{ + struct udevice *qfw_dev = dev_get_parent(bflow->dev); + ulong load, initrd; + int ret; + + load = env_get_hex("kernel_addr_r", 0); + initrd = env_get_hex("ramdisk_addr_r", 0); + log_debug("setup kernel %s %lx %lx\n", qfw_dev->name, load, initrd); + bflow->name = strdup("qfw"); + if (!bflow->name) + return log_msg_ret("name", -ENOMEM); + + ret = qemu_fwcfg_setup_kernel(qfw_dev, load, initrd); + log_debug("setup kernel result %d\n", ret); + if (ret) + return log_msg_ret("cmd", -EIO); + + bflow->state = BOOTFLOWST_READY; + + return 0; +} + +static int qfw_read_file(struct udevice *dev, struct bootflow *bflow, + const char *file_path, ulong addr, ulong *sizep) +{ + return -ENOSYS; +} + +static int qfw_boot(struct udevice *dev, struct bootflow *bflow) +{ + int ret; + + ret = run_command("booti ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdtcontroladdr}", + 0); + if (ret) { + ret = run_command("bootz ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} " + "${fdtcontroladdr}", 0); + } + + return ret ? -EIO : 0; +} + +static int qfw_bootmeth_bind(struct udevice *dev) +{ + struct bootmeth_uc_plat *plat = dev_get_uclass_plat(dev); + + plat->desc = "Sandbox boot for testing"; + + return 0; +} + +static struct bootmeth_ops qfw_bootmeth_ops = { + .check = qfw_check, + .read_bootflow = qfw_read_bootflow, + .read_file = qfw_read_file, + .boot = qfw_boot, +}; + +static const struct udevice_id qfw_bootmeth_ids[] = { + { .compatible = "u-boot,qfw-syslinux" }, + { } +}; + +U_BOOT_DRIVER(bootmeth_qfw) = { + .name = "bootmeth_qfw", + .id = UCLASS_BOOTMETH, + .of_match = qfw_bootmeth_ids, + .ops = &qfw_bootmeth_ops, + .bind = qfw_bootmeth_bind, +};

On Sat, Jan 28, 2023 at 03:00:25PM -0700, Simon Glass wrote:
This supports reading a kernel and ramdisk from qfw, then loading it with either the booti or bootz commands.
For now this uses the existing booti and bootz commands, rather than trying to call that functionality directly (e.g. do_bootm_states()). It does not require the HUSH parser though, which helps a little with size.
Signed-off-by: Simon Glass sjg@chromium.org
Applied to u-boot/master, thanks!

Drop use of the distro scripts and use standard boot instead.
Enable BOOTDEV_FULL just for convenience, although this does add quite a bit to the size.
Signed-off-by: Simon Glass sjg@chromium.org ---
configs/qemu_arm64_defconfig | 4 ++- configs/qemu_arm_defconfig | 4 ++- include/configs/qemu-arm.h | 54 ++---------------------------------- 3 files changed, 8 insertions(+), 54 deletions(-)
diff --git a/configs/qemu_arm64_defconfig b/configs/qemu_arm64_defconfig index 2f46030855d..40aec927fc9 100644 --- a/configs/qemu_arm64_defconfig +++ b/configs/qemu_arm64_defconfig @@ -13,13 +13,14 @@ CONFIG_SYS_LOAD_ADDR=0x40200000 CONFIG_ENV_ADDR=0x4000000 CONFIG_DEBUG_UART=y CONFIG_AHCI=y -CONFIG_DISTRO_DEFAULTS=y CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x40200000 CONFIG_FIT=y CONFIG_FIT_SIGNATURE=y CONFIG_FIT_VERBOSE=y CONFIG_FIT_BEST_MATCH=y +CONFIG_BOOTSTD_FULL=y +CONFIG_BOOTSTD_DEFAULTS=y CONFIG_LEGACY_IMAGE_FORMAT=y CONFIG_USE_PREBOOT=y # CONFIG_DISPLAY_CPUINFO is not set @@ -27,6 +28,7 @@ CONFIG_USE_PREBOOT=y CONFIG_PCI_INIT_R=y CONFIG_SYS_CBSIZE=512 CONFIG_SYS_PBSIZE=532 +CONFIG_CMD_BOOTZ=y CONFIG_CMD_BOOTEFI_SELFTEST=y CONFIG_CMD_NVEDIT_EFI=y CONFIG_CMD_DFU=y diff --git a/configs/qemu_arm_defconfig b/configs/qemu_arm_defconfig index f0ee54658a5..ad02526a5dc 100644 --- a/configs/qemu_arm_defconfig +++ b/configs/qemu_arm_defconfig @@ -14,13 +14,14 @@ CONFIG_SYS_LOAD_ADDR=0x40200000 CONFIG_ENV_ADDR=0x4000000 CONFIG_DEBUG_UART=y CONFIG_AHCI=y -CONFIG_DISTRO_DEFAULTS=y CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x40200000 CONFIG_FIT=y CONFIG_FIT_SIGNATURE=y CONFIG_FIT_VERBOSE=y CONFIG_FIT_BEST_MATCH=y +CONFIG_BOOTSTD_FULL=y +CONFIG_BOOTSTD_DEFAULTS=y CONFIG_LEGACY_IMAGE_FORMAT=y CONFIG_USE_PREBOOT=y # CONFIG_DISPLAY_CPUINFO is not set @@ -28,6 +29,7 @@ CONFIG_USE_PREBOOT=y CONFIG_PCI_INIT_R=y CONFIG_SYS_CBSIZE=512 CONFIG_SYS_PBSIZE=532 +CONFIG_CMD_BOOTZ=y CONFIG_SYS_BOOTM_LEN=0x4000000 CONFIG_CMD_BOOTEFI_SELFTEST=y CONFIG_CMD_NVEDIT_EFI=y diff --git a/include/configs/qemu-arm.h b/include/configs/qemu-arm.h index 45bd94ee5c7..02f9354c05d 100644 --- a/include/configs/qemu-arm.h +++ b/include/configs/qemu-arm.h @@ -21,60 +21,10 @@ EFI_GUID(0x058b7d83, 0x50d5, 0x4c47, 0xa1, 0x95, \ 0x60, 0xd8, 0x6a, 0xd3, 0x41, 0xc4)
-/* Try files from QEMU's -kernel/-initrd, through the QEMU firmware device. */ -#define BOOTENV_DEV_QFW(devtypeu, devtypel, instance) \ - "bootcmd_qfw= " \ - "if qfw load $kernel_addr_r $ramdisk_addr_r; then " \ - " booti $kernel_addr_r $ramdisk_addr_r:$filesize $fdtcontroladdr; " \ - " if test $? -eq 1; then " \ - " bootz $kernel_addr_r $ramdisk_addr_r:$filesize $fdtcontroladdr; " \ - " fi ; " \ - "fi\0" -#define BOOTENV_DEV_NAME_QFW(devtypeu, devtypel, instance) "qfw " - /* For timer, QEMU emulates an ARMv7/ARMv8 architected timer */
/* Environment options */ - -#if CONFIG_IS_ENABLED(CMD_USB) -# define BOOT_TARGET_USB(func) func(USB, usb, 0) -#else -# define BOOT_TARGET_USB(func) -#endif - -#if CONFIG_IS_ENABLED(CMD_SCSI) -# define BOOT_TARGET_SCSI(func) func(SCSI, scsi, 0) -#else -# define BOOT_TARGET_SCSI(func) -#endif - -#if CONFIG_IS_ENABLED(CMD_VIRTIO) -# define BOOT_TARGET_VIRTIO(func) func(VIRTIO, virtio, 0) -#else -# define BOOT_TARGET_VIRTIO(func) -#endif - -#if CONFIG_IS_ENABLED(CMD_NVME) -# define BOOT_TARGET_NVME(func) func(NVME, nvme, 0) -#else -# define BOOT_TARGET_NVME(func) -#endif - -#if CONFIG_IS_ENABLED(CMD_DHCP) -# define BOOT_TARGET_DHCP(func) func(DHCP, dhcp, na) -#else -# define BOOT_TARGET_DHCP(func) -#endif - -#define BOOT_TARGET_DEVICES(func) \ - func(QFW, qfw, na) \ - BOOT_TARGET_USB(func) \ - BOOT_TARGET_SCSI(func) \ - BOOT_TARGET_VIRTIO(func) \ - BOOT_TARGET_NVME(func) \ - BOOT_TARGET_DHCP(func) - -#include <config_distro_bootcmd.h> +#define BOOT_TARGETS "qfw usb scsi virtio nvme dhcp"
#define CFG_EXTRA_ENV_SETTINGS \ "fdt_high=0xffffffff\0" \ @@ -84,6 +34,6 @@ "pxefile_addr_r=0x40300000\0" \ "kernel_addr_r=0x40400000\0" \ "ramdisk_addr_r=0x44000000\0" \ - BOOTENV + "boot_targets=" BOOT_TARGETS "\0"
#endif /* __CONFIG_H */

On Sat, Jan 28, 2023 at 03:00:26PM -0700, Simon Glass wrote:
Drop use of the distro scripts and use standard boot instead.
Enable BOOTDEV_FULL just for convenience, although this does add quite a bit to the size.
Signed-off-by: Simon Glass sjg@chromium.org
Applied to u-boot/master, thanks!

Use the new environment format so we can drop most of the config.h file.
Signed-off-by: Simon Glass sjg@chromium.org ---
board/emulation/qemu-arm/qemu-arm.env | 12 ++++++++++++ include/configs/qemu-arm.h | 13 ------------- 2 files changed, 12 insertions(+), 13 deletions(-) create mode 100644 board/emulation/qemu-arm/qemu-arm.env
diff --git a/board/emulation/qemu-arm/qemu-arm.env b/board/emulation/qemu-arm/qemu-arm.env new file mode 100644 index 00000000000..e658d5ee7d6 --- /dev/null +++ b/board/emulation/qemu-arm/qemu-arm.env @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +/* environment for qemu-arm and qemu-arm64 */ + +fdt_high=0xffffffff +initrd_high=0xffffffff +fdt_addr=0x40000000 +scriptaddr=0x40200000 +pxefile_addr_r=0x40300000 +kernel_addr_r=0x40400000 +ramdisk_addr_r=0x44000000 +boot_targets=qfw usb scsi virtio nvme dhcp diff --git a/include/configs/qemu-arm.h b/include/configs/qemu-arm.h index 02f9354c05d..77ab5738254 100644 --- a/include/configs/qemu-arm.h +++ b/include/configs/qemu-arm.h @@ -23,17 +23,4 @@
/* For timer, QEMU emulates an ARMv7/ARMv8 architected timer */
-/* Environment options */ -#define BOOT_TARGETS "qfw usb scsi virtio nvme dhcp" - -#define CFG_EXTRA_ENV_SETTINGS \ - "fdt_high=0xffffffff\0" \ - "initrd_high=0xffffffff\0" \ - "fdt_addr=0x40000000\0" \ - "scriptaddr=0x40200000\0" \ - "pxefile_addr_r=0x40300000\0" \ - "kernel_addr_r=0x40400000\0" \ - "ramdisk_addr_r=0x44000000\0" \ - "boot_targets=" BOOT_TARGETS "\0" - #endif /* __CONFIG_H */

On Sat, Jan 28, 2023 at 03:00:27PM -0700, Simon Glass wrote:
Use the new environment format so we can drop most of the config.h file.
Signed-off-by: Simon Glass sjg@chromium.org
Applied to u-boot/master, thanks!

These are only used in one place, so move them there.
Signed-off-by: Simon Glass sjg@chromium.org ---
board/emulation/qemu-arm/qemu-arm.c | 10 ++++++++++ configs/qemu_arm64_defconfig | 1 + configs/qemu_arm_defconfig | 1 + include/configs/qemu-arm.h | 12 ------------ test/boot/bootdev.c | 25 ++++++++++++++----------- test/boot/bootstd_common.h | 2 +- 6 files changed, 27 insertions(+), 24 deletions(-)
diff --git a/board/emulation/qemu-arm/qemu-arm.c b/board/emulation/qemu-arm/qemu-arm.c index 3df3e41c0b2..dae37640bc5 100644 --- a/board/emulation/qemu-arm/qemu-arm.c +++ b/board/emulation/qemu-arm/qemu-arm.c @@ -15,6 +15,16 @@ #include <virtio.h>
#include <linux/kernel.h> +#include <linux/sizes.h> + +/* GUIDs for capsule updatable firmware images */ +#define QEMU_ARM_UBOOT_IMAGE_GUID \ + EFI_GUID(0xf885b085, 0x99f8, 0x45af, 0x84, 0x7d, \ + 0xd5, 0x14, 0x10, 0x7a, 0x4a, 0x2c) + +#define QEMU_ARM64_UBOOT_IMAGE_GUID \ + EFI_GUID(0x058b7d83, 0x50d5, 0x4c47, 0xa1, 0x95, \ + 0x60, 0xd8, 0x6a, 0xd3, 0x41, 0xc4)
#ifdef CONFIG_ARM64 #include <asm/armv8/mmu.h> diff --git a/configs/qemu_arm64_defconfig b/configs/qemu_arm64_defconfig index 40aec927fc9..f66ad32fc9b 100644 --- a/configs/qemu_arm64_defconfig +++ b/configs/qemu_arm64_defconfig @@ -72,3 +72,4 @@ CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_PCI=y CONFIG_TPM=y +CONFIG_HUSH_PARSER=y diff --git a/configs/qemu_arm_defconfig b/configs/qemu_arm_defconfig index ad02526a5dc..c2e25c1d6bc 100644 --- a/configs/qemu_arm_defconfig +++ b/configs/qemu_arm_defconfig @@ -74,3 +74,4 @@ CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_PCI=y CONFIG_TPM=y +CONFIG_HUSH_PARSER=y diff --git a/include/configs/qemu-arm.h b/include/configs/qemu-arm.h index 77ab5738254..e296f398798 100644 --- a/include/configs/qemu-arm.h +++ b/include/configs/qemu-arm.h @@ -6,21 +6,9 @@ #ifndef __CONFIG_H #define __CONFIG_H
-#include <linux/sizes.h> - /* Physical memory map */ - #define CFG_SYS_SDRAM_BASE 0x40000000
-/* GUIDs for capsule updatable firmware images */ -#define QEMU_ARM_UBOOT_IMAGE_GUID \ - EFI_GUID(0xf885b085, 0x99f8, 0x45af, 0x84, 0x7d, \ - 0xd5, 0x14, 0x10, 0x7a, 0x4a, 0x2c) - -#define QEMU_ARM64_UBOOT_IMAGE_GUID \ - EFI_GUID(0x058b7d83, 0x50d5, 0x4c47, 0xa1, 0x95, \ - 0x60, 0xd8, 0x6a, 0xd3, 0x41, 0xc4) - /* For timer, QEMU emulates an ARMv7/ARMv8 architected timer */
#endif /* __CONFIG_H */ diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c index ef5215bbcec..7beee9258d0 100644 --- a/test/boot/bootdev.c +++ b/test/boot/bootdev.c @@ -316,11 +316,12 @@ static int bootdev_test_hunter(struct unit_test_state *uts) ut_assert_nextline(" 5 ide ide_bootdev"); ut_assert_nextline(" 2 mmc mmc_bootdev"); ut_assert_nextline(" 4 nvme nvme_bootdev"); + ut_assert_nextline(" 4 qfw qfw_bootdev"); ut_assert_nextline(" 4 scsi scsi_bootdev"); ut_assert_nextline(" 4 spi_flash sf_bootdev"); ut_assert_nextline(" 5 usb usb_bootdev"); ut_assert_nextline(" 4 virtio virtio_bootdev"); - ut_assert_nextline("(total hunters: 9)"); + ut_assert_nextline("(total hunters: 10)"); ut_assert_console_end();
ut_assertok(bootdev_hunt("usb1", false)); @@ -328,8 +329,8 @@ static int bootdev_test_hunter(struct unit_test_state *uts) "Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found"); ut_assert_console_end();
- /* USB is sixth in the list, so bit 7 */ - ut_asserteq(BIT(7), std->hunters_used); + /* USB is 7th in the list, so bit 8 */ + ut_asserteq(BIT(8), std->hunters_used);
return 0; } @@ -350,7 +351,7 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts) ut_assert_nextline("Prio Used Uclass Hunter"); ut_assert_nextlinen("----"); ut_assert_nextline(" 6 ethernet eth_bootdev"); - ut_assert_skip_to_line("(total hunters: 9)"); + ut_assert_skip_to_line("(total hunters: 10)"); ut_assert_console_end();
/* Use the MMC hunter and see that it updates */ @@ -358,7 +359,7 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts) ut_assertok(run_command("bootdev hunt -l", 0)); ut_assert_skip_to_line(" 5 ide ide_bootdev"); ut_assert_nextline(" 2 * mmc mmc_bootdev"); - ut_assert_skip_to_line("(total hunters: 9)"); + ut_assert_skip_to_line("(total hunters: 10)"); ut_assert_console_end();
/* Scan all hunters */ @@ -376,6 +377,7 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts) /* mmc hunter has already been used so should not run again */
ut_assert_nextline("Hunting with: nvme"); + ut_assert_nextline("Hunting with: qfw"); ut_assert_nextline("Hunting with: scsi"); ut_assert_nextline("scanning bus for devices..."); ut_assert_skip_to_line("Hunting with: spi_flash"); @@ -394,11 +396,12 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts) ut_assert_nextline(" 5 * ide ide_bootdev"); ut_assert_nextline(" 2 * mmc mmc_bootdev"); ut_assert_nextline(" 4 * nvme nvme_bootdev"); + ut_assert_nextline(" 4 * qfw qfw_bootdev"); ut_assert_nextline(" 4 * scsi scsi_bootdev"); ut_assert_nextline(" 4 * spi_flash sf_bootdev"); ut_assert_nextline(" 5 * usb usb_bootdev"); ut_assert_nextline(" 4 * virtio virtio_bootdev"); - ut_assert_nextline("(total hunters: 9)"); + ut_assert_nextline("(total hunters: 10)"); ut_assert_console_end();
ut_asserteq(GENMASK(MAX_HUNTER, 0), std->hunters_used); @@ -585,8 +588,8 @@ static int bootdev_test_next_label(struct unit_test_state *uts) ut_asserteq_str("scsi.id0lun0.bootdev", dev->name); ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS, mflags);
- /* SCSI is sixth in the list, so bit 5 */ - ut_asserteq(BIT(MMC_HUNTER) | BIT(5), std->hunters_used); + /* SCSI is 7th in the list, so bit 6 */ + ut_asserteq(BIT(MMC_HUNTER) | BIT(6), std->hunters_used);
ut_assertok(bootdev_next_label(&iter, &dev, &mflags)); ut_assert_console_end(); @@ -596,7 +599,7 @@ static int bootdev_test_next_label(struct unit_test_state *uts) mflags);
/* dhcp: Ethernet is first so bit 0 */ - ut_asserteq(BIT(MMC_HUNTER) | BIT(5) | BIT(0), std->hunters_used); + ut_asserteq(BIT(MMC_HUNTER) | BIT(6) | BIT(0), std->hunters_used);
ut_assertok(bootdev_next_label(&iter, &dev, &mflags)); ut_assert_console_end(); @@ -606,7 +609,7 @@ static int bootdev_test_next_label(struct unit_test_state *uts) mflags);
/* pxe: Ethernet is first so bit 0 */ - ut_asserteq(BIT(MMC_HUNTER) | BIT(5) | BIT(0), std->hunters_used); + ut_asserteq(BIT(MMC_HUNTER) | BIT(6) | BIT(0), std->hunters_used);
mflags = 123; ut_asserteq(-ENODEV, bootdev_next_label(&iter, &dev, &mflags)); @@ -614,7 +617,7 @@ static int bootdev_test_next_label(struct unit_test_state *uts) ut_assert_console_end();
/* no change */ - ut_asserteq(BIT(MMC_HUNTER) | BIT(5) | BIT(0), std->hunters_used); + ut_asserteq(BIT(MMC_HUNTER) | BIT(6) | BIT(0), std->hunters_used);
return 0; } diff --git a/test/boot/bootstd_common.h b/test/boot/bootstd_common.h index 136a79b5178..4a126e43ff4 100644 --- a/test/boot/bootstd_common.h +++ b/test/boot/bootstd_common.h @@ -21,7 +21,7 @@ #define TEST_VERNUM 0x00010002
enum { - MAX_HUNTER = 8, + MAX_HUNTER = 9, MMC_HUNTER = 3, /* ID of MMC hunter */ };

On Sat, Jan 28, 2023 at 03:00:28PM -0700, Simon Glass wrote:
These are only used in one place, so move them there.
Signed-off-by: Simon Glass sjg@chromium.org
Applied to u-boot/master, thanks!

On Sat, Jan 28, 2023 at 03:00:15PM -0700, Simon Glass wrote:
This series fixes a few reported problems with virtio block-device handling.
It also moves QEMU over to use standard boot on ARM, by adding a suitable bootdev and bootmeth for qfw.
Finally, it moves the boards to use a text-based environment. The only remaining item in the config.h header file is CFG_SYS_SDRAM_BASE so it would be nice to move that to Kconfig, if possible.
Figuring out what to do about CFG_SYS_SDRAM_BASE is a good question. For this series, have you been able to perform other tests on top of it, such as verifying off the shelf distributions still boot / install as expected?

Hi Tom,
On Mon, 30 Jan 2023 at 10:20, Tom Rini trini@konsulko.com wrote:
On Sat, Jan 28, 2023 at 03:00:15PM -0700, Simon Glass wrote:
This series fixes a few reported problems with virtio block-device handling.
It also moves QEMU over to use standard boot on ARM, by adding a suitable bootdev and bootmeth for qfw.
Finally, it moves the boards to use a text-based environment. The only remaining item in the config.h header file is CFG_SYS_SDRAM_BASE so it would be nice to move that to Kconfig, if possible.
Figuring out what to do about CFG_SYS_SDRAM_BASE is a good question. For this series, have you been able to perform other tests on top of it, such as verifying off the shelf distributions still boot / install as expected?
I did not do a new install, but did check that it booting Debian OK. Should we try to get some of this into CI or would it be too painful?
I have done a lot of checking with RockPro64 which of course uses the same logic (except for qfw which is new and which I manually tested). Of course we also have a lot of unit tests for bootstd, to prevent regressionsl,
Regards, Simon
participants (2)
-
Simon Glass
-
Tom Rini