[Concept,02/16] emulation: Support the bootcmd more generally

Message ID 20251115185212.539268-3-sjg@u-boot.org
State New
Headers
Series Continue TKey development |

Commit Message

Simon Glass Nov. 15, 2025, 6:51 p.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

The code for obtaining a bootcmd from the host when running until QEMU
is currently x86-specific. In fact it can be supported on other
architecture.

Move it into a common place and update the documentation.

Signed-off-by: Simon Glass <simon.glass@canonical.com>
---

 arch/x86/cpu/qemu/qemu.c         | 28 ------------------------
 board/emulation/common/Makefile  |  3 +++
 board/emulation/common/bootcmd.c | 37 ++++++++++++++++++++++++++++++++
 doc/board/emulation/common.rst   | 28 ++++++++++++++++++++++++
 doc/board/emulation/index.rst    |  1 +
 doc/board/emulation/qemu-x86.rst | 18 ++--------------
 6 files changed, 71 insertions(+), 44 deletions(-)
 create mode 100644 board/emulation/common/bootcmd.c
 create mode 100644 doc/board/emulation/common.rst
  

Patch

diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c
index 24916d867ee..b393205acb3 100644
--- a/arch/x86/cpu/qemu/qemu.c
+++ b/arch/x86/cpu/qemu/qemu.c
@@ -153,31 +153,3 @@  int mp_determine_pci_dstirq(int bus, int dev, int func, int pirq)
 	return irq;
 }
 #endif
-
-#if CONFIG_IS_ENABLED(EVENT)
-static int qemu_get_bootcmd(void *ctx, struct event *event)
-{
-	struct event_bootcmd *bc = &event->data.bootcmd;
-	enum fw_cfg_selector select;
-	struct udevice *qfw_dev;
-	ulong size;
-
-	if (qfw_get_dev(&qfw_dev))
-		return 0;
-
-	if (qfw_locate_file(qfw_dev, "opt/u-boot/bootcmd", &select, &size))
-		return 0;
-	if (!size)
-		return 0;
-
-	/* Check if the command fits in the provided buffer with terminator */
-	if (size >= bc->size)
-		return -ENOSPC;
-
-	qfw_read_entry(qfw_dev, select, size, bc->bootcmd);
-	bc->bootcmd[size] = '\0';
-
-	return 0;
-}
-EVENT_SPY_FULL(EVT_BOOTCMD, qemu_get_bootcmd);
-#endif
diff --git a/board/emulation/common/Makefile b/board/emulation/common/Makefile
index c5b452e7e34..a91e4f16fef 100644
--- a/board/emulation/common/Makefile
+++ b/board/emulation/common/Makefile
@@ -2,3 +2,6 @@ 
 
 obj-$(CONFIG_SYS_MTDPARTS_RUNTIME) += qemu_mtdparts.o
 obj-$(CONFIG_SET_DFU_ALT_INFO) += qemu_dfu.o
+ifdef CONFIG_QFW
+obj-$(CONFIG_$(PHASE_)EVENT) += bootcmd.o
+endif
diff --git a/board/emulation/common/bootcmd.c b/board/emulation/common/bootcmd.c
new file mode 100644
index 00000000000..6fc7c618c8f
--- /dev/null
+++ b/board/emulation/common/bootcmd.c
@@ -0,0 +1,37 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2025 Canonical Ltd
+ * Written by Simon Glass <simon.glass@canonical.com>
+ */
+
+#include <errno.h>
+#include <event.h>
+#include <qfw.h>
+
+#if CONFIG_IS_ENABLED(EVENT)
+static int qemu_get_bootcmd(void *ctx, struct event *event)
+{
+	struct event_bootcmd *bc = &event->data.bootcmd;
+	enum fw_cfg_selector select;
+	struct udevice *qfw_dev;
+	ulong size;
+
+	if (qfw_get_dev(&qfw_dev))
+		return 0;
+
+	if (qfw_locate_file(qfw_dev, "opt/u-boot/bootcmd", &select, &size))
+		return 0;
+	if (!size)
+		return 0;
+
+	/* Check if the command fits in the provided buffer with terminator */
+	if (size >= bc->size)
+		return -ENOSPC;
+
+	qfw_read_entry(qfw_dev, select, size, bc->bootcmd);
+	bc->bootcmd[size] = '\0';
+
+	return 0;
+}
+EVENT_SPY_FULL(EVT_BOOTCMD, qemu_get_bootcmd);
+#endif
diff --git a/doc/board/emulation/common.rst b/doc/board/emulation/common.rst
new file mode 100644
index 00000000000..90dde5f442a
--- /dev/null
+++ b/doc/board/emulation/common.rst
@@ -0,0 +1,28 @@ 
+.. SPDX-License-Identifier: GPL-2.0+
+
+Common features
+===============
+
+It is possible to specify the boot command directly using the fw_cfg interface.
+This allows QEMU to control the boot command, which can be useful for automated
+testing or scripting. To use this feature, create a file containing the boot
+command and pass it to QEMU using the fw_cfg option.
+
+Here is an x86 example::
+
+   $ echo "qfw load; zboot 01000000 - 04000000 1b1ab50" > bootcmd.txt
+   $ qemu-system-x86_64 -nographic -bios path/to/u-boot.rom \
+     -fw_cfg name=opt/u-boot/bootcmd,file=bootcmd.txt
+
+U-Boot will read the boot command from the firmware configuration and execute it
+automatically during the boot process. This bypasses the normal distro boot
+sequence.
+
+Note that the boot command is limited in length and should not exceed the boot
+command buffer size. If the command is too long, U-Boot will fail to read it and
+fall back to the default boot behavior.
+
+The :doc:`script` and build-efi scripts provide a `-c` option for this feature,
+although it uses a string rather than a file.
+
+Note that ``CONFIG_QFW`` must be enabled for this feature to work.
diff --git a/doc/board/emulation/index.rst b/doc/board/emulation/index.rst
index 5a2a00ae225..6eccf7bad8a 100644
--- a/doc/board/emulation/index.rst
+++ b/doc/board/emulation/index.rst
@@ -8,6 +8,7 @@  Emulation
 
    acpi
    blkdev
+   common
    script
    qemu-arm
    qemu-mips
diff --git a/doc/board/emulation/qemu-x86.rst b/doc/board/emulation/qemu-x86.rst
index c2862e631ee..27f0d273f38 100644
--- a/doc/board/emulation/qemu-x86.rst
+++ b/doc/board/emulation/qemu-x86.rst
@@ -116,22 +116,8 @@  supports 32-bit.
 Specifying a boot command
 --------------------------
 
-It is possible to specify the boot command directly using the fw_cfg interface.
-This allows QEMU to control the boot command, which can be useful for automated
-testing or scripting. To use this feature, create a file containing the boot
-command and pass it to QEMU using the fw_cfg option::
-
-   $ echo "qfw load; zboot 01000000 - 04000000 1b1ab50" > bootcmd.txt
-   $ qemu-system-x86_64 -nographic -bios path/to/u-boot.rom \
-     -fw_cfg name=opt/u-boot/bootcmd,file=bootcmd.txt
-
-U-Boot will read the boot command from the firmware configuration and execute it
-automatically during the boot process. This bypasses the normal distro boot
-sequence.
-
-Note that the boot command is limited in length and should not exceed the boot
-command buffer size. If the command is too long, U-Boot will fail to read it and
-fall back to the default boot behavior.
+See :doc:`common` for details on how to provide a boot command to U-Boot on
+startup.
 
 Booting distros
 ---------------