diff mbox series

[v3,4/4] qemu: add sandbox driver and tests

Message ID 20210223114329.16729-5-ashe@kivikakk.ee
State Superseded
Delegated to: Tom Rini
Headers show
Series Move qfw to DM, add Arm support | expand

Commit Message

Asherah Connor Feb. 23, 2021, 11:43 a.m. UTC
We minimally exercise the sandbox driver.

Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
---

(no changes since v1)

 arch/sandbox/dts/sandbox.dtsi |   4 ++
 arch/sandbox/dts/test.dts     |   4 ++
 drivers/misc/Makefile         |  11 ++-
 drivers/misc/qfw_sandbox.c    | 129 ++++++++++++++++++++++++++++++++++
 test/dm/Makefile              |   1 +
 test/dm/qfw.c                 |  42 +++++++++++
 6 files changed, 185 insertions(+), 6 deletions(-)
 create mode 100644 drivers/misc/qfw_sandbox.c
 create mode 100644 test/dm/qfw.c

Comments

Asherah Connor Feb. 23, 2021, 12:26 p.m. UTC | #1
On 21/02/23 10:02:p, Asherah Connor wrote:
> We minimally exercise the sandbox driver.

It looks like the test in QEMU is pretty trivial.  I'll include it in
the next series version, but here's what it looks like.  New tests have
been tested as passing against qemu_arm, qemu_arm64, qemu-x86, and
qemu-x86_64.  :)

Best,

Asherah

--8<--

Subject: [PATCH] test: qemu: add simple test for cmd_qfw

Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
---
 test/py/tests/test_qfw.py | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
 create mode 100644 test/py/tests/test_qfw.py

diff --git a/test/py/tests/test_qfw.py b/test/py/tests/test_qfw.py
new file mode 100644
index 0000000000..a2631a0fa6
--- /dev/null
+++ b/test/py/tests/test_qfw.py
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2021, Asherah Connor <ashe@kivikakk.ee>
+
+# Test qfw command implementation
+
+import pytest
+
+@pytest.mark.buildconfigspec('cmd_qfw')
+def test_qfw_cpus(u_boot_console):
+    "Test QEMU firmware config reports the CPU count correctly."
+
+    output = u_boot_console.run_command('qfw cpus')
+    assert '1 cpu(s) online' in output
+
+@pytest.mark.buildconfigspec('cmd_qfw')
+def test_qfw_list(u_boot_console):
+    "Test QEMU firmware config lists devices."
+
+    output = u_boot_console.run_command('qfw list')
+    assert 'bootorder' in output
+    assert 'etc/table-loader' in output
--
2.20.1
Simon Glass Feb. 23, 2021, 3:58 p.m. UTC | #2
On Tue, 23 Feb 2021 at 06:44, Asherah Connor <ashe@kivikakk.ee> wrote:
>
> We minimally exercise the sandbox driver.
>
> Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
> ---
>
> (no changes since v1)
>
>  arch/sandbox/dts/sandbox.dtsi |   4 ++
>  arch/sandbox/dts/test.dts     |   4 ++
>  drivers/misc/Makefile         |  11 ++-
>  drivers/misc/qfw_sandbox.c    | 129 ++++++++++++++++++++++++++++++++++
>  test/dm/Makefile              |   1 +
>  test/dm/qfw.c                 |  42 +++++++++++
>  6 files changed, 185 insertions(+), 6 deletions(-)
>  create mode 100644 drivers/misc/qfw_sandbox.c
>  create mode 100644 test/dm/qfw.c

Reviewed-by: Simon Glass <sjg@chromium.org>
diff mbox series

Patch

diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index dc933f3bfc..7ce05b9662 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -390,6 +390,10 @@ 
 	sandbox_tee {
 		compatible = "sandbox,tee";
 	};
+
+	qfw {
+		compatible = "sandbox,qemu-fw-cfg-mmio";
+	};
 };
 
 &cros_ec {
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index d4195b45bb..4b3f8831d5 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -112,6 +112,10 @@ 
 		compatible = "sandbox,dsi-host";
 	};
 
