AMD northbridges: factor out CPU allocation

Factor CPU allocation out of AMD northbridge codes. As CPU topology
information is required for generation of certain ACPI tables, make
this code globally available.

For AMDK8 and AMDFAM10 northbridge, there is a possible case of
BSP CPU with lapicid!=0. We do not want to leave the lapic 0 from
devicetree unused, so always use that node for BSP CPU.

Change-Id: I8b1e73ed5b20b314f71dfd69a7b781ac05aea120
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: http://review.coreboot.org/1418
Tested-by: build bot (Jenkins)
Reviewed-by: Anton Kochkov <anton.kochkov@gmail.com>
Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
diff --git a/src/northbridge/amd/agesa/family10/northbridge.c b/src/northbridge/amd/agesa/family10/northbridge.c
index 3a3580a..0124076 100644
--- a/src/northbridge/amd/agesa/family10/northbridge.c
+++ b/src/northbridge/amd/agesa/family10/northbridge.c
@@ -1374,11 +1374,7 @@
 			extern CONST OPTIONS_CONFIG_TOPOLOGY ROMDATA TopologyConfiguration;
 			u32 modules = TopologyConfiguration.PlatformNumberOfModules;
 			u32 lapicid_start = 0;
-			struct device_path cpu_path;
-			device_t cpu;
 
-			/* Build the cpu device path */
-			cpu_path.type = DEVICE_PATH_APIC;
 			/*
 			 * APIC ID calucation is tightly coupled with AGESA v5 code.
 			 * This calculation MUST match the assignment calculation done
@@ -1394,22 +1390,11 @@
 			if (nodes * (cores_found + 1) >= 0x10) {
   				lapicid_start = 0x10;
 			}
-			cpu_path.apic.apic_id = (lapicid_start * (i/modules + 1)) + ((i % modules) ? (j + (cores_found + 1)) : j);
+			u32 apic_id = (lapicid_start * (i/modules + 1)) + ((i % modules) ? (j + (cores_found + 1)) : j);
 
-			/* Update CPU in devicetree. */
-			if (enable_node)
-				cpu = alloc_find_dev(cpu_bus, &cpu_path);
-			else
-				cpu = find_dev_path(cpu_bus, &cpu_path);
-			if (!cpu)
-				continue;
-
-			cpu->enabled = enable_node;
-			cpu->path.apic.node_id = i;
-			cpu->path.apic.core_id = j;
-			printk(BIOS_DEBUG, "CPU: %s %s\n",
-				dev_path(cpu), cpu->enabled?"enabled":"disabled");
-
+			device_t cpu = add_cpu_device(cpu_bus, apic_id, enable_node);
+			if (cpu)
+				amd_cpu_topology(cpu, i, j);
 		} //j
 	}
 	return max;
diff --git a/src/northbridge/amd/agesa/family14/northbridge.c b/src/northbridge/amd/agesa/family14/northbridge.c
index 2d0a85f..8742f11 100644
--- a/src/northbridge/amd/agesa/family14/northbridge.c
+++ b/src/northbridge/amd/agesa/family14/northbridge.c
@@ -831,6 +831,7 @@
 
 static u32 cpu_bus_scan(device_t dev, u32 max)
 {
+	struct bus *cpu_bus = dev->link_list;
 	device_t cpu;
 	int apic_id, cores_found;
 
@@ -842,20 +843,10 @@
 	cores_found = (pci_read_config32(dev_find_slot(0,PCI_DEVFN(0x18,0x3)), 0xe8) >> 12) & 3;
 	printk(BIOS_DEBUG, "  AP siblings=%d\n", cores_found);
 
-
 	for (apic_id = 0; apic_id <= cores_found; apic_id++) {
-		struct device_path cpu_path;
-
-		cpu_path.type = DEVICE_PATH_APIC;
-		cpu_path.apic.apic_id = apic_id;
-		cpu = alloc_find_dev(dev->link_list, &cpu_path);
-		if (!cpu)
-			continue;
-		cpu->enabled = 1;
-		cpu->path.apic.node_id = 0;
-		cpu->path.apic.core_id = apic_id;
-		printk(BIOS_DEBUG, "CPU: %s %s\n",
-			dev_path(cpu), cpu->enabled?"enabled":"disabled");
+		cpu = add_cpu_device(cpu_bus, apic_id, 1);
+		if (cpu)
+			amd_cpu_topology(cpu, 0, apic_id);
 	}
 	return max;
 }
