/* Methods called by run-time generated SSDT Processor objects */
Method (CPMA, 1, NotSerialized) {
// _MAT method - create an madt apic buffer
+ // Arg0 = Processor ID = Local APIC ID
// Local0 = CPON flag for this cpu
Store(DerefOf(Index(CPON, Arg0)), Local0)
// Local1 = Buffer (in madt apic form) to return
}
Method (CPST, 1, NotSerialized) {
// _STA method - return ON status of cpu
+ // Arg0 = Processor ID = Local APIC ID
// Local0 = CPON flag for this cpu
Store(DerefOf(Index(CPON, Arg0)), Local0)
If (Local0) { Return(0xF) } Else { Return(0x0) }
Store (PRS, Local5)
// Local2 = last read byte from bitmap
Store (Zero, Local2)
- // Local0 = cpuid iterator
+ // Local0 = Processor ID / APIC ID iterator
Store (Zero, Local0)
While (LLess(Local0, SizeOf(CPON))) {
// Local1 = CPON flag for this cpu
apic->length = sizeof(*apic);
apic->processor_id = i;
apic->local_apic_id = i;
- if (i < CountCPUs)
+ if (apic_id_is_present(apic->local_apic_id))
apic->flags = cpu_to_le32(1);
else
apic->flags = cpu_to_le32(0);
}
// build "Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...}"
+ // Arg0 = Processor ID = APIC ID
*(ssdt_ptr++) = 0x14; // MethodOp
ssdt_ptr = encodeLen(ssdt_ptr, 2+5+(12*acpi_cpus), 2);
*(ssdt_ptr++) = 'N';
ssdt_ptr = encodeLen(ssdt_ptr, 2+1+(1*acpi_cpus), 2);
*(ssdt_ptr++) = acpi_cpus;
for (i=0; i<acpi_cpus; i++)
- *(ssdt_ptr++) = (i < CountCPUs) ? 0x01 : 0x00;
+ *(ssdt_ptr++) = (apic_id_is_present(i)) ? 0x01 : 0x00;
// store pci io windows: start, end, length
// this way we don't have to do the math in the dsdt
core->proximity_lo = curnode;
memset(core->proximity_hi, 0, 3);
core->local_sapic_eid = 0;
- if (i < CountCPUs)
+ if (apic_id_is_present(i))
core->flags = cpu_to_le32(1);
else
- core->flags = 0;
+ core->flags = cpu_to_le32(0);
core++;
}
cpu->apicid = i;
cpu->apicver = apic_version;
/* cpu flags: enabled, bootstrap cpu */
- cpu->cpuflag = ((i<CountCPUs) ? 0x01 : 0x00) | ((i==0) ? 0x02 : 0x00);
+ cpu->cpuflag = (apic_id_is_present(i) ? 0x01 : 0x00) | ((i==0) ? 0x02 : 0x00);
cpu->cpusignature = cpuid_signature;
cpu->featureflag = cpuid_features;
cpu++;
u32 CountCPUs VAR16VISIBLE;
u32 MaxCountCPUs VAR16VISIBLE;
+// 256 bits for the found APIC IDs
+u32 FoundAPICIDs[256/32] VAR16VISIBLE;
extern void smp_ap_boot_code(void);
ASM16(
" .global smp_ap_boot_code\n"
" jmp 1b\n"
"2:\n"
+ // get apic ID on EBX, set bit on FoundAPICIDs
+ " movl $1, %eax\n"
+ " cpuid\n"
+ " shrl $24, %ebx\n"
+ " lock btsl %ebx, FoundAPICIDs\n"
+
// Increment the cpu counter
" lock incl CountCPUs\n"
" jmp 1b\n"
);
+int apic_id_is_present(u8 apic_id)
+{
+ return FoundAPICIDs[apic_id/32] & (1 << (apic_id % 32));
+}
+
// find and initialize the CPUs by launching a SIPI to them
void
smp_probe(void)
return;
}
+ // mark the BSP initial APIC ID as found, too:
+ u8 apic_id = ebx>>24;
+ FoundAPICIDs[apic_id/32] |= (1 << (apic_id % 32));
+
// Init the counter.
writel(&CountCPUs, 1);
extern u32 MaxCountCPUs;
void wrmsr_smp(u32 index, u64 val);
void smp_probe(void);
+int apic_id_is_present(u8 apic_id);
// coreboot.c
extern const char *CBvendor, *CBpart;