All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/5] Move qfw to DM, add Arm support
@ 2021-02-24  3:23 Asherah Connor
  2021-02-24  3:23 ` [PATCH v4 1/5] arm: x86: qemu: move qfw to DM uclass, " Asherah Connor
                   ` (5 more replies)
  0 siblings, 6 replies; 19+ messages in thread
From: Asherah Connor @ 2021-02-24  3:23 UTC (permalink / raw)
  To: u-boot

This series moves the QFW driver into a uclass, UCLASS_QFW, and splits
the driver into qfw_pio and qfw_mmio.  A sandbox driver is also added,
and a DM unit test against that driver.

On x86 a U_BOOT_DRVINFO is used to configure the qfw_pio (with compiled-
in constants used for PIO ports), otherwise we configure qfw_mmio from
device tree if present.

Version 4 of this series adds a test for the qfw command, exercising it
on QEMU in test/py/tests/test_qfw.py.  The introductory "move QFW to DM"
commit has been rolled into the uclass split one.  Documentation is
added.

To view the changes online, see:
https://git.src.kameliya.ee/~kameliya/u-boot/log/qfw-priv

Asherah Connor (5):
  arm: x86: qemu: move qfw to DM uclass, add Arm support
  arm: x86: qemu: unify qfw driver functions as qfw_
  qemu: add sandbox driver and tests
  test: qemu: add simple test for cmd_qfw
  qemu: add documentation to qfw.h

 arch/arm/Kconfig              |   1 +
 arch/sandbox/dts/sandbox.dtsi |   4 +
 arch/sandbox/dts/test.dts     |   4 +
 arch/x86/cpu/qemu/cpu.c       |   9 +-
 arch/x86/cpu/qemu/qemu.c      |  47 +------
 arch/x86/cpu/qfw_cpu.c        |  11 +-
 cmd/qfw.c                     |  56 ++++----
 common/Makefile               |   2 +
 common/qfw.c                  | 105 +++++++++++++++
 drivers/misc/Makefile         |   7 +-
 drivers/misc/qfw.c            | 242 ++++++++++++----------------------
 drivers/misc/qfw_mmio.c       | 119 +++++++++++++++++
 drivers/misc/qfw_pio.c        |  69 ++++++++++
 drivers/misc/qfw_sandbox.c    | 129 ++++++++++++++++++
 include/dm/uclass-id.h        |   1 +
 include/qfw.h                 | 145 ++++++++++++++++----
 test/dm/Makefile              |   1 +
 test/dm/qfw.c                 |  42 ++++++
 test/py/tests/test_qfw.py     |  21 +++
 19 files changed, 752 insertions(+), 263 deletions(-)
 create mode 100644 common/qfw.c
 create mode 100644 drivers/misc/qfw_mmio.c
 create mode 100644 drivers/misc/qfw_pio.c
 create mode 100644 drivers/misc/qfw_sandbox.c
 create mode 100644 test/dm/qfw.c
 create mode 100644 test/py/tests/test_qfw.py

-- 
2.20.1

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v4 1/5] arm: x86: qemu: move qfw to DM uclass, add Arm support
  2021-02-24  3:23 [PATCH v4 0/5] Move qfw to DM, add Arm support Asherah Connor
