[U-Boot] [PATCH 0/2] Board for QEMU's '-machine virt' on ARM

Hi,
Sending this out in a slightly unfinished state to gauge if there's interest in having this included in U-Boot. Basically this allows running U-Boot under QEMU's '-machine virt' emulation, thus making it possible to boot Linux distros that use the extlinux.conf booting method under '-machine virt'.
To some extent, this is currently possible by emulating and running U-Boot on some of the Versatile boards, but (IIRC) they have some limitations like limiting to 1GB of RAM or lacking support for PCI.
Tuomas Tynkkynen (2): PCI: Add driver for a 'pci-host-ecam-generic' host controller ARM: Add a new arch + board for QEMU's 'virt' machine
arch/arm/Kconfig | 10 +++ arch/arm/mach-qemu/Kconfig | 9 ++ board/qemu-arm/Makefile | 5 ++ board/qemu-arm/qemu-arm.c | 35 ++++++++ configs/qemu_arm_defconfig | 27 ++++++ drivers/pci/Kconfig | 8 ++ drivers/pci/Makefile | 1 + drivers/pci/pcie_ecam_generic.c | 193 ++++++++++++++++++++++++++++++++++++++++ include/configs/qemu-arm.h | 63 +++++++++++++ 9 files changed, 351 insertions(+) create mode 100644 arch/arm/mach-qemu/Kconfig create mode 100644 board/qemu-arm/Makefile create mode 100644 board/qemu-arm/qemu-arm.c create mode 100644 configs/qemu_arm_defconfig create mode 100644 drivers/pci/pcie_ecam_generic.c create mode 100644 include/configs/qemu-arm.h

QEMU emulates such a device with '-machine virt,highmem=off' on ARM. The 'highmem=off' part is required for things to work as the PCI code in U-Boot doesn't seem to support 64-bit BARs.
This driver is basically a copy-paste of the Xilinx PCIE driver with the Xilinx-specific bits removed and compatible string changed... The generic code should probably be extracted into some sort of library functions instead of duplicating them before committing this driver.
Signed-off-by: Tuomas Tynkkynen tuomas.tynkkynen@iki.fi --- drivers/pci/Kconfig | 8 ++ drivers/pci/Makefile | 1 + drivers/pci/pcie_ecam_generic.c | 193 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 202 insertions(+) create mode 100644 drivers/pci/pcie_ecam_generic.c
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index e2a1c0a409..745161fb9f 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -33,6 +33,14 @@ config PCI_PNP help Enable PCI memory and I/O space resource allocation and assignment.
+config PCIE_ECAM_GENERIC + bool "Generic PCI-E ECAM support" + default n + depends on DM_PCI + help + Say Y here if you want to enable support for generic ECAM-based + PCIe controllers, such as the one emulated by QEMU. + config PCIE_DW_MVEBU bool "Enable Armada-8K PCIe driver (DesignWare core)" default n diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index ad44e83996..5eb12efbf5 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_PCI) += pci.o pci_auto_old.o endif obj-$(CONFIG_PCI) += pci_auto_common.o pci_common.o
+obj-$(CONFIG_PCIE_ECAM_GENERIC) += pcie_ecam_generic.o obj-$(CONFIG_FSL_PCI_INIT) += fsl_pci_init.o obj-$(CONFIG_PCI_INDIRECT_BRIDGE) += pci_indirect.o obj-$(CONFIG_PCI_GT64120) += pci_gt64120.o diff --git a/drivers/pci/pcie_ecam_generic.c b/drivers/pci/pcie_ecam_generic.c new file mode 100644 index 0000000000..039e378cb0 --- /dev/null +++ b/drivers/pci/pcie_ecam_generic.c @@ -0,0 +1,193 @@ +/* + * Generic PCIE host provided by e.g. QEMU + * + * Heavily based on drivers/pci/pcie_xilinx.c + * + * Copyright (C) 2016 Imagination Technologies + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <dm.h> +#include <pci.h> + +#include <asm/io.h> + +/** + * struct generic_ecam_pcie - generic_ecam PCIe controller state + * @hose: The parent classes PCI controller state + * @cfg_base: The base address of memory mapped configuration space + */ +struct generic_ecam_pcie { + struct pci_controller hose; + void *cfg_base; +}; + +/** + * pcie_generic_ecam_config_address() - Calculate the address of a config access + * @pcie: Pointer to the PCI controller state + * @bdf: Identifies the PCIe device to access + * @offset: The offset into the device's configuration space + * @paddress: Pointer to the pointer to write the calculates address to + * + * Calculates the address that should be accessed to perform a PCIe + * configuration space access for a given device identified by the PCIe + * controller device @pcie and the bus, device & function numbers in @bdf. If + * access to the device is not valid then the function will return an error + * code. Otherwise the address to access will be written to the pointer pointed + * to by @paddress. + * + * Return: 0 on success, else -ENODEV + */ +static int pcie_generic_ecam_config_address(struct generic_ecam_pcie *pcie, pci_dev_t bdf, + uint offset, void **paddress) +{ + unsigned int bus = PCI_BUS(bdf); + unsigned int dev = PCI_DEV(bdf); + unsigned int func = PCI_FUNC(bdf); + void *addr; + + addr = pcie->cfg_base; + addr += bus << 20; + addr += dev << 15; + addr += func << 12; + addr += offset; + *paddress = addr; + + return 0; +} + +/** + * pcie_generic_ecam_read_config() - Read from configuration space + * @pcie: Pointer to the PCI controller state + * @bdf: Identifies the PCIe device to access + * @offset: The offset into the device's configuration space + * @valuep: A pointer at which to store the read value + * @size: Indicates the size of access to perform + * + * Read a value of size @size from offset @offset within the configuration + * space of the device identified by the bus, device & function numbers in @bdf + * on the PCI bus @bus. + * + * Return: 0 on success, else -ENODEV or -EINVAL + */ +static int pcie_generic_ecam_read_config(struct udevice *bus, pci_dev_t bdf, + uint offset, ulong *valuep, + enum pci_size_t size) +{ + struct generic_ecam_pcie *pcie = dev_get_priv(bus); + void *address; + int err; + + err = pcie_generic_ecam_config_address(pcie, bdf, offset, &address); + if (err < 0) { + *valuep = pci_get_ff(size); + return 0; + } + + switch (size) { + case PCI_SIZE_8: + *valuep = __raw_readb(address); + return 0; + case PCI_SIZE_16: + *valuep = __raw_readw(address); + return 0; + case PCI_SIZE_32: + *valuep = __raw_readl(address); + return 0; + default: + return -EINVAL; + } +} + +/** + * pcie_generic_ecam_write_config() - Write to configuration space + * @pcie: Pointer to the PCI controller state + * @bdf: Identifies the PCIe device to access + * @offset: The offset into the device's configuration space + * @value: The value to write + * @size: Indicates the size of access to perform + * + * Write the value @value of size @size from offset @offset within the + * configuration space of the device identified by the bus, device & function + * numbers in @bdf on the PCI bus @bus. + * + * Return: 0 on success, else -ENODEV or -EINVAL + */ +static int pcie_generic_ecam_write_config(struct udevice *bus, pci_dev_t bdf, + uint offset, ulong value, + enum pci_size_t size) +{ + struct generic_ecam_pcie *pcie = dev_get_priv(bus); + void *address; + int err; + + err = pcie_generic_ecam_config_address(pcie, bdf, offset, &address); + if (err < 0) + return 0; + + switch (size) { + case PCI_SIZE_8: + __raw_writeb(value, address); + return 0; + case PCI_SIZE_16: + __raw_writew(value, address); + return 0; + case PCI_SIZE_32: + __raw_writel(value, address); + return 0; + default: + return -EINVAL; + } +} + +/** + * pcie_generic_ecam_ofdata_to_platdata() - Translate from DT to device state + * @dev: A pointer to the device being operated on + * + * Translate relevant data from the device tree pertaining to device @dev into + * state that the driver will later make use of. This state is stored in the + * device's private data structure. + * + * Return: 0 on success, else -EINVAL + */ +static int pcie_generic_ecam_ofdata_to_platdata(struct udevice *dev) +{ + struct generic_ecam_pcie *pcie = dev_get_priv(dev); + struct fdt_resource reg_res; + DECLARE_GLOBAL_DATA_PTR; + int err; + + err = fdt_get_resource(gd->fdt_blob, dev_of_offset(dev), "reg", + 0, ®_res); + if (err < 0) { + error(""reg" resource not found\n"); + return err; + } + + pcie->cfg_base = map_physmem(reg_res.start, + fdt_resource_size(®_res), + MAP_NOCACHE); + + return 0; +} + +static const struct dm_pci_ops pcie_generic_ecam_ops = { + .read_config = pcie_generic_ecam_read_config, + .write_config = pcie_generic_ecam_write_config, +}; + +static const struct udevice_id pcie_generic_ecam_ids[] = { + { .compatible = "pci-host-ecam-generic" }, + { } +}; + +U_BOOT_DRIVER(pcie_generic_ecam) = { + .name = "pcie_generic_ecam", + .id = UCLASS_PCI, + .of_match = pcie_generic_ecam_ids, + .ops = &pcie_generic_ecam_ops, + .ofdata_to_platdata = pcie_generic_ecam_ofdata_to_platdata, + .priv_auto_alloc_size = sizeof(struct generic_ecam_pcie), +};

