Re: [RFC]RE: [PATCH] kvm-ia64 irq assignment 1/2 kernel

Alexander Graf
2008-06-11T14:24:22Z

[-- Attachment #1: Type: text/plain, Size: 2148 bytes --]

On Jun 10, 2008, at 12:57 AM, Xu, Anthony wrote:

> Thanks for comments
>
> Basically we are on the same page, while I didn't find your patch
> about
> irq assignment, can you post it in this thread again, thx?

I'll attach it to this mail.

> Below patch makes all PCI devices use level-trigger , active low
> interrupt, it worked well when running linux guest, I didn't try
> windows
> guest yet.
> (didn't have windows image in hand)
>
> Please comment!
>
> If this is acceptabled, we can figure out how to use IOAPIC in kvm/
> ia32
> based on this. Which will reduce irq sharing dramatically.
>
>
> Thanks,
> Anthony
>
>
>
> diff --git a/bios/acpi-dsdt.dsl b/bios/acpi-dsdt.dsl
> index 21fc76a..4b5e824 100755
> --- a/bios/acpi-dsdt.dsl
> +++ b/bios/acpi-dsdt.dsl
> @@ -974,7 +974,7 @@ DefinitionBlock (
> Name(_HID, EISAID("PNP0C0F")) // PCI interrupt
> link
> Name(_UID, 1)
> Name(_PRS, ResourceTemplate(){
> - Interrupt (, Level, ActiveHigh, Shared)
> + Interrupt (, Level, ActiveLow, Shared)

This looks pretty much correct to me ;-). You might also want to add
the GSI functionality I have in my patch. The only thing we have not
discussed so far is, how do interrupts get routed when _PIC is not set
to 1, aka the "boot case"?

>
> { 5, 10, 11 }
> })
> Method (_STA, 0, NotSerialized)

[...snip...]

>
> diff --git a/qemu/hw/pci.c b/qemu/hw/pci.c
> index a23a466..df0ea33 100644
> --- a/qemu/hw/pci.c
> +++ b/qemu/hw/pci.c
> @@ -548,7 +548,7 @@ static void pci_set_irq(void *opaque, int irq_num,
> int level)
> pci_dev = bus->parent_dev;
> }
> bus->irq_count[irq_num] += change;
> - bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] !=
> 0);
> + bus->set_irq(bus->irq_opaque, irq_num, !(bus-
> >irq_count[irq_num] !=
> 0));
> }

I don't think this is the right place to do it. Probably it would be a
better idea to have either the APIC emulation know that the levels are
reversed or make every device trigger ActiveLow interrupts.

Alex

