qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] xen: fix interrupt routing
@ 2011-05-18 17:53 stefano.stabellini
  2011-05-19  2:14 ` Isaku Yamahata
  2011-05-19  7:55 ` [Qemu-devel] [Xen-devel] " Ian Campbell
  0 siblings, 2 replies; 14+ messages in thread
From: stefano.stabellini @ 2011-05-18 17:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: xen-devel, agraf, Stefano Stabellini

From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

Match the routing informations built by seabios:

- remove i440fx_write_config_xen
we don't need to intercept pci config writes to i440FX;

- introduce piix3_write_config_xen
we do need to intercept pci config write to the PCI-ISA bridge to update
the PCI link routing;

- remove xen_pci_slot_get_pirq
we are now using the same link routing as seabios and qemu so we don't
need a diffirent get_pirq function;

- fix xen_piix3_set_irq
we always inject one of the 4 pci intx, so we can use
xc_hvm_set_isa_irq_level to inject the interrupt. Use pci_irqs as
initialized by seabios to map a pirq into an ISA irq. This has the
benefit of removing all the calls to xc_hvm_set_pci_intx_level that
doesn't work correctly anymore because from the same device number and
intx Xen calculates a different PCI link compared to Qemu and Seabios.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 hw/piix_pci.c |   21 ++++++++++++---------
 xen-all.c     |   16 ++++++++--------
 2 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 7f1c4cc..aae6a48 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -78,6 +78,8 @@ struct PCII440FXState {
 #define I440FX_SMRAM    0x72
 
 static void piix3_set_irq(void *opaque, int pirq, int level);
+static void piix3_write_config_xen(PCIDevice *dev,
+                               uint32_t address, uint32_t val, int len);
 
 /* return the global irq number corresponding to a given device irq
    pin. We could also use the bus number to have a more precise
@@ -173,13 +175,6 @@ static void i440fx_write_config(PCIDevice *dev,
     }
 }
 
-static void i440fx_write_config_xen(PCIDevice *dev,
-                                    uint32_t address, uint32_t val, int len)
-{
-    xen_piix_pci_write_config_client(address, val, len);
-    i440fx_write_config(dev, address, val, len);
-}
-
 static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id)
 {
     PCII440FXState *d = opaque;
@@ -301,7 +296,8 @@ PCIBus *i440fx_xen_init(PCII440FXState **pi440fx_state, int *piix3_devfn,
     PCIBus *b;
 
     b = i440fx_common_init("i440FX-xen", pi440fx_state, piix3_devfn, pic, ram_size);
-    pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq,
+    (*pi440fx_state)->piix3->dev.config_write = piix3_write_config_xen;
+    pci_bus_irqs(b, xen_piix3_set_irq, pci_slot_get_pirq,
                  (*pi440fx_state)->piix3, PIIX_NUM_PIRQS);
 
     return b;
@@ -365,6 +361,13 @@ static void piix3_write_config(PCIDevice *dev,
     }
 }
 
+static void piix3_write_config_xen(PCIDevice *dev,
+                               uint32_t address, uint32_t val, int len)
+{
+    xen_piix_pci_write_config_client(address, val, len);
+    piix3_write_config(dev, address, val, len);
+}
+
 static void piix3_reset(void *opaque)
 {
     PIIX3State *d = opaque;
@@ -471,7 +474,7 @@ static PCIDeviceInfo i440fx_info[] = {
         .qdev.vmsd    = &vmstate_i440fx,
         .qdev.no_user = 1,
         .init         = i440fx_initfn,
-        .config_write = i440fx_write_config_xen,
+        .config_write = i440fx_write_config,
     },{
         .qdev.name    = "PIIX3",
         .qdev.desc    = "ISA bridge",
diff --git a/xen-all.c b/xen-all.c
index 0eac202..7d7863f 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -70,17 +70,16 @@ typedef struct XenIOState {
     Notifier exit;
 } XenIOState;
 
-/* Xen specific function for piix pci */
+/* pci_irqs as initialized by seabios */
+uint8_t pci_irqs[4] = {
+    10, 10, 11, 11
+};
 
-int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
-{
-    return irq_num + ((pci_dev->devfn >> 3) << 2);
-}
+/* Xen specific function for piix pci */
 
-void xen_piix3_set_irq(void *opaque, int irq_num, int level)
+void xen_piix3_set_irq(void *opaque, int pirq, int level)
 {
-    xc_hvm_set_pci_intx_level(xen_xc, xen_domid, 0, 0, irq_num >> 2,
-                              irq_num & 3, level);
+    xc_hvm_set_isa_irq_level(xen_xc, xen_domid, pci_irqs[pirq], level);
 }
 
 void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
@@ -95,6 +94,7 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
         }
         v &= 0xf;
         if (((address + i) >= 0x60) && ((address + i) <= 0x63)) {
+            pci_irqs[address + i - 0x60] = v;
             xc_hvm_set_pci_link_route(xen_xc, xen_domid, address + i - 0x60, v);
         }
     }
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH] xen: fix interrupt routing
@ 2011-05-26 15:48 Stefano Stabellini
  2011-05-27 23:17 ` Alexander Graf
  0 siblings, 1 reply; 14+ messages in thread
From: Stefano Stabellini @ 2011-05-26 15:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Isaku Yamahata, xen-devel, Alexander Graf

xen: fix interrupt routing

- remove i440FX-xen and i440fx_write_config_xen
we don't need to intercept pci config writes to i440FX anymore;

- introduce PIIX3-xen and piix3_write_config_xen
we do need to intercept pci config write to the PCI-ISA bridge to update
the PCI link routing;

- set the number of PIIX3-xen interrupts lines to 128;

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

diff --git a/hw/pc.h b/hw/pc.h
index 0dcbee7..6d5730b 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -176,7 +176,6 @@ struct PCII440FXState;
 typedef struct PCII440FXState PCII440FXState;
 
 PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, qemu_irq *pic, ram_addr_t ram_size);
-PCIBus *i440fx_xen_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *pic, ram_addr_t ram_size);
 void i440fx_init_memory_mappings(PCII440FXState *d);
 
 /* piix4.c */
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 9a22a8a..ba198de 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -124,11 +124,7 @@ static void pc_init1(ram_addr_t ram_size,
     isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 24);
 
     if (pci_enabled) {
-        if (!xen_enabled()) {
-            pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size);
-        } else {
-            pci_bus = i440fx_xen_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size);
-        }
+        pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size);
     } else {
         pci_bus = NULL;
         i440fx_state = NULL;
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 7f1c4cc..3d73a42 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -40,6 +40,7 @@ typedef PCIHostState I440FXState;
 
 #define PIIX_NUM_PIC_IRQS       16      /* i8259 * 2 */
 #define PIIX_NUM_PIRQS          4ULL    /* PIRQ[A-D] */
+#define XEN_PIIX_NUM_PIRQS      128ULL
 #define PIIX_PIRQC              0x60
 
 typedef struct PIIX3State {
@@ -78,6 +79,8 @@ struct PCII440FXState {
 #define I440FX_SMRAM    0x72
 
 static void piix3_set_irq(void *opaque, int pirq, int level);
+static void piix3_write_config_xen(PCIDevice *dev,
+                               uint32_t address, uint32_t val, int len);
 
 /* return the global irq number corresponding to a given device irq
    pin. We could also use the bus number to have a more precise
@@ -173,13 +176,6 @@ static void i440fx_write_config(PCIDevice *dev,
     }
 }
 
-static void i440fx_write_config_xen(PCIDevice *dev,
-                                    uint32_t address, uint32_t val, int len)
-{
-    xen_piix_pci_write_config_client(address, val, len);
-    i440fx_write_config(dev, address, val, len);
-}
-
 static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id)
 {
     PCII440FXState *d = opaque;
@@ -267,8 +263,17 @@ static PCIBus *i440fx_common_init(const char *device_name,
     d = pci_create_simple(b, 0, device_name);
     *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d);
 
-    piix3 = DO_UPCAST(PIIX3State, dev,
-                      pci_create_simple_multifunction(b, -1, true, "PIIX3"));
+    if (xen_enabled()) {
+        piix3 = DO_UPCAST(PIIX3State, dev,
+                pci_create_simple_multifunction(b, -1, true, "PIIX3-xen"));
+        pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq,
+                piix3, XEN_PIIX_NUM_PIRQS);
+    } else {
+        piix3 = DO_UPCAST(PIIX3State, dev,
+                pci_create_simple_multifunction(b, -1, true, "PIIX3"));
+        pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3,
+                PIIX_NUM_PIRQS);
+    }
     piix3->pic = pic;
 
     (*pi440fx_state)->piix3 = piix3;
@@ -289,21 +294,6 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn,
     PCIBus *b;
 
     b = i440fx_common_init("i440FX", pi440fx_state, piix3_devfn, pic, ram_size);
-    pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, (*pi440fx_state)->piix3,
-                 PIIX_NUM_PIRQS);
-
-    return b;
-}
-
-PCIBus *i440fx_xen_init(PCII440FXState **pi440fx_state, int *piix3_devfn,
-                        qemu_irq *pic, ram_addr_t ram_size)
-{
-    PCIBus *b;
-
-    b = i440fx_common_init("i440FX-xen", pi440fx_state, piix3_devfn, pic, ram_size);
-    pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq,
-                 (*pi440fx_state)->piix3, PIIX_NUM_PIRQS);
-
     return b;
 }
 
@@ -365,6 +355,13 @@ static void piix3_write_config(PCIDevice *dev,
     }
 }
 
+static void piix3_write_config_xen(PCIDevice *dev,
+                               uint32_t address, uint32_t val, int len)
+{
+    xen_piix_pci_write_config_client(address, val, len);
+    piix3_write_config(dev, address, val, len);
+}
+
 static void piix3_reset(void *opaque)
 {
     PIIX3State *d = opaque;
@@ -465,14 +462,6 @@ static PCIDeviceInfo i440fx_info[] = {
         .init         = i440fx_initfn,
         .config_write = i440fx_write_config,
     },{
-        .qdev.name    = "i440FX-xen",
-        .qdev.desc    = "Host bridge",
-        .qdev.size    = sizeof(PCII440FXState),
-        .qdev.vmsd    = &vmstate_i440fx,
-        .qdev.no_user = 1,
-        .init         = i440fx_initfn,
-        .config_write = i440fx_write_config_xen,
-    },{
         .qdev.name    = "PIIX3",
         .qdev.desc    = "ISA bridge",
         .qdev.size    = sizeof(PIIX3State),
@@ -482,6 +471,15 @@ static PCIDeviceInfo i440fx_info[] = {
         .init         = piix3_initfn,
         .config_write = piix3_write_config,
     },{
+        .qdev.name    = "PIIX3-xen",
+        .qdev.desc    = "ISA bridge",
+        .qdev.size    = sizeof(PIIX3State),
+        .qdev.vmsd    = &vmstate_piix3,
+        .qdev.no_user = 1,
+        .no_hotplug   = 1,
+        .init         = piix3_initfn,
+        .config_write = piix3_write_config_xen,
+    },{
         /* end of list */
     }
 };

^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2011-06-15  8:25 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-05-18 17:53 [Qemu-devel] [PATCH] xen: fix interrupt routing stefano.stabellini
2011-05-19  2:14 ` Isaku Yamahata
2011-05-19 19:16   ` Stefano Stabellini
2011-05-19  7:55 ` [Qemu-devel] [Xen-devel] " Ian Campbell
2011-05-19 19:16   ` Stefano Stabellini
  -- strict thread matches above, loose matches on Subject: below --
2011-05-26 15:48 [Qemu-devel] " Stefano Stabellini
2011-05-27 23:17 ` Alexander Graf
2011-05-31 11:05   ` Stefano Stabellini
2011-06-14  9:25     ` Alexander Graf
2011-06-14 12:17       ` [Qemu-devel] [Xen-devel] " Ian Campbell
2011-06-14 12:30         ` Alexander Graf
2011-06-14 13:08           ` [Qemu-devel] " Jan Kiszka
2011-06-14 13:31             ` Stefano Stabellini
2011-06-14 13:27           ` [Qemu-devel] [Xen-devel] " Stefano Stabellini
2011-06-14 15:30             ` [Qemu-devel] " Jan Kiszka
2011-06-14 18:18               ` Stefano Stabellini
2011-06-15  8:24                 ` Alexander Graf

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).