Hi Tuomas,
On Wed, Aug 30, 2017 at 4:31 PM, Tuomas Tynkkynen tuomas.tynkkynen@iki.fi wrote:
QEMU emulates such a device with '-machine virt,highmem=off' on ARM. The 'highmem=off' part is required for things to work as the PCI code in U-Boot doesn't seem to support 64-bit BARs.
This driver is basically a copy-paste of the Xilinx PCIE driver with the Xilinx-specific bits removed and compatible string changed... The generic code should probably be extracted into some sort of library functions instead of duplicating them before committing this driver.
Signed-off-by: Tuomas Tynkkynen tuomas.tynkkynen@iki.fi
drivers/pci/Kconfig | 8 ++ drivers/pci/Makefile | 1 + drivers/pci/pcie_ecam_generic.c | 193 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 202 insertions(+) create mode 100644 drivers/pci/pcie_ecam_generic.c
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index e2a1c0a409..745161fb9f 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -33,6 +33,14 @@ config PCI_PNP help Enable PCI memory and I/O space resource allocation and assignment.
+config PCIE_ECAM_GENERIC
bool "Generic PCI-E ECAM support"
default n
nits: default n is not needed as it is the default value
depends on DM_PCI
help
Say Y here if you want to enable support for generic ECAM-based
PCIe controllers, such as the one emulated by QEMU.
config PCIE_DW_MVEBU bool "Enable Armada-8K PCIe driver (DesignWare core)" default n diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index ad44e83996..5eb12efbf5 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_PCI) += pci.o pci_auto_old.o endif obj-$(CONFIG_PCI) += pci_auto_common.o pci_common.o
+obj-$(CONFIG_PCIE_ECAM_GENERIC) += pcie_ecam_generic.o obj-$(CONFIG_FSL_PCI_INIT) += fsl_pci_init.o obj-$(CONFIG_PCI_INDIRECT_BRIDGE) += pci_indirect.o obj-$(CONFIG_PCI_GT64120) += pci_gt64120.o diff --git a/drivers/pci/pcie_ecam_generic.c b/drivers/pci/pcie_ecam_generic.c new file mode 100644 index 0000000000..039e378cb0 --- /dev/null +++ b/drivers/pci/pcie_ecam_generic.c @@ -0,0 +1,193 @@ +/*
- Generic PCIE host provided by e.g. QEMU
- Heavily based on drivers/pci/pcie_xilinx.c
- Copyright (C) 2016 Imagination Technologies
- SPDX-License-Identifier: GPL-2.0
- */
+#include <common.h> +#include <dm.h> +#include <pci.h>
+#include <asm/io.h>
+/**
- struct generic_ecam_pcie - generic_ecam PCIe controller state
- @hose: The parent classes PCI controller state
- @cfg_base: The base address of memory mapped configuration space
- */
+struct generic_ecam_pcie {
struct pci_controller hose;
This sounds like a non-DM PCI driver stuff. I don't see it is referenced in this driver.
void *cfg_base;
+};
+/**
- pcie_generic_ecam_config_address() - Calculate the address of a config access
- @pcie: Pointer to the PCI controller state
- @bdf: Identifies the PCIe device to access
- @offset: The offset into the device's configuration space
- @paddress: Pointer to the pointer to write the calculates address to
- Calculates the address that should be accessed to perform a PCIe
- configuration space access for a given device identified by the PCIe
- controller device @pcie and the bus, device & function numbers in @bdf. If
- access to the device is not valid then the function will return an error
- code. Otherwise the address to access will be written to the pointer pointed
- to by @paddress.
- Return: 0 on success, else -ENODEV
I see this driver always return 0.
- */
+static int pcie_generic_ecam_config_address(struct generic_ecam_pcie *pcie, pci_dev_t bdf,
uint offset, void **paddress)
+{
unsigned int bus = PCI_BUS(bdf);
unsigned int dev = PCI_DEV(bdf);
unsigned int func = PCI_FUNC(bdf);
void *addr;
addr = pcie->cfg_base;
addr += bus << 20;
addr += dev << 15;
addr += func << 12;
addr += offset;
*paddress = addr;
return 0;
+}
+/**
- pcie_generic_ecam_read_config() - Read from configuration space
- @pcie: Pointer to the PCI controller state
There is no pcie parameter, instead it's bus.
- @bdf: Identifies the PCIe device to access
- @offset: The offset into the device's configuration space
- @valuep: A pointer at which to store the read value
- @size: Indicates the size of access to perform
- Read a value of size @size from offset @offset within the configuration
- space of the device identified by the bus, device & function numbers in @bdf
- on the PCI bus @bus.
- Return: 0 on success, else -ENODEV or -EINVAL
- */
+static int pcie_generic_ecam_read_config(struct udevice *bus, pci_dev_t bdf,
uint offset, ulong *valuep,
enum pci_size_t size)
+{
struct generic_ecam_pcie *pcie = dev_get_priv(bus);
void *address;
int err;
err = pcie_generic_ecam_config_address(pcie, bdf, offset, &address);
if (err < 0) {
*valuep = pci_get_ff(size);
return 0;
}
switch (size) {
case PCI_SIZE_8:
*valuep = __raw_readb(address);
return 0;
case PCI_SIZE_16:
*valuep = __raw_readw(address);
return 0;
case PCI_SIZE_32:
*valuep = __raw_readl(address);
return 0;
default:
return -EINVAL;
}
+}
+/**
- pcie_generic_ecam_write_config() - Write to configuration space
- @pcie: Pointer to the PCI controller state
There is no pcie parameter, instead it's bus.
- @bdf: Identifies the PCIe device to access
- @offset: The offset into the device's configuration space
- @value: The value to write
- @size: Indicates the size of access to perform
- Write the value @value of size @size from offset @offset within the
- configuration space of the device identified by the bus, device & function
- numbers in @bdf on the PCI bus @bus.
- Return: 0 on success, else -ENODEV or -EINVAL
- */
+static int pcie_generic_ecam_write_config(struct udevice *bus, pci_dev_t bdf,
uint offset, ulong value,
enum pci_size_t size)
+{
struct generic_ecam_pcie *pcie = dev_get_priv(bus);
void *address;
int err;
err = pcie_generic_ecam_config_address(pcie, bdf, offset, &address);
if (err < 0)
return 0;
switch (size) {
case PCI_SIZE_8:
__raw_writeb(value, address);
return 0;
case PCI_SIZE_16:
__raw_writew(value, address);
return 0;
case PCI_SIZE_32:
__raw_writel(value, address);
return 0;
default:
return -EINVAL;
}
+}
+/**
- pcie_generic_ecam_ofdata_to_platdata() - Translate from DT to device state
- @dev: A pointer to the device being operated on
- Translate relevant data from the device tree pertaining to device @dev into
- state that the driver will later make use of. This state is stored in the
- device's private data structure.
- Return: 0 on success, else -EINVAL
- */
+static int pcie_generic_ecam_ofdata_to_platdata(struct udevice *dev) +{
struct generic_ecam_pcie *pcie = dev_get_priv(dev);
struct fdt_resource reg_res;
DECLARE_GLOBAL_DATA_PTR;
int err;
err = fdt_get_resource(gd->fdt_blob, dev_of_offset(dev), "reg",
0, ®_res);
if (err < 0) {
error("\"reg\" resource not found\n");
return err;
}
pcie->cfg_base = map_physmem(reg_res.start,
fdt_resource_size(®_res),
MAP_NOCACHE);
return 0;
+}
+static const struct dm_pci_ops pcie_generic_ecam_ops = {
.read_config = pcie_generic_ecam_read_config,
.write_config = pcie_generic_ecam_write_config,
+};
+static const struct udevice_id pcie_generic_ecam_ids[] = {
{ .compatible = "pci-host-ecam-generic" },
{ }
+};
+U_BOOT_DRIVER(pcie_generic_ecam) = {
.name = "pcie_generic_ecam",
.id = UCLASS_PCI,
.of_match = pcie_generic_ecam_ids,
.ops = &pcie_generic_ecam_ops,
.ofdata_to_platdata = pcie_generic_ecam_ofdata_to_platdata,
.priv_auto_alloc_size = sizeof(struct generic_ecam_pcie),
+};
Regards, Bin