[-- Attachment #2: apci.gsi.patch --]
[-- Type: application/octet-stream, Size: 10602 bytes --]

Hi,

in the DSDT there are two different ways of defining, how an interrupt
is supposed to be routed. Currently we are using the LNKA - LNKD method,
which afaict is for legacy support.
The other method is to directly tell the Operating System, which APIC
pin the device is attached to. We can get that information from the very
same entry, the LNKA to LNKD pseudo devices receive it.

For now this does not give any obvious improvement. It does leave room
for more advanced mappings, with several IOAPICs that can handle more
devices separately. This might help when we have a lot of devices, as
currently all devices sit on two interrupt lanes.

More importantly (for me) though, is that Darwin enables the APIC mode
unconditionally, so it won't easily run in legacy mode.

Regards,

Alex

Signed-off-by: Alexander Graf <agraf@suse.de>

diff --git a/bios/acpi-dsdt.dsl b/bios/acpi-dsdt.dsl
index d2e33f4..f718b2e 100755
--- a/bios/acpi-dsdt.dsl
+++ b/bios/acpi-dsdt.dsl
@@ -199,4 +199,10 @@ DefinitionBlock (
{
DBGL, 32,
}
+ /* PIC mode setting */
+ Name (PICF, 0x00)
+ Method (_PIC, 1, NotSerialized)
+ {
+ Store(Arg0, PICF)
+ }
}
@@ -199,10 +199,204 @@ DefinitionBlock (
Device(PCI0) {
Name (_HID, EisaId ("PNP0A03"))
Name (_ADR, 0x00)
Name (_UID, 1)
- Name(_PRT, Package() {
+ Name(APRT, Package() {
+ // PCI Slot 0
+ Package() {0x0000ffff, 0, 0, ARQ3},
+ Package() {0x0000ffff, 1, 0, ARQ0},
+ Package() {0x0000ffff, 2, 0, ARQ1},
+ Package() {0x0000ffff, 3, 0, ARQ2},
+
+ // PCI Slot 1
+ Package() {0x0001ffff, 0, 0, ARQ0},
+ Package() {0x0001ffff, 1, 0, ARQ1},
+ Package() {0x0001ffff, 2, 0, ARQ2},
+ Package() {0x0001ffff, 3, 0, ARQ3},
+
+ // PCI Slot 2
+ Package() {0x0002ffff, 0, 0, ARQ1},
+ Package() {0x0002ffff, 1, 0, ARQ2},
+ Package() {0x0002ffff, 2, 0, ARQ3},
+ Package() {0x0002ffff, 3, 0, ARQ0},
+
+ // PCI Slot 3
+ Package() {0x0003ffff, 0, 0, ARQ2},
+ Package() {0x0003ffff, 1, 0, ARQ3},
+ Package() {0x0003ffff, 2, 0, ARQ0},
+ Package() {0x0003ffff, 3, 0, ARQ1},
+
+ // PCI Slot 4
+ Package() {0x0004ffff, 0, 0, ARQ3},
+ Package() {0x0004ffff, 1, 0, ARQ0},
+ Package() {0x0004ffff, 2, 0, ARQ1},
+ Package() {0x0004ffff, 3, 0, ARQ2},
+
+ // PCI Slot 5
+ Package() {0x0005ffff, 0, 0, ARQ0},
+ Package() {0x0005ffff, 1, 0, ARQ1},
+ Package() {0x0005ffff, 2, 0, ARQ2},
+ Package() {0x0005ffff, 3, 0, ARQ3},
+
+ // PCI Slot 6
+ Package() {0x0006ffff, 0, 0, ARQ1},
+ Package() {0x0006ffff, 1, 0, ARQ2},
+ Package() {0x0006ffff, 2, 0, ARQ3},
+ Package() {0x0006ffff, 3, 0, ARQ0},
+
+ // PCI Slot 7
+ Package() {0x0007ffff, 0, 0, ARQ2},
+ Package() {0x0007ffff, 1, 0, ARQ3},
+ Package() {0x0007ffff, 2, 0, ARQ0},
+ Package() {0x0007ffff, 3, 0, ARQ1},
+
+ // PCI Slot 8
+ Package() {0x0008ffff, 0, 0, ARQ3},
+ Package() {0x0008ffff, 1, 0, ARQ0},
+ Package() {0x0008ffff, 2, 0, ARQ1},
+ Package() {0x0008ffff, 3, 0, ARQ2},
+
+ // PCI Slot 9
+ Package() {0x0009ffff, 0, 0, ARQ0},
+ Package() {0x0009ffff, 1, 0, ARQ1},
+ Package() {0x0009ffff, 2, 0, ARQ2},
+ Package() {0x0009ffff, 3, 0, ARQ3},
+
+ // PCI Slot 10
+ Package() {0x000affff, 0, 0, ARQ1},
+ Package() {0x000affff, 1, 0, ARQ2},
+ Package() {0x000affff, 2, 0, ARQ3},
+ Package() {0x000affff, 3, 0, ARQ0},
+
+ // PCI Slot 11
+ Package() {0x000bffff, 0, 0, ARQ2},
+ Package() {0x000bffff, 1, 0, ARQ3},
+ Package() {0x000bffff, 2, 0, ARQ0},
+ Package() {0x000bffff, 3, 0, ARQ1},
+
+ // PCI Slot 12
+ Package() {0x000cffff, 0, 0, ARQ3},
+ Package() {0x000cffff, 1, 0, ARQ0},
+ Package() {0x000cffff, 2, 0, ARQ1},
+ Package() {0x000cffff, 3, 0, ARQ2},
+
+ // PCI Slot 13
+ Package() {0x000dffff, 0, 0, ARQ0},
+ Package() {0x000dffff, 1, 0, ARQ1},
+ Package() {0x000dffff, 2, 0, ARQ2},
+ Package() {0x000dffff, 3, 0, ARQ3},
+
+ // PCI Slot 14
+ Package() {0x000effff, 0, 0, ARQ1},
+ Package() {0x000effff, 1, 0, ARQ2},
+ Package() {0x000effff, 2, 0, ARQ3},
+ Package() {0x000effff, 3, 0, ARQ0},
+
+ // PCI Slot 15
+ Package() {0x000fffff, 0, 0, ARQ2},
+ Package() {0x000fffff, 1, 0, ARQ3},
+ Package() {0x000fffff, 2, 0, ARQ0},
+ Package() {0x000fffff, 3, 0, ARQ1},
+
+ // PCI Slot 16
+ Package() {0x0010ffff, 0, 0, ARQ3},
+ Package() {0x0010ffff, 1, 0, ARQ0},
+ Package() {0x0010ffff, 2, 0, ARQ1},
+ Package() {0x0010ffff, 3, 0, ARQ2},
+
+ // PCI Slot 17
+ Package() {0x0011ffff, 0, 0, ARQ0},
+ Package() {0x0011ffff, 1, 0, ARQ1},
+ Package() {0x0011ffff, 2, 0, ARQ2},
+ Package() {0x0011ffff, 3, 0, ARQ3},
+
+ // PCI Slot 18
+ Package() {0x0012ffff, 0, 0, ARQ1},
+ Package() {0x0012ffff, 1, 0, ARQ2},
+ Package() {0x0012ffff, 2, 0, ARQ3},
+ Package() {0x0012ffff, 3, 0, ARQ0},
+
+ // PCI Slot 19
+ Package() {0x0013ffff, 0, 0, ARQ2},
+ Package() {0x0013ffff, 1, 0, ARQ3},
+ Package() {0x0013ffff, 2, 0, ARQ0},
+ Package() {0x0013ffff, 3, 0, ARQ1},
+
+ // PCI Slot 20
+ Package() {0x0014ffff, 0, 0, ARQ3},
+ Package() {0x0014ffff, 1, 0, ARQ0},
+ Package() {0x0014ffff, 2, 0, ARQ1},
+ Package() {0x0014ffff, 3, 0, ARQ2},
+
+ // PCI Slot 21
+ Package() {0x0015ffff, 0, 0, ARQ0},
+ Package() {0x0015ffff, 1, 0, ARQ1},
+ Package() {0x0015ffff, 2, 0, ARQ2},
+ Package() {0x0015ffff, 3, 0, ARQ3},
+
+ // PCI Slot 22
+ Package() {0x0016ffff, 0, 0, ARQ1},
+ Package() {0x0016ffff, 1, 0, ARQ2},
+ Package() {0x0016ffff, 2, 0, ARQ3},
+ Package() {0x0016ffff, 3, 0, ARQ0},
+
+ // PCI Slot 23
+ Package() {0x0017ffff, 0, 0, ARQ2},
+ Package() {0x0017ffff, 1, 0, ARQ3},
+ Package() {0x0017ffff, 2, 0, ARQ0},
+ Package() {0x0017ffff, 3, 0, ARQ1},
+
+ // PCI Slot 24
+ Package() {0x0018ffff, 0, 0, ARQ3},
+ Package() {0x0018ffff, 1, 0, ARQ0},
+ Package() {0x0018ffff, 2, 0, ARQ1},
+ Package() {0x0018ffff, 3, 0, ARQ2},
+
+ // PCI Slot 25
+ Package() {0x0019ffff, 0, 0, ARQ0},
+ Package() {0x0019ffff, 1, 0, ARQ1},
+ Package() {0x0019ffff, 2, 0, ARQ2},
+ Package() {0x0019ffff, 3, 0, ARQ3},
+
+ // PCI Slot 26
+ Package() {0x001affff, 0, 0, ARQ1},
+ Package() {0x001affff, 1, 0, ARQ2},
+ Package() {0x001affff, 2, 0, ARQ3},
+ Package() {0x001affff, 3, 0, ARQ0},
+
+ // PCI Slot 27
+ Package() {0x001bffff, 0, 0, ARQ2},
+ Package() {0x001bffff, 1, 0, ARQ3},
+ Package() {0x001bffff, 2, 0, ARQ0},
+ Package() {0x001bffff, 3, 0, ARQ1},
+
+ // PCI Slot 28
+ Package() {0x001cffff, 0, 0, ARQ3},
+ Package() {0x001cffff, 1, 0, ARQ0},
+ Package() {0x001cffff, 2, 0, ARQ1},
+ Package() {0x001cffff, 3, 0, ARQ2},
+
+ // PCI Slot 29
+ Package() {0x001dffff, 0, 0, ARQ0},
+ Package() {0x001dffff, 1, 0, ARQ1},
+ Package() {0x001dffff, 2, 0, ARQ2},
+ Package() {0x001dffff, 3, 0, ARQ3},
+
+ // PCI Slot 30
+ Package() {0x001effff, 0, 0, ARQ1},
+ Package() {0x001effff, 1, 0, ARQ2},
+ Package() {0x001effff, 2, 0, ARQ3},
+ Package() {0x001effff, 3, 0, ARQ0},
+
+ // PCI Slot 31
+ Package() {0x001fffff, 0, 0, ARQ2},
+ Package() {0x001fffff, 1, 0, ARQ3},
+ Package() {0x001fffff, 2, 0, ARQ0},
+ Package() {0x001fffff, 3, 0, ARQ1},
+ })
+
+ Name(LPRT, 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
table of the Bochs BIOS */

@@ -407,6 +681,18 @@ DefinitionBlock (
Package() {0x001fffff, 3, LNKB, 0},
})

+ Method (_PRT, 0, NotSerialized)
+ {
+ If (\PICF)
+ {
+ Return (APRT)
+ }
+ Else
+ {
+ Return (LPRT)
+ }
+ }
+
OperationRegion(PCST, SystemIO, 0xae00, 0x08)
Field (PCST, DWordAcc, NoLock, WriteAsZeros)
{
@@ -939,5 +1258,25 @@ DefinitionBlock (
PRQ3, 8
}

+ Method (ARQ0, 0, NotSerialized)
+ {
+ Return ( And ( PRQ0, 0x7f ) )
+ }
+
+ Method (ARQ1, 0, NotSerialized)
+ {
+ Return ( And ( PRQ1, 0x7f ) )
+ }
+
+ Method (ARQ2, 0, NotSerialized)
+ {
+ Return ( And ( PRQ2, 0x7f ) )
+ }
+
+ Method (ARQ3, 0, NotSerialized)
+ {
+ Return ( And ( PRQ3, 0x7f ) )
+ }
+
Device(LNKA){
Name(_HID, EISAID("PNP0C0F")) // PCI interrupt link

[-- Attachment #3: Type: text/plain, Size: 2 bytes --]