Эх сурвалжийг харах

x86: qemu: split qfw command interface and qfw core

This patch splits qfw command interface and qfw core function into two
files, and introduces a new Kconfig option (CONFIG_QFW) for qfw core.

Now when qfw command interface is enabled, it will automatically select
qfw core. This patch also makes the ACPI table generation select
CONFIG_QFW.

Signed-off-by: Miao Yan <yanmiaobest@gmail.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Miao Yan 9 жил өмнө
parent
commit
fcf5c04193

+ 1 - 1
arch/x86/Kconfig

@@ -439,7 +439,7 @@ config GENERATE_MP_TABLE
 config GENERATE_ACPI_TABLE
 config GENERATE_ACPI_TABLE
 	bool "Generate an ACPI (Advanced Configuration and Power Interface) table"
 	bool "Generate an ACPI (Advanced Configuration and Power Interface) table"
 	default n
 	default n
-	select CMD_QEMU_FW_CFG if QEMU
+	select QFW if QEMU
 	help
 	help
 	  The Advanced Configuration and Power Interface (ACPI) specification
 	  The Advanced Configuration and Power Interface (ACPI) specification
 	  provides an open standard for device configuration and management
 	  provides an open standard for device configuration and management

+ 2 - 2
arch/x86/cpu/mp_init.c

@@ -420,7 +420,7 @@ static int init_bsp(struct udevice **devp)
 	return 0;
 	return 0;
 }
 }
 
 
-#ifdef CONFIG_QEMU
+#ifdef CONFIG_QFW
 static int qemu_cpu_fixup(void)
 static int qemu_cpu_fixup(void)
 {
 {
 	int ret;
 	int ret;
@@ -496,7 +496,7 @@ int mp_init(struct mp_params *p)
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
-#ifdef CONFIG_QEMU
+#ifdef CONFIG_QFW
 	ret = qemu_cpu_fixup();
 	ret = qemu_cpu_fixup();
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;

+ 2 - 1
arch/x86/cpu/qemu/Makefile

@@ -7,5 +7,6 @@
 ifndef CONFIG_EFI_STUB
 ifndef CONFIG_EFI_STUB
 obj-y += car.o dram.o
 obj-y += car.o dram.o
 endif
 endif
-obj-y += cpu.o qemu.o
+obj-y += qemu.o
+obj-$(CONFIG_QFW) += cpu.o
 obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi_table.o
 obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi_table.o

+ 2 - 0
arch/x86/cpu/qemu/qemu.c

@@ -88,7 +88,9 @@ static void qemu_chipset_init(void)
 		enable_pm_ich9();
 		enable_pm_ich9();
 	}
 	}
 
 
+#ifdef CONFIG_QFW
 	qemu_fwcfg_init();
 	qemu_fwcfg_init();
+#endif
 }
 }
 
 
 int arch_cpu_init(void)
 int arch_cpu_init(void)

+ 1 - 0
cmd/Kconfig

@@ -596,6 +596,7 @@ config CMD_SOUND
 config CMD_QEMU_FW_CFG
 config CMD_QEMU_FW_CFG
 	bool "qfw"
 	bool "qfw"
 	depends on X86
 	depends on X86
+	select QFW
 	help
 	help
 	  This provides access to the QEMU firmware interface.  The main
 	  This provides access to the QEMU firmware interface.  The main
 	  feature is to allow easy loading of files passed to qemu-system
 	  feature is to allow easy loading of files passed to qemu-system

+ 1 - 1
cmd/Makefile

@@ -105,7 +105,7 @@ endif
 obj-y += pcmcia.o
 obj-y += pcmcia.o
 obj-$(CONFIG_CMD_PORTIO) += portio.o
 obj-$(CONFIG_CMD_PORTIO) += portio.o
 obj-$(CONFIG_CMD_PXE) += pxe.o
 obj-$(CONFIG_CMD_PXE) += pxe.o
