qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] Fix timer interrupt routing for non-ACPI guest
@ 2009-04-11  3:08 Ed Swierk
  2009-04-12 13:51 ` [Qemu-devel] " Sebastian Herbszt
  2009-04-13 16:21 ` [Qemu-devel] " Beth Kon
  0 siblings, 2 replies; 5+ messages in thread
From: Ed Swierk @ 2009-04-11  3:08 UTC (permalink / raw)
  To: bochs-developers, qemu-devel

Qemu 0.10.2 is unable to boot a non-ACPI kernel due to a BIOS bug:

ENABLING IO-APIC IRQs 
..TIMER: vector=0x31 apic1=0 pin1=0 apic2=-1 pin2=-1 
..MP-BIOS bug: 8254 timer not connected to IO-APIC 
...trying to set up timer (IRQ0) through the 8259A ... 
..... (found apic 0 pin 0) ... 
....... failed. 
...trying to set up timer as Virtual Wire IRQ... 

The interrupt routing table in the MPTABLE needs to route the timer
interrupt (IRQ 0) to IOAPIC pin 2.

A similar bug was recently fixed in the ACPI table code.  This patch
fixes the problem for non-ACPI guests.

Signed-off-by: Ed Swierk <eswierk@aristanetworks.com>

---
diff --git a/bios/rombios32.c b/bios/rombios32.c
index 7be4216..13d5435 100644
--- a/bios/rombios32.c
+++ b/bios/rombios32.c
@@ -1173,7 +1173,7 @@ static void mptable_init(void)
         putb(&q, 0); /* flags: po=0, el=0 */
         putb(&q, 0);
         putb(&q, 0); /* source bus ID = ISA */
-        putb(&q, i); /* source bus IRQ */
+        putb(&q, i == 2 ? 0 : i); /* source bus IRQ */
         putb(&q, ioapic_id); /* dest I/O APIC ID */
         putb(&q, i); /* dest I/O APIC interrupt in */
     }

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [Qemu-devel] Re: [PATCH] Fix timer interrupt routing for non-ACPI guest
  2009-04-11  3:08 [Qemu-devel] [PATCH] Fix timer interrupt routing for non-ACPI guest Ed Swierk
@ 2009-04-12 13:51 ` Sebastian Herbszt
  2009-04-12 21:46   ` Ed Swierk
  2009-04-13 16:21 ` [Qemu-devel] " Beth Kon
  1 sibling, 1 reply; 5+ messages in thread
From: Sebastian Herbszt @ 2009-04-12 13:51 UTC (permalink / raw)
  To: Ed Swierk, bochs-developers, qemu-devel

Ed Swierk wrote:
> Qemu 0.10.2 is unable to boot a non-ACPI kernel due to a BIOS bug:
> 
> ENABLING IO-APIC IRQs 
> ..TIMER: vector=0x31 apic1=0 pin1=0 apic2=-1 pin2=-1 
> ..MP-BIOS bug: 8254 timer not connected to IO-APIC 
> ...trying to set up timer (IRQ0) through the 8259A ... 
> ..... (found apic 0 pin 0) ... 
> ....... failed. 
> ...trying to set up timer as Virtual Wire IRQ... 

I tried Linux 2.6.27.7 and it seems to hang after
"...trying to set up timer as Virtual Wire IRQ...".

On 2.6.25.5 it managed to use Virtual Wire mode:

..TIMER: vector=0x31 apic1=0 pin1=0 apic2=-1 pin2=-1
..MP-BIOS bug: 8254 timer not connected to IO-APIC
...trying to set up timer (IRQ0) through the 8259A ...  failed.
...trying to set up timer as Virtual Wire IRQ... works.
testing the IO APIC.......................
.................................... done.

> The interrupt routing table in the MPTABLE needs to route the timer
> interrupt (IRQ 0) to IOAPIC pin 2.

Do you refer here to "5.3 Assigning of I/O Interrupts to the APIC I/O Unit"
from MultiProcessor Specification 1.4 or some other documentation?

> A similar bug was recently fixed in the ACPI table code. 

Can you point me to the patch?

> This patch fixes the problem for non-ACPI guests.

Linux displays the following without any patch:

Int: type 0, pol 0, trig 0, bus 00, IRQ 00, APIC ID 1, APIC INT 00
Int: type 0, pol 0, trig 0, bus 00, IRQ 01, APIC ID 1, APIC INT 01
Int: type 0, pol 0, trig 0, bus 00, IRQ 02, APIC ID 1, APIC INT 02
Int: type 0, pol 0, trig 0, bus 00, IRQ 03, APIC ID 1, APIC INT 03
...
..TIMER: vector=0x31 apic1=0 pin1=0 apic2=-1 pin2=-1

[older Linux output]
IRQ to pin mappings:
IRQ0 -> 0:0
IRQ1 -> 0:1
IRQ2 -> 0:2
IRQ3 -> 0:3

With your patch it's:

Int: type 0, pol 0, trig 0, bus 00, IRQ 00, APIC ID 1, APIC INT 00
Int: type 0, pol 0, trig 0, bus 00, IRQ 01, APIC ID 1, APIC INT 01
Int: type 0, pol 0, trig 0, bus 00, IRQ 00, APIC ID 1, APIC INT 02
Int: type 0, pol 0, trig 0, bus 00, IRQ 03, APIC ID 1, APIC INT 03
...
..TIMER: vector=0x31 apic1=0 pin1=0 apic2=-1 pin2=-1

[older Linux output]
IRQ to pin mappings:
IRQ0 -> 0:0-> 0:2
IRQ1 -> 0:1
IRQ3 -> 0:3

Is this mapping correct or should it rather be the following?

..TIMER: vector=0x31 apic1=0 pin1=2 apic2=-1 pin2=-1

IRQ0 -> 0:2
IRQ1 -> 0:1
IRQ3 -> 0:3

- Sebastian

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Qemu-devel] Re: [PATCH] Fix timer interrupt routing for non-ACPI guest
  2009-04-12 13:51 ` [Qemu-devel] " Sebastian Herbszt