@ 2021-02-24  3:23 ` Asherah Connor
  2021-02-25 19:31   ` Simon Glass
                     ` (2 more replies)
  2021-02-24  3:23 ` [PATCH v4 2/5] arm: x86: qemu: unify qfw driver functions as qfw_ Asherah Connor
                   ` (4 subsequent siblings)
  5 siblings, 3 replies; 19+ messages in thread
From: Asherah Connor @ 2021-02-24  3:23 UTC (permalink / raw)
  To: u-boot

Updates the QFW driver to use the driver model, splitting the driver
into qfw_pio and qfw_mmio (for non-x86) in their own uclass.

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

Changes in v4:
- PIO definitions are now #defines
- qfw_*_plat structs are no longer in header files
- Remove yield/pause in DMA wait loop
- Change struct udevice *qfw_get_dev(void) to int qfw_get_dev(struct
  udevice **)

 arch/arm/Kconfig         |   1 +
 arch/x86/cpu/qemu/cpu.c  |   9 +-
 arch/x86/cpu/qemu/qemu.c |  47 +-------
 arch/x86/cpu/qfw_cpu.c   |  11 +-
 cmd/qfw.c                |  52 ++++-----
 common/Makefile          |   2 +
 common/qfw.c             | 105 +++++++++++++++++
 drivers/misc/Makefile    |   6 +-
 drivers/misc/qfw.c       | 238 ++++++++++++++-------------------------
 drivers/misc/qfw_mmio.c  | 119 ++++++++++++++++++++
 drivers/misc/qfw_pio.c   |  69 ++++++++++++
 include/dm/uclass-id.h   |   1 +
 include/qfw.h            |  61 ++++++----
 13 files changed, 466 insertions(+), 255 deletions(-)
 create mode 100644 common/qfw.c
 create mode 100644 drivers/misc/qfw_mmio.c
 create mode 100644 drivers/misc/qfw_pio.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index d51abbeaf0..cd01dc458a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -937,6 +937,7 @@ config ARCH_QEMU
 	imply DM_RNG
 	imply DM_RTC
 	imply RTC_PL031
+	imply CMD_QFW
 
 config ARCH_RMOBILE
 	bool "Renesas ARM SoCs"
diff --git a/arch/x86/cpu/qemu/cpu.c b/arch/x86/cpu/qemu/cpu.c
index 9ce86b379c..c78e374644 100644
--- a/arch/x86/cpu/qemu/cpu.c
+++ b/arch/x86/cpu/qemu/cpu.c
@@ -22,7 +22,14 @@ int cpu_qemu_get_desc(const struct udevice *dev, char *buf, int size)
 
 static int cpu_qemu_get_count(const struct udevice *dev)
 {
-	return qemu_fwcfg_online_cpus();
+	int ret;
+	struct udevice *qfw_dev;
+
+	ret = qfw_get_dev(&qfw_dev);
+	if (ret)
+		return ret;
+
+	return qemu_fwcfg_online_cpus(qfw_dev);
 }
 
 static const struct cpu_ops cpu_qemu_ops = {
diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c
index 044a429c13..605f51e1b8 100644
--- a/arch/x86/cpu/qemu/qemu.c
+++ b/arch/x86/cpu/qemu/qemu.c
@@ -8,6 +8,7 @@
 #include <init.h>
 #include <pci.h>
 #include <qfw.h>
+#include <dm/platdata.h>
 #include <asm/irq.h>
 #include <asm/post.h>
 #include <asm/processor.h>
@@ -18,46 +19,10 @@ static bool i440fx;
 
 #ifdef CONFIG_QFW
 
-/* on x86, the qfw registers are all IO ports */
-#define FW_CONTROL_PORT	0x510
-#define FW_DATA_PORT		0x511
-#define FW_DMA_PORT_LOW	0x514
-#define FW_DMA_PORT_HIGH	0x518
-
-static void qemu_x86_fwcfg_read_entry_pio(uint16_t entry,
-		uint32_t size, void *address)
-{
-	uint32_t i = 0;
-	uint8_t *data = address;
-
-	/*
-	 * writting FW_CFG_INVALID will cause read operation to resume at
-	 * last offset, otherwise read will start at offset 0
-	 *
-	 * Note: on platform where the control register is IO port, the
-	 * endianness is little endian.
-	 */
-	if (entry != FW_CFG_INVALID)
-		outw(cpu_to_le16(entry), FW_CONTROL_PORT);
-
-	/* the endianness of data register is string-preserving */
-	while (size--)
-		data[i++] = inb(FW_DATA_PORT);
-}
-
-static void qemu_x86_fwcfg_read_entry_dma(struct fw_cfg_dma_access *dma)
-{
-	/* the DMA address register is big endian */
-	outl(cpu_to_be32((uintptr_t)dma), FW_DMA_PORT_HIGH);
-
-	while (be32_to_cpu(dma->control) & ~FW_CFG_DMA_ERROR)
-		__asm__ __volatile__ ("pause");
-}
-
-static struct fw_cfg_arch_ops fwcfg_x86_ops = {
-	.arch_read_pio = qemu_x86_fwcfg_read_entry_pio,
-	.arch_read_dma = qemu_x86_fwcfg_read_entry_dma
+U_BOOT_DRVINFO(x86_qfw_pio) = {
+	.name = "qfw_pio",
 };
+
 #endif
 
 static void enable_pm_piix(void)
@@ -132,10 +97,6 @@ static void qemu_chipset_init(void)
 
 		enable_pm_ich9();
 	}
-
-#ifdef CONFIG_QFW
-	qemu_fwcfg_init(&fwcfg_x86_ops);
-#endif
 }
 
 #if !CONFIG_IS_ENABLED(SPL_X86_32BIT_INIT)
diff --git a/arch/x86/cpu/qfw_cpu.c b/arch/x86/cpu/qfw_cpu.c
index b959eaddde..9700908064 100644
--- a/arch/x86/cpu/qfw_cpu.c
+++ b/arch/x86/cpu/qfw_cpu.c
@@ -18,7 +18,7 @@ int qemu_cpu_fixup(void)
 	int cpu_num;
 	int cpu_online;
 	struct uclass *uc;
-	struct udevice *dev, *pdev;
+	struct udevice *dev, *pdev, *qfwdev;
 	struct cpu_plat *plat;
 	char *cpu;
 
@@ -39,6 +39,13 @@ int qemu_cpu_fixup(void)
 		return -ENODEV;
 	}
 
+	/* get qfw dev */
+	ret = qfw_get_dev(&qfwdev);
+	if (ret) {
+		printf("unable to find qfw device\n");
+		return ret;
+	}
+
 	/* calculate cpus that are already bound */
 	cpu_num = 0;
 	for (uclass_find_first_device(UCLASS_CPU, &dev);
@@ -48,7 +55,7 @@ int qemu_cpu_fixup(void)
 	}
 
 	/* get actual cpu number */
-	cpu_online = qemu_fwcfg_online_cpus();
+	cpu_online = qemu_fwcfg_online_cpus(qfwdev);
 	if (cpu_online < 0) {
 		printf("unable to get online cpu number: %d\n", cpu_online);
 		return cpu_online;
diff --git a/cmd/qfw.c b/cmd/qfw.c
index bb571487f0..87af408a8d 100644
--- a/cmd/qfw.c
+++ b/cmd/qfw.c
@@ -8,19 +8,22 @@
 #include <env.h>
 #include <errno.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.
  */
-static int qemu_fwcfg_setup_kernel(void *load_addr, void *initrd_addr)
+static int qemu_fwcfg_cmd_setup_kernel(void *load_addr, void *initrd_addr)
 {
 	char *data_addr;
 	uint32_t setup_size, kernel_size, cmdline_size, initrd_size;
 
-	qemu_fwcfg_read_entry(FW_CFG_SETUP_SIZE, 4, &setup_size);
-	qemu_fwcfg_read_entry(FW_CFG_KERNEL_SIZE, 4, &kernel_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 (setup_size == 0 || kernel_size == 0) {
 		printf("warning: no kernel available\n");
@@ -28,28 +31,28 @@ static int qemu_fwcfg_setup_kernel(void *load_addr, void *initrd_addr)
 	}
 
 	data_addr = load_addr;
-	qemu_fwcfg_read_entry(FW_CFG_SETUP_DATA,
-			      le32_to_cpu(setup_size), data_addr);
+	qfw_read_entry(qfw_dev, FW_CFG_SETUP_DATA,
+		       le32_to_cpu(setup_size), data_addr);
 	data_addr += le32_to_cpu(setup_size);
 
-	qemu_fwcfg_read_entry(FW_CFG_KERNEL_DATA,
-			      le32_to_cpu(kernel_size), data_addr);
+	qfw_read_entry(qfw_dev, FW_CFG_KERNEL_DATA,
+		       le32_to_cpu(kernel_size), data_addr);
 	data_addr += le32_to_cpu(kernel_size);
 
 	data_addr = initrd_addr;
-	qemu_fwcfg_read_entry(FW_CFG_INITRD_SIZE, 4, &initrd_size);
+	qfw_read_entry(qfw_dev, FW_CFG_INITRD_SIZE, 4, &initrd_size);
 	if (initrd_size == 0) {
 		printf("warning: no initrd available\n");
 	} else {
-		qemu_fwcfg_read_entry(FW_CFG_INITRD_DATA,
-				      le32_to_cpu(initrd_size), data_addr);
+		qfw_read_entry(qfw_dev, FW_CFG_INITRD_DATA,
+			       le32_to_cpu(initrd_size), data_addr);
 		data_addr += le32_to_cpu(initrd_size);
 	}
 
-	qemu_fwcfg_read_entry(FW_CFG_CMDLINE_SIZE, 4, &cmdline_size);
+	qfw_read_entry(qfw_dev, FW_CFG_CMDLINE_SIZE, 4, &cmdline_size);
 	if (cmdline_size) {
-		qemu_fwcfg_read_entry(FW_CFG_CMDLINE_DATA,
-				      le32_to_cpu(cmdline_size), data_addr);
+		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
@@ -72,19 +75,18 @@ static int qemu_fwcfg_setup_kernel(void *load_addr, void *initrd_addr)
 	return 0;
 }
 
-static int qemu_fwcfg_list_firmware(void)
+static int qemu_fwcfg_cmd_list_firmware(void)
 {
 	int ret;
 	struct fw_cfg_file_iter iter;
 	struct fw_file *file;
 
 	/* make sure fw_list is loaded */
-	ret = qemu_fwcfg_read_firmware_list();
+	ret = qemu_fwcfg_read_firmware_list(qfw_dev);
 	if (ret)
 		return ret;
 
-
-	for (file = qemu_fwcfg_file_iter_init(&iter);
+	for (file = qemu_fwcfg_file_iter_init(qfw_dev, &iter);
 	     !qemu_fwcfg_file_iter_end(&iter);
 	     file = qemu_fwcfg_file_iter_next(&iter)) {
 		printf("%-56s\n", file->cfg.name);
@@ -96,7 +98,7 @@ static int qemu_fwcfg_list_firmware(void)
 static int qemu_fwcfg_do_list(struct cmd_tbl *cmdtp, int flag,
 			      int argc, char *const argv[])
 {
-	if (qemu_fwcfg_list_firmware() < 0)
+	if (qemu_fwcfg_cmd_list_firmware() < 0)
 		return CMD_RET_FAILURE;
 
 	return 0;
@@ -105,14 +107,7 @@ static int qemu_fwcfg_do_list(struct cmd_tbl *cmdtp, int flag,
 static int qemu_fwcfg_do_cpus(struct cmd_tbl *cmdtp, int flag,
 			      int argc, char *const argv[])
 {
-	int ret = qemu_fwcfg_online_cpus();
-	if (ret < 0) {
-		printf("QEMU fw_cfg interface not found\n");
-		return CMD_RET_FAILURE;
-	}
-
-	printf("%d cpu(s) online\n", qemu_fwcfg_online_cpus());
-
+	printf("%d cpu(s) online\n", qemu_fwcfg_online_cpus(qfw_dev));
 	return 0;
 }
 
@@ -153,7 +148,7 @@ static int qemu_fwcfg_do_load(struct cmd_tbl *cmdtp, int flag,
 		return CMD_RET_FAILURE;
 	}
 
-	return qemu_fwcfg_setup_kernel(load_addr, initrd_addr);
+	return qemu_fwcfg_cmd_setup_kernel(load_addr, initrd_addr);
 }
 
 static struct cmd_tbl fwcfg_commands[] = {
@@ -168,7 +163,8 @@ static int do_qemu_fw(struct cmd_tbl *cmdtp, int flag, int argc,
 	int ret;
 	struct cmd_tbl *fwcfg_cmd;
 
-	if (!qemu_fwcfg_present()) {
+	ret = qfw_get_dev(&qfw_dev);
+	if (ret) {
 		printf("QEMU fw_cfg interface not found\n");
 		return CMD_RET_USAGE;
 	}
diff --git a/common/Makefile b/common/Makefile
index daeea67cf2..f174a06c33 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -137,3 +137,5 @@ obj-$(CONFIG_CMD_LOADB) += xyzModem.o
 obj-$(CONFIG_$(SPL_TPL_)YMODEM_SUPPORT) += xyzModem.o
 
 obj-$(CONFIG_AVB_VERIFY) += avb_verify.o
+
+obj-$(CONFIG_QFW) += qfw.o
diff --git a/common/qfw.c b/common/qfw.c
new file mode 100644
index 0000000000..c0ffa20b74
--- /dev/null
+++ b/common/qfw.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2015 Miao Yan <yanmiaobest@gmail.com>
+ * (C) Copyright 2021 Asherah Connor <ashe@kivikakk.ee>
+ */
+
+#include <dm.h>
+#include <dm/uclass.h>
+#include <qfw.h>
+#include <stdlib.h>
+
+int qfw_get_dev(struct udevice **devp)
+{
+	return uclass_first_device(UCLASS_QFW, devp);
+}
+
+int qemu_fwcfg_online_cpus(struct udevice *dev)
+{
+	u16 nb_cpus;
+
+	qfw_read_entry(dev, FW_CFG_NB_CPUS, 2, &nb_cpus);
+
+	return le16_to_cpu(nb_cpus);
+}
+
+int qemu_fwcfg_read_firmware_list(struct udevice *dev)
+{
+	int i;
+	u32 count;
+	struct fw_file *file;
+	struct list_head *entry;
+
+	struct qfw_dev *qdev = dev_get_uclass_priv(dev);
+
+	/* don't read it twice */
+	if (!list_empty(&qdev->fw_list))
+		return 0;
+
+	qfw_read_entry(dev, FW_CFG_FILE_DIR, 4, &count);
+	if (!count)
+		return 0;
+
+	count = be32_to_cpu(count);
+	for (i = 0; i < count; i++) {
+		file = malloc(sizeof(*file));
+		if (!file) {
+			printf("error: allocating resource\n");
+			goto err;
+		}
+		qfw_read_entry(dev, FW_CFG_INVALID,
+			       sizeof(struct fw_cfg_file), &file->cfg);
+		file->addr = 0;
+		list_add_tail(&file->list, &qdev->fw_list);
+	}
+
+	return 0;
+
+err:
+	list_for_each(entry, &qdev->fw_list) {
+		file = list_entry(entry, struct fw_file, list);
+		free(file);
+	}
+
+	return -ENOMEM;
+}
+
+struct fw_file *qemu_fwcfg_find_file(struct udevice *dev, const char *name)
+{
+	struct list_head *entry;
+	struct fw_file *file;
+
+	struct qfw_dev *qdev = dev_get_uclass_priv(dev);
+
+	list_for_each(entry, &qdev->fw_list) {
+		file = list_entry(entry, struct fw_file, list);
+		if (!strcmp(file->cfg.name, name))
+			return file;
+	}
+
+	return NULL;
+}
+
+struct fw_file *qemu_fwcfg_file_iter_init(struct udevice *dev,
+					  struct fw_cfg_file_iter *iter)
+{
+	struct qfw_dev *qdev = dev_get_uclass_priv(dev);
+
+	iter->entry = qdev->fw_list.next;
+	iter->end = &qdev->fw_list;
+	return list_entry((struct list_head *)iter->entry,
+			  struct fw_file, list);
+}
+
+struct fw_file *qemu_fwcfg_file_iter_next(struct fw_cfg_file_iter *iter)
+{
+	iter->entry = ((struct list_head *)iter->entry)->next;
+	return list_entry((struct list_head *)iter->entry,
+			  struct fw_file, list);
+}
+
+bool qemu_fwcfg_file_iter_end(struct fw_cfg_file_iter *iter)
+{
+	return iter->entry == iter->end;
+}
+
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index d737203704..2988289ea3 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -55,7 +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_QFW
+obj-y += qfw.o
+obj-$(CONFIG_X86) += qfw_pio.o
+obj-$(CONFIG_ARM) += qfw_mmio.o
+endif
 obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o
 obj-$(CONFIG_ROCKCHIP_OTP) += rockchip-otp.o
 obj-$(CONFIG_SANDBOX) += syscon_sandbox.o misc_sandbox.o
diff --git a/drivers/misc/qfw.c b/drivers/misc/qfw.c
index f6eb6583ed..7ad8f0979b 100644
--- a/drivers/misc/qfw.c
+++ b/drivers/misc/qfw.c
@@ -1,25 +1,22 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
  * (C) Copyright 2015 Miao Yan <yanmiaobest@gmail.com>
+ * (C) Copyright 2021 Asherah Connor <ashe@kivikakk.ee>
  */
 
+#define LOG_CATEGORY UCLASS_QFW
+
 #include <common.h>
 #include <command.h>
 #include <errno.h>
 #include <log.h>
 #include <malloc.h>
 #include <qfw.h>
-#include <asm/io.h>
+#include <dm.h>
+#include <misc.h>
 #ifdef CONFIG_GENERATE_ACPI_TABLE
 #include <asm/tables.h>
 #endif
-#include <linux/list.h>
-
-static bool fwcfg_present;
-static bool fwcfg_dma_present;
-static struct fw_cfg_arch_ops *fwcfg_arch_ops;
-
-static LIST_HEAD(fw_list);
 
 #ifdef CONFIG_GENERATE_ACPI_TABLE
 /*
@@ -32,7 +29,8 @@ static LIST_HEAD(fw_list);
  *          be ignored.
  * @return: 0 on success, or negative value on failure
  */
-static int bios_linker_allocate(struct bios_linker_entry *entry, ulong *addr)
+static int bios_linker_allocate(struct udevice *dev,
+				struct bios_linker_entry *entry, ulong *addr)
 {
 	uint32_t size, align;
 	struct fw_file *file;
@@ -45,7 +43,7 @@ static int bios_linker_allocate(struct bios_linker_entry *entry, ulong *addr)
 		return -EINVAL;
 	}
 
-	file = qemu_fwcfg_find_file(entry->alloc.file);
+	file = qemu_fwcfg_find_file(dev, entry->alloc.file);
 	if (!file) {
 		printf("error: can't find file %s\n", entry->alloc.file);
 		return -ENOENT;
@@ -75,8 +73,8 @@ static int bios_linker_allocate(struct bios_linker_entry *entry, ulong *addr)
 	debug("bios_linker_allocate: allocate file %s, size %u, zone %d, align %u, addr 0x%lx\n",
 	      file->cfg.name, size, entry->alloc.zone, align, aligned_addr);
 
-	qemu_fwcfg_read_entry(be16_to_cpu(file->cfg.select),
-			      size, (void *)aligned_addr);
+	qfw_read_entry(dev, be16_to_cpu(file->cfg.select), size,
+		       (void *)aligned_addr);
 	file->addr = aligned_addr;
 
 	/* adjust address for low memory allocation */
@@ -94,16 +92,17 @@ static int bios_linker_allocate(struct bios_linker_entry *entry, ulong *addr)
  *          ACPI tables
  * @return: 0 on success, or negative value on failure
  */
-static int bios_linker_add_pointer(struct bios_linker_entry *entry)
+static int bios_linker_add_pointer(struct udevice *dev,
+				   struct bios_linker_entry *entry)
 {
 	struct fw_file *dest, *src;
 	uint32_t offset = le32_to_cpu(entry->pointer.offset);
 	uint64_t pointer = 0;
 
-	dest = qemu_fwcfg_find_file(entry->pointer.dest_file);
+	dest = qemu_fwcfg_find_file(dev, entry->pointer.dest_file);
 	if (!dest || !dest->addr)
 		return -ENOENT;
-	src = qemu_fwcfg_find_file(entry->pointer.src_file);
+	src = qemu_fwcfg_find_file(dev, entry->pointer.src_file);
 	if (!src || !src->addr)
 		return -ENOENT;
 
@@ -127,13 +126,14 @@ static int bios_linker_add_pointer(struct bios_linker_entry *entry)
  *          checksums
  * @return: 0 on success, or negative value on failure
  */
-static int bios_linker_add_checksum(struct bios_linker_entry *entry)
+static int bios_linker_add_checksum(struct udevice *dev,
+				    struct bios_linker_entry *entry)
 {
 	struct fw_file *file;
 	uint8_t *data, cksum = 0;
 	uint8_t *cksum_start;
 
-	file = qemu_fwcfg_find_file(entry->cksum.file);
+	file = qemu_fwcfg_find_file(dev, entry->cksum.file);
 	if (!file || !file->addr)
 		return -ENOENT;
 
@@ -149,20 +149,27 @@ static int bios_linker_add_checksum(struct bios_linker_entry *entry)
 /* This function loads and patches ACPI tables provided by QEMU */
 ulong write_acpi_tables(ulong addr)
 {
-	int i, ret = 0;
+	int i, ret;
 	struct fw_file *file;
 	struct bios_linker_entry *table_loader;
 	struct bios_linker_entry *entry;
 	uint32_t size;
+	struct udevice *dev;
+
+	ret = qfw_get_dev(&dev);
+	if (ret) {
+		printf("error: no qfw\n");
+		return addr;
+	}
 
 	/* make sure fw_list is loaded */
-	ret = qemu_fwcfg_read_firmware_list();
+	ret = qemu_fwcfg_read_firmware_list(dev);
 	if (ret) {
 		printf("error: can't read firmware file list\n");
 		return addr;
 	}
 
-	file = qemu_fwcfg_find_file("etc/table-loader");
+	file = qemu_fwcfg_find_file(dev, "etc/table-loader");
 	if (!file) {
 		printf("error: can't find etc/table-loader\n");
 		return addr;
@@ -180,24 +187,23 @@ ulong write_acpi_tables(ulong addr)
 		return addr;
 	}
 
-	qemu_fwcfg_read_entry(be16_to_cpu(file->cfg.select),
-			      size, table_loader);
+	qfw_read_entry(dev, be16_to_cpu(file->cfg.select), size, table_loader);
 
 	for (i = 0; i < (size / sizeof(*entry)); i++) {
 		entry = table_loader + i;
 		switch (le32_to_cpu(entry->command)) {
 		case BIOS_LINKER_LOADER_COMMAND_ALLOCATE:
-			ret = bios_linker_allocate(entry, &addr);
+			ret = bios_linker_allocate(dev, entry, &addr);
 			if (ret)
 				goto out;
 			break;
 		case BIOS_LINKER_LOADER_COMMAND_ADD_POINTER:
-			ret = bios_linker_add_pointer(entry);
+			ret = bios_linker_add_pointer(dev, entry);
 			if (ret)
 				goto out;
 			break;
 		case BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM:
-			ret = bios_linker_add_checksum(entry);
+			ret = bios_linker_add_checksum(dev, entry);
 			if (ret)
 				goto out;
 			break;
@@ -209,7 +215,7 @@ ulong write_acpi_tables(ulong addr)
 out:
 	if (ret) {
 		struct fw_cfg_file_iter iter;
-		for (file = qemu_fwcfg_file_iter_init(&iter);
+		for (file = qemu_fwcfg_file_iter_init(dev, &iter);
 		     !qemu_fwcfg_file_iter_end(&iter);
 		     file = qemu_fwcfg_file_iter_next(&iter)) {
 			if (file->addr) {
@@ -225,170 +231,90 @@ out:
 
 ulong acpi_get_rsdp_addr(void)
 {
+	int ret;
 	struct fw_file *file;
+	struct udevice *dev;
 
-	file = qemu_fwcfg_find_file("etc/acpi/rsdp");
+	ret = qfw_get_dev(&dev);
+	if (ret) {
+		printf("error: no qfw\n");
+		return 0;
+	}
+
+	file = qemu_fwcfg_find_file(dev, "etc/acpi/rsdp");
 	return file->addr;
 }
 #endif
 
-/* Read configuration item using fw_cfg PIO interface */
-static void qemu_fwcfg_read_entry_pio(uint16_t entry,
-		uint32_t size, void *address)
+static void qfw_read_entry_io(struct qfw_dev *qdev, u16 entry, u32 size,
+			      void *address)
 {
-	debug("qemu_fwcfg_read_entry_pio: entry 0x%x, size %u address %p\n",
-	      entry, size, address);
+	struct dm_qfw_ops *ops = dm_qfw_get_ops(qdev->dev);
 
-	return fwcfg_arch_ops->arch_read_pio(entry, size, address);
+	debug("%s: entry 0x%x, size %u address %p\n", __func__, entry, size,
+	      address);
+
+	ops->read_entry_io(qdev->dev, entry, size, address);
 }
 
-/* Read configuration item using fw_cfg DMA interface */
-static void qemu_fwcfg_read_entry_dma(uint16_t entry,
-		uint32_t size, void *address)
+static void qfw_read_entry_dma(struct qfw_dev *qdev, u16 entry, u32 size,
+			       void *address)
 {
-	struct fw_cfg_dma_access dma;
+	struct dm_qfw_ops *ops = dm_qfw_get_ops(qdev->dev);
 
-	dma.length = cpu_to_be32(size);
-	dma.address = cpu_to_be64((uintptr_t)address);
-	dma.control = cpu_to_be32(FW_CFG_DMA_READ);
+	struct qfw_dma dma = {
+		.length = cpu_to_be32(size),
+		.address = cpu_to_be64((uintptr_t)address),
+		.control = cpu_to_be32(FW_CFG_DMA_READ),
+	};
 
 	/*
-	 * writting FW_CFG_INVALID will cause read operation to resume at
-	 * last offset, otherwise read will start at offset 0
+	 * writing FW_CFG_INVALID will cause read operation to resume at last
+	 * offset, otherwise read will start at offset 0
 	 */
 	if (entry != FW_CFG_INVALID)
 		dma.control |= cpu_to_be32(FW_CFG_DMA_SELECT | (entry << 16));
 
-	barrier();
-
-	debug("qemu_fwcfg_read_entry_dma: entry 0x%x, size %u address %p, control 0x%x\n",
+	debug("%s: entry 0x%x, size %u address %p, control 0x%x\n", __func__,
 	      entry, size, address, be32_to_cpu(dma.control));
 
-	fwcfg_arch_ops->arch_read_dma(&dma);
-}
+	barrier();
 
-bool qemu_fwcfg_present(void)
-{
-	return fwcfg_present;
+	ops->read_entry_dma(qdev->dev, &dma);
 }
 
-bool qemu_fwcfg_dma_present(void)
+void qfw_read_entry(struct udevice *dev, u16 entry, u32 length, void *address)
 {
-	return fwcfg_dma_present;
-}
+	struct qfw_dev *qdev = dev_get_uclass_priv(dev);
 
-void qemu_fwcfg_read_entry(uint16_t entry, uint32_t length, void *address)
-{
-	if (fwcfg_dma_present)
-		qemu_fwcfg_read_entry_dma(entry, length, address);
+	if (qdev->dma_present)
+		qfw_read_entry_dma(qdev, entry, length, address);
 	else
-		qemu_fwcfg_read_entry_pio(entry, length, address);
+		qfw_read_entry_io(qdev, entry, length, address);
 }
 
-int qemu_fwcfg_online_cpus(void)
+int qfw_register(struct udevice *dev)
 {
-	uint16_t nb_cpus;
+	struct qfw_dev *qdev = dev_get_uclass_priv(dev);
+	u32 qemu, dma_enabled;
 
-	if (!fwcfg_present)
+	qdev->dev = dev;
+	INIT_LIST_HEAD(&qdev->fw_list);
+
+	qfw_read_entry_io(qdev, FW_CFG_SIGNATURE, 4, &qemu);
+	if (be32_to_cpu(qemu) != QEMU_FW_CFG_SIGNATURE)
 		return -ENODEV;
 
-	qemu_fwcfg_read_entry(FW_CFG_NB_CPUS, 2, &nb_cpus);
-
-	return le16_to_cpu(nb_cpus);
-}
-
-int qemu_fwcfg_read_firmware_list(void)
-{
-	int i;
-	uint32_t count;
-	struct fw_file *file;
-	struct list_head *entry;
-
-	/* don't read it twice */
-	if (!list_empty(&fw_list))
-		return 0;
-
-	qemu_fwcfg_read_entry(FW_CFG_FILE_DIR, 4, &count);
-	if (!count)
-		return 0;
-
-	count = be32_to_cpu(count);
-	for (i = 0; i < count; i++) {
-		file = malloc(sizeof(*file));
-		if (!file) {
-			printf("error: allocating resource\n");
-			goto err;
-		}
-		qemu_fwcfg_read_entry(FW_CFG_INVALID,
-				      sizeof(struct fw_cfg_file), &file->cfg);
-		file->addr = 0;
-		list_add_tail(&file->list, &fw_list);
-	}
+	qfw_read_entry_io(qdev, FW_CFG_ID, 1, &dma_enabled);
+	if (dma_enabled & FW_CFG_DMA_ENABLED)
+		qdev->dma_present = true;
 
 	return 0;
-
-err:
-	list_for_each(entry, &fw_list) {
-		file = list_entry(entry, struct fw_file, list);
-		free(file);
-	}
-
-	return -ENOMEM;
-}
-
-struct fw_file *qemu_fwcfg_find_file(const char *name)
-{
-	struct list_head *entry;
-	struct fw_file *file;
-
-	list_for_each(entry, &fw_list) {
-		file = list_entry(entry, struct fw_file, list);
-		if (!strcmp(file->cfg.name, name))
-			return file;
-	}
-
-	return NULL;
-}
-
-struct fw_file *qemu_fwcfg_file_iter_init(struct fw_cfg_file_iter *iter)
-{
-	iter->entry = fw_list.next;
-	return list_entry((struct list_head *)iter->entry,
-			  struct fw_file, list);
 }
 
-struct fw_file *qemu_fwcfg_file_iter_next(struct fw_cfg_file_iter *iter)
-{
-	iter->entry = ((struct list_head *)iter->entry)->next;
-	return list_entry((struct list_head *)iter->entry,
-			  struct fw_file, list);
-}
-
-bool qemu_fwcfg_file_iter_end(struct fw_cfg_file_iter *iter)
-{
-	return iter->entry == &fw_list;
-}
-
-void qemu_fwcfg_init(struct fw_cfg_arch_ops *ops)
-{
-	uint32_t qemu;
-	uint32_t dma_enabled;
+UCLASS_DRIVER(qfw) = {
+	.id		= UCLASS_QFW,
+	.name		= "qfw",
+	.per_device_auto	= sizeof(struct qfw_dev),
+};
 
-	fwcfg_present = false;
-	fwcfg_dma_present = false;
-	fwcfg_arch_ops = NULL;
-
-	if (!ops || !ops->arch_read_pio || !ops->arch_read_dma)
-		return;
-	fwcfg_arch_ops = ops;
-
-	qemu_fwcfg_read_entry_pio(FW_CFG_SIGNATURE, 4, &qemu);
-	if (be32_to_cpu(qemu) == QEMU_FW_CFG_SIGNATURE)
-		fwcfg_present = true;
-
-	if (fwcfg_present) {
-		qemu_fwcfg_read_entry_pio(FW_CFG_ID, 1, &dma_enabled);
-		if (dma_enabled & FW_CFG_DMA_ENABLED)
-			fwcfg_dma_present = true;
-	}
-}
diff --git a/drivers/misc/qfw_mmio.c b/drivers/misc/qfw_mmio.c
new file mode 100644
index 0000000000..f397384054
--- /dev/null
+++ b/drivers/misc/qfw_mmio.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * MMIO 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_mmio {
+	/*
+	 * Each access to the 64-bit data register can be 8/16/32/64 bits wide.
+	 */
+	union {
+		u8 data8;
+		u16 data16;
+		u32 data32;
+		u64 data64;
+	};
+	u16 selector;
+	u8 padding[6];
+	u64 dma;
+};
+
+struct qfw_mmio_plat {
+	volatile struct qfw_mmio *mmio;
+};
+
+static void qfw_mmio_read_entry_io(struct udevice *dev, u16 entry, u32 size,
+				   void *address)
+{
+	struct qfw_mmio_plat *plat = dev_get_plat(dev);
+
+	/*
+	 * writing FW_CFG_INVALID will cause read operation to resume at last
+	 * offset, otherwise read will start at offset 0
+	 *
+	 * Note: on platform where the control register is MMIO, the register
+	 * is big endian.
+	 */
+	if (entry != FW_CFG_INVALID)
+		plat->mmio->selector = cpu_to_be16(entry);
+
+	/* the endianness of data register is string-preserving */
+	while (size >= 8) {
+		*(u64 *)address = plat->mmio->data64;
+		address += 8;
+		size -= 8;
+	}
+	while (size >= 4) {
+		*(u32 *)address = plat->mmio->data32;
+		address += 4;
+		size -= 4;
+	}
+	while (size >= 2) {
+		*(u16 *)address = plat->mmio->data16;
+		address += 2;
+		size -= 2;
+	}
+	while (size >= 1) {
+		*(u8 *)address = plat->mmio->data8;
+		address += 1;
+		size -= 1;
+	}
+}
+
+/* Read configuration item using fw_cfg DMA interface */
+static void qfw_mmio_read_entry_dma(struct udevice *dev, struct qfw_dma *dma)
+{
+	struct qfw_mmio_plat *plat = dev_get_plat(dev);
+
+	/* the DMA address register is big-endian */
+	plat->mmio->dma = cpu_to_be64((uintptr_t)dma);
+
+	while (be32_to_cpu(dma->control) & ~FW_CFG_DMA_ERROR);
+}
+
+static int qfw_mmio_of_to_plat(struct udevice *dev)
+{
+	struct qfw_mmio_plat *plat = dev_get_plat(dev);
+
+	plat->mmio = map_physmem(dev_read_addr(dev),
+				 sizeof(struct qfw_mmio),
+				 MAP_NOCACHE);
+
+	return 0;
+}
+
+static int qfw_mmio_probe(struct udevice *dev)
+{
+	return qfw_register(dev);
+}
+
+static struct dm_qfw_ops qfw_mmio_ops = {
+	.read_entry_io = qfw_mmio_read_entry_io,
+	.read_entry_dma = qfw_mmio_read_entry_dma,
+};
+
+static const struct udevice_id qfw_mmio_ids[] = {
+	{ .compatible = "qemu,fw-cfg-mmio" },
+	{}
+};
+
+U_BOOT_DRIVER(qfw_mmio) = {
+	.name	= "qfw_mmio",
+	.id	= UCLASS_QFW,
+	.of_match	= qfw_mmio_ids,
+	.plat_auto	= sizeof(struct qfw_mmio_plat),
+	.of_to_plat	= qfw_mmio_of_to_plat,
+	.probe	= qfw_mmio_probe,
+	.ops	= &qfw_mmio_ops,
+};
diff --git a/drivers/misc/qfw_pio.c b/drivers/misc/qfw_pio.c
new file mode 100644
index 0000000000..e2f628d338
--- /dev/null
+++ b/drivers/misc/qfw_pio.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * PIO 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/io.h>
+#include <dm/device.h>
+#include <qfw.h>
+
+/*
+ * PIO ports are correct for x86, which appears to be the only arch that uses
+ * PIO.
+ */
+#define FW_CONTROL_PORT      0x510
+#define FW_DATA_PORT         0x511
+#define FW_DMA_PORT_LOW      0x514
+#define FW_DMA_PORT_HIGH     0x518
+
+static void qfw_pio_read_entry_io(struct udevice *dev, u16 entry, u32 size,
+				  void *address)
+{
+	/*
+	 * writing FW_CFG_INVALID will cause read operation to resume at last
+	 * offset, otherwise read will start at offset 0
+	 *
+	 * Note: on platform where the control register is IO port, the
+	 * endianness is little endian.
+	 */
+	if (entry != FW_CFG_INVALID)
+		outw(cpu_to_le16(entry), FW_CONTROL_PORT);
+
+	/* the endianness of data register is string-preserving */
+	u32 i = 0;
+	u8 *data = address;
+
+	while (size--)
+		data[i++] = inb(FW_DATA_PORT);
+}
+
+/* Read configuration item using fw_cfg DMA interface */
+static void qfw_pio_read_entry_dma(struct udevice *dev, struct qfw_dma *dma)
+{
+	/* the DMA address register is big-endian */
+	outl(cpu_to_be32((uintptr_t)dma), FW_DMA_PORT_HIGH);
+
+	while (be32_to_cpu(dma->control) & ~FW_CFG_DMA_ERROR);
+}
+
+static int qfw_pio_probe(struct udevice *dev)
+{
+	return qfw_register(dev);
+}
+
+static struct dm_qfw_ops qfw_pio_ops = {
+	.read_entry_io = qfw_pio_read_entry_io,
+	.read_entry_dma = qfw_pio_read_entry_dma,
+};
+
+U_BOOT_DRIVER(qfw_pio) = {
+	.name	= "qfw_pio",
+	.id	= UCLASS_QFW,
+	.probe	= qfw_pio_probe,
+	.ops	= &qfw_pio_ops,
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index d75de368c5..d800f679d5 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -90,6 +90,7 @@ enum uclass_id {
 	UCLASS_POWER_DOMAIN,	/* (SoC) Power domains */
 	UCLASS_PWM,		/* Pulse-width modulator */
 	UCLASS_PWRSEQ,		/* Power sequence device */
+	UCLASS_QFW,		/* QEMU firmware config device */
 	UCLASS_RAM,		/* RAM controller */
 	UCLASS_REGULATOR,	/* Regulator device */
 	UCLASS_REMOTEPROC,	/* Remote Processor device */
diff --git a/include/qfw.h b/include/qfw.h
index cea8e11d44..7b389dec25 100644
--- a/include/qfw.h
+++ b/include/qfw.h
@@ -82,19 +82,7 @@ struct fw_file {
 };
 
 struct fw_cfg_file_iter {
-	struct list_head *entry; /* structure to iterate file list */
-};
-
-struct fw_cfg_dma_access {
-	__be32 control;
-	__be32 length;
-	__be64 address;
-};
-
-struct fw_cfg_arch_ops {
-	void (*arch_read_pio)(uint16_t selector, uint32_t size,
-			void *address);
-	void (*arch_read_dma)(struct fw_cfg_dma_access *dma);
+	struct list_head *entry, *end; /* structures to iterate file list */
 };
 
 struct bios_linker_entry {
@@ -146,32 +134,57 @@ struct bios_linker_entry {
 	};
 } __packed;
 
+struct qfw_dma {
+	__be32 control;
+	__be32 length;
+	__be64 address;
+};
+
+struct qfw_dev {
+	struct udevice *dev;
+	bool dma_present;
+	struct list_head fw_list;
+};
+
+struct dm_qfw_ops {
+	void (*read_entry_io)(struct udevice *dev, u16 entry, u32 size,
+			      void *address);
+	void (*read_entry_dma)(struct udevice *dev, struct qfw_dma *dma);
+};
+
+#define dm_qfw_get_ops(dev) \
+		((struct dm_qfw_ops *)(dev)->driver->ops)
+
+int qfw_register(struct udevice *dev);
+
+struct udevice;
+
 /**
- * Initialize QEMU fw_cfg interface
+ * Get QEMU firmware config device.
  *
- * @ops: arch specific read operations
+ * @devp   Pointer to be filled with address of the qfw device.
+ *
+ * @return 0 on success, -ENODEV if the device is not available.
  */
-void qemu_fwcfg_init(struct fw_cfg_arch_ops *ops);
+int qfw_get_dev(struct udevice **devp);
 
-void qemu_fwcfg_read_entry(uint16_t entry, uint32_t length, void *address);
-int qemu_fwcfg_read_firmware_list(void);
-struct fw_file *qemu_fwcfg_find_file(const char *name);
+void qfw_read_entry(struct udevice *dev, u16 entry, u32 length, void *address);
+int qemu_fwcfg_read_firmware_list(struct udevice *dev);
+struct fw_file *qemu_fwcfg_find_file(struct udevice *dev, const char *name);
 
 /**
  * Get system cpu number
  *
  * @return:   cpu number in system
  */
-int qemu_fwcfg_online_cpus(void);
+int qemu_fwcfg_online_cpus(struct udevice *dev);
 
 /* helper functions to iterate firmware file list */
-struct fw_file *qemu_fwcfg_file_iter_init(struct fw_cfg_file_iter *iter);
+struct fw_file *qemu_fwcfg_file_iter_init(struct udevice *dev,
+					  struct fw_cfg_file_iter *iter);
 struct fw_file *qemu_fwcfg_file_iter_next(struct fw_cfg_file_iter *iter);
 bool qemu_fwcfg_file_iter_end(struct fw_cfg_file_iter *iter);
 
-bool qemu_fwcfg_present(void);
-bool qemu_fwcfg_dma_present(void);
-
 /**
  * qemu_cpu_fixup() - Fix up the CPUs for QEMU
  *
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v4 2/5] arm: x86: qemu: unify qfw driver functions as qfw_
  2021-02-24  3:23 [PATCH v4 0/5] Move qfw to DM, add Arm support Asherah Connor
  2021-02-24  3:23 ` [PATCH v4 1/5] arm: x86: qemu: move qfw to DM uclass, " Asherah Connor
