Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/49303 )
Change subject: cpu/x86/mpinit: Serialize microcode updates for HT threads ......................................................................
cpu/x86/mpinit: Serialize microcode updates for HT threads
This change affects Intel CPUs only. As most platforms are doing uCode update using FIT, they aren't affect by this code either.
Update microcode in MP-init using a single spinlock when running on a Hyper-Threading enabled CPU on pre FIT platforms. This will slow down the MP-init boot flow.
Intel SDM and various BWGs specify to use a semaphore to update microcode on one thread per code on Hyper-Threading enabled CPUs. As complex code would be necessary determining the core #ID, initializing and picking the right semaphore out of CONFIG_MAX_CPUS / 2, only every use a 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 neglectable.
This change is a counterproposal to the previous published patch series being much more unsophisticated.
Change-Id: I27bf5177859c12e92d6ce7a2966c965d7262b472 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- M src/cpu/intel/model_1067x/mp_init.c M src/cpu/intel/model_2065x/model_2065x_init.c M src/cpu/intel/model_206ax/model_206ax_init.c M src/cpu/x86/sipi_vector.S M src/soc/intel/baytrail/cpu.c M src/soc/intel/braswell/cpu.c 6 files changed, 21 insertions(+), 5 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/03/49303/1
diff --git a/src/cpu/intel/model_1067x/mp_init.c b/src/cpu/intel/model_1067x/mp_init.c index b56d106..ff6cbec 100644 --- a/src/cpu/intel/model_1067x/mp_init.c +++ b/src/cpu/intel/model_1067x/mp_init.c @@ -33,7 +33,7 @@ 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 db43353..88e42a5 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 @@ { 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 2afbfee..b08a86f 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 @@ { 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 02ad0d3..0a963f7 100644 --- a/src/cpu/x86/sipi_vector.S +++ b/src/cpu/x86/sipi_vector.S @@ -102,6 +102,13 @@ /* Save CPU number. */ mov %ecx, %esi
+ /* + * The following code only need 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,15 @@ test %edx, %edx jnz microcode_done
+ /* + * Intel SDM and various BWGs specify to use a semaphore to update microcode + * on one thread per code on Hyper-Threading enabled CPUs. As complex code would be + * necessary determining the core #ID, initializing and picking the right semaphore + * out of CONFIG_MAX_CPUS / 2, only every use a 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 neglectable. + */ + /* 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 2029017..e624240 100644 --- a/src/soc/intel/baytrail/cpu.c +++ b/src/soc/intel/baytrail/cpu.c @@ -149,7 +149,7 @@ 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 04bf108..0c6f463 100644 --- a/src/soc/intel/braswell/cpu.c +++ b/src/soc/intel/braswell/cpu.c @@ -152,7 +152,7 @@ const struct pattrs *pattrs = pattrs_get();
*microcode = pattrs->microcode_patch; - *parallel = 1; + *parallel = !intel_ht_supported(); }
static void per_cpu_smm_trigger(void)