diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2009-07-29 19:20:03 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2009-07-29 19:20:03 -0400 |
commit | b64db3047f7236441d04a2c25029d2512f31c775 (patch) | |
tree | e787e865b32c8de898bfc90260681dc07b37a0b3 /src/mptable.c | |
parent | df5a5fddf694a2fce40d57427c3c105b307622f7 (diff) | |
download | seabios-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.c | 34 |
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); } |