[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC PATCH 8/8] generic_pci: add interrupt map structures
From: |
Alvise Rigo |
Subject: |
[Qemu-devel] [RFC PATCH 8/8] generic_pci: add interrupt map structures |
Date: |
Fri, 11 Jul 2014 09:21:10 +0200 |
Create a generic_pci_host state to include the IRQ map to be used when
resolving the PCI interrupts. These structures can be useful to support
more complicated scenarios, like with multi functions PCI devices.
Signed-off-by: Alvise Rigo <address@hidden>
---
hw/pci-host/generic-pci.c | 37 ++++++++++++++++++++++++++-----------
include/hw/pci-host/pci_generic.h | 15 +++++++++++++--
2 files changed, 39 insertions(+), 13 deletions(-)
diff --git a/hw/pci-host/generic-pci.c b/hw/pci-host/generic-pci.c
index 1bde69c..24c0ce8 100644
--- a/hw/pci-host/generic-pci.c
+++ b/hw/pci-host/generic-pci.c
@@ -62,14 +62,19 @@ static void pci_generic_host_init(Object *obj)
PCI_DEVFN(0, 0), TYPE_PCIE_BUS);
h->bus = &s->pci_bus;
- object_initialize(&s->pci_dev, sizeof(s->pci_dev), TYPE_GENERIC_PCI_HOST);
- qdev_set_parent_bus(DEVICE(&s->pci_dev), BUS(&s->pci_bus));
+ object_initialize(&s->pci_gen, sizeof(s->pci_gen), TYPE_GENERIC_PCI_HOST);
+ qdev_set_parent_bus(DEVICE(&s->pci_gen), BUS(&s->pci_bus));
}
static int generic_pci_map_irq_fn(PCIDevice *pci_dev, int pin)
{
+ BusState *bus = qdev_get_parent_bus(&pci_dev->qdev);
+ PCIBus *pci_bus = PCI_BUS(bus);
+ PCIDevice *pdev = pci_bus->devices[PCI_DEVFN(0, 0)];
+ GenericPCIHostState *gps = PCI_GEN_HOST(pdev);
+
if (!pin) {
- return PCI_SLOT(pci_dev->devfn);
+ return gps->irqmap.slot_idx_map[PCI_SLOT(pci_dev->devfn)];
}
hw_error("generic_pci: only one pin per device supported.");
@@ -117,7 +122,7 @@ static void pci_generic_host_realize(DeviceState *dev,
Error **errp)
sysbus_init_mmio(sbd, &s->pci_mem_window);
/* TODO Remove once realize propagates to child devices. */
- object_property_set_bool(OBJECT(&s->pci_dev), true, "realized", errp);
+ object_property_set_bool(OBJECT(&s->pci_gen), true, "realized", errp);
}
static void pci_generic_host_class_init(ObjectClass *klass, void *data)
@@ -146,11 +151,11 @@ struct dt_irq_mapping {
/* Generate the irq_mapping data and return the number of the device attached
* to the device bus.
* */
-static int generate_int_mapping(struct dt_irq_mapping *irq_map)
+static int generate_int_mapping(struct dt_irq_mapping *irq_map, PCIVPBState *s)
{
BusState *inner_bus;
BusChild *inner;
- int num_slots = 0;
+ int slot_count = 0;
uint64_t *data_ptr = irq_map->data;
QLIST_FOREACH(inner_bus, &irq_map->dev->child_bus, sibling) {
@@ -158,19 +163,29 @@ static int generate_int_mapping(struct dt_irq_mapping
*irq_map)
DeviceState *dev = inner->child;
PCIDevice *pdev = PCI_DEVICE(dev);
int pci_slot = PCI_SLOT(pdev->devfn);
+ uint8_t *slot_idx = s->pci_gen.irqmap.slot_idx_map;
+ uint8_t *slot_irq = s->pci_gen.irqmap.slot_irq_map;
+
+ if (slot_count > MAX_PCI_DEVICES) {
+ hw_error("generic_pci: too many PCI devices.");
+ }
+
+ /* Every PCI slot has one interrupt mapped. */
+ slot_idx[pci_slot] = slot_count;
+ slot_irq[slot_count] = irq_map->base_irq_num + slot_count;
uint64_t buffer[IRQ_MAPPING_CELLS] =
{1, pci_slot << 11, 2, 0x00000000, 1, 0x1,
- 1, irq_map->gic_phandle, 1, 0, 1, irq_map->base_irq_num +
pci_slot,
+ 1, irq_map->gic_phandle, 1, 0, 1, slot_irq[slot_count],
1, 0x1};
memcpy(data_ptr, buffer, IRQ_MAPPING_CELLS * sizeof(*buffer));
- num_slots++;
+ slot_count++;
data_ptr += IRQ_MAPPING_CELLS;
}
}
- return num_slots;
+ return slot_count;
}
static void generate_dt_node(DeviceState *dev)
@@ -215,7 +230,7 @@ static void generate_dt_node(DeviceState *dev)
.data = int_mapping_data
};
- num_dev = generate_int_mapping(&dt_map);
+ num_dev = generate_int_mapping(&dt_map, s);
qemu_fdt_setprop_sized_cells_from_array(fdt, nodename, "interrupt-map",
(num_dev * IRQ_MAPPING_CELLS)/2, int_mapping_data);
@@ -228,7 +243,7 @@ static void generate_dt_node(DeviceState *dev)
static const TypeInfo pci_generic_host_info = {
.name = TYPE_GENERIC_PCI_HOST,
.parent = TYPE_PCI_DEVICE,
- .instance_size = sizeof(PCIDevice),
+ .instance_size = sizeof(GenericPCIHostState),
.class_init = pci_generic_host_class_init,
};
diff --git a/include/hw/pci-host/pci_generic.h
b/include/hw/pci-host/pci_generic.h
index 039549f..c65bc6c 100644
--- a/include/hw/pci-host/pci_generic.h
+++ b/include/hw/pci-host/pci_generic.h
@@ -14,6 +14,17 @@ struct dt_data {
};
typedef struct {
+ PCIDevice parent_obj;
+
+ struct irqmap {
+ /* slot_idx_map[i] = index inside slot_irq_map for device at slot i */
+ uint8_t slot_idx_map[PCI_SLOT_MAX];
+ /* slot_irq_map[i] = irq num. of the i-th device attached to the bus */
+ uint8_t slot_irq_map[MAX_PCI_DEVICES];
+ } irqmap;
+} GenericPCIHostState;
+
+typedef struct {
PCIHostState parent_obj;
qemu_irq irq[MAX_PCI_DEVICES];
@@ -27,7 +38,7 @@ typedef struct {
MemoryRegion pci_io_window;
MemoryRegion pci_mem_window;
PCIBus pci_bus;
- PCIDevice pci_dev;
+ GenericPCIHostState pci_gen;
/* Device tree data set by the machine
*/
struct dt_data dt_data;
@@ -45,7 +56,7 @@ typedef struct GenericPCIClass {
#define TYPE_GENERIC_PCI_HOST "generic_pci_host"
#define PCI_GEN_HOST(obj) \
- OBJECT_CHECK(PCIDevice, (obj), TYPE_GENERIC_PCIHOST)
+ OBJECT_CHECK(GenericPCIHostState, (obj), TYPE_GENERIC_PCI_HOST)
#define GENERIC_PCI_CLASS(klass) \
OBJECT_CLASS_CHECK(GenericPCIClass, (klass), TYPE_GENERIC_PCI)
--
1.9.1
- [Qemu-devel] [RFC PATCH 0/8] Add Generic PCI host device update, Alvise Rigo, 2014/07/11
- [Qemu-devel] [RFC PATCH 1/8] mach-virt: move GIC inside mach-virt structure, Alvise Rigo, 2014/07/11
- [Qemu-devel] [RFC PATCH 2/8] mach-virt: improve PCI memory topology definition, Alvise Rigo, 2014/07/11
- [Qemu-devel] [RFC PATCH 3/8] QEMUMachine: finalize_dt function, Alvise Rigo, 2014/07/11
- [Qemu-devel] [RFC PATCH 4/8] generic_pci: create header file, Alvise Rigo, 2014/07/11
- [Qemu-devel] [RFC PATCH 5/8] generic_pci: create own map irq function, Alvise Rigo, 2014/07/11
- [Qemu-devel] [RFC PATCH 6/8] generic_pci: generate dt node after devices init, Alvise Rigo, 2014/07/11
- [Qemu-devel] [RFC PATCH 7/8] generic_pci: realize device with machine data, Alvise Rigo, 2014/07/11
- [Qemu-devel] [RFC PATCH 8/8] generic_pci: add interrupt map structures,
Alvise Rigo <=
- Re: [Qemu-devel] [RFC PATCH 0/8] Add Generic PCI host device update, Peter Maydell, 2014/07/11