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/devices/cpu_device.c b/src/devices/cpu_device.c
new file mode 100644
index 0000000..b689f1a
--- /dev/null
+++ b/src/devices/cpu_device.c
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 Advanced Micro Devices, Inc.
+ * Copyright (C) 2012 Kyösti Mälkki <kyosti.malkki@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <device/device.h>
+#include <console/console.h>
+#include <cpu/x86/lapic.h>
+
+void remap_bsp_lapic(struct bus *cpu_bus)
+{
+	struct device_path cpu_path;
+	device_t cpu;
+	u32 bsp_lapic_id = lapicid();
+
+	if (bsp_lapic_id) {
+		cpu_path.type = DEVICE_PATH_APIC;
+		cpu_path.apic.apic_id = 0;
+		cpu = find_dev_path(cpu_bus, &cpu_path);
+		if (cpu)
+			cpu->path.apic.apic_id = bsp_lapic_id;
+	}
+}
+
+device_t add_cpu_device(struct bus *cpu_bus, unsigned apic_id, int enabled)
+{
+	struct device_path cpu_path;
+	device_t cpu;
+
+	/* Build the cpu device path */
+	cpu_path.type = DEVICE_PATH_APIC;
+	cpu_path.apic.apic_id = apic_id;
+
+	/* Update CPU in devicetree. */
+	if (enabled)
+		cpu = alloc_find_dev(cpu_bus, &cpu_path);
+	else
+		cpu = find_dev_path(cpu_bus, &cpu_path);
+	if (!cpu)
+		return NULL;
+
+	cpu->enabled = enabled;
+	printk(BIOS_DEBUG, "CPU: %s %s\n",
+		dev_path(cpu), cpu->enabled?"enabled":"disabled");
+
+	return cpu;
+}
+
+void set_cpu_topology(device_t cpu, unsigned node, unsigned package, unsigned core, unsigned thread)
+{
+	cpu->path.apic.node_id = node;
+	cpu->path.apic.package_id = package;
+	cpu->path.apic.core_id = core;
+	cpu->path.apic.thread_id = thread;
+}
+