-obj-$(CONFIG_CMD_QEMU_FW_CFG) += qemu_fw_cfg.o
+obj-$(CONFIG_CMD_QEMU_FW_CFG) += qfw.o
 obj-$(CONFIG_CMD_READ) += read.o
 obj-$(CONFIG_CMD_READ) += read.o
 obj-$(CONFIG_CMD_REGINFO) += reginfo.o
 obj-$(CONFIG_CMD_REGINFO) += reginfo.o
 obj-$(CONFIG_CMD_REISER) += reiser.o
 obj-$(CONFIG_CMD_REISER) += reiser.o

+ 0 - 172
cmd/qemu_fw_cfg.c → cmd/qfw.c

@@ -7,90 +7,7 @@
 #include <common.h>
 #include <common.h>
 #include <command.h>
 #include <command.h>
 #include <errno.h>
 #include <errno.h>
-#include <malloc.h>
 #include <qemu_fw_cfg.h>
 #include <qemu_fw_cfg.h>
-#include <asm/io.h>
-#include <linux/list.h>
-
-static bool fwcfg_present;
-static bool fwcfg_dma_present;
-
-static LIST_HEAD(fw_list);
-
-/* Read configuration item using fw_cfg PIO interface */
-static void qemu_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
-	 */
-	if (entry != FW_CFG_INVALID)
-		outw(entry, FW_CONTROL_PORT);
-	while (size--)
-		data[i++] = inb(FW_DATA_PORT);
-}
-
-/* Read configuration item using fw_cfg DMA interface */
-static void qemu_fwcfg_read_entry_dma(uint16_t entry,
-		uint32_t size, void *address)
-{
-	struct fw_cfg_dma_access dma;
-
-	dma.length = cpu_to_be32(size);
-	dma.address = cpu_to_be64((uintptr_t)address);
-	dma.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
-	 */
-	if (entry != FW_CFG_INVALID)
-		dma.control |= cpu_to_be32(FW_CFG_DMA_SELECT | (entry << 16));
-
-	barrier();
-
-	debug("qemu_fwcfg_dma_read_entry: addr %p, length %u control 0x%x\n",
-	      address, size, be32_to_cpu(dma.control));
-
-	outl(cpu_to_be32((uint32_t)&dma), FW_DMA_PORT_HIGH);
-
-	while (be32_to_cpu(dma.control) & ~FW_CFG_DMA_ERROR)
-		__asm__ __volatile__ ("pause");
-}
-
-bool qemu_fwcfg_present(void)
-{
-	return fwcfg_present;
-}
-
-bool qemu_fwcfg_dma_present(void)
-{
-	return fwcfg_dma_present;
-}
-
-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);
-	else
-		qemu_fwcfg_read_entry_pio(entry, length, address);
-}
-
-int qemu_fwcfg_online_cpus(void)
-{
-	uint16_t nb_cpus;
-
-	if (!fwcfg_present)
-		return -ENODEV;
-
-	qemu_fwcfg_read_entry(FW_CFG_NB_CPUS, 2, &nb_cpus);
-
-	return le16_to_cpu(nb_cpus);
-}
 
 
 /*
 /*
  * This function prepares kernel for zboot. It loads kernel data
  * This function prepares kernel for zboot. It loads kernel data
@@ -155,76 +72,6 @@ static int qemu_fwcfg_setup_kernel(void *load_addr, void *initrd_addr)
 	return 0;
 	return 0;
 }
 }
 
 
-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);
-	}
-
-	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(iter->entry, struct fw_file, list);
-}
-
-struct fw_file *qemu_fwcfg_file_iter_next(struct fw_cfg_file_iter *iter)
-{
-	iter->entry = iter->entry->next;
-	return list_entry(iter->entry, struct fw_file, list);
-}
-
-bool qemu_fwcfg_file_iter_end(struct fw_cfg_file_iter *iter)
-{
-	return iter->entry == &fw_list;
-}
-
 static int qemu_fwcfg_list_firmware(void)
 static int qemu_fwcfg_list_firmware(void)
 {
 {
 	int ret;
 	int ret;
@@ -246,25 +93,6 @@ static int qemu_fwcfg_list_firmware(void)
 	return 0;
 	return 0;
 }
 }
 
 
-void qemu_fwcfg_init(void)
-{
-	uint32_t qemu;
-	uint32_t dma_enabled;
-
-	fwcfg_present = false;
-	fwcfg_dma_present = false;
-
-	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;
-	}
-}
-
 static int qemu_fwcfg_do_list(cmd_tbl_t *cmdtp, int flag,
 static int qemu_fwcfg_do_list(cmd_tbl_t *cmdtp, int flag,
 		int argc, char * const argv[])
 		int argc, char * const argv[])
 {
 {

+ 6 - 0
drivers/misc/Kconfig

@@ -138,4 +138,10 @@ config WINBOND_W83627
 	  legacy UART or other devices in the Winbond Super IO chips
 	  legacy UART or other devices in the Winbond Super IO chips
 	  on X86 platforms.
 	  on X86 platforms.
 
 
+config QFW
+	bool
+	help
+	  Hidden option to enable QEMU fw_cfg interface. This will be selected by
+	  either CONFIG_CMD_QEMU_FW_CFG or CONFIG_GENERATE_ACPI_TABLE.
+
 endmenu
 endmenu

+ 1 - 0
drivers/misc/Makefile

@@ -43,3 +43,4 @@ obj-$(CONFIG_PCA9551_LED) += pca9551_led.o
 obj-$(CONFIG_RESET) += reset-uclass.o
 obj-$(CONFIG_RESET) += reset-uclass.o
 obj-$(CONFIG_FSL_DEVICE_DISABLE) += fsl_devdis.o
 obj-$(CONFIG_FSL_DEVICE_DISABLE) += fsl_devdis.o
 obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o
 obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o
+obj-$(CONFIG_QFW) += qemu_fw_cfg.o

+ 184 - 0
drivers/misc/qemu_fw_cfg.c

@@ -0,0 +1,184 @@
+/*
+ * (C) Copyright 2015 Miao Yan <yanmiaobest@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <errno.h>
+#include <malloc.h>
+#include <qemu_fw_cfg.h>
+#include <asm/io.h>
+#include <linux/list.h>
+
+static bool fwcfg_present;
+static bool fwcfg_dma_present;
+
+static LIST_HEAD(fw_list);
+
+/* Read configuration item using fw_cfg PIO interface */
+static void qemu_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
+	 */
+	if (entry != FW_CFG_INVALID)
+		outw(entry, FW_CONTROL_PORT);
+	while (size--)
+		data[i++] = inb(FW_DATA_PORT);
+}
+
+/* Read configuration item using fw_cfg DMA interface */
+static void qemu_fwcfg_read_entry_dma(uint16_t entry,
+		uint32_t size, void *address)
+{
+	struct fw_cfg_dma_access dma;
+
+	dma.length = cpu_to_be32(size);
+	dma.address = cpu_to_be64((uintptr_t)address);
+	dma.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
+	 */
+	if (entry != FW_CFG_INVALID)
+		dma.control |= cpu_to_be32(FW_CFG_DMA_SELECT | (entry << 16));
+
+	barrier();
+
+	debug("qemu_fwcfg_dma_read_entry: addr %p, length %u control 0x%x\n",
+	      address, size, be32_to_cpu(dma.control));
+
+	outl(cpu_to_be32((uint32_t)&dma), FW_DMA_PORT_HIGH);
+
+	while (be32_to_cpu(dma.control) & ~FW_CFG_DMA_ERROR)
+		__asm__ __volatile__ ("pause");
+}
+
+bool qemu_fwcfg_present(void)
+{
+	return fwcfg_present;
+}
+
+bool qemu_fwcfg_dma_present(void)
+{
+	return fwcfg_dma_present;
+}
+
+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);
+	else
+		qemu_fwcfg_read_entry_pio(entry, length, address);
+}
+
+int qemu_fwcfg_online_cpus(void)
+{
+	uint16_t nb_cpus;
+
+	if (!fwcfg_present)
+		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);
+	}
+
+	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(void)
+{
+	uint32_t qemu;
+	uint32_t dma_enabled;
+
+	fwcfg_present = false;
+	fwcfg_dma_present = false;
+
+	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;
+	}
+}