[PATCH] irq assignment

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>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


[Index of Archives]     [Linux KVM Devel]     [Linux Virtualization]     [Big List of Linux Books]     [Linux SCSI]     [Yosemite Forum]

  Powered by Linux