From: Ruslan Ruslichenko <Ruslan_Ruslichenko@epam.com>
The patch implements FDTGenericMMap interface for sysbus
device class. The implementation maps device's MMIO regions
based on 'reg' property in the Device tree.
This enables automatic memory mapping for the most QEMU
peripherals without the need of device-specific FDT
handling code.
Signed-off-by: Ruslan Ruslichenko <Ruslan_Ruslichenko@epam.com>
---
hw/core/sysbus.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index 3adf2f2faf..78b7827708 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -23,6 +23,8 @@
#include "monitor/monitor.h"
#include "system/address-spaces.h"
+#include "hw/core/fdt_generic_util.h"
+
static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent);
static char *sysbus_get_fw_dev_path(DeviceState *dev);
@@ -291,11 +293,32 @@ static char *sysbus_get_fw_dev_path(DeviceState *dev)
return g_strdup(qdev_fw_name(dev));
}
+static bool sysbus_parse_reg(FDTGenericMMap *obj, FDTGenericRegPropInfo reg,
+ Error **errp)
+{
+ int i;
+
+ for (i = 0; i < reg.n; ++i) {
+ MemoryRegion *mr_parent = (MemoryRegion *)
+ object_dynamic_cast(reg.parents[i], TYPE_MEMORY_REGION);
+ if (!mr_parent) {
+ /* evil */
+ mr_parent = get_system_memory();
+ }
+ memory_region_add_subregion_overlap(mr_parent, reg.a[i],
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(obj), i),
+ reg.p[i]);
+ }
+ return false;
+}
+
static void sysbus_device_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *k = DEVICE_CLASS(klass);
+ FDTGenericMMapClass *fmc = FDT_GENERIC_MMAP_CLASS(klass);
k->realize = sysbus_device_realize;
k->bus_type = TYPE_SYSTEM_BUS;
+ fmc->parse_reg = sysbus_parse_reg;
/*
* device_add plugs devices into a suitable bus. For "real" buses,
* that actually connects the device. For sysbus, the connections
@@ -354,6 +377,11 @@ static const TypeInfo sysbus_types[] = {
.abstract = true,
.class_size = sizeof(SysBusDeviceClass),
.class_init = sysbus_device_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_FDT_GENERIC_MMAP },
+ { },
+ },
+
},
{
.name = TYPE_DYNAMIC_SYS_BUS_DEVICE,
--
2.43.0