Kyösti Mälkki (kyosti.malkki@gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1142
-gerrit
commit a428c0216a66da85060f65854bcc349cf19b6546 Author: Kyösti Mälkki kyosti.malkki@gmail.com Date: Tue Jun 26 19:53:27 2012 +0300
Intel CPUs: execute microcode update only once per core
Early HT-enabled CPUs do not serialize microcode updates within a core. Solve this by running microcode updates on the thread with the smallest lapic ID of a core only.
Change-Id: I6a3cc9ecec2d8e0caed29605a9b19ec35a817620 Signed-off-by: Kyösti Mälkki kyosti.malkki@gmail.com --- src/cpu/intel/microcode/microcode.c | 25 +++++++++++++++++++++++++ 1 files changed, 25 insertions(+), 0 deletions(-)
diff --git a/src/cpu/intel/microcode/microcode.c b/src/cpu/intel/microcode/microcode.c index ec42fb9..b1b52a4 100644 --- a/src/cpu/intel/microcode/microcode.c +++ b/src/cpu/intel/microcode/microcode.c @@ -25,6 +25,7 @@ #endif #include <cpu/cpu.h> #include <cpu/x86/msr.h> +#include <cpu/x86/lapic.h> #include <cpu/intel/microcode.h>
struct microcode { @@ -68,6 +69,27 @@ static inline u32 read_microcode_rev(void) return msr.hi; }
+/* Microcode update needs to run only once per CPU core. Return true + * if running thread does not have the smallest lapic ID within a CPU core. + */ +static int intel_ht_sibling(void) +{ + unsigned int core_ids, apic_ids, threads; + + apic_ids = 1; + if (cpuid_eax(0) >= 1) + apic_ids = (cpuid_ebx(1) >> 16) & 0xff; + if (apic_ids < 1) + apic_ids = 1; + + core_ids = 1; + if (cpuid_eax(0) >= 4) + core_ids += (cpuid_eax(4) >> 26) & 0x3f; + + threads = (apic_ids / core_ids); + return !!(lapicid() & (threads-1)); +} + void intel_update_microcode(const void *microcode_updates) { u32 eax; @@ -77,6 +99,9 @@ void intel_update_microcode(const void *microcode_updates) const char *c; msr_t msr;
+ if (intel_ht_sibling()) + return; + /* CPUID sets MSR 0x8B iff a microcode update has been loaded. */ msr.lo = 0; msr.hi = 0;