From patchwork Tue Feb 16 04:11:58 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: MP table multicore patch Date: Tue, 16 Feb 2010 04:11:58 -0000 From: tpearson@raptorengineeringinc.com X-Patchwork-Id: 930 Message-Id: <47064.192.168.1.70.1266293518.squirrel@vali.starlink.edu> To: coreboot@coreboot.org Here is a cleaned up and tested version of the SMP APIC autodetect patch. Signed-off-by: Timothy Pearson --- It would of course be helpful to attach the patch. My Webmail client keeps eating it... Timothy Pearson Raptor Engineering --- /tahoe/coreboot_original/coreboot/src/arch/i386/smp/mpspec.c 2010-02-09 13:33:34.000000000 -0600 +++ coreboot/src/arch/i386/smp/mpspec.c 2010-02-15 21:05:22.982599965 -0600 @@ -91,6 +91,43 @@ smp_add_mpc_entry(mc, sizeof(*mpc)); } +void smp_scan_for_apics(struct mp_config_table *mc, struct device *parent, int boot_apic_id, unsigned apic_version, unsigned cpu_features, unsigned cpu_feature_flags) +{ + int p_it; + int c_it; + struct device *child; + + // Scan the root node for APIC clusters and APICs + for(p_it=0;p_it<(parent->links);p_it++) { + 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) { + // Found an APIC, add it to the MP table + if (child->enabled) { + unsigned long cpu_flag; + 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, boot_apic_id, apic_version, + cpu_features, cpu_feature_flags); + } + } + } + } +} + /* 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. @@ -105,32 +142,16 @@ unsigned cpu_features; unsigned cpu_feature_flags; struct cpuid_result result; - device_t cpu; + //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, boot_apic_id, apic_version, cpu_features, cpu_feature_flags); } void smp_write_bus(struct mp_config_table *mc, @@ -179,7 +200,7 @@ #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)); +// hexdump(__func__, mpc, sizeof(*mpc)); #endif }