x86: Ignore function number when writing PIRQ routing table
[oweals/u-boot.git] / arch / x86 / cpu / cpu.c
index bb4a110c0072e0d96b8efee2b58069233de7fdad..d108ee5c4e25538bc60314f19d03e83caf0837fc 100644 (file)
 
 #include <common.h>
 #include <command.h>
-#include <cpu.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>
@@ -164,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
@@ -520,16 +541,6 @@ char *cpu_get_name(char *name)
        return ptr;
 }
 
-int x86_cpu_get_desc(struct udevice *dev, char *buf, int size)
-{
-       if (size < CPU_MAX_NAME_LEN)
-               return -ENOSPC;
-
-       cpu_get_name(buf);
-
-       return 0;
-}
-
 int default_print_cpuinfo(void)
 {
        printf("CPU: %s, vendor %s, device %xh\n",
@@ -613,28 +624,47 @@ int last_stage_init(void)
 }
 #endif
 
-__weak int x86_init_cpus(void)
+#ifdef CONFIG_SMP
+static int enable_smis(struct udevice *cpu, void *unused)
 {
        return 0;
 }
 
-int cpu_init_r(void)
+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)
 {
-       return x86_init_cpus();
+       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
 
-static const struct cpu_ops cpu_x86_ops = {
-       .get_desc       = x86_cpu_get_desc,
-};
+__weak int x86_init_cpus(void)
+{
+#ifdef CONFIG_SMP
+       debug("Init additional CPUs\n");
+       x86_mp_init();
+#endif
 
-static const struct udevice_id cpu_x86_ids[] = {
-       { .compatible = "cpu-x86" },
-       { }
-};
+       return 0;
+}
 
-U_BOOT_DRIVER(cpu_x86_drv) = {
-       .name           = "cpu_x86",
-       .id             = UCLASS_CPU,
-       .of_match       = cpu_x86_ids,
-       .ops            = &cpu_x86_ops,
-};
+int cpu_init_r(void)
+{
+       return x86_init_cpus();
+}