@ 2021-02-24  3:23 ` Asherah Connor
  2021-02-25 19:31   ` Simon Glass
  2021-02-24  3:23 ` [PATCH v4 3/5] qemu: add sandbox driver and tests Asherah Connor
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 19+ messages in thread
From: Asherah Connor @ 2021-02-24  3:23 UTC (permalink / raw)
  To: u-boot

There's a mixture of "qemu_fwcfg_"-prefixed functions and
"qfw_"-prefixed ones.  Now that the qfw name is applied in multiple
places (i.e. the uclass itself, and each of its drivers), let's
consistently use the prefix "qfw_" for anything relating to the
drivers.

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

(no changes since v1)

 arch/x86/cpu/qemu/cpu.c |  2 +-
 arch/x86/cpu/qfw_cpu.c  |  2 +-
 cmd/qfw.c               | 10 +++++-----
 common/qfw.c            | 14 +++++++-------
 drivers/misc/qfw.c      | 20 ++++++++++----------
 include/qfw.h           | 16 ++++++++--------
 6 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/arch/x86/cpu/qemu/cpu.c b/arch/x86/cpu/qemu/cpu.c
index c78e374644..735b656084 100644
--- a/arch/x86/cpu/qemu/cpu.c
+++ b/arch/x86/cpu/qemu/cpu.c
@@ -29,7 +29,7 @@ static int cpu_qemu_get_count(const struct udevice *dev)
 	if (ret)
 		return ret;
 
-	return qemu_fwcfg_online_cpus(qfw_dev);
+	return qfw_online_cpus(qfw_dev);
 }
 
 static const struct cpu_ops cpu_qemu_ops = {
diff --git a/arch/x86/cpu/qfw_cpu.c b/arch/x86/cpu/qfw_cpu.c
index 9700908064..ee00b8fe73 100644
--- a/arch/x86/cpu/qfw_cpu.c
+++ b/arch/x86/cpu/qfw_cpu.c
@@ -55,7 +55,7 @@ int qemu_cpu_fixup(void)
 	}
 
 	/* get actual cpu number */
-	cpu_online = qemu_fwcfg_online_cpus(qfwdev);
+	cpu_online = qfw_online_cpus(qfwdev);
 	if (cpu_online < 0) {
 		printf("unable to get online cpu number: %d\n", cpu_online);
 		return cpu_online;
diff --git a/cmd/qfw.c b/cmd/qfw.c
index 87af408a8d..e6a9fdb2af 100644
--- a/cmd/qfw.c
+++ b/cmd/qfw.c
@@ -82,13 +82,13 @@ static int qemu_fwcfg_cmd_list_firmware(void)
 	struct fw_file *file;
 
 	/* make sure fw_list is loaded */
-	ret = qemu_fwcfg_read_firmware_list(qfw_dev);
+	ret = qfw_read_firmware_list(qfw_dev);
 	if (ret)
 		return ret;
 
-	for (file = qemu_fwcfg_file_iter_init(qfw_dev, &iter);
-	     !qemu_fwcfg_file_iter_end(&iter);
-	     file = qemu_fwcfg_file_iter_next(&iter)) {
+	for (file = qfw_file_iter_init(qfw_dev, &iter);
+	     !qfw_file_iter_end(&iter);
+	     file = qfw_file_iter_next(&iter)) {
 		printf("%-56s\n", file->cfg.name);
 	}
 
@@ -107,7 +107,7 @@ static int qemu_fwcfg_do_list(struct cmd_tbl *cmdtp, int flag,
 static int qemu_fwcfg_do_cpus(struct cmd_tbl *cmdtp, int flag,
 			      int argc, char *const argv[])
 {
-	printf("%d cpu(s) online\n", qemu_fwcfg_online_cpus(qfw_dev));
+	printf("%d cpu(s) online\n", qfw_online_cpus(qfw_dev));
 	return 0;
 }
 
diff --git a/common/qfw.c b/common/qfw.c
index c0ffa20b74..561b0dd9c0 100644
--- a/common/qfw.c
+++ b/common/qfw.c
@@ -14,7 +14,7 @@ int qfw_get_dev(struct udevice **devp)
 	return uclass_first_device(UCLASS_QFW, devp);
 }
 
-int qemu_fwcfg_online_cpus(struct udevice *dev)
+int qfw_online_cpus(struct udevice *dev)
 {
 	u16 nb_cpus;
 
@@ -23,7 +23,7 @@ int qemu_fwcfg_online_cpus(struct udevice *dev)
 	return le16_to_cpu(nb_cpus);
 }
 
-int qemu_fwcfg_read_firmware_list(struct udevice *dev)
+int qfw_read_firmware_list(struct udevice *dev)
 {
 	int i;
 	u32 count;
@@ -64,7 +64,7 @@ err:
 	return -ENOMEM;
 }
 
-struct fw_file *qemu_fwcfg_find_file(struct udevice *dev, const char *name)
+struct fw_file *qfw_find_file(struct udevice *dev, const char *name)
 {
 	struct list_head *entry;
 	struct fw_file *file;
@@ -80,8 +80,8 @@ struct fw_file *qemu_fwcfg_find_file(struct udevice *dev, const char *name)
 	return NULL;
 }
 
-struct fw_file *qemu_fwcfg_file_iter_init(struct udevice *dev,
-					  struct fw_cfg_file_iter *iter)
+struct fw_file *qfw_file_iter_init(struct udevice *dev,
+				   struct fw_cfg_file_iter *iter)
 {
 	struct qfw_dev *qdev = dev_get_uclass_priv(dev);
 
@@ -91,14 +91,14 @@ struct fw_file *qemu_fwcfg_file_iter_init(struct udevice *dev,
 			  struct fw_file, list);
 }
 
-struct fw_file *qemu_fwcfg_file_iter_next(struct fw_cfg_file_iter *iter)
+struct fw_file *qfw_file_iter_next(struct fw_cfg_file_iter *iter)
 {
 	iter->entry = ((struct list_head *)iter->entry)->next;
 	return list_entry((struct list_head *)iter->entry,
 			  struct fw_file, list);
 }
 
-bool qemu_fwcfg_file_iter_end(struct fw_cfg_file_iter *iter)
+bool qfw_file_iter_end(struct fw_cfg_file_iter *iter)
 {
 	return iter->entry == iter->end;
 }
diff --git a/drivers/misc/qfw.c b/drivers/misc/qfw.c
index 7ad8f0979b..b0c82e2098 100644
--- a/drivers/misc/qfw.c
+++ b/drivers/misc/qfw.c
@@ -43,7 +43,7 @@ static int bios_linker_allocate(struct udevice *dev,
 		return -EINVAL;
 	}
 
-	file = qemu_fwcfg_find_file(dev, entry->alloc.file);
+	file = qfw_find_file(dev, entry->alloc.file);
 	if (!file) {
 		printf("error: can't find file %s\n", entry->alloc.file);
 		return -ENOENT;
@@ -99,10 +99,10 @@ static int bios_linker_add_pointer(struct udevice *dev,
 	uint32_t offset = le32_to_cpu(entry->pointer.offset);
 	uint64_t pointer = 0;
 
-	dest = qemu_fwcfg_find_file(dev, entry->pointer.dest_file);
+	dest = qfw_find_file(dev, entry->pointer.dest_file);
 	if (!dest || !dest->addr)
 		return -ENOENT;
-	src = qemu_fwcfg_find_file(dev, entry->pointer.src_file);
+	src = qfw_find_file(dev, entry->pointer.src_file);
 	if (!src || !src->addr)
 		return -ENOENT;
 
@@ -133,7 +133,7 @@ static int bios_linker_add_checksum(struct udevice *dev,
 	uint8_t *data, cksum = 0;
 	uint8_t *cksum_start;
 
-	file = qemu_fwcfg_find_file(dev, entry->cksum.file);
+	file = qfw_find_file(dev, entry->cksum.file);
 	if (!file || !file->addr)
 		return -ENOENT;
 
@@ -163,13 +163,13 @@ ulong write_acpi_tables(ulong addr)
 	}
 
 	/* make sure fw_list is loaded */
-	ret = qemu_fwcfg_read_firmware_list(dev);
+	ret = qfw_read_firmware_list(dev);
 	if (ret) {
 		printf("error: can't read firmware file list\n");
 		return addr;
 	}
 
-	file = qemu_fwcfg_find_file(dev, "etc/table-loader");
+	file = qfw_find_file(dev, "etc/table-loader");
 	if (!file) {
 		printf("error: can't find etc/table-loader\n");
 		return addr;
@@ -215,9 +215,9 @@ ulong write_acpi_tables(ulong addr)
 out:
 	if (ret) {
 		struct fw_cfg_file_iter iter;
-		for (file = qemu_fwcfg_file_iter_init(dev, &iter);
-		     !qemu_fwcfg_file_iter_end(&iter);
-		     file = qemu_fwcfg_file_iter_next(&iter)) {
+		for (file = qfw_file_iter_init(dev, &iter);
+		     !qfw_file_iter_end(&iter);
+		     file = qfw_file_iter_next(&iter)) {
 			if (file->addr) {
 				free((void *)file->addr);
 				file->addr = 0;
@@ -241,7 +241,7 @@ ulong acpi_get_rsdp_addr(void)
 		return 0;
 	}
 
-	file = qemu_fwcfg_find_file(dev, "etc/acpi/rsdp");
+	file = qfw_find_file(dev, "etc/acpi/rsdp");
 	return file->addr;
 }
 #endif
diff --git a/include/qfw.h b/include/qfw.h
index 7b389dec25..41d4db08d6 100644
--- a/include/qfw.h
+++ b/include/qfw.h
@@ -8,7 +8,7 @@
 
 #include <linux/list.h>
 
-enum qemu_fwcfg_items {
+enum {
 	FW_CFG_SIGNATURE	= 0x00,
 	FW_CFG_ID		= 0x01,
 	FW_CFG_UUID		= 0x02,
@@ -169,21 +169,21 @@ struct udevice;
 int qfw_get_dev(struct udevice **devp);
 
 void qfw_read_entry(struct udevice *dev, u16 entry, u32 length, void *address);
-int qemu_fwcfg_read_firmware_list(struct udevice *dev);
-struct fw_file *qemu_fwcfg_find_file(struct udevice *dev, const char *name);
+int qfw_read_firmware_list(struct udevice *dev);
+struct fw_file *qfw_find_file(struct udevice *dev, const char *name);
 
 /**
  * Get system cpu number
  *
  * @return:   cpu number in system
  */
-int qemu_fwcfg_online_cpus(struct udevice *dev);
+int qfw_online_cpus(struct udevice *dev);
 
 /* helper functions to iterate firmware file list */
-struct fw_file *qemu_fwcfg_file_iter_init(struct udevice *dev,
-					  struct fw_cfg_file_iter *iter);
-struct fw_file *qemu_fwcfg_file_iter_next(struct fw_cfg_file_iter *iter);
-bool qemu_fwcfg_file_iter_end(struct fw_cfg_file_iter *iter);
+struct fw_file *qfw_file_iter_init(struct udevice *dev,
+				   struct fw_cfg_file_iter *iter);
+struct fw_file *qfw_file_iter_next(struct fw_cfg_file_iter *iter);
+bool qfw_file_iter_end(struct fw_cfg_file_iter *iter);
 
 /**
  * qemu_cpu_fixup() - Fix up the CPUs for QEMU
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v4 3/5] qemu: add sandbox driver and tests
  2021-02-24  3:23 [PATCH v4 0/5] Move qfw to DM, add Arm support Asherah Connor
  2021-02-24  3:23 ` [PATCH v4 1/5] arm: x86: qemu: move qfw to DM uclass, " Asherah Connor
  2021-02-24  3:23 ` [PATCH v4 2/5] arm: x86: qemu: unify qfw driver functions as qfw_ Asherah Connor
@ 2021-02-24  3:23 ` Asherah Connor
  2021-02-25 19:31   ` Simon Glass
  2021-02-24  3:23 ` [PATCH v4 4/5] test: qemu: add simple test for cmd_qfw Asherah Connor
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 19+ messages in thread
From: Asherah Connor @ 2021-02-24  3:23 UTC (permalink / raw)
  To: u-boot

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         |   1 +
 drivers/misc/qfw_sandbox.c    | 129 ++++++++++++++++++++++++++++++++++
 test/dm/Makefile              |   1 +
 test/dm/qfw.c                 |  42 +++++++++++
 6 files changed, 181 insertions(+)
 create mode 100644 drivers/misc/qfw_sandbox.c
 create mode 100644 test/dm/qfw.c

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 2988289ea3..c48f61b797 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -59,6 +59,7 @@ 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);
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v4 4/5] test: qemu: add simple test for cmd_qfw
  2021-02-24  3:23 [PATCH v4 0/5] Move qfw to DM, add Arm support Asherah Connor
                   ` (2 preceding siblings ...)
  2021-02-24  3:23 ` [PATCH v4 3/5] qemu: add sandbox driver and tests Asherah Connor
