>From 67806cc642cb666fb59fec60115fee37b80ecb3a Mon Sep 17 00:00:00 2001 From: Anthony Xu <anthony.xu@xxxxxxxxx> Date: Wed, 18 Jun 2008 14:32:46 -0400 Subject: [PATCH] Irq assignment 1. use bimodal _PRT 2. pci device can use irq > 15, reduce interrupt sharing 3. test by running linux guest in kvm-ia64, kvm-i32(w/ wo/ -no-kvm) signed-off-by: Anthony Xu <anthony.xu@xxxxxxxxx> --- bios/acpi-dsdt.dsl | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++- qemu/hw/apic.c | 22 ++++++++++++++++++- qemu/hw/ipf.c | 24 +++++++++++++++++++++ qemu/hw/pc.c | 2 +- qemu/hw/pc.h | 4 +++ qemu/hw/pci.c | 8 +++++++ 6 files changed, 116 insertions(+), 3 deletions(-) diff --git a/bios/acpi-dsdt.dsl b/bios/acpi-dsdt.dsl index d1bfa2c..62dd612 100755 --- a/bios/acpi-dsdt.dsl +++ b/bios/acpi-dsdt.dsl @@ -89,6 +89,12 @@ DefinitionBlock ( } } + Name (PICD, 0) + + Method(_PIC, 1) + { + Store(Arg0, PICD) + } /* PCI Bus definition */ Scope(\_SB) { @@ -96,7 +102,15 @@ DefinitionBlock ( Name (_HID, EisaId ("PNP0A03")) Name (_ADR, 0x00) Name (_UID, 1) - Name(_PRT, Package() { + + Method (_PRT,0) { + If (PICD) { + Return (PRTA) + } + Return (PRTP) + } + + Name (PRTP, Package() { /* PCI IRQ routing table, example from ACPI 2.0a specification, section 6.2.8.1 */ /* Note: we provide the same info as the PCI routing @@ -147,6 +161,49 @@ DefinitionBlock ( prt_slot3(0x001f), }) + Name (PRTA, Package() { + /* IOAPIC use fixed connection */ + +#define aprt_slot(nr, irq) \ + Package() { nr##ffff, 0, 0, irq }, \ + Package() { nr##ffff, 1, 0, irq }, \ + Package() { nr##ffff, 2, 0, irq }, \ + Package() { nr##ffff, 3, 0, irq } + + aprt_slot(0x0000, 16), + aprt_slot(0x0001, 17), + aprt_slot(0x0002, 18), + aprt_slot(0x0003, 19), + aprt_slot(0x0004, 20), + aprt_slot(0x0005, 21), + aprt_slot(0x0006, 22), + aprt_slot(0x0007, 23), + aprt_slot(0x0008, 16), + aprt_slot(0x0009, 17), + aprt_slot(0x000a, 18), + aprt_slot(0x000b, 19), + aprt_slot(0x000c, 20), + aprt_slot(0x000d, 21), + aprt_slot(0x000e, 22), + aprt_slot(0x000f, 23), + aprt_slot(0x0010, 16), + aprt_slot(0x0011, 17), + aprt_slot(0x0012, 18), + aprt_slot(0x0013, 19), + aprt_slot(0x0014, 20), + aprt_slot(0x0015, 21), + aprt_slot(0x0016, 22), + aprt_slot(0x0017, 23), + aprt_slot(0x0018, 16), + aprt_slot(0x0019, 17), + aprt_slot(0x001a, 18), + aprt_slot(0x001b, 19), + aprt_slot(0x001c, 20), + aprt_slot(0x001d, 21), + aprt_slot(0x001e, 22), + aprt_slot(0x001f, 23), + }) + OperationRegion(PCST, SystemIO, 0xae00, 0x08) Field (PCST, DWordAcc, NoLock, WriteAsZeros) { diff --git a/qemu/hw/apic.c b/qemu/hw/apic.c index 4ebf1ff..98bf3ad 100644 --- a/qemu/hw/apic.c +++ b/qemu/hw/apic.c @@ -1053,10 +1053,30 @@ static void ioapic_service(IOAPICState *s) } } +int ioapic_map_irq(int devfn, int irq_num) +{ + int irq; + irq = ((devfn >> 3) & 7) + 16; + return irq; +} + +static int ioapic_irq_count[IOAPIC_NUM_PINS]; + void ioapic_set_irq(void *opaque, int vector, int level) { IOAPICState *s = opaque; - + if( vector >= 16 ){ + if( level ) + ioapic_irq_count[vector] += 1; + else + ioapic_irq_count[vector] -= 1; + level = (ioapic_irq_count[vector] != 0); + } +#ifdef KVM_CAP_IRQCHIP + if (kvm_enabled()) + if (kvm_set_irq(vector, ioapic_irq_count[vector] == 0)) + return; +#endif if (vector >= 0 && vector < IOAPIC_NUM_PINS) { uint32_t mask = 1 << vector; uint64_t entry = s->ioredtbl[vector]; diff --git a/qemu/hw/ipf.c b/qemu/hw/ipf.c index b11e328..dabd7cc 100644 --- a/qemu/hw/ipf.c +++ b/qemu/hw/ipf.c @@ -672,3 +672,27 @@ QEMUMachine ipf_machine = { ipf_init_pci, VGA_RAM_SIZE + VGA_RAM_SIZE, }; + +#define IOAPIC_NUM_PINS 48 +static int ioapic_irq_count[IOAPIC_NUM_PINS]; + +int ioapic_map_irq(int devfn, int irq_num) +{ + int irq, dev; + dev = devfn >> 3; + irq = ((((dev << 2) + (dev >> 3) + irq_num) & 31) + 16); + return irq; +} + +void ioapic_set_irq(void *opaque, int vector, int level) +{ + if( level ) + ioapic_irq_count[vector] += 1; + else + ioapic_irq_count[vector] -= 1; + + if (kvm_enabled()) + if (kvm_set_irq(vector, ioapic_irq_count[vector] == 0)) + return; +} + diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c index 42c2687..bf49689 100644 --- a/qemu/hw/pc.c +++ b/qemu/hw/pc.c @@ -53,8 +53,8 @@ static fdctrl_t *floppy_controller; static RTCState *rtc_state; static PITState *pit; -static IOAPICState *ioapic; static PCIDevice *i440fx_state; +IOAPICState *ioapic; static void ioport80_write(void *opaque, uint32_t addr, uint32_t data) { diff --git a/qemu/hw/pc.h b/qemu/hw/pc.h index c284bf1..379b386 100644 --- a/qemu/hw/pc.h +++ b/qemu/hw/pc.h @@ -47,6 +47,7 @@ int apic_accept_pic_intr(CPUState *env); void apic_local_deliver(CPUState *env, int vector); int apic_get_interrupt(CPUState *env); IOAPICState *ioapic_init(void); +int ioapic_map_irq(int devfn, int irq_num); void ioapic_set_irq(void *opaque, int vector, int level); /* i8254.c */ @@ -95,6 +96,9 @@ void ioport_set_a20(int enable); int ioport_get_a20(void); CPUState *pc_new_cpu(int cpu, const char *cpu_model, int pci_enabled); +/* pc.c */ +extern IOAPICState *ioapic; + /* acpi.c */ extern int acpi_enabled; i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, diff --git a/qemu/hw/pci.c b/qemu/hw/pci.c index 92683d1..c1a0361 100644 --- a/qemu/hw/pci.c +++ b/qemu/hw/pci.c @@ -538,12 +538,20 @@ static void pci_set_irq(void *opaque, int irq_num, int level) PCIDevice *pci_dev = (PCIDevice *)opaque; PCIBus *bus; int change; + int irq; change = level - pci_dev->irq_state[irq_num]; if (!change) return; pci_dev->irq_state[irq_num] = level; + + irq = ioapic_map_irq(pci_dev->devfn, irq_num); +#if defined(TARGET_IA64) + ioapic_set_irq(NULL, irq, level); +#else + ioapic_set_irq(ioapic, irq, level); +#endif for (;;) { bus = pci_dev->bus; irq_num = bus->map_irq(pci_dev, irq_num); -- 1.5.5
Attachment:
0002-Irq-assignment.patch
Description: 0002-Irq-assignment.patch