/** @file\r
Implementation of loading microcode on processors.\r
\r
- Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
/**\r
Detect whether specified processor can find matching microcode patch and load it.\r
\r
+ @param PeiCpuMpData Pointer to PEI CPU MP Data\r
**/\r
VOID\r
MicrocodeDetect (\r
- VOID\r
+ IN PEI_CPU_MP_DATA *PeiCpuMpData\r
)\r
{\r
UINT64 MicrocodePatchAddress;\r
UINTN Index;\r
UINT8 PlatformId;\r
UINT32 RegEax;\r
+ UINT32 CurrentRevision;\r
UINT32 LatestRevision;\r
UINTN TotalSize;\r
UINT32 CheckSum32;\r
BOOLEAN CorrectMicrocode;\r
- INT32 CurrentSignature;\r
MICROCODE_INFO MicrocodeInfo;\r
\r
ZeroMem (&MicrocodeInfo, sizeof (MICROCODE_INFO));\r
return;\r
}\r
\r
+ CurrentRevision = GetCurrentMicrocodeSignature ();\r
+ if (CurrentRevision != 0) {\r
+ //\r
+ // Skip loading microcode if it has been loaded successfully\r
+ //\r
+ return;\r
+ }\r
+\r
ExtendedTableLength = 0;\r
//\r
// Here data of CPUID leafs have not been collected into context buffer, so\r
if (MicrocodeEntryPoint->HeaderVersion == 0x1) {\r
//\r
// It is the microcode header. It is not the padding data between microcode patches\r
- // becasue the padding data should not include 0x00000001 and it should be the repeated\r
+ // because the padding data should not include 0x00000001 and it should be the repeated\r
// byte format (like 0xXYXYXYXY....).\r
//\r
if (MicrocodeEntryPoint->ProcessorId == RegEax &&\r
MicrocodeEntryPoint = (EFI_CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + TotalSize);\r
} while (((UINTN) MicrocodeEntryPoint < MicrocodeEnd));\r
\r
- if (LatestRevision > 0) {\r
+ if (LatestRevision > CurrentRevision) {\r
//\r
- // Get microcode update signature of currently loaded microcode update\r
+ // BIOS only authenticate updates that contain a numerically larger revision\r
+ // than the currently loaded revision, where Current Signature < New Update\r
+ // Revision. A processor with no loaded update is considered to have a\r
+ // revision equal to zero.\r
//\r
- CurrentSignature = GetCurrentMicrocodeSignature ();\r
+ AsmWriteMsr64 (\r
+ EFI_MSR_IA32_BIOS_UPDT_TRIG,\r
+ (UINT64) (UINTN) MicrocodeInfo.MicrocodeData\r
+ );\r
//\r
- // If no microcode update has been loaded, then trigger microcode load.\r
+ // Get and check new microcode signature\r
//\r
- if (CurrentSignature == 0) {\r
- AsmWriteMsr64 (\r
- EFI_MSR_IA32_BIOS_UPDT_TRIG,\r
- (UINT64) (UINTN) MicrocodeInfo.MicrocodeData\r
- );\r
- MicrocodeInfo.Load = TRUE;\r
- } else {\r
- MicrocodeInfo.Load = FALSE;\r
+ CurrentRevision = GetCurrentMicrocodeSignature ();\r
+ if (CurrentRevision != LatestRevision) {\r
+ AcquireSpinLock(&PeiCpuMpData->MpLock);\r
+ DEBUG ((EFI_D_ERROR, "Updated microcode signature [0x%08x] does not match \\r
+ loaded microcode signature [0x%08x]\n", CurrentRevision, LatestRevision));\r
+ ReleaseSpinLock(&PeiCpuMpData->MpLock);\r
}\r
}\r
}\r