+	qfw {
+		compatible = "sandbox,qemu-fw-cfg-mmio";
+	};
+
 	a-test {
 		reg = <0 1>;
 		compatible = "denx,u-boot-fdt-test";
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index e6e1dfea95..ea04abd6c5 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -55,12 +55,11 @@  obj-$(CONFIG_NUVOTON_NCT6102D) += nuvoton_nct6102d.o
 obj-$(CONFIG_P2SB) += p2sb-uclass.o
 obj-$(CONFIG_PCA9551_LED) += pca9551_led.o
 obj-$(CONFIG_$(SPL_)PWRSEQ) += pwrseq-uclass.o
-obj-$(CONFIG_QFW) += qfw.o
-ifdef CONFIG_X86
-obj-$(CONFIG_QFW) += qfw_pio.o
-endif
-ifdef CONFIG_ARM
-obj-$(CONFIG_QFW) += qfw_mmio.o
+ifdef CONFIG_QFW
+obj-y	+= qfw.o
+obj-$(CONFIG_X86) += qfw_pio.o
+obj-$(CONFIG_ARM) += qfw_mmio.o
+obj-$(CONFIG_SANDBOX) += qfw_sandbox.o
 endif
 obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o
 obj-$(CONFIG_ROCKCHIP_OTP) += rockchip-otp.o
diff --git a/drivers/misc/qfw_sandbox.c b/drivers/misc/qfw_sandbox.c
new file mode 100644
index 0000000000..fc7006ae19
--- /dev/null
+++ b/drivers/misc/qfw_sandbox.c
@@ -0,0 +1,129 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Sandbox interface for QFW
+ *
+ * (C) Copyright 2015 Miao Yan <yanmiaobest@gmail.com>
+ * (C) Copyright 2021 Asherah Connor <ashe@kivikakk.ee>
+ */
+
+#define LOG_CATEGORY UCLASS_QFW
+
+#include <asm/types.h>
+#include <asm/io.h>
+#include <dm.h>
+#include <dm/device.h>
+#include <qfw.h>
+
+struct qfw_sandbox_plat {
+	u8 file_dir_offset;
+};
+
+static void qfw_sandbox_read_entry_io(struct udevice *dev, u16 entry, u32 size,
+				      void *address)
+{
+	debug("%s: entry 0x%x size %u address %p\n", __func__, entry, size,
+	      address);
+
+	switch (entry) {
+	case FW_CFG_SIGNATURE:
+		if (size == 4)
+			*((u32 *)address) = cpu_to_be32(QEMU_FW_CFG_SIGNATURE);
+		break;
+	case FW_CFG_ID:
+		/* Advertise DMA support */
+		if (size == 1)
+			*((u8 *)address) = FW_CFG_DMA_ENABLED;
+		break;
+	default:
+		debug("%s got unsupported entry 0x%x\n", __func__, entry);
+	/*
+	 * Sandbox driver doesn't support other entries here, assume we use DMA
+	 * to read them -- the uclass driver will exclusively use it when
+	 * advertised.
+	 */
+	}
+}
+
+static void qfw_sandbox_read_entry_dma(struct udevice *dev, struct qfw_dma *dma)
+{
+	u16 entry;
+	u32 control = be32_to_cpu(dma->control);
+	void *address = (void *)be64_to_cpu(dma->address);
+	u32 length = be32_to_cpu(dma->length);
+	struct qfw_sandbox_plat *plat = dev_get_plat(dev);
+	struct fw_cfg_file *file;
+
+	debug("%s\n", __func__);
+
+	if (!(control & FW_CFG_DMA_READ))
+		return;
+
+	if (control & FW_CFG_DMA_SELECT) {
+		/* Start new read. */
+		entry = control >> 16;
+
+		/* Arbitrary values to be used by tests. */
+		switch (entry) {
+		case FW_CFG_NB_CPUS:
+			if (length == 2)
+				*((u16 *)address) = cpu_to_le16(5);
+			break;
+		case FW_CFG_FILE_DIR:
+			if (length == 4) {
+				*((u32 *)address) = cpu_to_be32(2);
+				plat->file_dir_offset = 1;
+			}
+			break;
+		default:
+			debug("%s got unsupported entry 0x%x\n", __func__,
+			      entry);
+		}
+	} else if (plat->file_dir_offset && length == 64) {
+		file = address;
+		switch (plat->file_dir_offset) {
+		case 1:
+			file->size = cpu_to_be32(8);
+			file->select = cpu_to_be16(FW_CFG_FILE_FIRST);
+			strcpy(file->name, "test-one");
+			plat->file_dir_offset++;
+			break;
+		case 2:
+			file->size = cpu_to_be32(8);
+			file->select = cpu_to_be16(FW_CFG_FILE_FIRST + 1);
+			strcpy(file->name, "test-two");
+			plat->file_dir_offset++;
+			break;
+		}
+	}
+
+	/*
+	 * Signal that we are finished. No-one checks this in sandbox --
+	 * normally the platform-specific driver looks for it -- but let's
+	 * replicate the behaviour in case someone relies on it later.
+	 */
+	dma->control = 0;
+}
+
+static int qfw_sandbox_probe(struct udevice *dev)
+{
+	return qfw_register(dev);
+}
+
+static struct dm_qfw_ops qfw_sandbox_ops = {
+	.read_entry_io = qfw_sandbox_read_entry_io,
+	.read_entry_dma = qfw_sandbox_read_entry_dma,
+};
+
+static const struct udevice_id qfw_sandbox_ids[] = {
+	{ .compatible = "sandbox,qemu-fw-cfg-mmio" },
+	{}
+};
+
+U_BOOT_DRIVER(qfw_sandbox) = {
+	.name	= "qfw_sandbox",
+	.id	= UCLASS_QFW,
+	.of_match	= qfw_sandbox_ids,
+	.plat_auto	= sizeof(struct qfw_sandbox_plat),
+	.probe	= qfw_sandbox_probe,
+	.ops	= &qfw_sandbox_ops,
+};
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 6275ec56ea..bdca7ae613 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -95,5 +95,6 @@  obj-$(CONFIG_SCMI_FIRMWARE) += scmi.o
 ifneq ($(CONFIG_PINMUX),)
 obj-$(CONFIG_PINCONF) += pinmux.o
 endif
+obj-$(CONFIG_QFW) += qfw.o
 endif
 endif # !SPL
diff --git a/test/dm/qfw.c b/test/dm/qfw.c
new file mode 100644
index 0000000000..51b1c42dda
--- /dev/null
+++ b/test/dm/qfw.c
@@ -0,0 +1,42 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 Asherah Connor <ashe@kivikakk.ee>
+ */
+
+#include <common.h>
+#include <qfw.h>
+#include <dm.h>
+#include <asm/test.h>
+#include <dm/test.h>
+#include <test/ut.h>
+
+/*
+ * Exercise the device enough to be satisfied the initialisation and DMA
+ * interfaces work.
+ */
+
+static int dm_test_qfw_cpus(struct unit_test_state *uts)
+{
+	struct udevice *dev;
+
+	ut_assertok(uclass_first_device_err(UCLASS_QFW, &dev));
+	ut_asserteq(5, qfw_online_cpus(dev));
+
+	return 0;
+}
+
+DM_TEST(dm_test_qfw_cpus, UT_TESTF_SCAN_FDT);
+
+static int dm_test_qfw_firmware_list(struct unit_test_state *uts)
+{
+	struct udevice *dev;
+	struct fw_file *file;
+
+	ut_assertok(uclass_first_device_err(UCLASS_QFW, &dev));
+	ut_assertok(qfw_read_firmware_list(dev));
+	ut_assertok_ptr((file = qfw_find_file(dev, "test-one")));
+
+	return 0;
+}
+
+DM_TEST(dm_test_qfw_firmware_list, UT_TESTF_SCAN_FDT);