From: Anthony PERARD <anthony.perard@xxxxxxxxxx>
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@xxxxxxxxxx>
Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
Acked-by: Alexander Graf <agraf@xxxxxxx>
---
hw/pc.h | 1 +
hw/pc_piix.c | 6 +++++-
hw/piix_pci.c | 47 ++++++++++++++++++++++++++++++++++++++++++++---
hw/xen.h | 6 ++++++
xen-all.c | 31 +++++++++++++++++++++++++++++++
xen-stub.c | 13 +++++++++++++
6 files changed, 100 insertions(+), 4 deletions(-)
diff --git a/hw/pc.h b/hw/pc.h
index feb8a7a..85662c3 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -176,6 +176,7 @@ 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 8e5023e..b9b99d2 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -109,7 +109,11 @@ static void pc_init1(ram_addr_t ram_size,
isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 24);
if (pci_enabled) {
- pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size);
+ 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);
+ }
} else {
pci_bus = NULL;
i440fx_state = NULL;
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 358da58..c11a7f6 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -29,6 +29,7 @@
#include "isa.h"
#include "sysbus.h"
#include "range.h"
+#include "xen.h"
/*
* I440FX chipset data sheet.
@@ -151,6 +152,13 @@ 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;
@@ -216,7 +224,10 @@ static int i440fx_initfn(PCIDevice *dev)
return 0;
}
-PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq
*pic, ram_addr_t ram_size)
+static PCIBus *i440fx_common_init(const char *device_name,
+ PCII440FXState **pi440fx_state,
+ int *piix3_devfn,
+ qemu_irq *pic, ram_addr_t ram_size)
{
DeviceState *dev;
PCIBus *b;
@@ -230,13 +241,13 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int
*piix3_devfn, qemu_irq *
s->bus = b;
qdev_init_nofail(dev);
- d = pci_create_simple(b, 0, "i440FX");
+ 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"));
piix3->pic = pic;
- pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, 4);
+
(*pi440fx_state)->piix3 = piix3;
*piix3_devfn = piix3->dev.devfn;
@@ -249,6 +260,28 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int
*piix3_devfn, qemu_irq *
return b;
}
+PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn,
+ qemu_irq *pic, ram_addr_t ram_size)
+{
+ 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,
4);
+
+ 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, 4);
+
+ return b;
+}
+
/* PIIX3 PCI to ISA bridge */
static void piix3_set_irq(void *opaque, int irq_num, int level)
@@ -352,6 +385,14 @@ 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),
diff --git a/hw/xen.h b/hw/xen.h
index 726360a..620827d 100644
--- a/hw/xen.h
+++ b/hw/xen.h
@@ -8,6 +8,8 @@
*/
#include <inttypes.h>
+#include "qemu-common.h"
+
/* xen-machine.c */
enum xen_mode {
XEN_EMULATE = 0, // xen emulation, using xenner (default)
@@ -29,6 +31,10 @@ static inline int xen_enabled(void)
#endif
}
+int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num);
+void xen_piix3_set_irq(void *opaque, int irq_num, int level);
+void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len);
+
int xen_init(void);
#if defined(CONFIG_XEN) && CONFIG_XEN_CTRL_INTERFACE_VERSION < 400
diff --git a/xen-all.c b/xen-all.c
index e2872f9..0bc0978 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -6,9 +6,40 @@
*
*/
+#include "hw/pci.h"
#include "hw/xen_common.h"
#include "hw/xen_backend.h"
+/* Xen specific function for piix pci */
+
+int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
+{
+ return irq_num + ((pci_dev->devfn >> 3) << 2);
+}
+
+void xen_piix3_set_irq(void *opaque, 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);
+ }
+ }
+}
+
/* Initialise Xen */
int xen_init(void)
diff --git a/xen-stub.c b/xen-stub.c
index beb982f..dc90f10 100644
--- a/xen-stub.c
+++ b/xen-stub.c
@@ -9,6 +9,19 @@
#include "qemu-common.h"
#include "hw/xen.h"
+int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
+{
+ return -1;
+}
+
+void xen_piix3_set_irq(void *opaque, int irq_num, int level)
+{
+}
+
+void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
+{
+}
+
int xen_init(void)
{
return -ENOSYS;
--
1.7.2.3
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|