diff options
Diffstat (limited to 'src/cpu/intel/microcode')
-rw-r--r-- | src/cpu/intel/microcode/microcode.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/src/cpu/intel/microcode/microcode.c b/src/cpu/intel/microcode/microcode.c index 2c8a2121f2..51823ca6de 100644 --- a/src/cpu/intel/microcode/microcode.c +++ b/src/cpu/intel/microcode/microcode.c @@ -117,18 +117,15 @@ uint32_t get_microcode_checksum(const void *microcode) return ((struct microcode *)microcode)->cksum; } -const void *intel_microcode_find(void) +static const void *find_cbfs_microcode(void) { - static const struct microcode *ucode_updates; + const struct microcode *ucode_updates; size_t microcode_len; u32 eax; u32 pf, rev, sig, update_size; msr_t msr; struct cpuinfo_x86 c; - if (ucode_updates) - return ucode_updates; - ucode_updates = cbfs_map(MICROCODE_CBFS_FILE, µcode_len); if (ucode_updates == NULL) return NULL; @@ -170,11 +167,28 @@ const void *intel_microcode_find(void) microcode_len -= update_size; } - ucode_updates = NULL; - return NULL; } +const void *intel_microcode_find(void) +{ + static bool microcode_checked; + static const void *ucode_update; + + if (microcode_checked) + return ucode_update; + + /* + * Since this function caches the found microcode (NULL or a valid + * microcode pointer), it is expected to be run from BSP before starting + * any other APs. This sequence is not multithread safe otherwise. + */ + ucode_update = find_cbfs_microcode(); + microcode_checked = true; + + return ucode_update; +} + void intel_update_microcode_from_cbfs(void) { const void *patch = intel_microcode_find(); |