]> git.karo-electronics.de Git - karo-tx-uboot.git/blobdiff - arch/x86/cpu/cpu.c
dm: x86: baytrail: Correct PCI region 3 when driver model is used
[karo-tx-uboot.git] / arch / x86 / cpu / cpu.c
index bb4a110c0072e0d96b8efee2b58069233de7fdad..af927b94e0839b9211393cbd536046a7214d3c61 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/msr.h>
+#include <asm/mtrr.h>
 #include <asm/post.h>
 #include <asm/processor.h>
 #include <asm/processor-flags.h>
@@ -164,6 +167,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
@@ -330,6 +353,28 @@ int x86_cpu_init_f(void)
 
                gd->arch.has_mtrr = has_mtrr();
        }
+       /* Don't allow PCI region 3 to use memory in the 2-4GB memory hole */
+       gd->pci_ram_top = 0x80000000U;
+
+       /* Configure fixed range MTRRs for some legacy regions */
+       if (gd->arch.has_mtrr) {
+               u64 mtrr_cap;
+
+               mtrr_cap = native_read_msr(MTRR_CAP_MSR);
+               if (mtrr_cap & MTRR_CAP_FIX) {
+                       /* Mark the VGA RAM area as uncacheable */
+                       native_write_msr(MTRR_FIX_16K_A0000_MSR, 0, 0);
+
+                       /* Mark the PCI ROM area as uncacheable */
+                       native_write_msr(MTRR_FIX_4K_C0000_MSR, 0, 0);
+                       native_write_msr(MTRR_FIX_4K_C8000_MSR, 0, 0);
+                       native_write_msr(MTRR_FIX_4K_D0000_MSR, 0, 0);
+                       native_write_msr(MTRR_FIX_4K_D8000_MSR, 0, 0);
+
+                       /* Enable the fixed range MTRRs */
+                       msr_setbits_64(MTRR_DEF_TYPE_MSR, MTRR_DEF_TYPE_FIX_EN);
+               }
+       }
 
        return 0;
 }
@@ -520,16 +565,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 +648,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();
+}