cpu/x86: allow AP callbacks after MP init

There are circumstances where the APs need to run a piece of
code later in the boot flow. The current MP init just parks
the APs after MP init is completed so there's not an opportunity
to target running a piece of code on all the APs at a later time.
Therefore, provide an option, PARALLEL_MP_AP_WORK, that allows
the APs to perform callbacks.

BUG=chrome-os-partner:60657
BRANCH=reef

Change-Id: I849ecfdd6641dd9424943e246317cd1996ef1ba6
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: https://review.coreboot.org/17745
Tested-by: build bot (Jenkins)
Reviewed-by: Furquan Shaikh <furquan@google.com>
Reviewed-by: Lijian Zhao <lijian.zhao@intel.com>
diff --git a/src/arch/x86/cpu.c b/src/arch/x86/cpu.c
index fbd48b0..1e74d0c 100644
--- a/src/arch/x86/cpu.c
+++ b/src/arch/x86/cpu.c
@@ -11,11 +11,13 @@
  * GNU General Public License for more details.
  */
 
+#include <bootstate.h>
 #include <boot/coreboot_tables.h>
 #include <console/console.h>
 #include <cpu/cpu.h>
 #include <arch/io.h>
 #include <string.h>
+#include <cpu/x86/mp.h>
 #include <cpu/x86/mtrr.h>
 #include <cpu/x86/msr.h>
 #include <cpu/x86/lapic.h>
@@ -310,3 +312,14 @@
 	tsc_info->size = sizeof(*tsc_info);
 	tsc_info->freq_khz = freq_khz;
 }
+
+void arch_bootstate_coreboot_exit(void)
+{
+	/* APs are already parked by existing infrastructure. */
+	if (!IS_ENABLED(CONFIG_PARALLEL_MP_AP_WORK))
+		return;
+
+	/* APs are waiting for work. Last thing to do is park them. */
+	if (mp_park_aps())
+		printk(BIOS_ERR, "Parking APs failed.\n");
+}