[6/6] add interrupt override entries for IRQs 5, 9, 10, 11 to the MADT

Submitted by Gerd Hoffmann on Aug. 14, 2009, 12:21 p.m.

Details

Message ID 1250252518-29300-7-git-send-email-kraxel@redhat.com
State Superseded
Headers show

Commit Message

Gerd Hoffmann Aug. 14, 2009, 12:21 p.m.
so the OS knows that they're active high, level triggered. This allows
for proper ACPI event reporting such as the (emulated) power button and
should also fix the ACPI timer.

by Avi Kivity, adapted for upstream qemu by Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 rombios32.c |   20 +++++++++++++++++++-
 1 files changed, 19 insertions(+), 1 deletions(-)

Patch hide | download patch | download mbox

diff --git a/rombios32.c b/rombios32.c
index ece0865..624f39f 100644
--- a/rombios32.c
+++ b/rombios32.c
@@ -57,6 +57,9 @@  typedef unsigned long long uint64_t;
 #define APIC_ID      0x020
 #define APIC_LVT3    0x370
 
+/* IRQs 5,9,10,11 */
+#define PCI_ISA_IRQ_MASK    0x0e20U
+
 #define APIC_ENABLED 0x0100
 
 #define AP_BOOT_ADDR 0x9f000
@@ -1730,7 +1733,7 @@  void acpi_bios_init(void)
     madt_size = sizeof(*madt) +
         sizeof(struct madt_processor_apic) * max_cpus +
 #ifdef BX_QEMU
-        sizeof(struct madt_io_apic) + sizeof(struct madt_int_override);
+        sizeof(struct madt_io_apic) + sizeof(struct madt_int_override) * 5;
 #else
         sizeof(struct madt_io_apic);
 #endif
@@ -1828,6 +1831,21 @@  void acpi_bios_init(void)
         int_override->source = cpu_to_le32(0);
         int_override->gsi = cpu_to_le32(2);
         int_override->flags = cpu_to_le32(0);
+        int_override++;
+
+        for ( i = 0; i < 16; i++ ) {
+            if (!(PCI_ISA_IRQ_MASK & (1U << i))) {
+                /* No need for a INT source override structure. */
+                continue;
+            }
+            memset(int_override, 0, sizeof(*int_override));
+            int_override->type   = APIC_XRUPT_OVERRIDE;
+            int_override->length = sizeof(*int_override);
+            int_override->source = i;
+            int_override->gsi    = i;
+            int_override->flags  = 0xd; /* active high, level triggered */
+            int_override++;
+        }
 #endif
 
         acpi_build_table_header((struct acpi_table_header *)madt,