mb/emulation/x86: Add optional parallel_mp init support

This makes it possible to select both the legacy LAPIC AP init or the
newer parallel MP init.

Tested on i440fx with -smp 32.

Change-Id: I007b052ccd3c34648cd172344d55768232acfd88
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/48210
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Rudolph <siro@das-labor.org>
diff --git a/src/cpu/qemu-x86/Kconfig b/src/cpu/qemu-x86/Kconfig
index 2402932..641cea8 100644
--- a/src/cpu/qemu-x86/Kconfig
+++ b/src/cpu/qemu-x86/Kconfig
@@ -10,6 +10,19 @@
 
 # coreboot i440fx does not support SMM
 choice
+	prompt "AP init"
+	default CPU_QEMU_X86_LAPIC_INIT
+
+config CPU_QEMU_X86_LAPIC_INIT
+	bool "Legacy serial LAPIC init"
+
+config CPU_QEMU_X86_PARALLEL_MP
+	bool "Parallel MP init"
+	select PARALLEL_MP
+
+endchoice
+
+choice
 	prompt "SMM support"
 	default CPU_QEMU_X86_ASEG_SMM
 	depends on BOARD_EMULATION_QEMU_X86_Q35
@@ -20,6 +33,7 @@
 
 config CPU_QEMU_X86_ASEG_SMM
 	bool "SMM in ASEG"
+	depends on !PARALLEL_MP
 	select SMM_ASEG
 
 #config CPU_QEMU_X86_TSEG_SMM
diff --git a/src/mainboard/emulation/qemu-i440fx/northbridge.c b/src/mainboard/emulation/qemu-i440fx/northbridge.c
index d19d6c8..f49d47da 100644
--- a/src/mainboard/emulation/qemu-i440fx/northbridge.c
+++ b/src/mainboard/emulation/qemu-i440fx/northbridge.c
@@ -3,6 +3,7 @@
 #include <console/console.h>
 #include <cpu/cpu.h>
 #include <cpu/x86/lapic_def.h>
+#include <cpu/x86/mp.h>
 #include <arch/io.h>
 #include <device/pci_def.h>
 #include <device/pci_ops.h>
@@ -244,9 +245,22 @@
 #endif
 };
 
+static const struct mp_ops mp_ops_no_smm = {
+	.get_cpu_count = fw_cfg_max_cpus,
+};
+
+void mp_init_cpus(struct bus *cpu_bus)
+{
+	if (mp_init_with_smm(cpu_bus, &mp_ops_no_smm))
+		printk(BIOS_ERR, "MP initialization failure.\n");
+}
+
 static void cpu_bus_init(struct device *dev)
 {
-	initialize_cpus(dev->link_list);
+	if (CONFIG(PARALLEL_MP))
+		mp_cpu_bus_init(dev);
+	else
+		initialize_cpus(dev->link_list);
 }
 
 static void cpu_bus_scan(struct device *bus)