diff --git a/src/northbridge/amd/agesa/family15/northbridge.c b/src/northbridge/amd/agesa/family15/northbridge.c
index 02270e7..742ef89 100644
--- a/src/northbridge/amd/agesa/family15/northbridge.c
+++ b/src/northbridge/amd/agesa/family15/northbridge.c
@@ -1052,11 +1052,7 @@
 			extern CONST OPTIONS_CONFIG_TOPOLOGY ROMDATA TopologyConfiguration;
 			u32 modules = TopologyConfiguration.PlatformNumberOfModules;
 			u32 lapicid_start = 0;
-			struct device_path cpu_path;
-			device_t cpu;
 
-			/* Build the cpu device path */
-			cpu_path.type = DEVICE_PATH_APIC;
 			/*
 			 * APIC ID calucation is tightly coupled with AGESA v5 code.
 			 * This calculation MUST match the assignment calculation done
@@ -1078,23 +1074,13 @@
 				lapicid_start = (lapicid_start + 1) * core_max;
 				printk(BIOS_SPEW, "lpaicid_start=0x%x ", lapicid_start);
 			}
-			cpu_path.apic.apic_id = (lapicid_start * (i/modules + 1)) + ((i % modules) ? (j + (siblings + 1)) : j);
+			u32 apic_id = (lapicid_start * (i/modules + 1)) + ((i % modules) ? (j + (siblings + 1)) : j);
 			printk(BIOS_SPEW, "node 0x%x core 0x%x apicid=0x%x\n",
-					i, j, cpu_path.apic.apic_id);
+					i, j, apic_id);
 
-			/* Update CPU in devicetree. */
-			if (enable_node)
-				cpu = alloc_find_dev(cpu_bus, &cpu_path);
-			else
-				cpu = find_dev_path(cpu_bus, &cpu_path);
-			if (!cpu)
-				continue;
-
-			cpu->enabled = enable_node;
-			cpu->path.apic.node_id = i;
-			cpu->path.apic.core_id = j;
-			printk(BIOS_DEBUG, "CPU: %s %s\n",
-				dev_path(cpu), cpu->enabled?"enabled":"disabled");
+			device_t cpu = add_cpu_device(cpu_bus, apic_id, enable_node);
+			if (cpu)
+				amd_cpu_topology(cpu, i, j);
 		} //j
 	}
 	return max;
diff --git a/src/northbridge/amd/agesa/family15tn/northbridge.c b/src/northbridge/amd/agesa/family15tn/northbridge.c
index 6fc9434..063afa9 100644
--- a/src/northbridge/amd/agesa/family15tn/northbridge.c
+++ b/src/northbridge/amd/agesa/family15tn/northbridge.c
@@ -1060,11 +1060,7 @@
 			extern CONST OPTIONS_CONFIG_TOPOLOGY ROMDATA TopologyConfiguration;
 			u32 modules = TopologyConfiguration.PlatformNumberOfModules;
 			u32 lapicid_start = 0;
-			struct device_path cpu_path;
-			device_t cpu;
 
-			/* Build the cpu device path */
-			cpu_path.type = DEVICE_PATH_APIC;
 			/*
 			 * APIC ID calucation is tightly coupled with AGESA v5 code.
 			 * This calculation MUST match the assignment calculation done
@@ -1086,23 +1082,13 @@
 				lapicid_start = (lapicid_start + 1) * core_max;
 				printk(BIOS_SPEW, "lpaicid_start=0x%x ", lapicid_start);
 			}
-			cpu_path.apic.apic_id = (lapicid_start * (i/modules + 1)) + ((i % modules) ? (j + (siblings + 1)) : j);
+			u32 apic_id = (lapicid_start * (i/modules + 1)) + ((i % modules) ? (j + (siblings + 1)) : j);
 			printk(BIOS_SPEW, "node 0x%x core 0x%x apicid=0x%x\n",
-					i, j, cpu_path.apic.apic_id);
+					i, j, apic_id);
 
-			/* Update CPU in devicetree. */
-			if (enable_node)
-				cpu = alloc_find_dev(cpu_bus, &cpu_path);
-			else
-				cpu = find_dev_path(cpu_bus, &cpu_path);
-			if (!cpu)
-				continue;
-
-			cpu->enabled = enable_node;
-			cpu->path.apic.node_id = i;
-			cpu->path.apic.core_id = j;
-			printk(BIOS_DEBUG, "CPU: %s %s\n",
-				dev_path(cpu), cpu->enabled?"enabled":"disabled");
+			device_t cpu = add_cpu_device(cpu_bus, apic_id, enable_node);
+			if (cpu)
+				amd_cpu_topology(cpu, i, j);
 		} //j
 	}
 	return max;