aboutsummaryrefslogtreecommitdiffstats
path: root/src/mptable.c
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2009-07-29 19:20:03 -0400
committerKevin O'Connor <kevin@koconnor.net>2009-07-29 19:20:03 -0400
commitb64db3047f7236441d04a2c25029d2512f31c775 (patch)
treee787e865b32c8de898bfc90260681dc07b37a0b3 /src/mptable.c
parentdf5a5fddf694a2fce40d57427c3c105b307622f7 (diff)
downloadseabios-b64db3047f7236441d04a2c25029d2512f31c775.tar.gz
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 <jes@sgi.com>
Diffstat (limited to 'src/mptable.c')
-rw-r--r--src/mptable.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/src/mptable.c b/src/mptable.c
index 5758b28d..dd3b10af 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);
}