--- src/mptable.c | 26 ++++++++++++++++++++++---- 1 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/src/mptable.c b/src/mptable.c index 805fe1b..525188d 100644 --- a/src/mptable.c +++ b/src/mptable.c @@ -44,16 +44,32 @@ mptable_init(void) config->spec = 4; memcpy(config->oemid, CONFIG_CPUNAME8, sizeof(config->oemid)); memcpy(config->productid, "0.1 ", sizeof(config->productid)); - config->entrycount = MaxCountCPUs + 2 + 16; config->lapic = BUILD_APIC_ADDR;
// CPU definitions. u32 cpuid_signature, ebx, ecx, cpuid_features; cpuid(1, &cpuid_signature, &ebx, &ecx, &cpuid_features); struct mpt_cpu *cpus = (void*)&config[1]; - int i; - for (i = 0; i < MaxCountCPUs; i++) { + int i, actual_cpu_count; + for (i = 0, actual_cpu_count = 0; i < MaxCountCPUs; i++) { struct mpt_cpu *cpu = &cpus[i]; + int log_cpus = (ebx >> 16) & 0xff; + + /* Only populate the MPS tables with the first logical CPU in each + package */ + if ((cpuid_features & (1 << 28)) && + log_cpus > 1 && + ((log_cpus <= 2 && (i & 1) != 0) || + (log_cpus <= 4 && (i & 3) != 0) || + (log_cpus <= 8 && (i & 7) != 0) || + (log_cpus <= 16 && (i & 15) != 0) || + (log_cpus <= 32 && (i & 31) != 0) || + (log_cpus <= 64 && (i & 63) != 0) || + (log_cpus <= 128 && (i & 127) != 0))) + continue; + + actual_cpu_count++; + memset(cpu, 0, sizeof(*cpu)); cpu->type = MPT_TYPE_CPU; cpu->apicid = i; @@ -72,8 +88,10 @@ mptable_init(void) } }
+ config->entrycount = actual_cpu_count + 2 + 16; + /* isa bus */ - struct mpt_bus *bus = (void*)&cpus[MaxCountCPUs]; + struct mpt_bus *bus = (void*)&cpus[actual_cpu_count]; memset(bus, 0, sizeof(*bus)); bus->type = MPT_TYPE_BUS; memcpy(bus->bustype, "ISA ", sizeof(bus->bustype));