@ 2021-02-24  3:23 ` Asherah Connor
  2021-02-25 19:31   ` Simon Glass
  2021-02-24  3:23 ` [PATCH v4 5/5] qemu: add documentation to qfw.h Asherah Connor
  2021-02-25  7:11 ` [PATCH v4 0/5] Move qfw to DM, add Arm support Asherah Connor
  5 siblings, 1 reply; 19+ messages in thread
From: Asherah Connor @ 2021-02-24  3:23 UTC (permalink / raw)
  To: u-boot

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

(no changes since v1)

 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
+
+ at 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
+
+ at 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

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v4 5/5] qemu: add documentation to qfw.h
  2021-02-24  3:23 [PATCH v4 0/5] Move qfw to DM, add Arm support Asherah Connor
                   ` (3 preceding siblings ...)
  2021-02-24  3:23 ` [PATCH v4 4/5] test: qemu: add simple test for cmd_qfw Asherah Connor
@ 2021-02-24  3:23 ` Asherah Connor
  2021-02-25 19:31   ` Simon Glass
  2021-02-25 20:10   ` Heinrich Schuchardt
  2021-02-25  7:11 ` [PATCH v4 0/5] Move qfw to DM, add Arm support Asherah Connor
  5 siblings, 2 replies; 19+ messages in thread
