/**\r
Detect whether specified processor can find matching microcode patch and load it.\r
\r
- @param[in] CpuMpData The pointer to CPU MP Data structure.\r
+ @param[in] CpuMpData The pointer to CPU MP Data structure.\r
+ @param[in] IsBspCallIn Indicate whether the caller is BSP or not.\r
**/\r
VOID\r
MicrocodeDetect (\r
- IN CPU_MP_DATA *CpuMpData\r
+ IN CPU_MP_DATA *CpuMpData,\r
+ IN BOOLEAN IsBspCallIn\r
)\r
{\r
UINT32 ExtendedTableLength;\r
BOOLEAN CorrectMicrocode;\r
VOID *MicrocodeData;\r
MSR_IA32_PLATFORM_ID_REGISTER PlatformIdMsr;\r
+ UINT32 ProcessorFlags;\r
\r
if (CpuMpData->MicrocodePatchRegionSize == 0) {\r
//\r
}\r
\r
CurrentRevision = GetCurrentMicrocodeSignature ();\r
- if (CurrentRevision != 0) {\r
+ if (CurrentRevision != 0 && !IsBspCallIn) {\r
//\r
// Skip loading microcode if it has been loaded successfully\r
//\r
PlatformIdMsr.Uint64 = AsmReadMsr64 (MSR_IA32_PLATFORM_ID);\r
PlatformId = (UINT8) PlatformIdMsr.Bits.PlatformId;\r
\r
+ //\r
+ // Check whether AP has same processor with BSP.\r
+ // If yes, direct use microcode info saved by BSP.\r
+ //\r
+ if (!IsBspCallIn) {\r
+ if ((CpuMpData->ProcessorSignature == Eax.Uint32) &&\r
+ (CpuMpData->ProcessorFlags & (1 << PlatformId)) != 0) {\r
+ MicrocodeData = (VOID *)(UINTN) CpuMpData->MicrocodeDataAddress;\r
+ LatestRevision = CpuMpData->MicrocodeRevision;\r
+ goto Done;\r
+ }\r
+ }\r
+\r
LatestRevision = 0;\r
MicrocodeData = NULL;\r
MicrocodeEnd = (UINTN) (CpuMpData->MicrocodePatchAddress + CpuMpData->MicrocodePatchRegionSize);\r
}\r
if (CheckSum32 == 0) {\r
CorrectMicrocode = TRUE;\r
+ ProcessorFlags = MicrocodeEntryPoint->ProcessorFlags;\r
}\r
} else if ((MicrocodeEntryPoint->DataSize != 0) &&\r
(MicrocodeEntryPoint->UpdateRevision > LatestRevision)) {\r
// Find one\r
//\r
CorrectMicrocode = TRUE;\r
+ ProcessorFlags = ExtendedTable->ProcessorFlag;\r
break;\r
}\r
}\r
MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + TotalSize);\r
} while (((UINTN) MicrocodeEntryPoint < MicrocodeEnd));\r
\r
+Done:\r
if (LatestRevision > CurrentRevision) {\r
//\r
// BIOS only authenticate updates that contain a numerically larger revision\r
ReleaseSpinLock(&CpuMpData->MpLock);\r
}\r
}\r
+\r
+ if (IsBspCallIn && (LatestRevision != 0)) {\r
+ //\r
+ // Save BSP processor info and microcode info for later AP use.\r
+ //\r
+ CpuMpData->ProcessorSignature = Eax.Uint32;\r
+ CpuMpData->ProcessorFlags = ProcessorFlags;\r
+ CpuMpData->MicrocodeDataAddress = (UINTN) MicrocodeData;\r
+ CpuMpData->MicrocodeRevision = LatestRevision;\r
+ DEBUG ((DEBUG_INFO, "BSP Microcode:: signature [0x%08x], ProcessorFlags [0x%08x], \\r
+ MicroData [0x%08x], Revision [0x%08x]\n", Eax.Uint32, ProcessorFlags, (UINTN) MicrocodeData, LatestRevision));\r
+ }\r
}\r
BOOLEAN TimerInterruptState;\r
UINT64 MicrocodePatchAddress;\r
UINT64 MicrocodePatchRegionSize;\r
+\r
+ UINT32 ProcessorSignature;\r
+ UINT32 ProcessorFlags;\r
+ UINT64 MicrocodeDataAddress;\r
+ UINT32 MicrocodeRevision;\r
};\r
\r
extern EFI_GUID mCpuInitMpLibHobGuid;\r
/**\r
Detect whether specified processor can find matching microcode patch and load it.\r
\r
- @param[in] CpuMpData The pointer to CPU MP Data structure.\r
+ @param[in] CpuMpData The pointer to CPU MP Data structure.\r
+ @param[in] IsBspCallIn Indicate whether the caller is BSP or not.\r
**/\r
VOID\r
MicrocodeDetect (\r
- IN CPU_MP_DATA *CpuMpData\r
+ IN CPU_MP_DATA *CpuMpData,\r
+ IN BOOLEAN IsBspCallIn\r
);\r
\r
/**\r