@ 2009-04-12 21:46   ` Ed Swierk
  2009-04-13 15:49     ` Sebastian Herbszt
  0 siblings, 1 reply; 5+ messages in thread
From: Ed Swierk @ 2009-04-12 21:46 UTC (permalink / raw)
  To: Sebastian Herbszt; +Cc: bochs-developers, qemu-devel

On Sun, Apr 12, 2009 at 6:51 AM, Sebastian Herbszt <herbszt@gmx.de> wrote:
> Ed Swierk wrote:
>>
>> Qemu 0.10.2 is unable to boot a non-ACPI kernel due to a BIOS bug:
>>
>> ENABLING IO-APIC IRQs ..TIMER: vector=0x31 apic1=0 pin1=0 apic2=-1 pin2=-1
>> ..MP-BIOS bug: 8254 timer not connected to IO-APIC ...trying to set up timer
>> (IRQ0) through the 8259A ... ..... (found apic 0 pin 0) ... ....... failed.
>> ...trying to set up timer as Virtual Wire IRQ...
>
> I tried Linux 2.6.27.7 and it seems to hang after
> "...trying to set up timer as Virtual Wire IRQ...".
>
> On 2.6.25.5 it managed to use Virtual Wire mode:
>
> ..TIMER: vector=0x31 apic1=0 pin1=0 apic2=-1 pin2=-1
> ..MP-BIOS bug: 8254 timer not connected to IO-APIC
> ...trying to set up timer (IRQ0) through the 8259A ...  failed.
> ...trying to set up timer as Virtual Wire IRQ... works.
> testing the IO APIC.......................
> .................................... done.

Hmm, I guess the kernel got more picky since 2.6.25.

>> The interrupt routing table in the MPTABLE needs to route the timer
>> interrupt (IRQ 0) to IOAPIC pin 2.
>
> Do you refer here to "5.3 Assigning of I/O Interrupts to the APIC I/O Unit"
> from MultiProcessor Specification 1.4 or some other documentation?

I confess I haven't checked actual documentation; instead I've
referred to code from Coreboot that seems to work. For example the
bus_isa interrupts at
http://tracker.coreboot.org/trac/coreboot/browser/trunk/coreboot-v2/src/mainboard/msi/ms9185/mptable.c
.

>> A similar bug was recently fixed in the ACPI table code.
>
> Can you point me to the patch?

See the change to acpi_bios_init() in
http://git.kernel.org/?p=virt/bochs/bochs.git;a=commitdiff;h=b494def0e417778ed814692ce1db06cca3a757cf
.

