+ gpMP_LocalAPIC = (void*)MM_MapHWPage(mptable->LocalAPICMemMap, 1);
+
+ ents = mptable->Entries;
+ giNumCPUs = 0;
+
+ for( i = 0; i < mptable->EntryCount; i ++ )
+ {
+ int entSize = 0;
+ switch( ents->Type )
+ {
+ case 0: // Processor
+ entSize = 20;
+ Log("%i: Processor", i);
+ Log("\t.APICID = %i", ents->Proc.APICID);
+ Log("\t.APICVer = 0x%02x", ents->Proc.APICVer);
+ Log("\t.CPUFlags = 0x%02x", ents->Proc.CPUFlags);
+ Log("\t.CPUSignature = 0x%08x", ents->Proc.CPUSignature);
+ Log("\t.FeatureFlags = 0x%08x", ents->Proc.FeatureFlags);
+
+ // Check if there is too many processors
+ if(giNumCPUs >= MAX_CPUS) {
+ giNumCPUs ++; // If `giNumCPUs` > MAX_CPUS later, it will be clipped
+ break;
+ }
+
+ // Initialise CPU Info
+ gaAPIC_to_CPU[ents->Proc.APICID] = giNumCPUs;
+ gaCPUs[giNumCPUs].APICID = ents->Proc.APICID;
+ gaCPUs[giNumCPUs].State = 0;
+ giNumCPUs ++;
+
+ // Send IPI
+ MP_StartAP( giNumCPUs-1 );
+
+ break;
+ case 1: // Bus
+ entSize = 8;
+ Log("%i: Bus", i);
+ Log("\t.ID = %i", ents->Bus.ID);
+ Log("\t.TypeString = '%6c'", ents->Bus.TypeString);
+ break;
+ case 2: // I/O APIC
+ entSize = 8;
+ Log("%i: I/O APIC", i);
+ Log("\t.ID = %i", ents->IOAPIC.ID);
+ Log("\t.Version = 0x%02x", ents->IOAPIC.Version);
+ Log("\t.Flags = 0x%02x", ents->IOAPIC.Flags);
+ Log("\t.Addr = 0x%08x", ents->IOAPIC.Addr);
+ break;
+ case 3: // I/O Interrupt Assignment
+ entSize = 8;
+ Log("%i: I/O Interrupt Assignment", i);
+ Log("\t.IntType = %i", ents->IOInt.IntType);
+ Log("\t.Flags = 0x%04x", ents->IOInt.Flags);
+ Log("\t.SourceBusID = 0x%02x", ents->IOInt.SourceBusID);
+ Log("\t.SourceBusIRQ = 0x%02x", ents->IOInt.SourceBusIRQ);
+ Log("\t.DestAPICID = 0x%02x", ents->IOInt.DestAPICID);
+ Log("\t.DestAPICIRQ = 0x%02x", ents->IOInt.DestAPICIRQ);
+ break;
+ case 4: // Local Interrupt Assignment
+ entSize = 8;
+ Log("%i: Local Interrupt Assignment", i);
+ Log("\t.IntType = %i", ents->LocalInt.IntType);
+ Log("\t.Flags = 0x%04x", ents->LocalInt.Flags);
+ Log("\t.SourceBusID = 0x%02x", ents->LocalInt.SourceBusID);
+ Log("\t.SourceBusIRQ = 0x%02x", ents->LocalInt.SourceBusIRQ);
+ Log("\t.DestLocalAPICID = 0x%02x", ents->LocalInt.DestLocalAPICID);
+ Log("\t.DestLocalAPICIRQ = 0x%02x", ents->LocalInt.DestLocalAPICIRQ);
+ break;
+ default:
+ Log("%i: Unknown (%i)", i, ents->Type);
+ break;
+ }
+ ents = (void*)( (Uint)ents + entSize );
+ }
+
+ if( giNumCPUs > MAX_CPUS ) {
+ Warning("Too many CPUs detected (%i), only using %i of them", giNumCPUs, MAX_CPUS);
+ }
+