mirror of https://gitee.com/openkylin/qemu.git
piix_pci: Introduces Xen specific call for irq.
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> Acked-by: Alexander Graf <agraf@suse.de> Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
parent
1611977c3d
commit
4144530012
1
hw/pc.h
1
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 */
|
||||
|
|
|
@ -120,7 +120,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;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "isa.h"
|
||||
#include "sysbus.h"
|
||||
#include "range.h"
|
||||
#include "xen.h"
|
||||
|
||||
/*
|
||||
* I440FX chipset data sheet.
|
||||
|
@ -172,6 +173,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;
|
||||
|
@ -239,7 +247,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;
|
||||
|
@ -253,13 +264,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, PIIX_NUM_PIRQS);
|
||||
|
||||
(*pi440fx_state)->piix3 = piix3;
|
||||
|
||||
*piix3_devfn = piix3->dev.devfn;
|
||||
|
@ -272,6 +283,30 @@ 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,
|
||||
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;
|
||||
}
|
||||
|
||||
/* PIIX3 PCI to ISA bridge */
|
||||
static void piix3_set_irq_pic(PIIX3State *piix3, int pic_irq)
|
||||
{
|
||||
|
@ -429,6 +464,14 @@ 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",
|
||||
|
|
6
hw/xen.h
6
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);
|
||||
int xen_hvm_init(void);
|
||||
void xen_vcpu_init(void);
|
||||
|
|
31
xen-all.c
31
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* VCPU Operations, MMIO, IO ring ... */
|
||||
|
||||
static void xen_reset_vcpu(void *opaque)
|
||||
|
|
13
xen-stub.c
13
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;
|
||||
|
|
Loading…
Reference in New Issue