From 6fc6a394e3cc64bd27052d480ff2baf11354af54 Mon Sep 17 00:00:00 2001 From: "Peter H. Froehlich" Date: Sun, 18 Oct 2015 00:40:12 -0400 Subject: [PATCH] More sanity checks, slightly improved header. --- mp.c | 23 +++++++++++++++++++---- mp.h | 17 ++++++++++++----- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/mp.c b/mp.c index 90fa48a..3500e27 100644 --- a/mp.c +++ b/mp.c @@ -45,7 +45,7 @@ mpsearch1(uint a, int len) // spec is in one of the following three locations: // 1) in the first KB of the EBDA; // 2) in the last KB of system base memory; -// 3) in the BIOS ROM between 0xE0000 and 0xFFFFF. +// 3) in the BIOS ROM between 0xF0000 and 0xFFFFF. static struct mp* mpsearch(void) { @@ -81,7 +81,7 @@ mpconfig(struct mp **pmp) conf = (struct mpconf*) P2V((uint) mp->physaddr); if(memcmp(conf, "PCMP", 4) != 0) return 0; - if(conf->version != 1 && conf->version != 4) + if(conf->specrev != 1 && conf->specrev != 4) return 0; if(sum((uchar*)conf, conf->length) != 0) return 0; @@ -106,7 +106,17 @@ mpinit(void) switch(*p){ case MPPROC: proc = (struct mpproc*)p; - if (ncpu >= NCPU) { + if(!(proc->flags & MP_PROC_ENABLED)){ + cprintf("mpinit: ignoring cpu %d, not enabled\n", proc->apicid); + p += sizeof(struct mpproc); + continue; + } + if(!(proc->feature & MP_PROC_APIC)){ + cprintf("mpinit: cpu %d has no working APIC, ignored\n", proc->apicid); + p += sizeof(struct mpproc); + continue; + } + if(ncpu >= NCPU){ cprintf("mpinit: more than %d cpus, ignoring cpu%d\n", NCPU, proc->apicid); p += sizeof(struct mpproc); @@ -122,7 +132,12 @@ mpinit(void) continue; case MPIOAPIC: ioapic = (struct mpioapic*)p; - ioapicid = ioapic->apicno; + if(!(ioapic->flags & MP_APIC_ENABLED)){ + cprintf("mpinit: ioapic %d disabled, ignored\n", ioapic->apicid); + p += sizeof(struct mpioapic); + continue; + } + ioapicid = ioapic->apicid; p += sizeof(struct mpioapic); continue; case MPBUS: diff --git a/mp.h b/mp.h index 4d17283..7b83a68 100644 --- a/mp.h +++ b/mp.h @@ -14,9 +14,10 @@ struct mp { // floating pointer struct mpconf { // configuration table header uchar signature[4]; // "PCMP" ushort length; // total table length - uchar version; // [14] + uchar specrev; // [14] uchar checksum; // all bytes must add up to 0 - uchar product[20]; // product id + uchar oemid[8]; // OEM id + uchar productid[12]; // product id uint *oemtable; // OEM table pointer ushort oemlength; // OEM table length ushort entry; // entry count @@ -31,18 +32,24 @@ struct mpproc { // processor table entry uchar apicid; // local APIC id uchar version; // local APIC verison uchar flags; // CPU flags - #define MPBOOT 0x02 // This proc is the bootstrap processor. + #define MP_PROC_ENABLED (1 << 0) // Usable by the OS. + #define MP_PROC_BOOT (1 << 1) // Bootstrap processor. uchar signature[4]; // CPU signature uint feature; // feature flags from CPUID instruction + #define MP_PROC_FPU (1 << 0) // Has a floating point unit. + #define MP_PROC_MCE (1 << 7) // Supports machine check exception. + #define MP_PROC_CX8 (1 << 8) // Supports 8-byte compare-and-exchange. + #define MP_PROC_APIC (1 << 9) // Integrated APIC present and enabled. uchar reserved[8]; }; struct mpioapic { // I/O APIC table entry uchar type; // entry type (2) - uchar apicno; // I/O APIC id + uchar apicid; // I/O APIC id uchar version; // I/O APIC version uchar flags; // I/O APIC flags - uint *addr; // I/O APIC address + #define MP_APIC_ENABLED (1 << 0) // Usable by the OS. + uint *addr; // I/O APIC address }; // Table entry types -- 2.50.1