diff --git a/src/soc/intel/skylake/bootblock/cpu.c b/src/soc/intel/skylake/bootblock/cpu.c index d4506e592a..2e3e000aaa 100644 --- a/src/soc/intel/skylake/bootblock/cpu.c +++ b/src/soc/intel/skylake/bootblock/cpu.c @@ -178,11 +178,33 @@ static void check_for_clean_reset(void) soft_reset(); } +static int need_microcode_update(void) +{ + /* If PRMRR/SGX is supported the FIT microcode load step will set + * msr 0x08b with the Patch revision id one less than the id in the + * microcode binary. The PRMRR support is indicated in the MSR + * MTRRCAP[12]. Check for this feature and avoid reloading the + * same microcode during early cpu initialization. + */ + msr = rdmsr(MTRRcap_MSR); + return (msr.lo & PRMRR_SUPPORTED) && (current_rev != patch->rev - 1); +} + static void bootblock_cpu_init(void) { + const struct microcode *patch; + u32 current_rev; + msr_t msr; + /* Set flex ratio and reset if needed */ set_flex_ratio_to_tdp_nominal(); check_for_clean_reset(); enable_rom_caching(); - intel_update_microcode_from_cbfs(); + + patch = intel_microcode_find(); + + current_rev = read_microcode_rev(); + + if (need_microcode_update()) + intel_update_microcode_from_cbfs(); } diff --git a/src/soc/intel/skylake/include/soc/msr.h b/src/soc/intel/skylake/include/soc/msr.h index b857dbe85e..390375703e 100644 --- a/src/soc/intel/skylake/include/soc/msr.h +++ b/src/soc/intel/skylake/include/soc/msr.h @@ -105,6 +105,6 @@ /* MTRRcap_MSR bits */ #define SMRR_SUPPORTED (1<<11) -#define EMRR_SUPPORTED (1<<12) +#define PRMRR_SUPPORTED (1<<12) #endif