From 002610f620553bec06e5724052fc5cc5f34eb1e8 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 7 Jun 2015 11:33:13 +0800 Subject: x86: fsp: Load GDT before calling FspInitEntry Currently the FSP execution environment GDT is setup by U-Boot in arch/x86/cpu/start16.S, which works pretty well. But if we try to move the FspInitEntry call a little bit later to better fit into U-Boot's initialization sequence, FSP will fail to bring up the AP due to #GP fault as AP's GDT is duplicated from BSP whose GDT is now moved into CAR, and unfortunately FSP calls AP initialization after it disables the CAR. So basically the BSP's GDT still refers to the one in the CAR, whose content is no longer available, so when AP starts up and loads its segment register, it blows up. To resolve this, we load GDT before calling into FspInitEntry. The GDT is the same one used in arch/x86/cpu/start16.S, which is in the ROM and exists forever. Signed-off-by: Bin Meng Tested-by: Andrew Bradford Tested-by: Simon Glass Acked-by: Simon Glass --- arch/x86/cpu/cpu.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'arch/x86/cpu/cpu.c') diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index bb4a110c00..b6c585a28f 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -164,6 +164,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 -- cgit From be3f06bcc47e04bfc5fb7c900958918e2d019ef4 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Fri, 12 Jun 2015 14:52:20 +0800 Subject: x86: dm: Clean up cpu drivers This commit does the following to clean up x86 cpu dm drivers: - Move cpu_x86 driver codes from arch/x86/cpu/cpu.c to a dedicated file arch/x86/cpu/cpu_x86.c - Rename x86_cpu_get_desc() to cpu_x86_get_desc() to keep consistent naming with other dm drivers - Add a new cpu_x86_bind() in the cpu_x86 driver which does exactly the same as the one in the intel baytrail cpu driver - Update intel baytrail cpu driver to use cpu_x86_get_desc() and cpu_x86_bind() Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/cpu/cpu.c | 28 ---------------------------- 1 file changed, 28 deletions(-) (limited to 'arch/x86/cpu/cpu.c') diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index b6c585a28f..1dfd9e6d27 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -21,8 +21,6 @@ #include #include -#include -#include #include #include #include @@ -540,16 +538,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", @@ -642,19 +630,3 @@ int cpu_init_r(void) { return x86_init_cpus(); } - -static const struct cpu_ops cpu_x86_ops = { - .get_desc = x86_cpu_get_desc, -}; - -static const struct udevice_id cpu_x86_ids[] = { - { .compatible = "cpu-x86" }, - { } -}; - -U_BOOT_DRIVER(cpu_x86_drv) = { - .name = "cpu_x86", - .id = UCLASS_CPU, - .of_match = cpu_x86_ids, - .ops = &cpu_x86_ops, -}; -- cgit From 6e6f4ce4f82501e35301322872152fe28846d743 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 17 Jun 2015 11:15:36 +0800 Subject: x86: Move MP initialization codes into a common place Most of the MP initialization codes in arch/x86/cpu/baytrail/cpu.c is common to all x86 processors, except detect_num_cpus() which varies from cpu to cpu. Move these to arch/x86/cpu/cpu.c and implement the new 'get_count' method for baytrail and cpu_x86 drivers. Now we call cpu_get_count() in mp_init() to get the number of CPUs. Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/cpu/cpu.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'arch/x86/cpu/cpu.c') diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index 1dfd9e6d27..a6e88cfe19 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -21,10 +21,13 @@ #include #include +#include #include #include #include #include +#include +#include #include #include #include @@ -621,8 +624,45 @@ int last_stage_init(void) } #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; + + lapic_setup(); + + 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; } -- cgit From 61788e468ebe4a7b8c852ab4e761e084a7975a93 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 17 Jun 2015 11:15:37 +0800 Subject: x86: Move lapic_setup() call into init_bsp() Currently lapic_setup() is called before calling mp_init(), which then calls init_bsp() where it calls enable_lapic(), which was already enabled in lapic_setup(). Hence move lapic_setup() call into init_bsp() to avoid the duplication. Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/cpu/cpu.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/x86/cpu/cpu.c') diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index a6e88cfe19..d108ee5c4e 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -640,8 +640,6 @@ static int x86_mp_init(void) { struct mp_params mp_params; - lapic_setup(); - mp_params.parallel_microcode_load = 0, mp_params.flight_plan = &mp_steps[0]; mp_params.num_records = ARRAY_SIZE(mp_steps); -- cgit From 43dd22f5fc4c368616721a69e5ea0769abf292dc Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Mon, 6 Jul 2015 16:31:30 +0800 Subject: x86: Setup fixed range MTRRs for legacy regions We should setup fixed range MTRRs for some legacy regions like VGA RAM and PCI ROM areas as uncacheable. Note FSP may setup these to other cache settings, but we can override this in x86_cpu_init_f(). Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/cpu/cpu.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'arch/x86/cpu/cpu.c') diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index d108ee5c4e..9afdafb17e 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include #include @@ -352,6 +354,26 @@ int x86_cpu_init_f(void) gd->arch.has_mtrr = has_mtrr(); } + /* 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; } -- cgit From b9da5086b88a1565c7aede14e68bef2456c44475 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 3 Jul 2015 18:28:27 -0600 Subject: dm: x86: baytrail: Correct PCI region 3 when driver model is used Commit afbbd413a fixed this for non-driver-model. Make sure that the driver model code handles this also. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/cpu/cpu.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/x86/cpu/cpu.c') diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index 9afdafb17e..af927b94e0 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -353,6 +353,8 @@ 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) { -- cgit