Patchwork [12/15] piix_pci: Introduces Xen specific call for irq.

login
register
mail settings
Submitter Stefano Stabellini
Date Aug. 23, 2010, 9:50 a.m.
Message ID <1282557052-14285-12-git-send-email-stefano.stabellini@eu.citrix.com>
Download mbox | patch
Permalink /patch/62469/
State New
Headers show

Comments

Stefano Stabellini - Aug. 23, 2010, 9:50 a.m.
From: Anthony PERARD <anthony.perard@citrix.com>

This patch introduces Xen specific call in piix_pci.

The specific part for Xen is in write_config, set_irq and get_pirq.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 hw/piix_pci.c |   19 ++++++++++++++++---
 hw/xen.h      |    3 +++
 xen-all.c     |   25 +++++++++++++++++++++++++
 xen-stub.c    |    9 +++++++++
 4 files changed, 53 insertions(+), 3 deletions(-)
Isaku Yamahata - Aug. 24, 2010, 11:20 a.m.
On Mon, Aug 23, 2010 at 10:50:49AM +0100, stefano.stabellini@eu.citrix.com wrote:
> From: Anthony PERARD <anthony.perard@citrix.com>
> 
> This patch introduces Xen specific call in piix_pci.
> 
> The specific part for Xen is in write_config, set_irq and get_pirq.
> 
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> ---
>  hw/piix_pci.c |   19 ++++++++++++++++---
>  hw/xen.h      |    3 +++
>  xen-all.c     |   25 +++++++++++++++++++++++++
>  xen-stub.c    |    9 +++++++++
>  4 files changed, 53 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/piix_pci.c b/hw/piix_pci.c
> index f152a0f..994057f 100644
> --- a/hw/piix_pci.c
> +++ b/hw/piix_pci.c
> @@ -28,6 +28,7 @@
>  #include "pci_host.h"
>  #include "isa.h"
>  #include "sysbus.h"
> +#include "xen.h"
>  
>  /*
>   * I440FX chipset data sheet.
> @@ -61,9 +62,13 @@ static void piix3_set_irq(void *opaque, int irq_num, int level);
>     mapping. */
>  static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
>  {
> -    int slot_addend;
> -    slot_addend = (pci_dev->devfn >> 3) - 1;
> -    return (irq_num + slot_addend) & 3;
> +    if (!xen_enabled()) {
> +        int slot_addend;
> +        slot_addend = (pci_dev->devfn >> 3) - 1;
> +        return (irq_num + slot_addend) & 3;
> +    } else {
> +        return irq_num + ((pci_dev->devfn >> 3) << 2);
> +    }
>  }
>  
>  static void update_pam(PCII440FXState *d, uint32_t start, uint32_t end, int r)

pci_slot_get_pirq() is passed to pci_bus_irqs() in i440fx_init().
It would be better to pass xen specific function to pci_bus_irqs() instead of
dynamic check.


