xen: fix interrupt routing
Compared to the last version I only added a comment to the code. - 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 line to 128; Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
parent
ebed85058b
commit
bf09551a6b
1
hw/pc.h
1
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 */
|
||||
|
@ -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;
|
||||
|
@ -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,21 @@ 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"));
|
||||
/* Xen supports additional interrupt routes from the PCI devices to
|
||||
* the IOAPIC: the four pins of each PCI device on the bus are also
|
||||
* connected to the IOAPIC directly.
|
||||
* These additional routes can be discovered through ACPI. */
|
||||
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 +298,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 +359,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;
|
||||
@ -464,14 +465,6 @@ static PCIDeviceInfo i440fx_info[] = {
|
||||
.no_hotplug = 1,
|
||||
.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",
|
||||
@ -481,6 +474,15 @@ static PCIDeviceInfo i440fx_info[] = {
|
||||
.no_hotplug = 1,
|
||||
.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 */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user