Hi,
On 08/31/2017 09:51 AM, Bin Meng wrote:
Hi Tuomas,
On Wed, Aug 30, 2017 at 4:31 PM, Tuomas Tynkkynen tuomas.tynkkynen@iki.fi wrote:
QEMU emulates such a device with '-machine virt,highmem=off' on ARM. The 'highmem=off' part is required for things to work as the PCI code in U-Boot doesn't seem to support 64-bit BARs.
This driver is basically a copy-paste of the Xilinx PCIE driver with the Xilinx-specific bits removed and compatible string changed... The generic code should probably be extracted into some sort of library functions instead of duplicating them before committing this driver.
Signed-off-by: Tuomas Tynkkynen tuomas.tynkkynen@iki.fi
drivers/pci/Kconfig | 8 ++ drivers/pci/Makefile | 1 + drivers/pci/pcie_ecam_generic.c | 193 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 202 insertions(+) create mode 100644 drivers/pci/pcie_ecam_generic.c
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index e2a1c0a409..745161fb9f 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -33,6 +33,14 @@ config PCI_PNP help Enable PCI memory and I/O space resource allocation and assignment.
+config PCIE_ECAM_GENERIC
bool "Generic PCI-E ECAM support"
default n
nits: default n is not needed as it is the default value
Seems I have copied from PCIE_DW_MVEBU below. Removed.
depends on DM_PCI
help
Say Y here if you want to enable support for generic ECAM-based
PCIe controllers, such as the one emulated by QEMU.
- config PCIE_DW_MVEBU bool "Enable Armada-8K PCIe driver (DesignWare core)" default n
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index ad44e83996..5eb12efbf5 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_PCI) += pci.o pci_auto_old.o endif obj-$(CONFIG_PCI) += pci_auto_common.o pci_common.o
+obj-$(CONFIG_PCIE_ECAM_GENERIC) += pcie_ecam_generic.o obj-$(CONFIG_FSL_PCI_INIT) += fsl_pci_init.o obj-$(CONFIG_PCI_INDIRECT_BRIDGE) += pci_indirect.o obj-$(CONFIG_PCI_GT64120) += pci_gt64120.o diff --git a/drivers/pci/pcie_ecam_generic.c b/drivers/pci/pcie_ecam_generic.c new file mode 100644 index 0000000000..039e378cb0 --- /dev/null +++ b/drivers/pci/pcie_ecam_generic.c @@ -0,0 +1,193 @@ +/*
- Generic PCIE host provided by e.g. QEMU
- Heavily based on drivers/pci/pcie_xilinx.c
- Copyright (C) 2016 Imagination Technologies
- SPDX-License-Identifier: GPL-2.0
- */
+#include <common.h> +#include <dm.h> +#include <pci.h>
+#include <asm/io.h>
+/**
- struct generic_ecam_pcie - generic_ecam PCIe controller state
- @hose: The parent classes PCI controller state
- @cfg_base: The base address of memory mapped configuration space
- */
+struct generic_ecam_pcie {
struct pci_controller hose;
This sounds like a non-DM PCI driver stuff. I don't see it is referenced in this driver.
Indeed, it appears to be leftover code also in the pcie_xilinx that I copied from. Also a bunch of other drivers that have had a DM conversion have this as leftovers. I will clean them up also.
void *cfg_base;
+};
+/**
- pcie_generic_ecam_config_address() - Calculate the address of a config access
- @pcie: Pointer to the PCI controller state
- @bdf: Identifies the PCIe device to access
- @offset: The offset into the device's configuration space
- @paddress: Pointer to the pointer to write the calculates address to
- Calculates the address that should be accessed to perform a PCIe
- configuration space access for a given device identified by the PCIe
- controller device @pcie and the bus, device & function numbers in @bdf. If
- access to the device is not valid then the function will return an error
- code. Otherwise the address to access will be written to the pointer pointed
- to by @paddress.
- Return: 0 on success, else -ENODEV
I see this driver always return 0.
Will fix the comment. I kept the same signature for config_address since I'm planning to have common parts of .write_config and .read_config abstracted (similar to pci_generic_config_{read,write} in Linux) instead of copy pasting the same code the 3rd time in U-Boot.
- */
+static int pcie_generic_ecam_config_address(struct generic_ecam_pcie *pcie, pci_dev_t bdf,
uint offset, void **paddress)
+{
unsigned int bus = PCI_BUS(bdf);
unsigned int dev = PCI_DEV(bdf);
unsigned int func = PCI_FUNC(bdf);
void *addr;
addr = pcie->cfg_base;
addr += bus << 20;
addr += dev << 15;
addr += func << 12;
addr += offset;
*paddress = addr;
return 0;
+}
+/**
- pcie_generic_ecam_read_config() - Read from configuration space
- @pcie: Pointer to the PCI controller state
There is no pcie parameter, instead it's bus.
Again a problem inherited from pcie_xilinx... will fix there as well.
- @bdf: Identifies the PCIe device to access
- @offset: The offset into the device's configuration space
- @valuep: A pointer at which to store the read value
- @size: Indicates the size of access to perform
- Read a value of size @size from offset @offset within the configuration
- space of the device identified by the bus, device & function numbers in @bdf
- on the PCI bus @bus.
- Return: 0 on success, else -ENODEV or -EINVAL
- */
+static int pcie_generic_ecam_read_config(struct udevice *bus, pci_dev_t bdf,
uint offset, ulong *valuep,
enum pci_size_t size)
+{
struct generic_ecam_pcie *pcie = dev_get_priv(bus);
void *address;
int err;
err = pcie_generic_ecam_config_address(pcie, bdf, offset, &address);
if (err < 0) {
*valuep = pci_get_ff(size);
return 0;
}
switch (size) {
case PCI_SIZE_8:
*valuep = __raw_readb(address);
return 0;
case PCI_SIZE_16:
*valuep = __raw_readw(address);
return 0;
case PCI_SIZE_32:
*valuep = __raw_readl(address);
return 0;
default:
return -EINVAL;
}
+}
+/**
- pcie_generic_ecam_write_config() - Write to configuration space
- @pcie: Pointer to the PCI controller state
There is no pcie parameter, instead it's bus.
Ditto.

This board builds an U-Boot binary that is bootable with QEMU's 'virt' machine on ARM. The minimal QEMU command line is:
qemu-system-arm -machine virt,highmem=off -bios u-boot.bin
(Note that the 'highmem=off' parameter to the 'virt' machine is required for PCI to work in U-Boot.) This command line enables the following: - u-boot.bin loaded and executing in the emulated flash at address 0x0 - A generated device tree blob placed at the start of RAM - A freely configurable amount of RAM, described by the DTB - A PL011 serial port, discoverable via the DTB - An ARMv7 architected timer - PSCI for rebooting the system - A generic ECAM-based PCI host controller, discoverable via the DTB
Additionally, QEMU allows plugging a bunch of useful peripherals to the PCI bus. The following ones are supported by both U-Boot and Linux:
- To enable a Serial ATA disk via an Intel ICH9 AHCI controller, pass e.g.: -drive if=none,file=disk.img,id=mydisk -device ich9-ahci,id=ahci -device ide-drive,drive=mydisk,bus=ahci.0 - To enable an Intel E1000 network adapter, pass e.g.: -net nic,model=e1000 -net user - To add an EHCI-compliant USB host controller, pass e.g.: -device usb-ehci,id=ehci
Signed-off-by: Tuomas Tynkkynen tuomas.tynkkynen@iki.fi --- arch/arm/Kconfig | 10 ++++++++ arch/arm/mach-qemu/Kconfig | 9 +++++++ board/qemu-arm/Makefile | 5 ++++ board/qemu-arm/qemu-arm.c | 35 ++++++++++++++++++++++++++ configs/qemu_arm_defconfig | 27 ++++++++++++++++++++ include/configs/qemu-arm.h | 63 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 149 insertions(+) create mode 100644 arch/arm/mach-qemu/Kconfig create mode 100644 board/qemu-arm/Makefile create mode 100644 board/qemu-arm/qemu-arm.c create mode 100644 configs/qemu_arm_defconfig create mode 100644 include/configs/qemu-arm.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 53d0831935..0d01ba1b73 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -630,6 +630,14 @@ config ARCH_MX5 select CPU_V7 select BOARD_EARLY_INIT_F
+config ARCH_QEMU + bool "QEMU Virtual Platform" + select CPU_V7 + select ARCH_SUPPORT_PSCI + select DM + select DM_SERIAL + select OF_CONTROL + config ARCH_RMOBILE bool "Renesas ARM SoCs" select DM @@ -1149,6 +1157,8 @@ source "arch/arm/mach-stm32/Kconfig"
source "arch/arm/mach-sunxi/Kconfig"
+source "arch/arm/mach-qemu/Kconfig" + source "arch/arm/mach-tegra/Kconfig"
source "arch/arm/mach-uniphier/Kconfig" diff --git a/arch/arm/mach-qemu/Kconfig b/arch/arm/mach-qemu/Kconfig new file mode 100644 index 0000000000..89d2a36719 --- /dev/null +++ b/arch/arm/mach-qemu/Kconfig @@ -0,0 +1,9 @@ +if ARCH_QEMU + +config SYS_BOARD + default "qemu-arm" + +config SYS_CONFIG_NAME + default "qemu-arm" + +endif diff --git a/board/qemu-arm/Makefile b/board/qemu-arm/Makefile new file mode 100644 index 0000000000..3e9907d983 --- /dev/null +++ b/board/qemu-arm/Makefile @@ -0,0 +1,5 @@ +# +# SPDX-License-Identifier: GPL-2.0 +# + +obj-y += qemu-arm.o diff --git a/board/qemu-arm/qemu-arm.c b/board/qemu-arm/qemu-arm.c new file mode 100644 index 0000000000..90d7badbf4 --- /dev/null +++ b/board/qemu-arm/qemu-arm.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017 Tuomas Tynkkynen + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <fdtdec.h> + +DECLARE_GLOBAL_DATA_PTR; + +int board_init(void) +{ + return 0; +} + +int dram_init(void) +{ + if (fdtdec_setup_memory_size() != 0) + return -EINVAL; + + return 0; +} + +int dram_init_banksize(void) +{ + fdtdec_setup_memory_banksize(); + + return 0; +} + +void *board_fdt_blob_setup(void) +{ + /* QEMU loads a generated DTB for us at the start of RAM. */ + return (void *)CONFIG_SYS_SDRAM_BASE; +} diff --git a/configs/qemu_arm_defconfig b/configs/qemu_arm_defconfig new file mode 100644 index 0000000000..d34512dd0d --- /dev/null +++ b/configs/qemu_arm_defconfig @@ -0,0 +1,27 @@ +CONFIG_ARM=y +CONFIG_ARM_SMCCC=y +CONFIG_ARCH_QEMU=y +CONFIG_AHCI=y +CONFIG_DISTRO_DEFAULTS=y +# CONFIG_DISPLAY_CPUINFO is not set +# CONFIG_DISPLAY_BOARDINFO is not set +# CONFIG_CMD_IMLS is not set +CONFIG_CMD_PCI=y +CONFIG_CMD_USB=y +CONFIG_OF_BOARD=y +CONFIG_AHCI_PCI=y +CONFIG_BLK=y +# CONFIG_MMC is not set +CONFIG_DM_ETH=y +CONFIG_E1000=y +CONFIG_PCI=y +CONFIG_DM_PCI=y +CONFIG_PCIE_ECAM_GENERIC=y +CONFIG_SCSI=y +CONFIG_DM_SCSI=y +CONFIG_SYSRESET=y +CONFIG_SYSRESET_PSCI=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_PCI=y diff --git a/include/configs/qemu-arm.h b/include/configs/qemu-arm.h new file mode 100644 index 0000000000..2bcc0efad0 --- /dev/null +++ b/include/configs/qemu-arm.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2017 Tuomas Tynkkynen + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include <linux/sizes.h> + +/* Physical memory map */ +#define CONFIG_SYS_TEXT_BASE 0x00000000 + +#define CONFIG_NR_DRAM_BANKS 1 +#define CONFIG_SYS_SDRAM_BASE 0x40000000 + +/* The DTB generated by QEMU is placed at start of RAM, stay away from there */ +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_2M) +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_2M) +#define CONFIG_SYS_MALLOC_LEN SZ_16M + +/* QEMU's PL011 serial port is detected via FDT using the device model */ +#define CONFIG_PL01X_SERIAL + +/* QEMU implements a 62.5MHz architected timer */ +/* FIXME: can we rely on CNTFREQ instead of hardcoding this fact here? */ +#define CONFIG_SYS_ARCH_TIMER +#define CONFIG_SYS_HZ 1000 +#define CONFIG_SYS_HZ_CLOCK 62500000 + +/* Command prompt options */ +#define CONFIG_SYS_CBSIZE 512 /* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +#define CONFIG_SYS_MAXARGS 64 /* max command args */ + +/* For block devices, QEMU emulates an ICH9 AHCI controller over PCI */ +#define CONFIG_SYS_SCSI_MAX_SCSI_ID 8 +#define CONFIG_SCSI_AHCI +#define CONFIG_LIBATA + +/* Environment options */ +#define CONFIG_ENV_SIZE SZ_64K + +#include <config_distro_defaults.h> + +#define BOOT_TARGET_DEVICES(func) \ + func(SCSI, scsi, 0) + +#include <config_distro_bootcmd.h> + +#define CONFIG_PREBOOT "pci enum" +#define CONFIG_EXTRA_ENV_SETTINGS \ + "fdt_addr=0x40000000\0" \ + "scriptaddr=0x40200000\0" \ + "pxefile_addr_r=0x40300000\0" \ + "kernel_addr_r=0x40400000\0" \ + "ramdisk_addr_r=0x44000000\0" \ + BOOTENV + +#endif /* __CONFIG_H */