> @@ -142,6 +147,9 @@ static void i440fx_write_config(PCIDevice *dev,
>  {
>      PCII440FXState *d = DO_UPCAST(PCII440FXState, dev, dev);
>  
> +    if (xen_enabled())
> +        xen_piix_pci_write_config_client(address, val, len);
> +
>      /* XXX: implement SMRAM.D_LOCK */
>      pci_default_write_config(dev, address, val, len);
>      if (ranges_overlap(address, len, I440FX_PAM, I440FX_PAM_SIZE) ||

Maybe do we want another PCIDeviceInfo whose difference is .write_config?
I'm not sure which is better, though.


> @@ -255,6 +263,11 @@ static void piix3_set_irq(void *opaque, int irq_num, int level)
>      int i, pic_irq, pic_level;
>      PIIX3State *piix3 = opaque;
>  
> +    if (xen_enabled()) {
> +        xen_piix3_set_irq(irq_num, level);
> +        return;
> +    }
> +
>      piix3->pci_irq_levels[irq_num] = level;

Ditto. Pass xen_piix3_set_irq() to pci_bus_irqs()?

thanks,

>  
>      /* now we change the pic irq level according to the piix irq mappings */
> diff --git a/hw/xen.h b/hw/xen.h
> index f1d01d3..77012c2 100644
> --- a/hw/xen.h
> +++ b/hw/xen.h
> @@ -26,4 +26,7 @@ extern int xen_allowed;
>  #define xen_enabled() (0)
>  #endif
>  
> +void xen_piix3_set_irq(int irq_num, int level);
> +void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len);
> +
>  #endif /* QEMU_HW_XEN_H */
> diff --git a/xen-all.c b/xen-all.c
> index e69de29..2d789ad 100644
> --- a/xen-all.c
> +++ b/xen-all.c
> @@ -0,0 +1,25 @@
> +#include "config.h"
> +
> +#include "hw/xen.h"
> +#include "hw/xen_backend.h"
> +
> +void xen_piix3_set_irq(int irq_num, int level)
> +{
> +    xc_hvm_set_pci_intx_level(xen_xc, xen_domid, 0, 0, irq_num >> 2,
> +            irq_num & 3, level);
> +}
> +
> +void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
> +{
> +    int i;
> +
> +    /* Scan for updates to PCI link routes (0x60-0x63). */
> +    for (i = 0; i < len; i++) {
> +        uint8_t v = (val >> (8*i)) & 0xff;
> +        if (v & 0x80)
> +            v = 0;
> +        v &= 0xf;
> +        if (((address+i) >= 0x60) && ((address+i) <= 0x63))
> +            xc_hvm_set_pci_link_route(xen_xc, xen_domid, address + i - 0x60, v);
> +    }
> +}
> diff --git a/xen-stub.c b/xen-stub.c
> index e69de29..38c64cf 100644
> --- a/xen-stub.c
> +++ b/xen-stub.c
> @@ -0,0 +1,9 @@
> +#include "hw/xen.h"
> +
> +void xen_piix3_set_irq(int irq_num, int level)
> +{
> +}
> +
> +void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
> +{
> +}
> -- 
> 1.7.0.4
> 
>

Patch

diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index f152a0f..994057f 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -28,6 +28,7 @@ 
 #include "pci_host.h"
 #include "isa.h"
 #include "sysbus.h"
+#include "xen.h"
 
 /*
  * I440FX chipset data sheet.
@@ -61,9 +62,13 @@  static void piix3_set_irq(void *opaque, int irq_num, int level);
    mapping. */
 static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
 {
-    int slot_addend;
-    slot_addend = (pci_dev->devfn >> 3) - 1;
-    return (irq_num + slot_addend) & 3;
+    if (!xen_enabled()) {
+        int slot_addend;
+        slot_addend = (pci_dev->devfn >> 3) - 1;
+        return (irq_num + slot_addend) & 3;
+    } else {
+        return irq_num + ((pci_dev->devfn >> 3) << 2);
+    }
 }
 
 static void update_pam(PCII440FXState *d, uint32_t start, uint32_t end, int r)
@@ -142,6 +147,9 @@  static void i440fx_write_config(PCIDevice *dev,
 {
     PCII440FXState *d = DO_UPCAST(PCII440FXState, dev, dev);
 
+    if (xen_enabled())
+        xen_piix_pci_write_config_client(address, val, len);
+
     /* XXX: implement SMRAM.D_LOCK */
     pci_default_write_config(dev, address, val, len);
     if (ranges_overlap(address, len, I440FX_PAM, I440FX_PAM_SIZE) ||
@@ -255,6 +263,11 @@  static void piix3_set_irq(void *opaque, int irq_num, int level)
     int i, pic_irq, pic_level;
     PIIX3State *piix3 = opaque;
 
+    if (xen_enabled()) {
+        xen_piix3_set_irq(irq_num, level);
+        return;
+    }
+
     piix3->pci_irq_levels[irq_num] = level;
 
     /* now we change the pic irq level according to the piix irq mappings */
diff --git a/hw/xen.h b/hw/xen.h
index f1d01d3..77012c2 100644
--- a/hw/xen.h
+++ b/hw/xen.h
@@ -26,4 +26,7 @@  extern int xen_allowed;
 #define xen_enabled() (0)
 #endif
 
+void xen_piix3_set_irq(int irq_num, int level);
+void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len);
+
 #endif /* QEMU_HW_XEN_H */
diff --git a/xen-all.c b/xen-all.c
index e69de29..2d789ad 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -0,0 +1,25 @@ 
+#include "config.h"
+
+#include "hw/xen.h"
+#include "hw/xen_backend.h"
+
+void xen_piix3_set_irq(int irq_num, int level)
+{
+    xc_hvm_set_pci_intx_level(xen_xc, xen_domid, 0, 0, irq_num >> 2,
+            irq_num & 3, level);
+}
+
+void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
+{
+    int i;
+
+    /* Scan for updates to PCI link routes (0x60-0x63). */
+    for (i = 0; i < len; i++) {
+        uint8_t v = (val >> (8*i)) & 0xff;
+        if (v & 0x80)
+            v = 0;
+        v &= 0xf;
+        if (((address+i) >= 0x60) && ((address+i) <= 0x63))
+            xc_hvm_set_pci_link_route(xen_xc, xen_domid, address + i - 0x60, v);
+    }
+}
diff --git a/xen-stub.c b/xen-stub.c
index e69de29..38c64cf 100644
--- a/xen-stub.c
+++ b/xen-stub.c
@@ -0,0 +1,9 @@ 
+#include "hw/xen.h"
+
+void xen_piix3_set_irq(int irq_num, int level)
+{
+}
+
+void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
+{
+}