X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=arch%2Fx86%2Fcpu%2Fcpu.c;h=d108ee5c4e25538bc60314f19d03e83caf0837fc;hb=8c38e4d0b8d37dcd3bfd2293481e220b1b4a3a42;hp=78eb3feb3b14ca97888b38079f526bca20eeca8c;hpb=52845296be8190c3f581090d6336fa033f2bd2d8;p=oweals%2Fu-boot.git diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index 78eb3feb3b..d108ee5c4e 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 @@ -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(); +}