From: Asherah Connor @ 2021-02-24  3:23 UTC (permalink / raw)
  To: u-boot

Also rename a "length" to "size" for consistency with the rest of qfw.

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

(no changes since v1)

 drivers/misc/qfw.c |  6 ++--
 include/qfw.h      | 86 +++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 84 insertions(+), 8 deletions(-)

diff --git a/drivers/misc/qfw.c b/drivers/misc/qfw.c
index b0c82e2098..3e8c1a9cda 100644
--- a/drivers/misc/qfw.c
+++ b/drivers/misc/qfw.c
@@ -283,14 +283,14 @@ static void qfw_read_entry_dma(struct qfw_dev *qdev, u16 entry, u32 size,
 	ops->read_entry_dma(qdev->dev, &dma);
 }
 
-void qfw_read_entry(struct udevice *dev, u16 entry, u32 length, void *address)
+void qfw_read_entry(struct udevice *dev, u16 entry, u32 size, void *address)
 {
 	struct qfw_dev *qdev = dev_get_uclass_priv(dev);
 
 	if (qdev->dma_present)
-		qfw_read_entry_dma(qdev, entry, length, address);
+		qfw_read_entry_dma(qdev, entry, size, address);
 	else
-		qfw_read_entry_io(qdev, entry, length, address);
+		qfw_read_entry_io(qdev, entry, size, address);
 }
 
 int qfw_register(struct udevice *dev)
diff --git a/include/qfw.h b/include/qfw.h
index 41d4db08d6..d59c71a5dd 100644
--- a/include/qfw.h
+++ b/include/qfw.h
@@ -8,6 +8,11 @@
 
 #include <linux/list.h>
 
