[RFC] kvm irq assignment

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

 



Hi all,
Thanks for your comments.

I made this new patch based on your comments

1. use bimodal _PRT, to take advantage of IOAPIC pin 16~23
	the mapping is simple,  slot  ->  (slot&7)+16 IOAPIC pin,
someone may provide good mapping ?
2. use ISA-bridge configure space 0x64 byte as a communication
mechansim.
	When guest BIOS invokes _PIC, the value is passed to qemu
through byte 0x64.
             qemu know whether it is PIC mode and APIC mode by checking
byte 0x64.
3. pci_slot_get_pirq and piix3_set_irq adopt different operation based
on PIC mode/APIC mode
4. All pci devices are still using active high level-triggered
interrupt, while IOAPIC pin 16~23 use active low level-triggered
interrupt.
   piix3_set_irq is responsible to reserve the level if it is in APIC
mode.
5. interrupt sharing for PCI devices is still supported


Test by runing guest linux, NIC is using IOAPIC pin > 15
  0:     980211    IO-APIC-edge  timer
  1:        179    IO-APIC-edge  i8042
  8:          0    IO-APIC-edge  rtc
  9:          0   IO-APIC-level  acpi
 12:        289    IO-APIC-edge  i8042
 14:       3266    IO-APIC-edge  ide0
 15:      13489    IO-APIC-edge  ide1
185:        485   IO-APIC-level  eth0

Didn't try guest linux only with PIC, I think it works, because the path
for PIC is not changed at all.


Please comment!

Thanks,
Anthony






diff --git a/bios/acpi-dsdt.dsl b/bios/acpi-dsdt.dsl
index 21fc76a..64219f2 100755
--- a/bios/acpi-dsdt.dsl
+++ b/bios/acpi-dsdt.dsl
@@ -201,14 +201,24 @@ DefinitionBlock (
         }
     }
 
+    Name (PICD, 0)
 
