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.c112
1 files changed, 65 insertions, 47 deletions
diff --git a/src/cpu/intel/haswell/haswell_init.c b/src/cpu/intel/haswell/haswell_init.c
index b7bea20734..10f09938d2 100644
--- a/src/cpu/intel/haswell/haswell_init.c
+++ b/src/cpu/intel/haswell/haswell_init.c
@@ -27,6 +27,7 @@
#include <cpu/cpu.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/msr.h>
+#include <cpu/x86/mp.h>
#include <cpu/x86/lapic.h>
#include <cpu/intel/microcode.h>
#include <cpu/intel/speedstep.h>
@@ -679,28 +680,6 @@ static void configure_mca(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);
-
/* Setup MTRRs based on physical address size. */
x86_setup_fixed_mtrrs();
x86_setup_var_mtrrs(cpuid_eax(0x80000008) & 0xff, 2);
@@ -712,9 +691,6 @@ static void bsp_init_before_ap_bringup(struct bus *cpu_bus)
calibrate_24mhz_bclk();
configure_pch_power_sharing();
}
-
- /* Call through the cpu driver's initialization. */
- cpu_initialize(0);
}
/* All CPUs including BSP will run the following function. */
@@ -749,12 +725,57 @@ static void haswell_init(device_t cpu)
enable_turbo();
}
+/* MP initialization support. */
+static const void *microcode_patch;
+int ht_disabled;
+
+static int adjust_apic_id_ht_disabled(int index, int apic_id)
+{
+ return 2 * index;
+}
+
+static void relocate_and_load_microcode(void *unused)
+{
+ /* Relocate the SMM handler. */
+ smm_relocate();
+
+ /* After SMM relocation a 2nd microcode load is required. */
+ intel_microcode_load_unlocked(microcode_patch);
+}
+
+static void enable_smis(void *unused)
+{
+ /* Now that all APs have been relocated as well as the BSP let SMIs
+ * start flowing. */
+ southbridge_smm_enable_smi();
+
+ /* Lock down the SMRAM space. */
+ smm_lock();
+}
+
+static struct mp_flight_record mp_steps[] = {
+ MP_FR_NOBLOCK_APS(relocate_and_load_microcode, NULL,
+ relocate_and_load_microcode, NULL),
+ MP_FR_BLOCK_APS(mp_initialize_cpu, NULL, mp_initialize_cpu, NULL),
+ /* Wait for APs to finish initialization before proceeding. */
+ MP_FR_BLOCK_APS(NULL, NULL, enable_smis, NULL),
+};
+
void bsp_init_and_start_aps(struct bus *cpu_bus)
{
- int max_cpus;
- int num_aps;
- const void *microcode_patch;
void *smm_save_area;
+ int num_threads;
+ int num_cores;
+ msr_t msr;
+ struct mp_params mp_params;
+
+ msr = rdmsr(CORE_THREAD_COUNT_MSR);
+ num_threads = (msr.lo >> 0) & 0xffff;
+ num_cores = (msr.lo >> 16) & 0xffff;
+ printk(BIOS_DEBUG, "CPU has %u cores, %u threads enabled.\n",
+ num_cores, num_threads);
+
+ ht_disabled = num_threads == num_cores;
/* Perform any necessary BSP initialization before APs are brought up.
* This call also allows the BSP to prepare for any secondary effects
@@ -766,27 +787,24 @@ void bsp_init_and_start_aps(struct bus *cpu_bus)
/* Save default SMM area before relocation occurs. */
smm_save_area = backup_default_smm_area();
- /* 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;
+ mp_params.num_cpus = num_threads;
+ mp_params.parallel_microcode_load = 1;
+ if (ht_disabled)
+ mp_params.adjust_apic_id = adjust_apic_id_ht_disabled;
+ else
+ mp_params.adjust_apic_id = NULL;
+ mp_params.flight_plan = &mp_steps[0];
+ mp_params.num_records = ARRAY_SIZE(mp_steps);
+ mp_params.microcode_pointer = microcode_patch;
+
+ /* Load relocation and permeanent handlers. Then initiate relocation. */
+ if (smm_initialize())
+ printk(BIOS_CRIT, "SMM Initialiazation failed...\n");
+
+ if (mp_init(cpu_bus, &mp_params)) {
+ printk(BIOS_ERR, "MP initialization failure.\n");
}
- 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 Initialization failed...\n");
- return;
- }
-
- /* After SMM relocation a 2nd microcode load is required. */
- intel_microcode_load_unlocked(microcode_patch);
-
/* Restore the default SMM region. */
restore_default_smm_area(smm_save_area);
}