Index: src/arch/i386/smp/mpspec.c =================================================================== --- src/arch/i386/smp/mpspec.c (revision 5127) +++ src/arch/i386/smp/mpspec.c (working copy) @@ -91,6 +91,52 @@ smp_add_mpc_entry(mc, sizeof(*mpc)); } +void smp_scan_for_apics(struct mp_config_table *mc, struct device *parent) +{ + int c_it; + struct device *child; + /* Scan all links of the root node for APIC clusters and APICs */ + for(c_it=0; c_it < parent->links; c_it++) { + for (child = parent->link[c_it].children; child; child = child->sibling) { + /* Is this an APIC? */ + if (child->path.type == DEVICE_PATH_APIC) { + int boot_apic_id; + unsigned apic_version; + unsigned long cpu_flag; + unsigned cpu_features; + unsigned cpu_feature_flags; + struct cpuid_result result; + + if (!child->enabled) + continue; + + /* Found an APIC, add it to the MP table */ + boot_apic_id = lapicid(); + apic_version = lapic_read(LAPIC_LVR) & 0xff; + + result = cpuid(1); + cpu_features = result.eax; + cpu_feature_flags = result.edx; + + cpu_flag = MPC_CPU_ENABLED; + if (boot_apic_id == child->path.apic.apic_id) { + cpu_flag = MPC_CPU_ENABLED | MPC_CPU_BOOTPROCESSOR; + } + smp_write_processor(mc, + child->path.apic.apic_id, apic_version, + cpu_flag, cpu_features, cpu_feature_flags + ); + } + + // Or an APIC cluster? + if (child->path.type == DEVICE_PATH_APIC_CLUSTER) { + // Found an APIC cluster, scan it for APICs + smp_scan_for_apics(mc, child); + } + } + } +} + /* If we assume a symmetric processor configuration we can * get all of the information we need to write the processor * entry from the bootstrap processor. @@ -100,37 +146,8 @@ */ void smp_write_processors(struct mp_config_table *mc) { - int boot_apic_id; - unsigned apic_version; - unsigned cpu_features; - unsigned cpu_feature_flags; - struct cpuid_result result; - device_t cpu; - - boot_apic_id = lapicid(); - apic_version = lapic_read(LAPIC_LVR) & 0xff; - result = cpuid(1); - cpu_features = result.eax; - cpu_feature_flags = result.edx; - for(cpu = all_devices; cpu; cpu = cpu->next) { - unsigned long cpu_flag; - if ((cpu->path.type != DEVICE_PATH_APIC) || - (cpu->bus->dev->path.type != DEVICE_PATH_APIC_CLUSTER)) - { - continue; - } - if (!cpu->enabled) { - continue; - } - cpu_flag = MPC_CPU_ENABLED; - if (boot_apic_id == cpu->path.apic.apic_id) { - cpu_flag = MPC_CPU_ENABLED | MPC_CPU_BOOTPROCESSOR; - } - smp_write_processor(mc, - cpu->path.apic.apic_id, apic_version, - cpu_flag, cpu_features, cpu_feature_flags - ); - } + // Scan the root node for APIC clusters and APICs + smp_scan_for_apics(mc, all_devices); } void smp_write_bus(struct mp_config_table *mc, @@ -179,7 +196,6 @@ #ifdef DEBUG_MPTABLE printk_debug("add intsrc srcbus 0x%x srcbusirq 0x%x, dstapic 0x%x, dstirq 0x%x\n", srcbus, srcbusirq, dstapic, dstirq); - hexdump(__func__, mpc, sizeof(*mpc)); #endif }