Hi Tuomas,
On Wed, Aug 30, 2017 at 4:31 PM, Tuomas Tynkkynen tuomas.tynkkynen@iki.fi wrote:
This board builds an U-Boot binary that is bootable with QEMU's 'virt' machine on ARM. The minimal QEMU command line is:
qemu-system-arm -machine virt,highmem=off -bios u-boot.bin
(Note that the 'highmem=off' parameter to the 'virt' machine is required for PCI to work in U-Boot.) This command line enables the following: - u-boot.bin loaded and executing in the emulated flash at address 0x0 - A generated device tree blob placed at the start of RAM - A freely configurable amount of RAM, described by the DTB - A PL011 serial port, discoverable via the DTB - An ARMv7 architected timer - PSCI for rebooting the system - A generic ECAM-based PCI host controller, discoverable via the DTB
Additionally, QEMU allows plugging a bunch of useful peripherals to the PCI bus. The following ones are supported by both U-Boot and Linux:
- To enable a Serial ATA disk via an Intel ICH9 AHCI controller, pass e.g.: -drive if=none,file=disk.img,id=mydisk -device ich9-ahci,id=ahci -device ide-drive,drive=mydisk,bus=ahci.0
- To enable an Intel E1000 network adapter, pass e.g.: -net nic,model=e1000 -net user
- To add an EHCI-compliant USB host controller, pass e.g.: -device usb-ehci,id=ehci
Can we enable the NVMe driver (CONFIG_NVME) here?
Signed-off-by: Tuomas Tynkkynen tuomas.tynkkynen@iki.fi
arch/arm/Kconfig | 10 ++++++++ arch/arm/mach-qemu/Kconfig | 9 +++++++ board/qemu-arm/Makefile | 5 ++++ board/qemu-arm/qemu-arm.c | 35 ++++++++++++++++++++++++++ configs/qemu_arm_defconfig | 27 ++++++++++++++++++++ include/configs/qemu-arm.h | 63 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 149 insertions(+) create mode 100644 arch/arm/mach-qemu/Kconfig create mode 100644 board/qemu-arm/Makefile create mode 100644 board/qemu-arm/qemu-arm.c create mode 100644 configs/qemu_arm_defconfig create mode 100644 include/configs/qemu-arm.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 53d0831935..0d01ba1b73 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -630,6 +630,14 @@ config ARCH_MX5 select CPU_V7 select BOARD_EARLY_INIT_F
+config ARCH_QEMU
bool "QEMU Virtual Platform"
select CPU_V7
select ARCH_SUPPORT_PSCI
select DM
select DM_SERIAL
select OF_CONTROL
config ARCH_RMOBILE bool "Renesas ARM SoCs" select DM @@ -1149,6 +1157,8 @@ source "arch/arm/mach-stm32/Kconfig"
source "arch/arm/mach-sunxi/Kconfig"
+source "arch/arm/mach-qemu/Kconfig"
Can you insert this by following alphabetical order?
source "arch/arm/mach-tegra/Kconfig"
source "arch/arm/mach-uniphier/Kconfig" diff --git a/arch/arm/mach-qemu/Kconfig b/arch/arm/mach-qemu/Kconfig new file mode 100644 index 0000000000..89d2a36719 --- /dev/null +++ b/arch/arm/mach-qemu/Kconfig @@ -0,0 +1,9 @@ +if ARCH_QEMU
+config SYS_BOARD
default "qemu-arm"
+config SYS_CONFIG_NAME
default "qemu-arm"
+endif diff --git a/board/qemu-arm/Makefile b/board/qemu-arm/Makefile new file mode 100644 index 0000000000..3e9907d983 --- /dev/null +++ b/board/qemu-arm/Makefile
Can this new board be put into the board/emulation/qemu-arm directory? Since qemu-x86 is put there.
@@ -0,0 +1,5 @@ +# +# SPDX-License-Identifier: GPL-2.0 +#
+obj-y += qemu-arm.o diff --git a/board/qemu-arm/qemu-arm.c b/board/qemu-arm/qemu-arm.c new file mode 100644 index 0000000000..90d7badbf4 --- /dev/null +++ b/board/qemu-arm/qemu-arm.c @@ -0,0 +1,35 @@ +/*
- Copyright (c) 2017 Tuomas Tynkkynen
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <fdtdec.h>
+DECLARE_GLOBAL_DATA_PTR;
This is not needed as gd is not referenced in this file.
+int board_init(void) +{
return 0;
+}
+int dram_init(void) +{
if (fdtdec_setup_memory_size() != 0)
return -EINVAL;
return 0;
+}
+int dram_init_banksize(void) +{
fdtdec_setup_memory_banksize();
return 0;
+}
+void *board_fdt_blob_setup(void) +{
/* QEMU loads a generated DTB for us at the start of RAM. */
return (void *)CONFIG_SYS_SDRAM_BASE;
+} diff --git a/configs/qemu_arm_defconfig b/configs/qemu_arm_defconfig new file mode 100644 index 0000000000..d34512dd0d --- /dev/null +++ b/configs/qemu_arm_defconfig @@ -0,0 +1,27 @@ +CONFIG_ARM=y +CONFIG_ARM_SMCCC=y +CONFIG_ARCH_QEMU=y +CONFIG_AHCI=y +CONFIG_DISTRO_DEFAULTS=y +# CONFIG_DISPLAY_CPUINFO is not set +# CONFIG_DISPLAY_BOARDINFO is not set +# CONFIG_CMD_IMLS is not set +CONFIG_CMD_PCI=y +CONFIG_CMD_USB=y +CONFIG_OF_BOARD=y +CONFIG_AHCI_PCI=y +CONFIG_BLK=y +# CONFIG_MMC is not set +CONFIG_DM_ETH=y +CONFIG_E1000=y +CONFIG_PCI=y +CONFIG_DM_PCI=y +CONFIG_PCIE_ECAM_GENERIC=y +CONFIG_SCSI=y +CONFIG_DM_SCSI=y +CONFIG_SYSRESET=y +CONFIG_SYSRESET_PSCI=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_PCI=y diff --git a/include/configs/qemu-arm.h b/include/configs/qemu-arm.h new file mode 100644 index 0000000000..2bcc0efad0 --- /dev/null +++ b/include/configs/qemu-arm.h @@ -0,0 +1,63 @@ +/*
- Copyright (c) 2017 Tuomas Tynkkynen
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef __CONFIG_H +#define __CONFIG_H
+#include <linux/sizes.h>
+/* Physical memory map */ +#define CONFIG_SYS_TEXT_BASE 0x00000000
+#define CONFIG_NR_DRAM_BANKS 1 +#define CONFIG_SYS_SDRAM_BASE 0x40000000
+/* The DTB generated by QEMU is placed at start of RAM, stay away from there */ +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_2M) +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_2M) +#define CONFIG_SYS_MALLOC_LEN SZ_16M
+/* QEMU's PL011 serial port is detected via FDT using the device model */ +#define CONFIG_PL01X_SERIAL
+/* QEMU implements a 62.5MHz architected timer */ +/* FIXME: can we rely on CNTFREQ instead of hardcoding this fact here? */ +#define CONFIG_SYS_ARCH_TIMER +#define CONFIG_SYS_HZ 1000 +#define CONFIG_SYS_HZ_CLOCK 62500000
+/* Command prompt options */ +#define CONFIG_SYS_CBSIZE 512 /* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +#define CONFIG_SYS_MAXARGS 64 /* max command args */
+/* For block devices, QEMU emulates an ICH9 AHCI controller over PCI */ +#define CONFIG_SYS_SCSI_MAX_SCSI_ID 8 +#define CONFIG_SCSI_AHCI +#define CONFIG_LIBATA
+/* Environment options */ +#define CONFIG_ENV_SIZE SZ_64K
+#include <config_distro_defaults.h>
+#define BOOT_TARGET_DEVICES(func) \
func(SCSI, scsi, 0)
+#include <config_distro_bootcmd.h>
+#define CONFIG_PREBOOT "pci enum" +#define CONFIG_EXTRA_ENV_SETTINGS \
"fdt_addr=0x40000000\0" \
"scriptaddr=0x40200000\0" \
"pxefile_addr_r=0x40300000\0" \
"kernel_addr_r=0x40400000\0" \
"ramdisk_addr_r=0x44000000\0" \
BOOTENV
+#endif /* __CONFIG_H */
Regards, Bin