-    /* PCI Bus definition */
+
+    /*PCI Bus definition */
     Scope(\_SB) {
         Device(PCI0) {
             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
@@ -407,6 +417,202 @@ DefinitionBlock (
                 Package() {0x001fffff, 3, LNKB, 0},
             })
 
+            Name(PRTA, Package() {
+                /* IOAPIC use fixed connection */
+
+                // PCI Slot 0
+                Package() {0x0000ffff, 0, 0, 16},
+                Package() {0x0000ffff, 1, 0, 16},
+                Package() {0x0000ffff, 2, 0, 16},
+                Package() {0x0000ffff, 3, 0, 16},
+
+                // PCI Slot 1
+                Package() {0x0001ffff, 0, 0, 17},
+                Package() {0x0001ffff, 1, 0, 17},
+                Package() {0x0001ffff, 2, 0, 17},
+                Package() {0x0001ffff, 3, 0, 17},
+
+                // PCI Slot 2
+                Package() {0x0002ffff, 0, 0, 18},
+                Package() {0x0002ffff, 1, 0, 18},
+                Package() {0x0002ffff, 2, 0, 18},
+                Package() {0x0002ffff, 3, 0, 18},
+
+                // PCI Slot 3
+                Package() {0x0003ffff, 0, 0, 19},
+                Package() {0x0003ffff, 1, 0, 19},
+                Package() {0x0003ffff, 2, 0, 19},
+                Package() {0x0003ffff, 3, 0, 19},
+
+                // PCI Slot 4
+                Package() {0x0004ffff, 0, 0, 20},
+                Package() {0x0004ffff, 1, 0, 20},
+                Package() {0x0004ffff, 2, 0, 20},
+                Package() {0x0004ffff, 3, 0, 20},
+
+                // PCI Slot 5
+                Package() {0x0005ffff, 0, 0, 21},
+                Package() {0x0005ffff, 1, 0, 21},
+                Package() {0x0005ffff, 2, 0, 21},
+                Package() {0x0005ffff, 3, 0, 21},
+
+                // PCI Slot 6
+                Package() {0x0006ffff, 0, 0, 22},
+                Package() {0x0006ffff, 1, 0, 22},
+                Package() {0x0006ffff, 2, 0, 22},
+                Package() {0x0006ffff, 3, 0, 22},
+
+                // PCI Slot 7
+                Package() {0x0007ffff, 0, 0, 23},
+                Package() {0x0007ffff, 1, 0, 23},
+                Package() {0x0007ffff, 2, 0, 23},
+                Package() {0x0007ffff, 3, 0, 23},
+
+                // PCI Slot 8
+                Package() {0x0008ffff, 0, 0, 16},
+                Package() {0x0008ffff, 1, 0, 16},
+                Package() {0x0008ffff, 2, 0, 16},
+                Package() {0x0008ffff, 3, 0, 16},
+
+                // PCI Slot 9
+                Package() {0x0009ffff, 0, 0, 17},
+                Package() {0x0009ffff, 1, 0, 17},
+                Package() {0x0009ffff, 2, 0, 17},
+                Package() {0x0009ffff, 3, 0, 17},
+
+                // PCI Slot 10
+                Package() {0x000affff, 0, 0, 18},
+                Package() {0x000affff, 1, 0, 18},
+                Package() {0x000affff, 2, 0, 18},
+                Package() {0x000affff, 3, 0, 18},
+
+                // PCI Slot 11
+                Package() {0x000bffff, 0, 0, 19},
+                Package() {0x000bffff, 1, 0, 19},
+                Package() {0x000bffff, 2, 0, 19},
+                Package() {0x000bffff, 3, 0, 19},
+
+                // PCI Slot 12
+                Package() {0x000cffff, 0, 0, 20},
+                Package() {0x000cffff, 1, 0, 20},
+                Package() {0x000cffff, 2, 0, 20},
+                Package() {0x000cffff, 3, 0, 20},
+
+                // PCI Slot 13
+                Package() {0x000dffff, 0, 0, 21},
+                Package() {0x000dffff, 1, 0, 21},
+                Package() {0x000dffff, 2, 0, 21},
+                Package() {0x000dffff, 3, 0, 21},
+
+                // PCI Slot 14
+                Package() {0x000effff, 0, 0, 22},
+                Package() {0x000effff, 1, 0, 22},
+                Package() {0x000effff, 2, 0, 22},
+                Package() {0x000effff, 3, 0, 22},
+
+                // PCI Slot 15
+                Package() {0x000fffff, 0, 0, 23},
+                Package() {0x000fffff, 1, 0, 23},
+                Package() {0x000fffff, 2, 0, 23},
+                Package() {0x000fffff, 3, 0, 23},
+
+                // PCI Slot 16
+                Package() {0x0010ffff, 0, 0, 16},
+                Package() {0x0010ffff, 1, 0, 16},
+                Package() {0x0010ffff, 2, 0, 16},
+                Package() {0x0010ffff, 3, 0, 16},
+
+                // PCI Slot 17
+                Package() {0x0011ffff, 0, 0, 17},
+                Package() {0x0011ffff, 1, 0, 17},
+                Package() {0x0011ffff, 2, 0, 17},
+                Package() {0x0011ffff, 3, 0, 17},
+
+                // PCI Slot 18
+                Package() {0x0012ffff, 0, 0, 18},
+                Package() {0x0012ffff, 1, 0, 18},
+                Package() {0x0012ffff, 2, 0, 18},
+                Package() {0x0012ffff, 3, 0, 18},
+
+                // PCI Slot 19
+                Package() {0x0013ffff, 0, 0, 19},
+                Package() {0x0013ffff, 1, 0, 19},
+                Package() {0x0013ffff, 2, 0, 19},
+                Package() {0x0013ffff, 3, 0, 19},
+
+                // PCI Slot 20
+                Package() {0x0014ffff, 0, 0, 20},
+                Package() {0x0014ffff, 1, 0, 20},
+                Package() {0x0014ffff, 2, 0, 20},
+                Package() {0x0014ffff, 3, 0, 20},
+
+                // PCI Slot 21
+                Package() {0x0015ffff, 0, 0, 21},
+                Package() {0x0015ffff, 1, 0, 21},
+                Package() {0x0015ffff, 2, 0, 21},
+                Package() {0x0015ffff, 3, 0, 21},
+
+                // PCI Slot 22
+                Package() {0x0016ffff, 0, 0, 22},
+                Package() {0x0016ffff, 1, 0, 22},
+                Package() {0x0016ffff, 2, 0, 22},
+                Package() {0x0016ffff, 3, 0, 22},
+
+                // PCI Slot 23
+                Package() {0x0017ffff, 0, 0, 23},
+                Package() {0x0017ffff, 1, 0, 23},
+                Package() {0x0017ffff, 2, 0, 23},
+                Package() {0x0017ffff, 3, 0, 23},
+
+                // PCI Slot 24
+                Package() {0x0018ffff, 0, 0, 16},
+                Package() {0x0018ffff, 1, 0, 16},
+                Package() {0x0018ffff, 2, 0, 16},
+                Package() {0x0018ffff, 3, 0, 16},
+
+                // PCI Slot 25
+                Package() {0x0019ffff, 0, 0, 17},
+                Package() {0x0019ffff, 1, 0, 17},
+                Package() {0x0019ffff, 2, 0, 17},
+                Package() {0x0019ffff, 3, 0, 17},
+
+                // PCI Slot 26
+                Package() {0x001affff, 0, 0, 18},
+                Package() {0x001affff, 1, 0, 18},
+                Package() {0x001affff, 2, 0, 18},
+                Package() {0x001affff, 3, 0, 18},
+
+                // PCI Slot 27
+                Package() {0x001bffff, 0, 0, 19},
+                Package() {0x001bffff, 1, 0, 19},
+                Package() {0x001bffff, 2, 0, 19},
+                Package() {0x001bffff, 3, 0, 19},
+
+                // PCI Slot 28
+                Package() {0x001cffff, 0, 0, 20},
+                Package() {0x001cffff, 1, 0, 20},
+                Package() {0x001cffff, 2, 0, 20},
+                Package() {0x001cffff, 3, 0, 20},
+
+                // PCI Slot 29
+                Package() {0x001dffff, 0, 0, 21},
+                Package() {0x001dffff, 1, 0, 21},
+                Package() {0x001dffff, 2, 0, 21},
+                Package() {0x001dffff, 3, 0, 21},
+
+                // PCI Slot 30
+                Package() {0x001effff, 0, 0, 22},
+                Package() {0x001effff, 1, 0, 22},
+                Package() {0x001effff, 2, 0, 22},
+                Package() {0x001effff, 3, 0, 22},
+
+                // PCI Slot 31
+                Package() {0x001fffff, 0, 0, 23},
+                Package() {0x001fffff, 1, 0, 23},
+                Package() {0x001fffff, 2, 0, 23},
+                Package() {0x001fffff, 3, 0, 23},
+            })
+
             OperationRegion(PCST, SystemIO, 0xae00, 0x08)
             Field (PCST, DWordAcc, NoLock, WriteAsZeros)
 	    {
@@ -770,6 +976,9 @@ DefinitionBlock (
             /* PIIX PCI to ISA irq remapping */
             OperationRegion (P40C, PCI_Config, 0x60, 0x04)
 
+            /* APIC and PIC flag */
+            OperationRegion (P40D, PCI_Config, 0x64, 0x01)
+
             /* Real-time clock */
             Device (RTC)
             {
@@ -960,6 +1169,19 @@ DefinitionBlock (
 	}
     }
 
+
+    Field (\_SB.PCI0.ISA.P40D, ByteAcc, NoLock, Preserve)
+    {
+       FLAG,  8,
+    }
+
+    Method(_PIC, 1)
+    {
+        Store(Arg0, PICD)
+        Store(Arg0, FLAG)
+    }
+
+
     /* PCI IRQs */
     Scope(\_SB) {
          Field (\_SB.PCI0.ISA.P40C, ByteAcc, NoLock, Preserve)
diff --git a/qemu/hw/piix_pci.c b/qemu/hw/piix_pci.c
index 90cb3a6..da6bcab 100644
--- a/qemu/hw/piix_pci.c
+++ b/qemu/hw/piix_pci.c
@@ -28,6 +28,7 @@
 
 typedef uint32_t pci_addr_t;
 #include "pci_host.h"
+#include "qemu-kvm.h"
 
 typedef PCIHostState I440FXState;
 
@@ -45,6 +46,25 @@ static uint32_t i440fx_addr_readl(void* opaque,
uint32_t addr)
 
 static void piix3_set_irq(qemu_irq *pic, int irq_num, int level);
 
+/* PIIX3 PCI to ISA bridge */
+
+PCIDevice *piix3_dev;
+PCIDevice *piix4_dev;
+
+
+#ifdef KVM_CAP_IRQCHIP
+static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
+{
+    int slot_addend;
+    if( piix3_dev->config[0x64])  // APIC mode
+        return ((pci_dev->devfn >> 3) & 7)+16;
+    else {		// PIC mode
+        slot_addend = (pci_dev->devfn >> 3) - 1;
+        return (irq_num + slot_addend) & 3;
+    }
+}
+
+#else
 /* return the global irq number corresponding to a given device irq
    pin. We could also use the bus number to have a more precise
    mapping. */
@@ -54,6 +74,7 @@ static int pci_slot_get_pirq(PCIDevice *pci_dev, int
irq_num)
     slot_addend = (pci_dev->devfn >> 3) - 1;
     return (irq_num + slot_addend) & 3;
 }
+#endif
 
 static target_phys_addr_t isa_page_descs[384 / 4];
 static uint8_t smm_enabled;
@@ -171,12 +192,17 @@ static int i440fx_load(QEMUFile* f, void *opaque,
int version_id)
 
 PCIBus *i440fx_init(PCIDevice **pi440fx_state, qemu_irq *pic)
 {
+    int irq_num;
     PCIBus *b;
     PCIDevice *d;
     I440FXState *s;
-
+#ifdef KVM_CAP_IRQCHIP
+    irq_num = 24;
+#else
+    irq_num = 4;
+#endif
     s = qemu_mallocz(sizeof(I440FXState));
-    b = pci_register_bus(piix3_set_irq, pci_slot_get_pirq, pic, 0, 4);
+    b = pci_register_bus(piix3_set_irq, pci_slot_get_pirq, pic, 0,
irq_num);
     s->bus = b;
 
     register_ioport_write(0xcf8, 4, 4, i440fx_addr_writel, s);
@@ -208,10 +234,6 @@ PCIBus *i440fx_init(PCIDevice **pi440fx_state,
qemu_irq *pic)
     return b;
 }
 
-/* PIIX3 PCI to ISA bridge */
-
-PCIDevice *piix3_dev;
-PCIDevice *piix4_dev;
 
 /* just used for simpler irq handling. */
 #define PCI_IRQ_WORDS   ((PCI_DEVICES_MAX + 31) / 32)
@@ -220,6 +242,12 @@ static void piix3_set_irq(qemu_irq *pic, int
irq_num, int level)
 {
     int i, pic_irq, pic_level;
 
+#ifdef KVM_CAP_IRQCHIP
+    if (piix3_dev->config[0x64]){  // APIC mode
+        kvm_set_irq(irq_num, !level);
+        return;
+    }
+#endif
     pci_irq_levels[irq_num] = level;
 
     /* now we change the pic irq level according to the piix irq
mappings */
--
To unsubscribe from this list: send the line "unsubscribe kvm-ia64" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

  Powered by Linux