x86: Ignore function number when writing PIRQ routing table
[oweals/u-boot.git] / arch / x86 / cpu / cpu.c
index 78eb3feb3b14ca97888b38079f526bca20eeca8c..d108ee5c4e25538bc60314f19d03e83caf0837fc 100644 (file)
 
 #include <common.h>
 #include <command.h>
+#include <dm.h>
 #include <errno.h>
 #include <malloc.h>
 #include <asm/control_regs.h>
 #include <asm/cpu.h>
+#include <asm/lapic.h>
+#include <asm/mp.h>
 #include <asm/post.h>
 #include <asm/processor.h>
 #include <asm/processor-flags.h>
@@ -162,6 +165,26 @@ void setup_gdt(gd_t *id, u64 *gdt_addr)
        load_fs(X86_GDT_ENTRY_32BIT_FS);
 }
 
+#ifdef CONFIG_HAVE_FSP
+/*
+ * Setup FSP execution environment GDT
+ *
+ * Per Intel FSP external architecture specification, before calling any FSP
+ * APIs, we need make sure the system is in flat 32-bit mode and both the code
+ * and data selectors should have full 4GB access range. Here we reuse the one
+ * we used in arch/x86/cpu/start16.S, and reload the segement registers.
+ */
+void setup_fsp_gdt(void)
+{
+       load_gdt((const u64 *)(gdt_rom + CONFIG_RESET_SEG_START), 4);
+       load_ds(X86_GDT_ENTRY_32BIT_DS);
+       load_ss(X86_GDT_ENTRY_32BIT_DS);
+       load_es(X86_GDT_ENTRY_32BIT_DS);
+       load_fs(X86_GDT_ENTRY_32BIT_DS);
+       load_gs(X86_GDT_ENTRY_32BIT_DS);
+}
+#endif
+
 int __weak x86_cleanup_before_linux(void)
 {
 #ifdef CONFIG_BOOTSTAGE_STASH
@@ -600,3 +623,48 @@ int last_stage_init(void)
        return 0;
 }
 #endif
+
+#ifdef CONFIG_SMP
+static int enable_smis(struct udevice *cpu, void *unused)
+{
+       return 0;
+}
+
+static struct mp_flight_record mp_steps[] = {
+       MP_FR_BLOCK_APS(mp_init_cpu, NULL, mp_init_cpu, NULL),
+       /* Wait for APs to finish initialization before proceeding */
+       MP_FR_BLOCK_APS(NULL, NULL, enable_smis, NULL),
+};
+
+static int x86_mp_init(void)
+{
+       struct mp_params mp_params;
+
+       mp_params.parallel_microcode_load = 0,
+       mp_params.flight_plan = &mp_steps[0];
+       mp_params.num_records = ARRAY_SIZE(mp_steps);
+       mp_params.microcode_pointer = 0;
+
+       if (mp_init(&mp_params)) {
+               printf("Warning: MP init failure\n");
+               return -EIO;
+       }
+
+       return 0;
+}
+#endif
+
+__weak int x86_init_cpus(void)
+{
+#ifdef CONFIG_SMP
+       debug("Init additional CPUs\n");
+       x86_mp_init();
+#endif
+
+       return 0;
+}
+
+int cpu_init_r(void)
+{
+       return x86_init_cpus();
+}