Patchwork MP table multicore patch

login
register
about
Submitter tpearson@raptorengineeringinc.com
Date 2010-02-16 04:11:58
Message ID <47064.192.168.1.70.1266293518.squirrel@vali.starlink.edu>
Download mbox | patch
Permalink /patch/930/
State Superseded
Headers show

Comments

tpearson@raptorengineeringinc.com - 2010-02-16 04:11:58
Here is a cleaned up and tested version of the SMP APIC autodetect patch.

Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>

---

It would of course be helpful to attach the patch.  My Webmail client
keeps eating it...

Timothy Pearson
Raptor Engineering

Patch

--- /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
 }