Hi,
On 08/31/2017 09:55 AM, Bin Meng wrote:
Hi Tuomas,
On Wed, Aug 30, 2017 at 4:31 PM, Tuomas Tynkkynen tuomas.tynkkynen@iki.fi wrote:
This board builds an U-Boot binary that is bootable with QEMU's 'virt' machine on ARM. The minimal QEMU command line is:
qemu-system-arm -machine virt,highmem=off -bios u-boot.bin
(Note that the 'highmem=off' parameter to the 'virt' machine is required for PCI to work in U-Boot.) This command line enables the following: - u-boot.bin loaded and executing in the emulated flash at address 0x0 - A generated device tree blob placed at the start of RAM - A freely configurable amount of RAM, described by the DTB - A PL011 serial port, discoverable via the DTB - An ARMv7 architected timer - PSCI for rebooting the system - A generic ECAM-based PCI host controller, discoverable via the DTB
Additionally, QEMU allows plugging a bunch of useful peripherals to the PCI bus. The following ones are supported by both U-Boot and Linux:
- To enable a Serial ATA disk via an Intel ICH9 AHCI controller, pass e.g.: -drive if=none,file=disk.img,id=mydisk -device ich9-ahci,id=ahci -device ide-drive,drive=mydisk,bus=ahci.0
- To enable an Intel E1000 network adapter, pass e.g.: -net nic,model=e1000 -net user
- To add an EHCI-compliant USB host controller, pass e.g.: -device usb-ehci,id=ehci
Can we enable the NVMe driver (CONFIG_NVME) here?
Yes, 'nvme scan' and 'nvme list' it appear to work. I'll enable it. There is a bunch of spew of this form though:
CACHE: Misaligned operation at range [bef5d000, bef5d020]
Signed-off-by: Tuomas Tynkkynen tuomas.tynkkynen@iki.fi
arch/arm/Kconfig | 10 ++++++++ arch/arm/mach-qemu/Kconfig | 9 +++++++ board/qemu-arm/Makefile | 5 ++++ board/qemu-arm/qemu-arm.c | 35 ++++++++++++++++++++++++++ configs/qemu_arm_defconfig | 27 ++++++++++++++++++++ include/configs/qemu-arm.h | 63 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 149 insertions(+) create mode 100644 arch/arm/mach-qemu/Kconfig create mode 100644 board/qemu-arm/Makefile create mode 100644 board/qemu-arm/qemu-arm.c create mode 100644 configs/qemu_arm_defconfig create mode 100644 include/configs/qemu-arm.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 53d0831935..0d01ba1b73 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -630,6 +630,14 @@ config ARCH_MX5 select CPU_V7 select BOARD_EARLY_INIT_F
+config ARCH_QEMU
bool "QEMU Virtual Platform"
select CPU_V7
select ARCH_SUPPORT_PSCI
select DM
select DM_SERIAL
select OF_CONTROL
- config ARCH_RMOBILE bool "Renesas ARM SoCs" select DM
@@ -1149,6 +1157,8 @@ source "arch/arm/mach-stm32/Kconfig"
source "arch/arm/mach-sunxi/Kconfig"
+source "arch/arm/mach-qemu/Kconfig"
Can you insert this by following alphabetical order?
Oops, yes of course.
source "arch/arm/mach-tegra/Kconfig"
source "arch/arm/mach-uniphier/Kconfig" diff --git a/arch/arm/mach-qemu/Kconfig b/arch/arm/mach-qemu/Kconfig new file mode 100644 index 0000000000..89d2a36719 --- /dev/null +++ b/arch/arm/mach-qemu/Kconfig @@ -0,0 +1,9 @@ +if ARCH_QEMU
+config SYS_BOARD
default "qemu-arm"
+config SYS_CONFIG_NAME
default "qemu-arm"
+endif diff --git a/board/qemu-arm/Makefile b/board/qemu-arm/Makefile new file mode 100644 index 0000000000..3e9907d983 --- /dev/null +++ b/board/qemu-arm/Makefile
Can this new board be put into the board/emulation/qemu-arm directory? Since qemu-x86 is put there.
Sure. There is still qemu-mips directly under board/ though.
@@ -0,0 +1,5 @@ +# +# SPDX-License-Identifier: GPL-2.0 +#
+obj-y += qemu-arm.o diff --git a/board/qemu-arm/qemu-arm.c b/board/qemu-arm/qemu-arm.c new file mode 100644 index 0000000000..90d7badbf4 --- /dev/null +++ b/board/qemu-arm/qemu-arm.c @@ -0,0 +1,35 @@ +/*
- Copyright (c) 2017 Tuomas Tynkkynen
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <fdtdec.h>
+DECLARE_GLOBAL_DATA_PTR;
This is not needed as gd is not referenced in this file.
Now removed.
Thank you for the review.

Hi Tuomas,
On Fri, Sep 1, 2017 at 5:56 AM, Tuomas Tynkkynen dezgeg@gmail.com wrote:
Hi,
On 08/31/2017 09:55 AM, Bin Meng wrote:
Hi Tuomas,
On Wed, Aug 30, 2017 at 4:31 PM, Tuomas Tynkkynen tuomas.tynkkynen@iki.fi wrote:
This board builds an U-Boot binary that is bootable with QEMU's 'virt' machine on ARM. The minimal QEMU command line is:
qemu-system-arm -machine virt,highmem=off -bios u-boot.bin
(Note that the 'highmem=off' parameter to the 'virt' machine is required for PCI to work in U-Boot.) This command line enables the following: - u-boot.bin loaded and executing in the emulated flash at address 0x0 - A generated device tree blob placed at the start of RAM - A freely configurable amount of RAM, described by the DTB - A PL011 serial port, discoverable via the DTB - An ARMv7 architected timer - PSCI for rebooting the system - A generic ECAM-based PCI host controller, discoverable via the DTB
Additionally, QEMU allows plugging a bunch of useful peripherals to the PCI bus. The following ones are supported by both U-Boot and Linux:
- To enable a Serial ATA disk via an Intel ICH9 AHCI controller, pass
e.g.: -drive if=none,file=disk.img,id=mydisk -device ich9-ahci,id=ahci -device ide-drive,drive=mydisk,bus=ahci.0
- To enable an Intel E1000 network adapter, pass e.g.: -net nic,model=e1000 -net user
- To add an EHCI-compliant USB host controller, pass e.g.: -device usb-ehci,id=ehci
Can we enable the NVMe driver (CONFIG_NVME) here?
Yes, 'nvme scan' and 'nvme list' it appear to work. I'll enable it. There is a bunch of spew of this form though:
CACHE: Misaligned operation at range [bef5d000, bef5d020]
I think I've fixed this already and is now in v2017.09-rc3. But rc3 is still not shown on git.denx.de. Not sure why.
Signed-off-by: Tuomas Tynkkynen tuomas.tynkkynen@iki.fi
arch/arm/Kconfig | 10 ++++++++ arch/arm/mach-qemu/Kconfig | 9 +++++++ board/qemu-arm/Makefile | 5 ++++ board/qemu-arm/qemu-arm.c | 35 ++++++++++++++++++++++++++ configs/qemu_arm_defconfig | 27 ++++++++++++++++++++ include/configs/qemu-arm.h | 63 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 149 insertions(+) create mode 100644 arch/arm/mach-qemu/Kconfig create mode 100644 board/qemu-arm/Makefile create mode 100644 board/qemu-arm/qemu-arm.c create mode 100644 configs/qemu_arm_defconfig create mode 100644 include/configs/qemu-arm.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 53d0831935..0d01ba1b73 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -630,6 +630,14 @@ config ARCH_MX5 select CPU_V7 select BOARD_EARLY_INIT_F
+config ARCH_QEMU
bool "QEMU Virtual Platform"
select CPU_V7
select ARCH_SUPPORT_PSCI
select DM
select DM_SERIAL
select OF_CONTROL
- config ARCH_RMOBILE bool "Renesas ARM SoCs" select DM
@@ -1149,6 +1157,8 @@ source "arch/arm/mach-stm32/Kconfig"
source "arch/arm/mach-sunxi/Kconfig"
+source "arch/arm/mach-qemu/Kconfig"
Can you insert this by following alphabetical order?
Oops, yes of course.
source "arch/arm/mach-tegra/Kconfig"
source "arch/arm/mach-uniphier/Kconfig" diff --git a/arch/arm/mach-qemu/Kconfig b/arch/arm/mach-qemu/Kconfig new file mode 100644 index 0000000000..89d2a36719 --- /dev/null +++ b/arch/arm/mach-qemu/Kconfig @@ -0,0 +1,9 @@ +if ARCH_QEMU
+config SYS_BOARD
default "qemu-arm"
+config SYS_CONFIG_NAME
default "qemu-arm"
+endif diff --git a/board/qemu-arm/Makefile b/board/qemu-arm/Makefile new file mode 100644 index 0000000000..3e9907d983 --- /dev/null +++ b/board/qemu-arm/Makefile
Can this new board be put into the board/emulation/qemu-arm directory? Since qemu-x86 is put there.
Sure. There is still qemu-mips directly under board/ though.
Yep, so a separate patch to move all these qemu- boards into emulation would be nice.
@@ -0,0 +1,5 @@ +# +# SPDX-License-Identifier: GPL-2.0 +#
+obj-y += qemu-arm.o diff --git a/board/qemu-arm/qemu-arm.c b/board/qemu-arm/qemu-arm.c new file mode 100644 index 0000000000..90d7badbf4 --- /dev/null +++ b/board/qemu-arm/qemu-arm.c @@ -0,0 +1,35 @@ +/*
- Copyright (c) 2017 Tuomas Tynkkynen
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <fdtdec.h>
+DECLARE_GLOBAL_DATA_PTR;
This is not needed as gd is not referenced in this file.
Now removed.
Thank you for the review.
Regards, Bin

On Wed, Aug 30, 2017 at 9:31 AM, Tuomas Tynkkynen tuomas.tynkkynen@iki.fi wrote:
Hi,
Sending this out in a slightly unfinished state to gauge if there's interest in having this included in U-Boot. Basically this allows running U-Boot under QEMU's '-machine virt' emulation, thus making it possible to boot Linux distros that use the extlinux.conf booting method under '-machine virt'.
I'm definitely interested, and I'm aware of others that are as well. Being able to do that an use things like virtio drivers and easily doing CPU/mem bits would be great.
Peter
To some extent, this is currently possible by emulating and running U-Boot on some of the Versatile boards, but (IIRC) they have some limitations like limiting to 1GB of RAM or lacking support for PCI.
Tuomas Tynkkynen (2): PCI: Add driver for a 'pci-host-ecam-generic' host controller ARM: Add a new arch + board for QEMU's 'virt' machine
arch/arm/Kconfig | 10 +++ arch/arm/mach-qemu/Kconfig | 9 ++ board/qemu-arm/Makefile | 5 ++ board/qemu-arm/qemu-arm.c | 35 ++++++++ configs/qemu_arm_defconfig | 27 ++++++ drivers/pci/Kconfig | 8 ++ drivers/pci/Makefile | 1 + drivers/pci/pcie_ecam_generic.c | 193 ++++++++++++++++++++++++++++++++++++++++ include/configs/qemu-arm.h | 63 +++++++++++++ 9 files changed, 351 insertions(+) create mode 100644 arch/arm/mach-qemu/Kconfig create mode 100644 board/qemu-arm/Makefile create mode 100644 board/qemu-arm/qemu-arm.c create mode 100644 configs/qemu_arm_defconfig create mode 100644 drivers/pci/pcie_ecam_generic.c create mode 100644 include/configs/qemu-arm.h
-- 2.13.0
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot

On Wed, Aug 30, 2017 at 10:09:27PM +0100, Peter Robinson wrote:
On Wed, Aug 30, 2017 at 9:31 AM, Tuomas Tynkkynen tuomas.tynkkynen@iki.fi wrote:
Hi,
Sending this out in a slightly unfinished state to gauge if there's interest in having this included in U-Boot. Basically this allows running U-Boot under QEMU's '-machine virt' emulation, thus making it possible to boot Linux distros that use the extlinux.conf booting method under '-machine virt'.
I'm definitely interested, and I'm aware of others that are as well. Being able to do that an use things like virtio drivers and easily doing CPU/mem bits would be great.
I too would like to see this happen. Can you please make sure to update .travis.yml in the next iteration to add it to the list of qemu boards we run and pass tests to (and so also send a PR for the uboot hooks repo) ? Then we can see about follow-up work to enable more and more tests on this platform as well, thanks!
participants (5)
-
Bin Meng
-
Peter Robinson
-
Tom Rini
-
Tuomas Tynkkynen
-
Tuomas Tynkkynen