From: Eric Auger <eric.auger@linaro.org>
To: eric.auger@st.com, eric.auger@linaro.org, qemu-devel@nongnu.org,
peter.maydell@linaro.org
Cc: kvmarm@lists.cs.columbia.edu, patches@linaro.org
Subject: [Qemu-devel] [PATCH v13 3/4] hw/arm/virt: add dynamic sysbus device support
Date: Tue, 2 Jun 2015 12:29:13 +0100 [thread overview]
Message-ID: <1433244554-12898-4-git-send-email-eric.auger@linaro.org> (raw)
In-Reply-To: <1433244554-12898-1-git-send-email-eric.auger@linaro.org>
Allows sysbus devices to be instantiated from command line by
using -device option. Machvirt creates a platform bus at init.
The dynamic sysbus devices are attached to this platform bus device.
The platform bus device registers a machine init done notifier
whose role will be to bind the dynamic sysbus devices. Indeed
dynamic sysbus devices are created after machine init.
machvirt also registers a notifier that will build the device
tree nodes for the platform bus and its children dynamic sysbus
devices.
Signed-off-by: Eric Auger <eric.auger@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
---
v12 -> v13:
- Changed start IRQ number of platform bus to 112 after the addition
of MSI range
v11 -> v12:
- resize PLATFORM_BUS_NUM_IRQS to 64 instead of 32
- overall NUM_IRQS changed to 256. This leaves space for MSI
looming addition
- VIRT_PLATFORM_BUS size changed from 4MB to 32MB and base set at
0xc000000
- Add Alex R-b
v8 -> v9:
- PLATFORM_BUS_NUM_IRQS set to 32 instead of 20
- platform bus irq now start at 64 instead of 48
- remove change of indentation in a15memmap
- correct misc style issues
v7 -> v8:
- rebase on 2.2.0
- in machvirt_init, create_platform_bus simply is added
after the arm_load_kernel call instead of moving this latter.
Related comment slighly reworded.
- Due to those changes I dropped Alex and Shannon's Reviewed-by
v6 -> v7:
Take into account Shannon comments:
- remove PLATFORM_BUS_FIRST_IRQ macro
- correct platform bus size to 0x400000
- add an additional comment in a15irqmap related to
PLATFORM_BUS_NUM_IRQS
v5 -> v6:
- Take into account Peter's comments:
- platform_bus_params initialized from vbi->memmap and vbi->irqmap.
As a consequence, const is removed. Also alignment in a15memmap
is slightly changed.
- ARMPlatformBusSystemParams handle removed from create_platform_bus
prototype
- arm_load_kernel has become a machine init done notifier registration.
It must be called before platform_bus_create to guarantee the correct
notifier execution sequence
v4 -> v5:
- platform_bus_params becomes static const
- reword comment in create_platform_bus
- reword the commit message
v3 -> v4:
- use platform bus object, instantiated in create_platform_bus
- device tree generation for platform bus and children dynamic
sysbus devices is no more handled at reset but in a
machine_init_done_notifier (due to the change in implementaion
of ARM load dtb using rom_add_blob_fixed).
- device tree enhancement now takes into account the case of
user provided dtb. Before the user dtb was overwritten which
was wrong. However in case the dtb is provided by the user,
dynamic sysbus nodes are not added there.
- renaming of MACHVIRT_PLATFORM defines
- MACHVIRT_PLATFORM_PAGE_SHIFT and SIZE_PAGES not needed anymore,
hence removed.
- DynSysbusParams struct renamed into ARMPlatformBusSystemParams
and above params removed.
- separation of dt creation and QEMU binding is not mandated anymore
since the device tree is not created from scratch anymore. Instead
the modify_dtb function is used.
- create_platform_bus registers another machine init done notifier
to start VFIO IRQ handling. This latter executes after the
dynamic sysbus device binding.
v2 -> v3:
- renaming of arm_platform_bus_create_devtree and arm_load_dtb
- add copyright in hw/arm/dyn_sysbus_devtree.c
v1 -> v2:
- remove useless vfio-platform.h include file
- s/MACHVIRT_PLATFORM_HOLE/MACHVIRT_PLATFORM_SIZE
- use dyn_sysbus_binding and dyn_sysbus_devtree
- dynamic sysbus platform buse size shrinked to 4MB and
moved between RTC and MMIO
v1:
Inspired from what Alex Graf did in ppc e500
https://lists.gnu.org/archive/html/qemu-ppc/2014-07/msg00012.html
---
hw/arm/virt.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++-
include/hw/arm/virt.h | 1 +
2 files changed, 60 insertions(+), 1 deletion(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 4bb7175..02b91ba 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -45,9 +45,11 @@
#include "qemu/error-report.h"
#include "hw/pci-host/gpex.h"
#include "hw/arm/virt-acpi-build.h"
+#include "hw/arm/sysbus-fdt.h"
+#include "hw/platform-bus.h"
/* Number of external interrupt lines to configure the GIC with */
-#define NUM_IRQS 128
+#define NUM_IRQS 256
#define GIC_FDT_IRQ_TYPE_SPI 0
#define GIC_FDT_IRQ_TYPE_PPI 1
@@ -60,6 +62,10 @@
#define GIC_FDT_IRQ_PPI_CPU_START 8
#define GIC_FDT_IRQ_PPI_CPU_WIDTH 8
+#define PLATFORM_BUS_NUM_IRQS 64
+
+static ARMPlatformBusSystemParams platform_bus_params;
+
typedef struct VirtBoardInfo {
struct arm_boot_info bootinfo;
const char *cpu_model;
@@ -116,6 +122,7 @@ static const MemMapEntry a15memmap[] = {
[VIRT_FW_CFG] = { 0x09020000, 0x0000000a },
[VIRT_MMIO] = { 0x0a000000, 0x00000200 },
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
+ [VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 },
[VIRT_PCIE_MMIO] = { 0x10000000, 0x2eff0000 },
[VIRT_PCIE_PIO] = { 0x3eff0000, 0x00010000 },
[VIRT_PCIE_ECAM] = { 0x3f000000, 0x01000000 },
@@ -128,6 +135,7 @@ static const int a15irqmap[] = {
[VIRT_PCIE] = 3, /* ... to 6 */
[VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
[VIRT_GIC_V2M] = 48, /* ...to 48 + NUM_GICV2M_SPIS - 1 */
+ [VIRT_PLATFORM_BUS] = 112, /* ...to 112 + PLATFORM_BUS_NUM_IRQS -1 */
};
static VirtBoardInfo machines[] = {
@@ -728,6 +736,47 @@ static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic)
g_free(nodename);
}
+static void create_platform_bus(VirtBoardInfo *vbi, qemu_irq *pic)
+{
+ DeviceState *dev;
+ SysBusDevice *s;
+ int i;
+ ARMPlatformBusFDTParams *fdt_params = g_new(ARMPlatformBusFDTParams, 1);
+ MemoryRegion *sysmem = get_system_memory();
+
+ platform_bus_params.platform_bus_base = vbi->memmap[VIRT_PLATFORM_BUS].base;
+ platform_bus_params.platform_bus_size = vbi->memmap[VIRT_PLATFORM_BUS].size;
+ platform_bus_params.platform_bus_first_irq = vbi->irqmap[VIRT_PLATFORM_BUS];
+ platform_bus_params.platform_bus_num_irqs = PLATFORM_BUS_NUM_IRQS;
+
+ fdt_params->system_params = &platform_bus_params;
+ fdt_params->binfo = &vbi->bootinfo;
+ fdt_params->intc = "/intc";
+ /*
+ * register a machine init done notifier that creates the device tree
+ * nodes of the platform bus and its children dynamic sysbus devices
+ */
+ arm_register_platform_bus_fdt_creator(fdt_params);
+
+ dev = qdev_create(NULL, TYPE_PLATFORM_BUS_DEVICE);
+ dev->id = TYPE_PLATFORM_BUS_DEVICE;
+ qdev_prop_set_uint32(dev, "num_irqs",
+ platform_bus_params.platform_bus_num_irqs);
+ qdev_prop_set_uint32(dev, "mmio_size",
+ platform_bus_params.platform_bus_size);
+ qdev_init_nofail(dev);
+ s = SYS_BUS_DEVICE(dev);
+
+ for (i = 0; i < platform_bus_params.platform_bus_num_irqs; i++) {
+ int irqn = platform_bus_params.platform_bus_first_irq + i;
+ sysbus_connect_irq(s, i, pic[irqn]);
+ }
+
+ memory_region_add_subregion(sysmem,
+ platform_bus_params.platform_bus_base,
+ sysbus_mmio_get_region(s, 0));
+}
+
static void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size)
{
const VirtBoardInfo *board = (const VirtBoardInfo *)binfo;
@@ -865,6 +914,14 @@ static void machvirt_init(MachineState *machine)
vbi->bootinfo.get_dtb = machvirt_dtb;
vbi->bootinfo.firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
arm_load_kernel(ARM_CPU(first_cpu), &vbi->bootinfo);
+
+ /*
+ * arm_load_kernel machine init done notifier registration must
+ * happen before the platform_bus_create call. In this latter,
+ * another notifier is registered which adds platform bus nodes.
+ * Notifiers are executed in registration reverse order.
+ */
+ create_platform_bus(vbi, pic);
}
static bool virt_get_secure(Object *obj, Error **errp)
@@ -903,6 +960,7 @@ static void virt_class_init(ObjectClass *oc, void *data)
mc->desc = "ARM Virtual Machine",
mc->init = machvirt_init;
mc->max_cpus = 8;
+ mc->has_dynamic_sysbus = true;
}
static const TypeInfo machvirt_info = {
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 003ef29..d22fd8e 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -55,6 +55,7 @@ enum {
VIRT_PCIE_PIO,
VIRT_PCIE_ECAM,
VIRT_GIC_V2M,
+ VIRT_PLATFORM_BUS,
};
typedef struct MemMapEntry {
--
1.8.3.2
next prev parent reply other threads:[~2015-06-02 11:29 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-06-02 11:29 [Qemu-devel] [PATCH v13 0/4] machvirt dynamic sysbus device instantiation Eric Auger
2015-06-02 11:29 ` [Qemu-devel] [PATCH v13 1/4] hw/arm/sysbus-fdt: helpers for platform bus nodes addition Eric Auger
2015-06-02 11:29 ` [Qemu-devel] [PATCH v13 2/4] hw/arm/boot: arm_load_kernel implemented as a machine init done notifier Eric Auger
2015-06-02 11:29 ` Eric Auger [this message]
2015-06-02 11:29 ` [Qemu-devel] [PATCH v13 4/4] hw/arm/virt: change indentation in a15memmap Eric Auger
2015-06-02 11:48 ` Shannon Zhao
2015-06-02 15:40 ` [Qemu-devel] [PATCH v13 0/4] machvirt dynamic sysbus device instantiation Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1433244554-12898-4-git-send-email-eric.auger@linaro.org \
--to=eric.auger@linaro.org \
--cc=eric.auger@st.com \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=patches@linaro.org \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).