// 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)
{
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;
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);
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:
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
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