Implement irq override support for timer interrupts. This matches what QEMU+BOCHS has been doing for the latest 8 months, and is also what real hardware does. Windows expects this according to Beth Kon. Signed-off-by: Jes Sorensen --- src/acpi.c | 10 ++++++++++ src/mptable.c | 16 +++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) Index: seabios/src/acpi.c =================================================================== --- seabios.orig/src/acpi.c +++ seabios/src/acpi.c @@ -440,6 +440,16 @@ void acpi_bios_init(void) io_apic->interrupt = cpu_to_le32(0); struct madt_intsrcovr *intsrcovr = (void*)&io_apic[1]; + + memset(intsrcovr, 0, sizeof(*intsrcovr)); + intsrcovr->type = APIC_XRUPT_OVERRIDE; + intsrcovr->length = sizeof(*intsrcovr); + intsrcovr->source = 0; + intsrcovr->gsi = 2; + intsrcovr->flags = 0; /* conforms to bus specifications */ + intsrcovr++; + madt_size += sizeof(struct madt_intsrcovr); + for (i = 0; i < 16; i++) { if (!(PCI_ISA_IRQ_MASK & (1 << i))) /* No need for a INT source override structure. */ Index: seabios/src/mptable.c =================================================================== --- seabios.orig/src/mptable.c +++ seabios/src/mptable.c @@ -29,7 +29,7 @@ mptable_init(void) + sizeof(struct mpt_cpu) * smp_cpus + sizeof(struct mpt_bus) + sizeof(struct mpt_ioapic) - + sizeof(struct mpt_intsrc) * 16); + + sizeof(struct mpt_intsrc) * 15); if (start + length > bios_table_end_addr) { dprintf(1, "No room for MPTABLE!\n"); return; @@ -96,13 +96,23 @@ mptable_init(void) /* irqs */ struct mpt_intsrc *intsrcs = (void *)&ioapic[1]; + int j = 0; for(i = 0; i < 16; i++) { - struct mpt_intsrc *isrc = &intsrcs[i]; + /* One entry per ioapic interrupt destination. Destination 2 is covered + by irq0->inti2 override (i == 0). Source IRQ 2 is unused */ + if (i == 2) { + j = 1; + continue; + } + struct mpt_intsrc *isrc = &intsrcs[i - j]; memset(isrc, 0, sizeof(*isrc)); isrc->type = MPT_TYPE_INTSRC; isrc->srcbusirq = i; isrc->dstapic = ioapic_id; - isrc->dstirq = i; + if (i == 0) + isrc->dstirq = 2; + else + isrc->dstirq = i; } // Set checksum.