aboutsummaryrefslogtreecommitdiff
path: root/src/soc/intel/common/block/cpu
diff options
context:
space:
mode:
authorBarnali Sarkar <barnali.sarkar@intel.com>2017-06-13 19:17:35 +0530
committerAaron Durbin <adurbin@chromium.org>2017-06-23 15:48:30 +0000
commit91d38a5b0e070e75f32b30cb7297a801e31282f6 (patch)
tree5f784d79ac6220ed86b0a04994b60827ab103b0b /src/soc/intel/common/block/cpu
parent71dacacb748a73e44ea86ec571cc4ec9ff667d9d (diff)
soc/intel/common/block: Add common MP Init code
This patch contains State Machine callbacks init_cpus() and post_cpu_init(). Also, it has the SOC call for CPU feature programming. Change-Id: I5b20d413c85bf7ec6ed89b4cdf1770c33507236b Signed-off-by: Barnali Sarkar <barnali.sarkar@intel.com> Reviewed-on: https://review.coreboot.org/20189 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src/soc/intel/common/block/cpu')
-rw-r--r--src/soc/intel/common/block/cpu/Kconfig13
-rw-r--r--src/soc/intel/common/block/cpu/Makefile.inc1
-rw-r--r--src/soc/intel/common/block/cpu/cpulib.c14
-rw-r--r--src/soc/intel/common/block/cpu/mp_init.c141
4 files changed, 168 insertions, 1 deletions
diff --git a/src/soc/intel/common/block/cpu/Kconfig b/src/soc/intel/common/block/cpu/Kconfig
index 56b0064d59..48f3f1645c 100644
--- a/src/soc/intel/common/block/cpu/Kconfig
+++ b/src/soc/intel/common/block/cpu/Kconfig
@@ -2,11 +2,22 @@ config SOC_INTEL_COMMON_BLOCK_CPU
bool
default n
help
- This option helps to select Intel Common CPU Model support code
+ This option selects Intel Common CPU Model support code
which provides various CPU related APIs which are common
between all Intel Processor families. Common CPU code is supported
for SOCs starting from SKL,KBL,APL, and future.
+config SOC_INTEL_COMMON_BLOCK_CPU_MPINIT
+ bool
+ default n
+ help
+ This option selects Intel Common CPU MP Init code. In
+ this common MP Init mechanism, the MP Init is occurring before
+ calling FSP Silicon Init. Hence, MP Init will be pulled to
+ BS_DEV_INIT_CHIPS Entry. And on Exit of BS_DEV_INIT, it is
+ ensured that all MTRRs are re-programmed based on the DRAM
+ resource settings.
+
config SOC_INTEL_COMMON_BLOCK_CAR
bool
default n
diff --git a/src/soc/intel/common/block/cpu/Makefile.inc b/src/soc/intel/common/block/cpu/Makefile.inc
index 4253844582..aa61ffc7f2 100644
--- a/src/soc/intel/common/block/cpu/Makefile.inc
+++ b/src/soc/intel/common/block/cpu/Makefile.inc
@@ -7,3 +7,4 @@ romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU) += cpulib.c
postcar-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CAR) += car/exit_car.S
ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU) += cpulib.c
+ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU_MPINIT) += mp_init.c
diff --git a/src/soc/intel/common/block/cpu/cpulib.c b/src/soc/intel/common/block/cpu/cpulib.c
index 325e1bb857..5920512cd4 100644
--- a/src/soc/intel/common/block/cpu/cpulib.c
+++ b/src/soc/intel/common/block/cpu/cpulib.c
@@ -226,3 +226,17 @@ void cpu_enable_untrusted_mode(void)
msr.lo |= ENABLE_IA_UNTRUSTED;
wrmsr(MSR_POWER_MISC, msr);
}
+
+/*
+ * This function fills in the number of Cores(physical) and Threads(virtual)
+ * of the CPU in the function arguments. It also returns if the number of cores
+ * and number of threads are equal.
+ */
+int cpu_read_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;
+ return (*num_virt == *num_phys);
+}
diff --git a/src/soc/intel/common/block/cpu/mp_init.c b/src/soc/intel/common/block/cpu/mp_init.c
new file mode 100644
index 0000000000..e147bb01f3
--- /dev/null
+++ b/src/soc/intel/common/block/cpu/mp_init.c
@@ -0,0 +1,141 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Intel Corporation.
+ *
+ * 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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/io.h>
+#include <assert.h>
+#include <bootstate.h>
+#include <cpu/cpu.h>
+#include <cpu/x86/mtrr.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/mp.h>
+#include <cpu/intel/microcode.h>
+#include <intelblocks/cpulib.h>
+#include <intelblocks/fast_spi.h>
+#include <intelblocks/mp_init.h>
+#include <intelblocks/msr.h>
+#include <soc/cpu.h>
+
+static const void *microcode_patch;
+
+/* SoC override function */
+__attribute__((weak)) void soc_core_init(device_t dev, const void *microcode)
+{
+ /* no-op */
+}
+
+__attribute__((weak)) void soc_init_cpus(struct bus *cpu_bus,
+ const void *microcode)
+{
+ /* no-op */
+}
+
+static void init_one_cpu(device_t dev)
+{
+ soc_core_init(dev, microcode_patch);
+ intel_microcode_load_unlocked(microcode_patch);
+}
+
+static struct device_operations cpu_dev_ops = {
+ .init = init_one_cpu,
+};
+
+static struct cpu_device_id cpu_table[] = {
+ { X86_VENDOR_INTEL, CPUID_SKYLAKE_C0 },
+ { X86_VENDOR_INTEL, CPUID_SKYLAKE_D0 },
+ { X86_VENDOR_INTEL, CPUID_SKYLAKE_HQ0 },
+ { X86_VENDOR_INTEL, CPUID_SKYLAKE_HR0 },
+ { X86_VENDOR_INTEL, CPUID_KABYLAKE_G0 },
+ { X86_VENDOR_INTEL, CPUID_KABYLAKE_H0 },
+ { X86_VENDOR_INTEL, CPUID_KABYLAKE_Y0 },
+ { X86_VENDOR_INTEL, CPUID_KABYLAKE_HA0 },
+ { X86_VENDOR_INTEL, CPUID_KABYLAKE_HB0 },
+ { 0, 0 },
+};
+
+static const struct cpu_driver driver __cpu_driver = {
+ .ops = &cpu_dev_ops,
+ .id_table = cpu_table,
+};
+
+/*
+ * MP Init callback function to Find CPU Topology. This function is common
+ * among all SOCs and thus its in Common CPU block.
+ */
+int get_cpu_count(void)
+{
+ unsigned int num_virt_cores, num_phys_cores;
+
+ cpu_read_topology(&num_phys_cores, &num_virt_cores);
+
+ printk(BIOS_DEBUG, "Detected %u core, %u thread CPU.\n",
+ num_phys_cores, num_virt_cores);
+
+ return num_virt_cores;
+}
+
+/*
+ * MP Init callback function(get_microcode_info) to find the Microcode at
+ * Pre MP Init phase. This function is common among all SOCs and thus its in
+ * Common CPU block.
+ * This function also fills in the microcode patch (in *microcode), and also
+ * sets the argument *parallel to 1, which allows microcode loading in all
+ * APs to occur in parallel during MP Init.
+ */
+void get_microcode_info(const void **microcode, int *parallel)
+{
+ *microcode =microcode_patch;
+ *parallel = 1;
+}
+
+static void init_cpus(void *unused)
+{
+ device_t dev = dev_find_path(NULL, DEVICE_PATH_CPU_CLUSTER);
+ assert(dev != NULL);
+
+ microcode_patch = intel_microcode_find();
+ intel_microcode_load_unlocked(microcode_patch);
+
+ /*
+ * TODO: This parameter "microcode_patch" should be removed
+ * in this function call once the following two cases are resolved -
+ *
+ * 1) SGX enabling for the BSP issue gets solved, due to which
+ * configure_sgx() function is kept inside soc/cpu.c soc_init_cpus().
+ * 2) uCode loading after SMM relocation is deleted inside
+ * per_cpu_smm_trigger() mp_ops callback function in soc/cpu.c,
+ * since as per current BWG, uCode loading can be done after
+ * all feature programmings are done. There is no specific
+ * recommendation to do it after SMM Relocation.
+ */
+ soc_init_cpus(dev->link_list, microcode_patch);
+}
+
+/* Ensure to re-program all MTRRs based on DRAM resource settings */
+static void post_cpus_init(void *unused)
+{
+ if (mp_run_on_all_cpus(&x86_setup_mtrrs_with_detect, 1000) < 0)
+ printk(BIOS_ERR, "MTRR programming failure\n");
+
+ /* Temporarily cache the memory-mapped boot media. */
+ if (IS_ENABLED(CONFIG_BOOT_DEVICE_MEMORY_MAPPED) &&
+ IS_ENABLED(CONFIG_BOOT_DEVICE_SPI_FLASH))
+ fast_spi_cache_bios_region();
+
+ x86_mtrr_check();
+}
+
+/* Do CPU MP Init before FSP Silicon Init */
+BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_ENTRY, init_cpus, NULL);
+BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, post_cpus_init, NULL);