summaryrefslogtreecommitdiff
path: root/src/soc/intel/apollolake/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/intel/apollolake/cpu.c')
-rw-r--r--src/soc/intel/apollolake/cpu.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/soc/intel/apollolake/cpu.c b/src/soc/intel/apollolake/cpu.c
index a49bf471a9..b8bf39197e 100644
--- a/src/soc/intel/apollolake/cpu.c
+++ b/src/soc/intel/apollolake/cpu.c
@@ -13,6 +13,7 @@
#include <cpu/x86/mtrr.h>
#include <cpu/x86/smm.h>
#include <cpu/intel/em64t100_save_state.h>
+#include <cpu/intel/microcode.h>
#include <cpu/intel/smm_reloc.h>
#include <device/device.h>
#include <device/pci.h>
@@ -279,3 +280,26 @@ void mp_init_cpus(struct bus *cpu_bus)
CONFIG(BOOT_DEVICE_SPI_FLASH))
fast_spi_cache_bios_region();
}
+
+#if CONFIG(SOC_INTEL_GEMINILAKE)
+int soc_skip_ucode_update(u32 current_patch_id, u32 new_patch_id)
+{
+ /*
+ * If PRMRR/SGX is supported the FIT microcode load will set the 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]. If SGX is not enabled, check and avoid reloading the
+ * same microcode during CPU initialization. If SGX is enabled, as
+ * part of SGX BIOS initialization steps, the same microcode needs to
+ * be reloaded after the core PRMRR MSRs are programmed.
+ */
+ const msr_t mtrr_cap = rdmsr(MTRR_CAP_MSR);
+ if (mtrr_cap.lo & MTRR_CAP_PRMRR) {
+ const msr_t prmrr_phys_base = rdmsr(MSR_PRMRR_PHYS_BASE);
+ if (prmrr_phys_base.raw) {
+ return 0;
+ }
+ }
+ return current_patch_id == new_patch_id - 1;
+}
+#endif