summaryrefslogtreecommitdiff
path: root/src/cpu/intel/haswell/haswell_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/intel/haswell/haswell_init.c')
-rw-r--r--src/cpu/intel/haswell/haswell_init.c145
1 files changed, 50 insertions, 95 deletions
diff --git a/src/cpu/intel/haswell/haswell_init.c b/src/cpu/intel/haswell/haswell_init.c
index 9e62b31eb9..82430b750d 100644
--- a/src/cpu/intel/haswell/haswell_init.c
+++ b/src/cpu/intel/haswell/haswell_init.c
@@ -442,71 +442,30 @@ static void configure_mca(void)
static unsigned ehci_debug_addr;
#endif
-/*
- * Initialize any extra cores/threads in this package.
- */
-static void intel_cores_init(device_t cpu)
-{
- struct cpuid_result result;
- unsigned threads_per_package, threads_per_core, i;
-
- /* Logical processors (threads) per core */
- result = cpuid_ext(0xb, 0);
- threads_per_core = result.ebx & 0xffff;
-
- /* Logical processors (threads) per package */
- result = cpuid_ext(0xb, 1);
- threads_per_package = result.ebx & 0xffff;
-
- /* Only initialize extra cores from BSP */
- if (cpu->path.apic.apic_id)
- return;
-
- printk(BIOS_DEBUG, "CPU: %u has %u cores, %u threads per core\n",
- cpu->path.apic.apic_id, threads_per_package/threads_per_core,
- threads_per_core);
-
- for (i = 1; i < threads_per_package; ++i) {
- struct device_path cpu_path;
- device_t new;
-
- /* Build the cpu device path */
- cpu_path.type = DEVICE_PATH_APIC;
- cpu_path.apic.apic_id =
- cpu->path.apic.apic_id + i;
-
- /* Update APIC ID if no hyperthreading */
- if (threads_per_core == 1)
- cpu_path.apic.apic_id <<= 1;
-
- /* Allocate the new cpu device structure */
- new = alloc_dev(cpu->bus, &cpu_path);
- if (!new)
- continue;
-
- printk(BIOS_DEBUG, "CPU: %u has core %u\n",
- cpu->path.apic.apic_id,
- new->path.apic.apic_id);
-
-#if CONFIG_SMP && CONFIG_MAX_CPUS > 1
- /* Start the new cpu */
- if (!start_cpu(new)) {
- /* Record the error in cpu? */
- printk(BIOS_ERR, "CPU %u would not start!\n",
- new->path.apic.apic_id);
- }
-#endif
- }
-}
-
-static void bsp_init_before_ap_bringup(void)
+static void bsp_init_before_ap_bringup(struct bus *cpu_bus)
{
+ struct device_path cpu_path;
+ struct cpu_info *info;
char processor_name[49];
/* Print processor name */
fill_processor_name(processor_name);
printk(BIOS_INFO, "CPU: %s.\n", processor_name);
+ /* Ensure the local apic is enabled */
+ enable_lapic();
+
+ /* Set the device path of the boot cpu. */
+ cpu_path.type = DEVICE_PATH_APIC;
+ cpu_path.apic.apic_id = lapicid();
+
+ /* Find the device structure for the boot cpu. */
+ info = cpu_info();
+ info->cpu = alloc_find_dev(cpu_bus, &cpu_path);
+
+ if (info->index != 0)
+ printk(BIOS_CRIT, "BSP index(%d) != 0!\n", info->index);
+
#if CONFIG_USBDEBUG
// Is this caution really needed?
if(!ehci_debug_addr)
@@ -523,23 +482,12 @@ static void bsp_init_before_ap_bringup(void)
set_ehci_debug(ehci_debug_addr);
#endif
- enable_lapic();
-}
-
-static void ap_init(device_t cpu)
-{
- /* Microcode needs to be loaded before caching is enabled. */
- intel_update_microcode_from_cbfs();
-
- /* Turn on caching if we haven't already */
- x86_enable_cache();
- x86_setup_fixed_mtrrs();
- x86_setup_var_mtrrs(cpuid_eax(0x80000008) & 0xff, 2);
-
- enable_lapic();
+ /* Call through the cpu driver's initialization. */
+ cpu_initialize(0);
}
-static void cpu_common_init(device_t cpu)
+/* All CPUs including BSP will run the following function. */
+static void haswell_init(device_t cpu)
{
/* Clear out pending MCEs */
configure_mca();
@@ -572,33 +520,40 @@ static void cpu_common_init(device_t cpu)
void bsp_init_and_start_aps(struct bus *cpu_bus)
{
+ int max_cpus;
+ int num_aps;
+ const void *microcode_patch;
+
/* Perform any necesarry BSP initialization before APs are brought up.
* This call alos allows the BSP to prepare for any secondary effects
* from calling cpu_initialize() such as smm_init(). */
- bsp_init_before_ap_bringup();
-
- /*
- * This calls into the gerneic initialize_cpus() which attempts to
- * start APs on the APIC bus in the devicetree. No APs get started
- * because there is only the BSP and a placeholder (disabled) in the
- * devicetree. initialize_cpus() also does SMM initialization by way
- * of smm_init(). It will eventually call cpu_initialize(0) which calls
- * dev_ops->init(). For Haswell the dev_ops->init() starts up the APs
- * by way of intel_cores_init().
- */
- initialize_cpus(cpu_bus);
-}
+ bsp_init_before_ap_bringup(cpu_bus);
-static void haswell_init(device_t cpu)
-{
- if (cpu->path.apic.apic_id == 0) {
- cpu_common_init(cpu);
- /* Start up extra cores */
- intel_cores_init(cpu);
- } else {
- ap_init(cpu);
- cpu_common_init(cpu);
+ microcode_patch = intel_microcode_find();
+
+ /* This needs to be called after the mtrr setup so the BSP mtrrs
+ * can be mirrored by the APs. */
+ if (setup_ap_init(cpu_bus, &max_cpus, microcode_patch)) {
+ printk(BIOS_CRIT, "AP setup initialization failed. "
+ "No APs will be brought up.\n");
+ return;
+ }
+
+ num_aps = max_cpus - 1;
+ if (start_aps(cpu_bus, num_aps)) {
+ printk(BIOS_CRIT, "AP startup failed. Trying to continue.\n");
}
+
+ if (smm_initialize()) {
+ printk(BIOS_CRIT, "SMM Initialiazation failed...\n");
+ return;
+ }
+
+ /* Release APs to perform SMM relocation. */
+ release_aps_for_smm_relocation();
+
+ /* After SMM relocation a 2nd microcode load is required. */
+ intel_microcode_load_unlocked(microcode_patch);
}
static struct device_operations cpu_dev_ops = {