>> This patch fixes the problem for non-ACPI guests.
>
> Linux displays the following without any patch:
>
> Int: type 0, pol 0, trig 0, bus 00, IRQ 00, APIC ID 1, APIC INT 00
> Int: type 0, pol 0, trig 0, bus 00, IRQ 01, APIC ID 1, APIC INT 01
> Int: type 0, pol 0, trig 0, bus 00, IRQ 02, APIC ID 1, APIC INT 02
> Int: type 0, pol 0, trig 0, bus 00, IRQ 03, APIC ID 1, APIC INT 03
> ...
> ..TIMER: vector=0x31 apic1=0 pin1=0 apic2=-1 pin2=-1
>
> [older Linux output]
> IRQ to pin mappings:
> IRQ0 -> 0:0
> IRQ1 -> 0:1
> IRQ2 -> 0:2
> IRQ3 -> 0:3
>
> With your patch it's:
>
> Int: type 0, pol 0, trig 0, bus 00, IRQ 00, APIC ID 1, APIC INT 00
> Int: type 0, pol 0, trig 0, bus 00, IRQ 01, APIC ID 1, APIC INT 01
> Int: type 0, pol 0, trig 0, bus 00, IRQ 00, APIC ID 1, APIC INT 02
> Int: type 0, pol 0, trig 0, bus 00, IRQ 03, APIC ID 1, APIC INT 03
> ...
> ..TIMER: vector=0x31 apic1=0 pin1=0 apic2=-1 pin2=-1
>
> [older Linux output]
> IRQ to pin mappings:
> IRQ0 -> 0:0-> 0:2
> IRQ1 -> 0:1
> IRQ3 -> 0:3
>
> Is this mapping correct or should it rather be the following?
>
> ..TIMER: vector=0x31 apic1=0 pin1=2 apic2=-1 pin2=-1
>
> IRQ0 -> 0:2
> IRQ1 -> 0:1
> IRQ3 -> 0:3

I suspect the latter is correct but I don't know that it really makes
a difference, at least to Linux.

--Ed

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Qemu-devel] Re: [PATCH] Fix timer interrupt routing for non-ACPI guest
  2009-04-12 21:46   ` Ed Swierk
@ 2009-04-13 15:49     ` Sebastian Herbszt
  0 siblings, 0 replies; 5+ messages in thread
From: Sebastian Herbszt @ 2009-04-13 15:49 UTC (permalink / raw)
  To: Ed Swierk; +Cc: bochs-developers, qemu-devel

Ed Swierk wrote:
>>> The interrupt routing table in the MPTABLE needs to route the timer
>>> interrupt (IRQ 0) to IOAPIC pin 2.
>>
>> Do you refer here to "5.3 Assigning of I/O Interrupts to the APIC I/O Unit"
>> from MultiProcessor Specification 1.4 or some other documentation?
>
> I confess I haven't checked actual documentation; instead I've
> referred to code from Coreboot that seems to work. For example the
> bus_isa interrupts at
> http://tracker.coreboot.org/trac/coreboot/browser/trunk/coreboot-v2/src/mainboard/msi/ms9185/mptable.c
> .

Looks like this sets:

ExtINT IRQ0 -> 0:0
INT IRQ1 -> 0:1
INT IRQ0 -> 0:2
INT IRQ3 -> 0:3

This seems to also be what VMware provides:

Int: type 3, pol 1, trig 1, bus 02, IRQ 00, APIC ID 1, APIC INT 00
Int: type 0, pol 1, trig 1, bus 02, IRQ 01, APIC ID 1, APIC INT 01
Int: type 0, pol 1, trig 1, bus 02, IRQ 00, APIC ID 1, APIC INT 02
Int: type 0, pol 1, trig 1, bus 02, IRQ 03, APIC ID 1, APIC INT 03
..TIMER: vector=0x31 apic1=0 pin1=2 apic2=0 pin2=0
 
>> ..TIMER: vector=0x31 apic1=0 pin1=2 apic2=-1 pin2=-1
>>
>> IRQ0 -> 0:2
>> IRQ1 -> 0:1
>> IRQ3 -> 0:3
>
> I suspect the latter is correct but I don't know that it really makes
> a difference, at least to Linux.

We can achieve this

Int: type 3, pol 0, trig 0, bus 00, IRQ 00, APIC ID 1, APIC INT 00
Int: type 0, pol 0, trig 0, bus 00, IRQ 00, APIC ID 1, APIC INT 02
Int: type 0, pol 0, trig 0, bus 00, IRQ 01, APIC ID 1, APIC INT 01
Int: type 0, pol 0, trig 0, bus 00, IRQ 03, APIC ID 1, APIC INT 03
..TIMER: vector=0x31 apic1=0 pin1=2 apic2=0 pin2=0

with the following patch.

- Sebastian

Index: bochs-cvs/bios/rombios32.c
===================================================================
--- bochs-cvs.orig/bios/rombios32.c
+++ bochs-cvs/bios/rombios32.c
@@ -1142,16 +1142,27 @@ static void mptable_init(void)
     putb(&q, 1); /* enable */
     putle32(&q, 0xfec00000); /* I/O APIC addr */