+/*
+ * List of firmware configuration item selectors. The official source of truth
+ * for these is the QEMU source itself; see
+ * https://github.com/qemu/qemu/blob/master/hw/nvram/fw_cfg.c
+ */
 enum {
 	FW_CFG_SIGNATURE	= 0x00,
 	FW_CFG_ID		= 0x01,
@@ -66,8 +71,10 @@ enum {
 #define FW_CFG_DMA_SKIP	(1 << 2)
 #define FW_CFG_DMA_SELECT	(1 << 3)
 
+/* Bit set in FW_CFG_ID response to indicate DMA interface availability. */
 #define FW_CFG_DMA_ENABLED	(1 << 1)
 
+/* Structs read from FW_CFG_FILE_DIR. */
 struct fw_cfg_file {
 	__be32 size;
 	__be16 select;
@@ -134,27 +141,56 @@ struct bios_linker_entry {
 	};
 } __packed;
 
+/* DMA transfer control data between UCLASS_QFW and QEMU. */
 struct qfw_dma {
 	__be32 control;
 	__be32 length;
 	__be64 address;
 };
 
+/* uclass per-device configuration information */
 struct qfw_dev {
-	struct udevice *dev;
-	bool dma_present;
-	struct list_head fw_list;
+	struct udevice *dev;		/* Transport device */
+	bool dma_present;		/* DMA interface usable? */
+	struct list_head fw_list;	/* Cached firmware file list */
 };
 
+/* Ops used internally between UCLASS_QFW and its driver implementations. */
 struct dm_qfw_ops {
+	/**
+	 * read_entry_io() - Read a firmware config entry using the regular
+	 * IO interface for the platform (either PIO or MMIO)
+	 *
+	 * Supply FW_CFG_INVALID as the entry to continue a previous read.  In
+	 * this case, no selector will be issued before reading.
+	 *
+	 * @dev: Device to use
+	 * @entry: Firmware config entry number (e.g. FW_CFG_SIGNATURE)
+	 * @size: Number of bytes to read
+	 * @address: Target location for read
+	 */
 	void (*read_entry_io)(struct udevice *dev, u16 entry, u32 size,
 			      void *address);
+
+	/**
+	 * read_entry_dma() - Read a firmware config entry using the DMA
+	 * interface
+	 *
+	 * Supply FW_CFG_INVALID as the entry to continue a previous read.  In
+	 * this case, no selector will be issued before reading.
+	 *
+	 * This method assumes DMA availability has already been confirmed.
+	 *
+	 * @dev: Device to use
+	 * @dma: DMA transfer control struct
+	 */
 	void (*read_entry_dma)(struct udevice *dev, struct qfw_dma *dma);
 };
 
 #define dm_qfw_get_ops(dev) \
 		((struct dm_qfw_ops *)(dev)->driver->ops)
 
+/* Used internally by driver implementations on successful probe. */
 int qfw_register(struct udevice *dev);
 
 struct udevice;
@@ -168,8 +204,37 @@ struct udevice;
  */
 int qfw_get_dev(struct udevice **devp);
 
-void qfw_read_entry(struct udevice *dev, u16 entry, u32 length, void *address);
+/**
+ * Read a QEMU firmware config entry
+ *
+ * The appropriate transport and interface will be selected automatically.
+ *
+ * @dev: Device to use
+ * @entry: Firmware config entry number (e.g. FW_CFG_SIGNATURE)
+ * @size: Number of bytes to read
+ * @address: Target location for read
+ */
+void qfw_read_entry(struct udevice *dev, u16 entry, u32 size, void *address);
+
+/**
+ * Reads the QEMU firmware config file list, for later use with qfw_find_file.
+ *
+ * If the list has already been read, returns 0 (success).
+ *
+ * @dev: Device to use
+ *
+ * @return 0 on success, -ENOMEM if unable to allocate.
+ */
 int qfw_read_firmware_list(struct udevice *dev);
+
+/**
+ * Finds a file by name in the QEMU firmware config file list.
+ *
+ * @dev: Device to use
+ * @name: Name of file to locate (e.g. "etc/table-loader")
+ *
+ * @return pointer to fw_file struct if found, NULL if not present.
+ */
 struct fw_file *qfw_find_file(struct udevice *dev, const char *name);
 
 /**
@@ -179,7 +244,18 @@ struct fw_file *qfw_find_file(struct udevice *dev, const char *name);
  */
 int qfw_online_cpus(struct udevice *dev);
 
-/* helper functions to iterate firmware file list */
+/**
+ * Helper functions to iterate firmware file list. Suggested use:
+ *
+ * struct fw_cfg_file_iter iter;
+ * struct fw_file *file;
+ *
+ * for (file = qfw_file_iter_init(dev, &iter);
+ *      !qfw_file_iter_end(&iter);
+ *      file = qfw_file_iter_next(&iter)) {
+ *         // use `file'
+ * }
+ */
 struct fw_file *qfw_file_iter_init(struct udevice *dev,
 				   struct fw_cfg_file_iter *iter);
 struct fw_file *qfw_file_iter_next(struct fw_cfg_file_iter *iter);
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v4 0/5] Move qfw to DM, add Arm support
  2021-02-24  3:23 [PATCH v4 0/5] Move qfw to DM, add Arm support Asherah Connor
                   ` (4 preceding siblings ...)
  2021-02-24  3:23 ` [PATCH v4 5/5] qemu: add documentation to qfw.h Asherah Connor
@ 2021-02-25  7:11 ` Asherah Connor
  5 siblings, 0 replies; 19+ messages in thread
From: Asherah Connor @ 2021-02-25  7:11 UTC (permalink / raw)
  To: u-boot

On 21/02/24 02:02:p, Asherah Connor wrote:
> This series moves the QFW driver into a uclass, UCLASS_QFW, and splits
> the driver into qfw_pio and qfw_mmio.  A sandbox driver is also added,
> and a DM unit test against that driver.

I thought it might be worth adding: I've continued and implemented in my
own branch a qemu_ramfb VIDEO driver on top of this series (+158 -28),
and it works great!  I'm looking forward to sending it once this series
is up to scratch.

Best,

Asherah

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v4 2/5] arm: x86: qemu: unify qfw driver functions as qfw_
  2021-02-24  3:23 ` [PATCH v4 2/5] arm: x86: qemu: unify qfw driver functions as qfw_ Asherah Connor
@ 2021-02-25 19:31   ` Simon Glass
  0 siblings, 0 replies; 19+ messages in thread
From: Simon Glass @ 2021-02-25 19:31 UTC (permalink / raw)
  To: u-boot

On Tue, 23 Feb 2021 at 22:24, Asherah Connor <ashe@kivikakk.ee> wrote:
>
> There's a mixture of "qemu_fwcfg_"-prefixed functions and
> "qfw_"-prefixed ones.  Now that the qfw name is applied in multiple
> places (i.e. the uclass itself, and each of its drivers), let's
> consistently use the prefix "qfw_" for anything relating to the
> drivers.
>
> Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
> ---
>
> (no changes since v1)
>
>  arch/x86/cpu/qemu/cpu.c |  2 +-
>  arch/x86/cpu/qfw_cpu.c  |  2 +-
>  cmd/qfw.c               | 10 +++++-----
>  common/qfw.c            | 14 +++++++-------
>  drivers/misc/qfw.c      | 20 ++++++++++----------
>  include/qfw.h           | 16 ++++++++--------
>  6 files changed, 32 insertions(+), 32 deletions(-)

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

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v4 3/5] qemu: add sandbox driver and tests
  2021-02-24  3:23 ` [PATCH v4 3/5] qemu: add sandbox driver and tests Asherah Connor
@ 2021-02-25 19:31   ` Simon Glass
  0 siblings, 0 replies; 19+ messages in thread
From: Simon Glass @ 2021-02-25 19:31 UTC (permalink / raw)
  To: u-boot

On Tue, 23 Feb 2021 at 22:24, 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         |   1 +
>  drivers/misc/qfw_sandbox.c    | 129 ++++++++++++++++++++++++++++++++++
>  test/dm/Makefile              |   1 +
>  test/dm/qfw.c                 |  42 +++++++++++
>  6 files changed, 181 insertions(+)
>  create mode 100644 drivers/misc/qfw_sandbox.c
>  create mode 100644 test/dm/qfw.c
>

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

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v4 4/5] test: qemu: add simple test for cmd_qfw
  2021-02-24  3:23 ` [PATCH v4 4/5] test: qemu: add simple test for cmd_qfw Asherah Connor
@ 2021-02-25 19:31   ` Simon Glass
  0 siblings, 0 replies; 19+ messages in thread
From: Simon Glass @ 2021-02-25 19:31 UTC (permalink / raw)
  To: u-boot

On Tue, 23 Feb 2021 at 22:24, Asherah Connor <ashe@kivikakk.ee> wrote:
>
> Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
> ---
>
> (no changes since v1)
>
>  test/py/tests/test_qfw.py | 21 +++++++++++++++++++++
>  1 file changed, 21 insertions(+)
>  create mode 100644 test/py/tests/test_qfw.py

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

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v4 5/5] qemu: add documentation to qfw.h
  2021-02-24  3:23 ` [PATCH v4 5/5] qemu: add documentation to qfw.h Asherah Connor
@ 2021-02-25 19:31   ` Simon Glass
  2021-02-26  4:49     ` Asherah Connor
  2021-02-25 20:10   ` Heinrich Schuchardt
  1 sibling, 1 reply; 19+ messages in thread
From: Simon Glass @ 2021-02-25 19:31 UTC (permalink / raw)
  To: u-boot

Hi Asherah,

On Tue, 23 Feb 2021 at 22:24, Asherah Connor <ashe@kivikakk.ee> wrote:
>
> Also rename a "length" to "size" for consistency with the rest of qfw.

Here also you add comments so should mention that.

>
> Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
> ---
>
> (no changes since v1)
>
>  drivers/misc/qfw.c |  6 ++--
>  include/qfw.h      | 86 +++++++++++++++++++++++++++++++++++++++++++---
>  2 files changed, 84 insertions(+), 8 deletions(-)
>

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

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v4 1/5] arm: x86: qemu: move qfw to DM uclass, add Arm support
  2021-02-24  3:23 ` [PATCH v4 1/5] arm: x86: qemu: move qfw to DM uclass, " Asherah Connor
@ 2021-02-25 19:31   ` Simon Glass
  2021-02-26  2:14   ` Bin Meng
  2021-02-26  5:07   ` Bin Meng
  2 siblings, 0 replies; 19+ messages in thread
From: Simon Glass @ 2021-02-25 19:31 UTC (permalink / raw)
  To: u-boot

On Tue, 23 Feb 2021 at 22:24, Asherah Connor <ashe@kivikakk.ee> wrote:
>
> Updates the QFW driver to use the driver model, splitting the driver
> into qfw_pio and qfw_mmio (for non-x86) in their own uclass.
>
> Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
> ---
>
> Changes in v4:
> - PIO definitions are now #defines
> - qfw_*_plat structs are no longer in header files
> - Remove yield/pause in DMA wait loop
> - Change struct udevice *qfw_get_dev(void) to int qfw_get_dev(struct
>   udevice **)
>
>  arch/arm/Kconfig         |   1 +
>  arch/x86/cpu/qemu/cpu.c  |   9 +-
>  arch/x86/cpu/qemu/qemu.c |  47 +-------
>  arch/x86/cpu/qfw_cpu.c   |  11 +-
>  cmd/qfw.c                |  52 ++++-----
>  common/Makefile          |   2 +
>  common/qfw.c             | 105 +++++++++++++++++
>  drivers/misc/Makefile    |   6 +-
>  drivers/misc/qfw.c       | 238 ++++++++++++++-------------------------
>  drivers/misc/qfw_mmio.c  | 119 ++++++++++++++++++++
>  drivers/misc/qfw_pio.c   |  69 ++++++++++++
>  include/dm/uclass-id.h   |   1 +
>  include/qfw.h            |  61 ++++++----
>  13 files changed, 466 insertions(+), 255 deletions(-)
>  create mode 100644 common/qfw.c
>  create mode 100644 drivers/misc/qfw_mmio.c
>  create mode 100644 drivers/misc/qfw_pio.c

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

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v4 5/5] qemu: add documentation to qfw.h
  2021-02-24  3:23 ` [PATCH v4 5/5] qemu: add documentation to qfw.h Asherah Connor
  2021-02-25 19:31   ` Simon Glass
@ 2021-02-25 20:10   ` Heinrich Schuchardt
  2021-02-26  4:51     ` Asherah Connor
  1 sibling, 1 reply; 19+ messages in thread
From: Heinrich Schuchardt @ 2021-02-25 20:10 UTC (permalink / raw)
  To: u-boot

On 2/24/21 4:23 AM, Asherah Connor wrote:
> Also rename a "length" to "size" for consistency with the rest of qfw.
>
> Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
> ---
>
> (no changes since v1)
>
>   drivers/misc/qfw.c |  6 ++--
>   include/qfw.h      | 86 +++++++++++++++++++++++++++++++++++++++++++---
>   2 files changed, 84 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/misc/qfw.c b/drivers/misc/qfw.c
> index b0c82e2098..3e8c1a9cda 100644
> --- a/drivers/misc/qfw.c
> +++ b/drivers/misc/qfw.c
> @@ -283,14 +283,14 @@ static void qfw_read_entry_dma(struct qfw_dev *qdev, u16 entry, u32 size,
>   	ops->read_entry_dma(qdev->dev, &dma);
>   }
>
> -void qfw_read_entry(struct udevice *dev, u16 entry, u32 length, void *address)
> +void qfw_read_entry(struct udevice *dev, u16 entry, u32 size, void *address)
>   {
>   	struct qfw_dev *qdev = dev_get_uclass_priv(dev);
>
>   	if (qdev->dma_present)
> -		qfw_read_entry_dma(qdev, entry, length, address);
> +		qfw_read_entry_dma(qdev, entry, size, address);
>   	else
> -		qfw_read_entry_io(qdev, entry, length, address);
> +		qfw_read_entry_io(qdev, entry, size, address);
>   }
>
>   int qfw_register(struct udevice *dev)
> diff --git a/include/qfw.h b/include/qfw.h
> index 41d4db08d6..d59c71a5dd 100644
> --- a/include/qfw.h
> +++ b/include/qfw.h
> @@ -8,6 +8,11 @@
>
>   #include <linux/list.h>
>
> +/*
> + * List of firmware configuration item selectors. The official source of truth
> + * for these is the QEMU source itself; see
> + * https://github.com/qemu/qemu/blob/master/hw/nvram/fw_cfg.c
> + */
>   enum {
>   	FW_CFG_SIGNATURE	= 0x00,
>   	FW_CFG_ID		= 0x01,
> @@ -66,8 +71,10 @@ enum {
>   #define FW_CFG_DMA_SKIP	(1 << 2)
>   #define FW_CFG_DMA_SELECT	(1 << 3)
>
> +/* Bit set in FW_CFG_ID response to indicate DMA interface availability. */
>   #define FW_CFG_DMA_ENABLED	(1 << 1)
>
> +/* Structs read from FW_CFG_FILE_DIR. */
>   struct fw_cfg_file {
>   	__be32 size;
>   	__be16 select;
> @@ -134,27 +141,56 @@ struct bios_linker_entry {
>   	};
>   } __packed;
>
> +/* DMA transfer control data between UCLASS_QFW and QEMU. */
>   struct qfw_dma {
>   	__be32 control;
>   	__be32 length;
>   	__be64 address;
>   };
>
> +/* uclass per-device configuration information */
>   struct qfw_dev {
> -	struct udevice *dev;
> -	bool dma_present;
> -	struct list_head fw_list;
> +	struct udevice *dev;		/* Transport device */
> +	bool dma_present;		/* DMA interface usable? */
> +	struct list_head fw_list;	/* Cached firmware file list */
>   };
>
> +/* Ops used internally between UCLASS_QFW and its driver implementations. */
>   struct dm_qfw_ops {
> +	/**
> +	 * read_entry_io() - Read a firmware config entry using the regular
> +	 * IO interface for the platform (either PIO or MMIO)
> +	 *
> +	 * Supply FW_CFG_INVALID as the entry to continue a previous read.  In
> +	 * this case, no selector will be issued before reading.
> +	 *
> +	 * @dev: Device to use
> +	 * @entry: Firmware config entry number (e.g. FW_CFG_SIGNATURE)
> +	 * @size: Number of bytes to read
> +	 * @address: Target location for read
> +	 */
>   	void (*read_entry_io)(struct udevice *dev, u16 entry, u32 size,
>   			      void *address);
> +
> +	/**
> +	 * read_entry_dma() - Read a firmware config entry using the DMA
> +	 * interface
> +	 *
> +	 * Supply FW_CFG_INVALID as the entry to continue a previous read.  In
> +	 * this case, no selector will be issued before reading.
> +	 *
> +	 * This method assumes DMA availability has already been confirmed.
> +	 *
> +	 * @dev: Device to use
> +	 * @dma: DMA transfer control struct
> +	 */
>   	void (*read_entry_dma)(struct udevice *dev, struct qfw_dma *dma);
>   };
>
>   #define dm_qfw_get_ops(dev) \
>   		((struct dm_qfw_ops *)(dev)->driver->ops)
>
> +/* Used internally by driver implementations on successful probe. */
>   int qfw_register(struct udevice *dev);
>
>   struct udevice;
> @@ -168,8 +204,37 @@ struct udevice;
>    */
>   int qfw_get_dev(struct udevice **devp);
>
> -void qfw_read_entry(struct udevice *dev, u16 entry, u32 length, void *address);
> +/**
> + * Read a QEMU firmware config entry

This will not generate documentation for qfw_read_entry() with Sphinx.

See
https://www.kernel.org/doc/html/latest/doc-guide/kernel-doc.html#function-documentation

> + *
> + * The appropriate transport and interface will be selected automatically.
> + *
> + * @dev: Device to use
> + * @entry: Firmware config entry number (e.g. FW_CFG_SIGNATURE)
> + * @size: Number of bytes to read
> + * @address: Target location for read
> + */
> +void qfw_read_entry(struct udevice *dev, u16 entry, u32 size, void *address);
> +
> +/**
> + * Reads the QEMU firmware config file list, for later use with qfw_find_file.
> + *
> + * If the list has already been read, returns 0 (success).
> + *
> + * @dev: Device to use
> + *
> + * @return 0 on success, -ENOMEM if unable to allocate.

This is not valid Sphinx syntax.

> + */
>   int qfw_read_firmware_list(struct udevice *dev);
> +
> +/**
> + * Finds a file by name in the QEMU firmware config file list.

Function name missing.

> + *
> + * @dev: Device to use
> + * @name: Name of file to locate (e.g. "etc/table-loader")
> + *
> + * @return pointer to fw_file struct if found, NULL if not present.

Invalid syntax.

> + */
>   struct fw_file *qfw_find_file(struct udevice *dev, const char *name);
>
>   /**
> @@ -179,7 +244,18 @@ struct fw_file *qfw_find_file(struct udevice *dev, const char *name);
>    */
>   int qfw_online_cpus(struct udevice *dev);
>
> -/* helper functions to iterate firmware file list */
> +/**
> + * Helper functions to iterate firmware file list. Suggested use:

Please, describe each function individually in Sphinx style.

Best regards

Heinrich

> + *
> + * struct fw_cfg_file_iter iter;
> + * struct fw_file *file;
> + *
> + * for (file = qfw_file_iter_init(dev, &iter);
> + *      !qfw_file_iter_end(&iter);
> + *      file = qfw_file_iter_next(&iter)) {
> + *         // use `file'
> + * }
> + */
>   struct fw_file *qfw_file_iter_init(struct udevice *dev,
>   				   struct fw_cfg_file_iter *iter);
>   struct fw_file *qfw_file_iter_next(struct fw_cfg_file_iter *iter);
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v4 1/5] arm: x86: qemu: move qfw to DM uclass, add Arm support
  2021-02-24  3:23 ` [PATCH v4 1/5] arm: x86: qemu: move qfw to DM uclass, " Asherah Connor
  2021-02-25 19:31   ` Simon Glass
