diff options
Diffstat (limited to 'src/soc')
-rw-r--r-- | src/soc/intel/apollolake/Makefile.inc | 2 | ||||
-rw-r--r-- | src/soc/intel/apollolake/cpu.c | 97 | ||||
-rw-r--r-- | src/soc/intel/apollolake/include/soc/cpu.h | 6 |
3 files changed, 105 insertions, 0 deletions
diff --git a/src/soc/intel/apollolake/Makefile.inc b/src/soc/intel/apollolake/Makefile.inc index dd2213e869..3b31f12c6b 100644 --- a/src/soc/intel/apollolake/Makefile.inc +++ b/src/soc/intel/apollolake/Makefile.inc @@ -6,6 +6,7 @@ subdirs-y += ../../../cpu/x86/lapic subdirs-y += ../../../cpu/x86/mtrr subdirs-y += ../../../cpu/x86/smm subdirs-y += ../../../cpu/x86/tsc +subdirs-y += ../../../cpu/x86/cache bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/cache_as_ram.S @@ -24,6 +25,7 @@ romstage-y += memmap.c romstage-y += mmap_boot.c smm-y += placeholders.c +ramstage-y += cpu.c ramstage-y += placeholders.c ramstage-y += gpio.c ramstage-$(CONFIG_SOC_UART_DEBUG) += uart_early.c diff --git a/src/soc/intel/apollolake/cpu.c b/src/soc/intel/apollolake/cpu.c new file mode 100644 index 0000000000..0724439210 --- /dev/null +++ b/src/soc/intel/apollolake/cpu.c @@ -0,0 +1,97 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015-2016 Intel Corp. + * (Written by Andrey Petrov <andrey.petrov@intel.com> for Intel Corp.) + * (Written by Alexandru Gagniuc <alexandrux.gagniuc@intel.com> for Intel Corp.) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <console/console.h> +#include <cpu/cpu.h> +#include <cpu/x86/cache.h> +#include <cpu/x86/mp.h> +#include <cpu/x86/msr.h> +#include <cpu/x86/mtrr.h> +#include <device/device.h> +#include <device/pci.h> +#include <soc/cpu.h> + +static struct device_operations cpu_dev_ops = { + .init = DEVICE_NOOP, +}; + +static struct cpu_device_id cpu_table[] = { + { X86_VENDOR_INTEL, CPUID_APOLLOLAKE_A0 }, + { X86_VENDOR_INTEL, CPUID_APOLLOLAKE_B0 }, + { 0, 0 }, +}; + +static const struct cpu_driver driver __cpu_driver = { + .ops = &cpu_dev_ops, + .id_table = cpu_table, +}; + +static void read_cpu_topology(unsigned int *num_phys, unsigned int *num_virt) +{ + msr_t msr; + msr = rdmsr(MSR_CORE_THREAD_COUNT); + *num_virt = (msr.lo >> 0) & 0xffff; + *num_phys = (msr.lo >> 16) & 0xffff; +} + +/* + * Do essential initialization tasks before APs can be fired up + * + * 1. Prevent race condition in MTRR solution. Enable MTRRs on the BSP. This + * creates the MTRR solution that the APs will use. Otherwise APs will try to + * apply the incomplete solution as the BSP is calculating it. + */ +static void bsp_pre_mp_setup(void) +{ + x86_setup_mtrrs_with_detect(); + x86_mtrr_check(); +} + +/* + * CPU initialization recipe + * + * Note that no microcode update is passed to the init function. CSE updates + * the microcode on all cores before releasing them from reset. That means that + * the BSP and all APs will come up with the same microcode revision. + */ +static struct mp_flight_record flight_plan[] = { + /* NOTE: MTRR solution must be calculated before firing up the APs */ + MP_FR_NOBLOCK_APS(mp_initialize_cpu, NULL, mp_initialize_cpu, NULL), +}; + +void apollolake_init_cpus(device_t dev) +{ + unsigned int num_virt_cores, num_phys_cores; + + /* Pre-flight check */ + bsp_pre_mp_setup(); + + /* Find CPU topology */ + read_cpu_topology(&num_phys_cores, &num_virt_cores); + printk(BIOS_DEBUG, "Detected %u core, %u thread CPU.\n", + num_phys_cores, num_virt_cores); + + /* Systems check */ + struct mp_params flight_data_recorder = { + .num_cpus = num_virt_cores, + .parallel_microcode_load = 0, + .microcode_pointer = NULL, + .adjust_apic_id = NULL, + .flight_plan = flight_plan, + .num_records = ARRAY_SIZE(flight_plan), + }; + + /* Clear for take-off */ + if (mp_init(dev->link_list, &flight_data_recorder) < 0) + printk(BIOS_ERR, "MP initialization failure.\n"); +} diff --git a/src/soc/intel/apollolake/include/soc/cpu.h b/src/soc/intel/apollolake/include/soc/cpu.h index 870f474c87..765be7037e 100644 --- a/src/soc/intel/apollolake/include/soc/cpu.h +++ b/src/soc/intel/apollolake/include/soc/cpu.h @@ -14,12 +14,18 @@ #define _SOC_APOLLOLAKE_CPU_H_ #include <cpu/x86/msr.h> +#include <device/device.h> #define CPUID_APOLLOLAKE_A0 0x506c8 +#define CPUID_APOLLOLAKE_B0 0x506c9 #define MSR_PLATFORM_INFO 0xce #define MSR_POWER_MISC 0x120 +#define MSR_CORE_THREAD_COUNT 0x35 #define BASE_CLOCK_MHZ 100 +void apollolake_init_cpus(struct device *dev); + + #endif /* _SOC_APOLLOLAKE_CPU_H_ */ |