+    putb(&q, 3); /* entry type = I/O interrupt */
+    putb(&q, 3); /* interrupt type = ExtINT */
+    putb(&q, 0); /* flags: po=0, el=0 */
+    putb(&q, 0);
+    putb(&q, 0); /* source bus ID = ISA */
+    putb(&q, 0); /* source bus IRQ */
+    putb(&q, ioapic_id); /* dest I/O APIC ID */
+    putb(&q, 0); /* dest I/O APIC interrupt in */
+
     /* irqs */
     for(i = 0; i < 16; i++) {
+        if (i == 2)
+            continue;
         putb(&q, 3); /* entry type = I/O interrupt */
         putb(&q, 0); /* interrupt type = vectored interrupt */
         putb(&q, 0); /* flags: po=0, el=0 */
         putb(&q, 0);
         putb(&q, 0); /* source bus ID = ISA */
-        putb(&q, (i == 2) ? 0 : i); /* source bus IRQ */
+        putb(&q, i); /* source bus IRQ */
         putb(&q, ioapic_id); /* dest I/O APIC ID */
-        putb(&q, i); /* dest I/O APIC interrupt in */
+        putb(&q, (i == 0) ? 2 : i); /* dest I/O APIC interrupt in */
     }
     /* patch length */
     len = q - mp_config_table;

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH] Fix timer interrupt routing for non-ACPI guest
  2009-04-11  3:08 [Qemu-devel] [PATCH] Fix timer interrupt routing for non-ACPI guest Ed Swierk
  2009-04-12 13:51 ` [Qemu-devel] " Sebastian Herbszt
@ 2009-04-13 16:21 ` Beth Kon
  1 sibling, 0 replies; 5+ messages in thread
From: Beth Kon @ 2009-04-13 16:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: bochs-developers

Ed Swierk wrote:
> Qemu 0.10.2 is unable to boot a non-ACPI kernel due to a BIOS bug:
>
> ENABLING IO-APIC IRQs 
> ..TIMER: vector=0x31 apic1=0 pin1=0 apic2=-1 pin2=-1 
> ..MP-BIOS bug: 8254 timer not connected to IO-APIC 
> ...trying to set up timer (IRQ0) through the 8259A ... 
> ..... (found apic 0 pin 0) ... 
> ....... failed. 
> ...trying to set up timer as Virtual Wire IRQ... 
>
> The interrupt routing table in the MPTABLE needs to route the timer
> interrupt (IRQ 0) to IOAPIC pin 2.
>
> A similar bug was recently fixed in the ACPI table code.  This patch
> fixes the problem for non-ACPI guests.
>
> Signed-off-by: Ed Swierk <eswierk@aristanetworks.com>
>
> ---
> diff --git a/bios/rombios32.c b/bios/rombios32.c
> index 7be4216..13d5435 100644
> --- a/bios/rombios32.c
> +++ b/bios/rombios32.c
> @@ -1173,7 +1173,7 @@ static void mptable_init(void)
>          putb(&q, 0); /* flags: po=0, el=0 */
>          putb(&q, 0);
>          putb(&q, 0); /* source bus ID = ISA */
> -        putb(&q, i); /* source bus IRQ */
> +        putb(&q, i == 2 ? 0 : i); /* source bus IRQ */
>          putb(&q, ioapic_id); /* dest I/O APIC ID */
>          putb(&q, i); /* dest I/O APIC interrupt in */
>      }
>
>
>
>   
This was an oversight on my part when I submitted the HPET patches for 
qemu. I properly modified the ACPI configuration, but missed the 
non-ACPI case.

This patch is not quite correct and I will submit the necessary patch 
shortly.

A bit of the history...

This issue surfaced when I implemented the HPET and discovered that 
Win2k8 would only work if the HPET interrupt was routed to IOAPIC inti2. 
This is a common configuration (overriding irq0->inti2). The HPET spec 
states that "Timer 0 will be routed to IRQ0 in the Non-APIC or IRQ2 in 
the I/O APIC", and Windows appears to expect it regardless of how 
overrides are reported by the BIOS. So the decision was made to always 
have the override.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2009-04-13 16:21 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-04-11  3:08 [Qemu-devel] [PATCH] Fix timer interrupt routing for non-ACPI guest Ed Swierk
2009-04-12 13:51 ` [Qemu-devel] " Sebastian Herbszt
2009-04-12 21:46   ` Ed Swierk
2009-04-13 15:49     ` Sebastian Herbszt
2009-04-13 16:21 ` [Qemu-devel] " Beth Kon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).