@ 2021-02-26  2:14   ` Bin Meng
  2021-02-26  2:19     ` Bin Meng
  2021-02-26  5:07   ` Bin Meng
  2 siblings, 1 reply; 19+ messages in thread
From: Bin Meng @ 2021-02-26  2:14 UTC (permalink / raw)
  To: u-boot

Hi Asherah,

On Wed, Feb 24, 2021 at 11:23 AM Asherah Connor <ashe@kivikakk.ee> wrote:
>
> Updates the QFW driver to use the driver model, splitting the driver
> into qfw_pio and qfw_mmio (for non-x86) in their own uclass.
>
> Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
> ---
>
> Changes in v4:
> - PIO definitions are now #defines
> - qfw_*_plat structs are no longer in header files
> - Remove yield/pause in DMA wait loop
> - Change struct udevice *qfw_get_dev(void) to int qfw_get_dev(struct
>   udevice **)
>
>  arch/arm/Kconfig         |   1 +
>  arch/x86/cpu/qemu/cpu.c  |   9 +-
>  arch/x86/cpu/qemu/qemu.c |  47 +-------
>  arch/x86/cpu/qfw_cpu.c   |  11 +-
>  cmd/qfw.c                |  52 ++++-----
>  common/Makefile          |   2 +
>  common/qfw.c             | 105 +++++++++++++++++
>  drivers/misc/Makefile    |   6 +-
>  drivers/misc/qfw.c       | 238 ++++++++++++++-------------------------
>  drivers/misc/qfw_mmio.c  | 119 ++++++++++++++++++++
>  drivers/misc/qfw_pio.c   |  69 ++++++++++++
>  include/dm/uclass-id.h   |   1 +
>  include/qfw.h            |  61 ++++++----
>  13 files changed, 466 insertions(+), 255 deletions(-)
>  create mode 100644 common/qfw.c
>  create mode 100644 drivers/misc/qfw_mmio.c
>  create mode 100644 drivers/misc/qfw_pio.c
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index d51abbeaf0..cd01dc458a 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -937,6 +937,7 @@ config ARCH_QEMU
>         imply DM_RNG
>         imply DM_RTC
>         imply RTC_PL031
> +       imply CMD_QFW

This patch mixed two things together. The adding ARM support should
not belong to this patch.

>
>  config ARCH_RMOBILE
>         bool "Renesas ARM SoCs"
> diff --git a/arch/x86/cpu/qemu/cpu.c b/arch/x86/cpu/qemu/cpu.c
> index 9ce86b379c..c78e374644 100644

Regards,
Bin

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v4 1/5] arm: x86: qemu: move qfw to DM uclass, add Arm support
  2021-02-26  2:14   ` Bin Meng
@ 2021-02-26  2:19     ` Bin Meng
  2021-02-26  4:54       ` Asherah Connor
  0 siblings, 1 reply; 19+ messages in thread
From: Bin Meng @ 2021-02-26  2:19 UTC (permalink / raw)
  To: u-boot

Hi Asherah,

On Fri, Feb 26, 2021 at 10:14 AM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> Hi Asherah,
>
> On Wed, Feb 24, 2021 at 11:23 AM Asherah Connor <ashe@kivikakk.ee> wrote:
> >
> > Updates the QFW driver to use the driver model, splitting the driver
> > into qfw_pio and qfw_mmio (for non-x86) in their own uclass.
> >
> > Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
> > ---
> >
> > Changes in v4:
> > - PIO definitions are now #defines
> > - qfw_*_plat structs are no longer in header files
> > - Remove yield/pause in DMA wait loop
> > - Change struct udevice *qfw_get_dev(void) to int qfw_get_dev(struct
> >   udevice **)
> >
> >  arch/arm/Kconfig         |   1 +
> >  arch/x86/cpu/qemu/cpu.c  |   9 +-
> >  arch/x86/cpu/qemu/qemu.c |  47 +-------
> >  arch/x86/cpu/qfw_cpu.c   |  11 +-
> >  cmd/qfw.c                |  52 ++++-----
> >  common/Makefile          |   2 +
> >  common/qfw.c             | 105 +++++++++++++++++
> >  drivers/misc/Makefile    |   6 +-
> >  drivers/misc/qfw.c       | 238 ++++++++++++++-------------------------
> >  drivers/misc/qfw_mmio.c  | 119 ++++++++++++++++++++
> >  drivers/misc/qfw_pio.c   |  69 ++++++++++++
> >  include/dm/uclass-id.h   |   1 +
> >  include/qfw.h            |  61 ++++++----
> >  13 files changed, 466 insertions(+), 255 deletions(-)
> >  create mode 100644 common/qfw.c
> >  create mode 100644 drivers/misc/qfw_mmio.c
> >  create mode 100644 drivers/misc/qfw_pio.c
> >
> > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> > index d51abbeaf0..cd01dc458a 100644
> > --- a/arch/arm/Kconfig
> > +++ b/arch/arm/Kconfig
> > @@ -937,6 +937,7 @@ config ARCH_QEMU
> >         imply DM_RNG
> >         imply DM_RTC
> >         imply RTC_PL031
> > +       imply CMD_QFW
>
> This patch mixed two things together. The adding ARM support should
> not belong to this patch.

So we need to split the patch like this:

1. Convert the existing QFW driver of x86 to QFW uclass driver
2. Add a new QFW mmio driver
3. Enable the driver on QEMU ARM

Regards,
Bin

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v4 5/5] qemu: add documentation to qfw.h
  2021-02-25 19:31   ` Simon Glass
@ 2021-02-26  4:49     ` Asherah Connor
  0 siblings, 0 replies; 19+ messages in thread
From: Asherah Connor @ 2021-02-26  4:49 UTC (permalink / raw)
  To: u-boot

On 21/02/25 02:02:p, Simon Glass wrote:
> On Tue, 23 Feb 2021 at 22:24, Asherah Connor <ashe@kivikakk.ee> wrote:
> >
> > Also rename a "length" to "size" for consistency with the rest of qfw.
> 
> Here also you add comments so should mention that.

I thought that may be considered redundant with the subject; will add to
both.

Best,

Asherah

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v4 5/5] qemu: add documentation to qfw.h
  2021-02-25 20:10   ` Heinrich Schuchardt
@ 2021-02-26  4:51     ` Asherah Connor
  0 siblings, 0 replies; 19+ messages in thread
From: Asherah Connor @ 2021-02-26  4:51 UTC (permalink / raw)
  To: u-boot

