From b64db3047f7236441d04a2c25029d2512f31c775 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Wed, 29 Jul 2009 19:20:03 -0400 Subject: [PATCH 1/1] mptable and madt irq override 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. Based on patch by Jes Sorensen --- src/acpi.c | 11 ++++++++++- src/mptable.c | 34 ++++++++++++++++++++++++---------- src/util.h | 3 +++ 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/acpi.c b/src/acpi.c index bafdd6b..ef4eaf9 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -331,7 +331,16 @@ build_madt(struct rsdt_descriptor_rev1 *rsdt) io_apic->interrupt = cpu_to_le32(0); struct madt_intsrcovr *intsrcovr = (void*)&io_apic[1]; - for (i = 0; i < 16; i++) { + if (irq0override) { + 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++; + } + for (i = 1; i < 16; i++) { if (!(PCI_ISA_IRQ_MASK & (1 << i))) /* No need for a INT source override structure. */ continue; diff --git a/src/mptable.c b/src/mptable.c index 5758b28..dd3b10a 100644 --- a/src/mptable.c +++ b/src/mptable.c @@ -10,6 +10,12 @@ #include "config.h" // CONFIG_* #include "mptable.h" // MPTABLE_SIGNATURE +#if CONFIG_KVM +int irq0override = 1; +#else +int irq0override = 0; +#endif + void mptable_init(void) { @@ -48,7 +54,6 @@ mptable_init(void) // Config structure. memset(config, 0, sizeof(*config)); config->signature = MPCONFIG_SIGNATURE; - config->length = length - sizeof(*floating); config->spec = 4; memcpy(config->oemid, CONFIG_CPUNAME8, sizeof(config->oemid)); memcpy(config->productid, "0.1 ", sizeof(config->productid)); @@ -94,19 +99,28 @@ mptable_init(void) ioapic->apicaddr = BUILD_IOAPIC_ADDR; /* irqs */ - struct mpt_intsrc *intsrcs = (void *)&ioapic[1]; - for(i = 0; i < 16; i++) { - struct mpt_intsrc *isrc = &intsrcs[i]; - memset(isrc, 0, sizeof(*isrc)); - isrc->type = MPT_TYPE_INTSRC; - isrc->srcbusirq = i; - isrc->dstapic = ioapic_id; - isrc->dstirq = i; + struct mpt_intsrc *intsrc = (void*)&ioapic[1]; + for (i = 0; i < 16; i++) { + memset(intsrc, 0, sizeof(*intsrc)); + intsrc->type = MPT_TYPE_INTSRC; + intsrc->srcbusirq = i; + intsrc->dstapic = ioapic_id; + intsrc->dstirq = i; + if (irq0override) { + /* Destination 2 is covered by irq0->inti2 override (i == + 0). Source IRQ 2 is unused */ + if (i == 0) + intsrc->dstirq = 2; + else if (i == 2) + intsrc--; + } + intsrc++; } // Set checksum. + config->length = (void*)intsrc - (void*)config; config->checksum -= checksum(config, config->length); dprintf(1, "MP table addr=%p MPC table addr=%p size=%d\n", - floating, config, length); + floating, config, config->length); } diff --git a/src/util.h b/src/util.h index 22b58bc..6cdcffe 100644 --- a/src/util.h +++ b/src/util.h @@ -244,4 +244,7 @@ void reset_vector() __attribute__ ((noreturn)); // misc.c extern u8 BiosChecksum; +// mptable.c +extern int irq0override; + #endif // util.h -- 2.25.1