Message ID | 1284722107-28550-6-git-send-email-anthony.perard@citrix.com |
---|---|
State | New |
Headers | show |
On Fri, Sep 17, 2010 at 11:15 AM, <anthony.perard@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 | 10 +++++++++- > hw/xen.h | 6 ++++++ > xen-all.c | 29 +++++++++++++++++++++++++++++ > xen-stub.c | 13 +++++++++++++ > 4 files changed, 57 insertions(+), 1 deletions(-) > > diff --git a/hw/piix_pci.c b/hw/piix_pci.c > index f152a0f..41a342f 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. > @@ -142,6 +143,9 @@ static void i440fx_write_config(PCIDevice *dev, > { > PCII440FXState *d = DO_UPCAST(PCII440FXState, dev, dev); > > + if (xen_enabled()) braces > + 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) || > @@ -235,7 +239,11 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq * > 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); > + if (xen_enabled()) { > + pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq, piix3, 4); > + } else { > + pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, 4); > + } > (*pi440fx_state)->piix3 = piix3; > > *piix3_devfn = piix3->dev.devfn; > diff --git a/hw/xen.h b/hw/xen.h > index 14bbb6e..c5189b1 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) > @@ -26,6 +28,10 @@ extern int xen_allowed; > #define xen_enabled() (0) > #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(int smp_cpus); > > #endif /* QEMU_HW_XEN_H */ > diff --git a/xen-all.c b/xen-all.c > index f505563..948e439 100644 > --- a/xen-all.c > +++ b/xen-all.c > @@ -8,9 +8,38 @@ > > #include "config.h" > > +#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) address should be target_phys_addr_t. > +{ > + int i; > + > + /* Scan for updates to PCI link routes (0x60-0x63). */ > + for (i = 0; i < len; i++) { > + uint8_t v = (val >> (8*i)) & 0xff; Please add spaces around '*'. > + if (v & 0x80) braces > + v = 0; > + v &= 0xf; > + if (((address+i) >= 0x60) && ((address+i) <= 0x63)) Braces and spaces around '+'. > + xc_hvm_set_pci_link_route(xen_xc, xen_domid, address + i - 0x60, v); > + } > +} > + > /* Initialise Xen */ > > int xen_init(int smp_cpus) > diff --git a/xen-stub.c b/xen-stub.c > index 0fa9c51..07e64bc 100644 > --- a/xen-stub.c > +++ b/xen-stub.c > @@ -11,6 +11,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) Also here the address should be target_phys_addr_t.
On Fri, Sep 17, 2010 at 12:15:00PM +0100, anthony.perard@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 | 10 +++++++++- > hw/xen.h | 6 ++++++ > xen-all.c | 29 +++++++++++++++++++++++++++++ > xen-stub.c | 13 +++++++++++++ > 4 files changed, 57 insertions(+), 1 deletions(-) > > diff --git a/hw/piix_pci.c b/hw/piix_pci.c > index f152a0f..41a342f 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. > @@ -142,6 +143,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 I wasn't clear enough. This dynamic check can also be eliminated. Something like the following pseudo code. i440fx_init() ... if (xen_enabled) { d = pci_create_simple(b, 0, "i440FX-xen"); } else } d = pci_create_simple(b, 0, "i440FX"); } static PCIDeviceInfo i440fx_info[] = { { .qdev.name = "i440FX", ... .config_write = i440fx_write_config, },{ .qdev.name = "i440FX-xen", ... .config_write = i440fx_write_config_xen, },{ i440fx_write_config_xen() { xen_piix_pci_write_config_client(); i440fx_write_config() } > @@ -235,7 +239,11 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq * > 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); > + if (xen_enabled()) { > + pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq, piix3, 4); > + } else { > + pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, 4); > + } > (*pi440fx_state)->piix3 = piix3; > > *piix3_devfn = piix3->dev.devfn; > diff --git a/hw/xen.h b/hw/xen.h > index 14bbb6e..c5189b1 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) > @@ -26,6 +28,10 @@ extern int xen_allowed; > #define xen_enabled() (0) > #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(int smp_cpus); > > #endif /* QEMU_HW_XEN_H */ > diff --git a/xen-all.c b/xen-all.c > index f505563..948e439 100644 > --- a/xen-all.c > +++ b/xen-all.c > @@ -8,9 +8,38 @@ > > #include "config.h" > > +#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(int smp_cpus) > diff --git a/xen-stub.c b/xen-stub.c > index 0fa9c51..07e64bc 100644 > --- a/xen-stub.c > +++ b/xen-stub.c > @@ -11,6 +11,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(int smp_cpus) > { > return -ENOSYS; > -- > 1.6.5 > >
diff --git a/hw/piix_pci.c b/hw/piix_pci.c index f152a0f..41a342f 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. @@ -142,6 +143,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) || @@ -235,7 +239,11 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq * 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); + if (xen_enabled()) { + pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq, piix3, 4); + } else { + pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, 4); + } (*pi440fx_state)->piix3 = piix3; *piix3_devfn = piix3->dev.devfn; diff --git a/hw/xen.h b/hw/xen.h index 14bbb6e..c5189b1 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) @@ -26,6 +28,10 @@ extern int xen_allowed; #define xen_enabled() (0) #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(int smp_cpus); #endif /* QEMU_HW_XEN_H */ diff --git a/xen-all.c b/xen-all.c index f505563..948e439 100644 --- a/xen-all.c +++ b/xen-all.c @@ -8,9 +8,38 @@ #include "config.h" +#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(int smp_cpus) diff --git a/xen-stub.c b/xen-stub.c index 0fa9c51..07e64bc 100644 --- a/xen-stub.c +++ b/xen-stub.c @@ -11,6 +11,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(int smp_cpus) { return -ENOSYS;