qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Alvise Rigo <a.rigo@virtualopensystems.com>
To: qemu-devel@nongnu.org, rob.herring@linaro.org
Cc: tech@virtualopensystems.com, Alvise Rigo <a.rigo@virtualopensystems.com>
Subject: [Qemu-devel] [RFC PATCH 8/8] generic_pci: add interrupt map structures
Date: Fri, 11 Jul 2014 09:21:10 +0200	[thread overview]
Message-ID: <1405063270-18902-9-git-send-email-a.rigo@virtualopensystems.com> (raw)
In-Reply-To: <1405063270-18902-1-git-send-email-a.rigo@virtualopensystems.com>

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 <a.rigo@virtualopensystems.com>
---
 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

  parent reply	other threads:[~2014-07-11  7:21 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-11  7:21 [Qemu-devel] [RFC PATCH 0/8] Add Generic PCI host device update Alvise Rigo
2014-07-11  7:21 ` [Qemu-devel] [RFC PATCH 1/8] mach-virt: move GIC inside mach-virt structure Alvise Rigo
2014-07-11  7:21 ` [Qemu-devel] [RFC PATCH 2/8] mach-virt: improve PCI memory topology definition Alvise Rigo
2014-07-11  7:21 ` [Qemu-devel] [RFC PATCH 3/8] QEMUMachine: finalize_dt function Alvise Rigo
2014-07-11  7:21 ` [Qemu-devel] [RFC PATCH 4/8] generic_pci: create header file Alvise Rigo
2014-07-11  7:21 ` [Qemu-devel] [RFC PATCH 5/8] generic_pci: create own map irq function Alvise Rigo
2014-07-11  7:21 ` [Qemu-devel] [RFC PATCH 6/8] generic_pci: generate dt node after devices init Alvise Rigo
2014-11-05 12:26   ` Claudio Fontana
2014-11-06 10:27     ` alvise rigo
2014-07-11  7:21 ` [Qemu-devel] [RFC PATCH 7/8] generic_pci: realize device with machine data Alvise Rigo
2014-07-11  7:21 ` Alvise Rigo [this message]
2014-07-11  9:09 ` [Qemu-devel] [RFC PATCH 0/8] Add Generic PCI host device update Peter Maydell
2014-07-11  9:28   ` Alvise Rigo
2014-07-13 14:28     ` Rob Herring
2014-09-09 16:35     ` Claudio Fontana
2014-09-10  7:31       ` alvise rigo
2014-11-05 10:23 ` Claudio Fontana
2014-11-05 11:09   ` alvise rigo
2014-11-07 15:40 ` Claudio Fontana
2014-11-10 10:00   ` alvise rigo
2014-11-11  3:24     ` Ming Lei
2014-11-11  4:22       ` Ming Lei
2014-11-11 10:26         ` Claudio Fontana

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=1405063270-18902-9-git-send-email-a.rigo@virtualopensystems.com \
    --to=a.rigo@virtualopensystems.com \
    --cc=qemu-devel@nongnu.org \
    --cc=rob.herring@linaro.org \
    --cc=tech@virtualopensystems.com \
    /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).