diff --git a/src/cpu/intel/model_1067x/mp_init.c b/src/cpu/intel/model_1067x/mp_init.c index b56d106922..ff6cbec8dc 100644 --- a/src/cpu/intel/model_1067x/mp_init.c +++ b/src/cpu/intel/model_1067x/mp_init.c @@ -33,7 +33,7 @@ static int get_cpu_count(void) static void get_microcode_info(const void **microcode, int *parallel) { *microcode = microcode_patch; - *parallel = 1; + *parallel = !intel_ht_supported(); } /* the SMRR enable and lock bit need to be set in IA32_FEATURE_CONTROL diff --git a/src/cpu/intel/model_2065x/model_2065x_init.c b/src/cpu/intel/model_2065x/model_2065x_init.c index db433536cf..88e42a5051 100644 --- a/src/cpu/intel/model_2065x/model_2065x_init.c +++ b/src/cpu/intel/model_2065x/model_2065x_init.c @@ -251,7 +251,7 @@ static void get_microcode_info(const void **microcode, int *parallel) { microcode_patch = intel_microcode_find(); *microcode = microcode_patch; - *parallel = 1; + *parallel = !intel_ht_supported(); } static void per_cpu_smm_trigger(void) diff --git a/src/cpu/intel/model_206ax/model_206ax_init.c b/src/cpu/intel/model_206ax/model_206ax_init.c index 2afbfeecec..b08a86fba2 100644 --- a/src/cpu/intel/model_206ax/model_206ax_init.c +++ b/src/cpu/intel/model_206ax/model_206ax_init.c @@ -497,7 +497,7 @@ static void get_microcode_info(const void **microcode, int *parallel) { microcode_patch = intel_microcode_find(); *microcode = microcode_patch; - *parallel = 1; + *parallel = !intel_ht_supported(); } static void per_cpu_smm_trigger(void) diff --git a/src/cpu/x86/sipi_vector.S b/src/cpu/x86/sipi_vector.S index 02ad0d367a..e1b90890ed 100644 --- a/src/cpu/x86/sipi_vector.S +++ b/src/cpu/x86/sipi_vector.S @@ -102,6 +102,13 @@ _start: /* Save CPU number. */ mov %ecx, %esi + /* + * The following code only needs to run on Intel platforms and thus the caller + * doesn't provide a microcode_ptr if not on Intel. + * On Intel platforms which update microcode using FIT the version check will + * also skip the microcode update. + */ + /* Determine if one should check microcode versions. */ mov microcode_ptr, %edi test %edi, %edi @@ -116,6 +123,16 @@ _start: test %edx, %edx jnz microcode_done + /* + * Intel SDM and various BWGs specify to use a semaphore to update microcode + * on one thread per core on Hyper-Threading enabled CPUs. Due to this complex + * code would be necessary to determine the core #ID, initializing and picking + * the right semaphore out of CONFIG_MAX_CPUS / 2. + * Instead of the per core approachm, as recommended, use one global spinlock. + * Assuming that only pre-FIT platforms with Hyper-Threading enabled and at + * most 8 threads will ever run into this condition, the boot delay is negligible. + */ + /* Determine if parallel microcode loading is allowed. */ cmpl $0xffffffff, microcode_lock je load_microcode diff --git a/src/soc/intel/baytrail/cpu.c b/src/soc/intel/baytrail/cpu.c index 2029017e1f..e624240d92 100644 --- a/src/soc/intel/baytrail/cpu.c +++ b/src/soc/intel/baytrail/cpu.c @@ -149,7 +149,7 @@ static void get_microcode_info(const void **microcode, int *parallel) const struct pattrs *pattrs = pattrs_get(); *microcode = pattrs->microcode_patch; - *parallel = 1; + *parallel = !intel_ht_supported(); } static void per_cpu_smm_trigger(void) diff --git a/src/soc/intel/braswell/cpu.c b/src/soc/intel/braswell/cpu.c index 04bf1082c3..0c6f463438 100644 --- a/src/soc/intel/braswell/cpu.c +++ b/src/soc/intel/braswell/cpu.c @@ -152,7 +152,7 @@ static void get_microcode_info(const void **microcode, int *parallel) const struct pattrs *pattrs = pattrs_get(); *microcode = pattrs->microcode_patch; - *parallel = 1; + *parallel = !intel_ht_supported(); } static void per_cpu_smm_trigger(void)