On 21/02/25 09:02:p, Heinrich Schuchardt wrote:
> > -void qfw_read_entry(struct udevice *dev, u16 entry, u32 length, void *address);
> > +/**
> > + * Read a QEMU firmware config entry
> 
> This will not generate documentation for qfw_read_entry() with Sphinx.
> 
> See
> https://www.kernel.org/doc/html/latest/doc-guide/kernel-doc.html#function-documentation

Thank you!  I am now testing documentation produced using

scripts/kernel-doc -man include/qfw.h | man --local-file -

If there's a better way, please let me know.

> > + * @return 0 on success, -ENOMEM if unable to allocate.
> 
> This is not valid Sphinx syntax.
[...]
> function name missing.
[...]
> invalid syntax.
[...]
> Please, describe each function individually in Sphinx style.

I'll correct these in the next version.  Thank you!

Best,

Asherah

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v4 1/5] arm: x86: qemu: move qfw to DM uclass, add Arm support
  2021-02-26  2:19     ` Bin Meng
@ 2021-02-26  4:54       ` Asherah Connor
  0 siblings, 0 replies; 19+ messages in thread
From: Asherah Connor @ 2021-02-26  4:54 UTC (permalink / raw)
  To: u-boot

Hi Bin,

On 21/02/26 10:02:p, Bin Meng wrote:
> On Fri, Feb 26, 2021 at 10:14 AM Bin Meng <bmeng.cn@gmail.com> wrote:
> > This patch mixed two things together. The adding ARM support should
> > not belong to this patch.
> 
> So we need to split the patch like this:
> 
> 1. Convert the existing QFW driver of x86 to QFW uclass driver
> 2. Add a new QFW mmio driver
> 3. Enable the driver on QEMU ARM

Thanks for taking a look!  I'll redo the series accordingly.

Best,

Asherah

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v4 1/5] arm: x86: qemu: move qfw to DM uclass, add Arm support
  2021-02-24  3:23 ` [PATCH v4 1/5] arm: x86: qemu: move qfw to DM uclass, " Asherah Connor
  2021-02-25 19:31   ` Simon Glass
  2021-02-26  2:14   ` Bin Meng
@ 2021-02-26  5:07   ` Bin Meng
  2 siblings, 0 replies; 19+ messages in thread
From: Bin Meng @ 2021-02-26  5:07 UTC (permalink / raw)
  To: u-boot

Hi Asherah,

On Wed, Feb 24, 2021 at 11:23 AM Asherah Connor <ashe@kivikakk.ee> wrote:
>
> Updates the QFW driver to use the driver model, splitting the driver
> into qfw_pio and qfw_mmio (for non-x86) in their own uclass.
>
> Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
> ---
>
> Changes in v4:
> - PIO definitions are now #defines
> - qfw_*_plat structs are no longer in header files
> - Remove yield/pause in DMA wait loop
> - Change struct udevice *qfw_get_dev(void) to int qfw_get_dev(struct
>   udevice **)
>
>  arch/arm/Kconfig         |   1 +
>  arch/x86/cpu/qemu/cpu.c  |   9 +-
>  arch/x86/cpu/qemu/qemu.c |  47 +-------
>  arch/x86/cpu/qfw_cpu.c   |  11 +-
>  cmd/qfw.c                |  52 ++++-----
>  common/Makefile          |   2 +
>  common/qfw.c             | 105 +++++++++++++++++
>  drivers/misc/Makefile    |   6 +-
>  drivers/misc/qfw.c       | 238 ++++++++++++++-------------------------
>  drivers/misc/qfw_mmio.c  | 119 ++++++++++++++++++++
>  drivers/misc/qfw_pio.c   |  69 ++++++++++++
>  include/dm/uclass-id.h   |   1 +
>  include/qfw.h            |  61 ++++++----
>  13 files changed, 466 insertions(+), 255 deletions(-)
>  create mode 100644 common/qfw.c
>  create mode 100644 drivers/misc/qfw_mmio.c
>  create mode 100644 drivers/misc/qfw_pio.c
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index d51abbeaf0..cd01dc458a 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -937,6 +937,7 @@ config ARCH_QEMU
>         imply DM_RNG
>         imply DM_RTC
>         imply RTC_PL031
> +       imply CMD_QFW
>
>  config ARCH_RMOBILE
>         bool "Renesas ARM SoCs"
> diff --git a/arch/x86/cpu/qemu/cpu.c b/arch/x86/cpu/qemu/cpu.c
> index 9ce86b379c..c78e374644 100644
> --- a/arch/x86/cpu/qemu/cpu.c
> +++ b/arch/x86/cpu/qemu/cpu.c
> @@ -22,7 +22,14 @@ int cpu_qemu_get_desc(const struct udevice *dev, char *buf, int size)
>
>  static int cpu_qemu_get_count(const struct udevice *dev)
>  {
> -       return qemu_fwcfg_online_cpus();
> +       int ret;
> +       struct udevice *qfw_dev;
> +
> +       ret = qfw_get_dev(&qfw_dev);
> +       if (ret)
> +               return ret;
> +
> +       return qemu_fwcfg_online_cpus(qfw_dev);
>  }
>
>  static const struct cpu_ops cpu_qemu_ops = {
> diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c
> index 044a429c13..605f51e1b8 100644
> --- a/arch/x86/cpu/qemu/qemu.c
> +++ b/arch/x86/cpu/qemu/qemu.c
> @@ -8,6 +8,7 @@
>  #include <init.h>
>  #include <pci.h>
>  #include <qfw.h>
> +#include <dm/platdata.h>
>  #include <asm/irq.h>
>  #include <asm/post.h>
>  #include <asm/processor.h>
> @@ -18,46 +19,10 @@ static bool i440fx;
>
>  #ifdef CONFIG_QFW
>
> -/* on x86, the qfw registers are all IO ports */
> -#define FW_CONTROL_PORT        0x510
> -#define FW_DATA_PORT           0x511
> -#define FW_DMA_PORT_LOW        0x514
> -#define FW_DMA_PORT_HIGH       0x518
> -
> -static void qemu_x86_fwcfg_read_entry_pio(uint16_t entry,
> -               uint32_t size, void *address)
> -{
> -       uint32_t i = 0;
> -       uint8_t *data = address;
> -
> -       /*
> -        * writting FW_CFG_INVALID will cause read operation to resume at
> -        * last offset, otherwise read will start at offset 0
> -        *
> -        * Note: on platform where the control register is IO port, the
> -        * endianness is little endian.
> -        */
> -       if (entry != FW_CFG_INVALID)
> -               outw(cpu_to_le16(entry), FW_CONTROL_PORT);
> -
> -       /* the endianness of data register is string-preserving */
> -       while (size--)
> -               data[i++] = inb(FW_DATA_PORT);
> -}
> -
> -static void qemu_x86_fwcfg_read_entry_dma(struct fw_cfg_dma_access *dma)
> -{
> -       /* the DMA address register is big endian */
> -       outl(cpu_to_be32((uintptr_t)dma), FW_DMA_PORT_HIGH);
> -
> -       while (be32_to_cpu(dma->control) & ~FW_CFG_DMA_ERROR)
> -               __asm__ __volatile__ ("pause");
> -}
> -
> -static struct fw_cfg_arch_ops fwcfg_x86_ops = {
> -       .arch_read_pio = qemu_x86_fwcfg_read_entry_pio,
> -       .arch_read_dma = qemu_x86_fwcfg_read_entry_dma
> +U_BOOT_DRVINFO(x86_qfw_pio) = {
> +       .name = "qfw_pio",
>  };
> +
>  #endif
>
>  static void enable_pm_piix(void)
> @@ -132,10 +97,6 @@ static void qemu_chipset_init(void)
>
>                 enable_pm_ich9();
>         }
> -
> -#ifdef CONFIG_QFW
> -       qemu_fwcfg_init(&fwcfg_x86_ops);
> -#endif
>  }
>
>  #if !CONFIG_IS_ENABLED(SPL_X86_32BIT_INIT)
> diff --git a/arch/x86/cpu/qfw_cpu.c b/arch/x86/cpu/qfw_cpu.c
> index b959eaddde..9700908064 100644
> --- a/arch/x86/cpu/qfw_cpu.c
> +++ b/arch/x86/cpu/qfw_cpu.c
> @@ -18,7 +18,7 @@ int qemu_cpu_fixup(void)
>         int cpu_num;
>         int cpu_online;
>         struct uclass *uc;
> -       struct udevice *dev, *pdev;
> +       struct udevice *dev, *pdev, *qfwdev;
>         struct cpu_plat *plat;
>         char *cpu;
>
> @@ -39,6 +39,13 @@ int qemu_cpu_fixup(void)
>                 return -ENODEV;
>         }
>
> +       /* get qfw dev */
> +       ret = qfw_get_dev(&qfwdev);
> +       if (ret) {
> +               printf("unable to find qfw device\n");
> +               return ret;
> +       }
> +
>         /* calculate cpus that are already bound */
>         cpu_num = 0;
>         for (uclass_find_first_device(UCLASS_CPU, &dev);
> @@ -48,7 +55,7 @@ int qemu_cpu_fixup(void)
>         }
>
>         /* get actual cpu number */
> -       cpu_online = qemu_fwcfg_online_cpus();
> +       cpu_online = qemu_fwcfg_online_cpus(qfwdev);
>         if (cpu_online < 0) {
>                 printf("unable to get online cpu number: %d\n", cpu_online);
>                 return cpu_online;
> diff --git a/cmd/qfw.c b/cmd/qfw.c
> index bb571487f0..87af408a8d 100644
> --- a/cmd/qfw.c
> +++ b/cmd/qfw.c
> @@ -8,19 +8,22 @@
>  #include <env.h>
>  #include <errno.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.
>   */
> -static int qemu_fwcfg_setup_kernel(void *load_addr, void *initrd_addr)
> +static int qemu_fwcfg_cmd_setup_kernel(void *load_addr, void *initrd_addr)
>  {
>         char *data_addr;
>         uint32_t setup_size, kernel_size, cmdline_size, initrd_size;
>
> -       qemu_fwcfg_read_entry(FW_CFG_SETUP_SIZE, 4, &setup_size);
> -       qemu_fwcfg_read_entry(FW_CFG_KERNEL_SIZE, 4, &kernel_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 (setup_size == 0 || kernel_size == 0) {
>                 printf("warning: no kernel available\n");
> @@ -28,28 +31,28 @@ static int qemu_fwcfg_setup_kernel(void *load_addr, void *initrd_addr)
>         }
>
>         data_addr = load_addr;
> -       qemu_fwcfg_read_entry(FW_CFG_SETUP_DATA,
> -                             le32_to_cpu(setup_size), data_addr);
> +       qfw_read_entry(qfw_dev, FW_CFG_SETUP_DATA,
> +                      le32_to_cpu(setup_size), data_addr);
>         data_addr += le32_to_cpu(setup_size);
>
> -       qemu_fwcfg_read_entry(FW_CFG_KERNEL_DATA,
> -                             le32_to_cpu(kernel_size), data_addr);
> +       qfw_read_entry(qfw_dev, FW_CFG_KERNEL_DATA,
> +                      le32_to_cpu(kernel_size), data_addr);
>         data_addr += le32_to_cpu(kernel_size);
>
>         data_addr = initrd_addr;
> -       qemu_fwcfg_read_entry(FW_CFG_INITRD_SIZE, 4, &initrd_size);
> +       qfw_read_entry(qfw_dev, FW_CFG_INITRD_SIZE, 4, &initrd_size);
>         if (initrd_size == 0) {
>                 printf("warning: no initrd available\n");
>         } else {
> -               qemu_fwcfg_read_entry(FW_CFG_INITRD_DATA,
> -                                     le32_to_cpu(initrd_size), data_addr);
> +               qfw_read_entry(qfw_dev, FW_CFG_INITRD_DATA,
> +                              le32_to_cpu(initrd_size), data_addr);
>                 data_addr += le32_to_cpu(initrd_size);
>         }
>
> -       qemu_fwcfg_read_entry(FW_CFG_CMDLINE_SIZE, 4, &cmdline_size);
> +       qfw_read_entry(qfw_dev, FW_CFG_CMDLINE_SIZE, 4, &cmdline_size);
>         if (cmdline_size) {
> -               qemu_fwcfg_read_entry(FW_CFG_CMDLINE_DATA,
> -                                     le32_to_cpu(cmdline_size), data_addr);
> +               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
> @@ -72,19 +75,18 @@ static int qemu_fwcfg_setup_kernel(void *load_addr, void *initrd_addr)
>         return 0;
>  }
>
> -static int qemu_fwcfg_list_firmware(void)
> +static int qemu_fwcfg_cmd_list_firmware(void)
>  {
>         int ret;
>         struct fw_cfg_file_iter iter;
>         struct fw_file *file;
>
>         /* make sure fw_list is loaded */
> -       ret = qemu_fwcfg_read_firmware_list();
> +       ret = qemu_fwcfg_read_firmware_list(qfw_dev);
>         if (ret)
>                 return ret;
>
> -
> -       for (file = qemu_fwcfg_file_iter_init(&iter);
> +       for (file = qemu_fwcfg_file_iter_init(qfw_dev, &iter);
>              !qemu_fwcfg_file_iter_end(&iter);
>              file = qemu_fwcfg_file_iter_next(&iter)) {
>                 printf("%-56s\n", file->cfg.name);
> @@ -96,7 +98,7 @@ static int qemu_fwcfg_list_firmware(void)
>  static int qemu_fwcfg_do_list(struct cmd_tbl *cmdtp, int flag,
>                               int argc, char *const argv[])
>  {
> -       if (qemu_fwcfg_list_firmware() < 0)
> +       if (qemu_fwcfg_cmd_list_firmware() < 0)
>                 return CMD_RET_FAILURE;
>
>         return 0;
> @@ -105,14 +107,7 @@ static int qemu_fwcfg_do_list(struct cmd_tbl *cmdtp, int flag,
>  static int qemu_fwcfg_do_cpus(struct cmd_tbl *cmdtp, int flag,
>                               int argc, char *const argv[])
>  {
> -       int ret = qemu_fwcfg_online_cpus();
> -       if (ret < 0) {
> -               printf("QEMU fw_cfg interface not found\n");
> -               return CMD_RET_FAILURE;
> -       }
> -
> -       printf("%d cpu(s) online\n", qemu_fwcfg_online_cpus());
> -
> +       printf("%d cpu(s) online\n", qemu_fwcfg_online_cpus(qfw_dev));
>         return 0;
>  }
>
> @@ -153,7 +148,7 @@ static int qemu_fwcfg_do_load(struct cmd_tbl *cmdtp, int flag,
>                 return CMD_RET_FAILURE;
>         }
>
> -       return qemu_fwcfg_setup_kernel(load_addr, initrd_addr);
> +       return qemu_fwcfg_cmd_setup_kernel(load_addr, initrd_addr);
>  }
>
>  static struct cmd_tbl fwcfg_commands[] = {
> @@ -168,7 +163,8 @@ static int do_qemu_fw(struct cmd_tbl *cmdtp, int flag, int argc,
>         int ret;
>         struct cmd_tbl *fwcfg_cmd;
>
> -       if (!qemu_fwcfg_present()) {
> +       ret = qfw_get_dev(&qfw_dev);
> +       if (ret) {
>                 printf("QEMU fw_cfg interface not found\n");
>                 return CMD_RET_USAGE;
>         }
> diff --git a/common/Makefile b/common/Makefile
> index daeea67cf2..f174a06c33 100644
> --- a/common/Makefile
> +++ b/common/Makefile
> @@ -137,3 +137,5 @@ obj-$(CONFIG_CMD_LOADB) += xyzModem.o
>  obj-$(CONFIG_$(SPL_TPL_)YMODEM_SUPPORT) += xyzModem.o
>
>  obj-$(CONFIG_AVB_VERIFY) += avb_verify.o
> +
> +obj-$(CONFIG_QFW) += qfw.o
> diff --git a/common/qfw.c b/common/qfw.c
> new file mode 100644
> index 0000000000..c0ffa20b74
> --- /dev/null
> +++ b/common/qfw.c
> @@ -0,0 +1,105 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * (C) Copyright 2015 Miao Yan <yanmiaobest@gmail.com>
> + * (C) Copyright 2021 Asherah Connor <ashe@kivikakk.ee>
> + */
> +
> +#include <dm.h>
> +#include <dm/uclass.h>
> +#include <qfw.h>
> +#include <stdlib.h>
> +
> +int qfw_get_dev(struct udevice **devp)
> +{
> +       return uclass_first_device(UCLASS_QFW, devp);
> +}
> +
> +int qemu_fwcfg_online_cpus(struct udevice *dev)
> +{
> +       u16 nb_cpus;
> +
> +       qfw_read_entry(dev, FW_CFG_NB_CPUS, 2, &nb_cpus);
> +
> +       return le16_to_cpu(nb_cpus);
> +}
> +
> +int qemu_fwcfg_read_firmware_list(struct udevice *dev)
> +{
> +       int i;
> +       u32 count;
> +       struct fw_file *file;
> +       struct list_head *entry;
> +
> +       struct qfw_dev *qdev = dev_get_uclass_priv(dev);
> +
> +       /* don't read it twice */
> +       if (!list_empty(&qdev->fw_list))
> +               return 0;
> +
> +       qfw_read_entry(dev, FW_CFG_FILE_DIR, 4, &count);
> +       if (!count)
> +               return 0;
> +
> +       count = be32_to_cpu(count);
> +       for (i = 0; i < count; i++) {
> +               file = malloc(sizeof(*file));
> +               if (!file) {
> +                       printf("error: allocating resource\n");
> +                       goto err;
> +               }
> +               qfw_read_entry(dev, FW_CFG_INVALID,
> +                              sizeof(struct fw_cfg_file), &file->cfg);
> +               file->addr = 0;
> +               list_add_tail(&file->list, &qdev->fw_list);
> +       }
> +
> +       return 0;
> +
> +err:
> +       list_for_each(entry, &qdev->fw_list) {
> +               file = list_entry(entry, struct fw_file, list);
> +               free(file);
> +       }
> +
> +       return -ENOMEM;
> +}
> +
> +struct fw_file *qemu_fwcfg_find_file(struct udevice *dev, const char *name)
> +{
> +       struct list_head *entry;
> +       struct fw_file *file;
> +
> +       struct qfw_dev *qdev = dev_get_uclass_priv(dev);
> +
> +       list_for_each(entry, &qdev->fw_list) {
> +               file = list_entry(entry, struct fw_file, list);
> +               if (!strcmp(file->cfg.name, name))
> +                       return file;
> +       }
> +
> +       return NULL;
> +}
> +
> +struct fw_file *qemu_fwcfg_file_iter_init(struct udevice *dev,
> +                                         struct fw_cfg_file_iter *iter)
> +{
> +       struct qfw_dev *qdev = dev_get_uclass_priv(dev);
> +
> +       iter->entry = qdev->fw_list.next;
> +       iter->end = &qdev->fw_list;
> +       return list_entry((struct list_head *)iter->entry,
> +                         struct fw_file, list);
> +}
> +
> +struct fw_file *qemu_fwcfg_file_iter_next(struct fw_cfg_file_iter *iter)
> +{
> +       iter->entry = ((struct list_head *)iter->entry)->next;
> +       return list_entry((struct list_head *)iter->entry,
> +                         struct fw_file, list);
> +}
> +
> +bool qemu_fwcfg_file_iter_end(struct fw_cfg_file_iter *iter)
> +{
> +       return iter->entry == iter->end;
> +}
> +
> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> index d737203704..2988289ea3 100644
> --- a/drivers/misc/Makefile
> +++ b/drivers/misc/Makefile
> @@ -55,7 +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_QFW
> +obj-y += qfw.o
> +obj-$(CONFIG_X86) += qfw_pio.o
> +obj-$(CONFIG_ARM) += qfw_mmio.o

This does not scale when we reuse this driver on RISC-V, as I saw your
QEMU patch.

So we can do like this:

CONFIG_QFW_PIO and CONFIG_QFW_MMIO

Let QEMU x86 select CONFIG_QFW_PIO, and ARM (RISC-V in the future)
select CONFIG_QFW_MMIO

> +endif
>  obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o
>  obj-$(CONFIG_ROCKCHIP_OTP) += rockchip-otp.o
>  obj-$(CONFIG_SANDBOX) += syscon_sandbox.o misc_sandbox.o

[snip]

Regards,
Bin

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2021-02-26  5:07 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-24  3:23 [PATCH v4 0/5] Move qfw to DM, add Arm support Asherah Connor
2021-02-24  3:23 ` [PATCH v4 1/5] arm: x86: qemu: move qfw to DM uclass, " Asherah Connor
2021-02-25 19:31   ` Simon Glass
2021-02-26  2:14   ` Bin Meng
2021-02-26  2:19     ` Bin Meng
2021-02-26  4:54       ` Asherah Connor
2021-02-26  5:07   ` Bin Meng
2021-02-24  3:23 ` [PATCH v4 2/5] arm: x86: qemu: unify qfw driver functions as qfw_ Asherah Connor
2021-02-25 19:31   ` Simon Glass
2021-02-24  3:23 ` [PATCH v4 3/5] qemu: add sandbox driver and tests Asherah Connor
2021-02-25 19:31   ` Simon Glass
2021-02-24  3:23 ` [PATCH v4 4/5] test: qemu: add simple test for cmd_qfw Asherah Connor
2021-02-25 19:31   ` Simon Glass
2021-02-24  3:23 ` [PATCH v4 5/5] qemu: add documentation to qfw.h Asherah Connor
2021-02-25 19:31   ` Simon Glass
2021-02-26  4:49     ` Asherah Connor
2021-02-25 20:10   ` Heinrich Schuchardt
2021-02-26  4:51     ` Asherah Connor
2021-02-25  7:11 ` [PATCH v4 0/5] Move qfw to DM, add Arm support Asherah Connor

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.