UefiCpuPkg/MpInitLib: Use BSP uCode for APs if possible.
Search uCode costs much time, if AP has same processor type with BSP, AP can use BSP saved uCode info to get better performance. This change enables this solution. Cc: Laszlo Ersek <lersek@redhat.com> Cc: Ruiyu Ni <ruiyu.ni@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Eric Dong <eric.dong@intel.com> Acked-by: Laszlo Ersek <lersek@redhat.com> Regression-tested-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
This commit is contained in:
@@ -35,11 +35,13 @@ GetCurrentMicrocodeSignature (
|
||||
/**
|
||||
Detect whether specified processor can find matching microcode patch and load it.
|
||||
|
||||
@param[in] CpuMpData The pointer to CPU MP Data structure.
|
||||
@param[in] CpuMpData The pointer to CPU MP Data structure.
|
||||
@param[in] IsBspCallIn Indicate whether the caller is BSP or not.
|
||||
**/
|
||||
VOID
|
||||
MicrocodeDetect (
|
||||
IN CPU_MP_DATA *CpuMpData
|
||||
IN CPU_MP_DATA *CpuMpData,
|
||||
IN BOOLEAN IsBspCallIn
|
||||
)
|
||||
{
|
||||
UINT32 ExtendedTableLength;
|
||||
@@ -58,6 +60,7 @@ MicrocodeDetect (
|
||||
BOOLEAN CorrectMicrocode;
|
||||
VOID *MicrocodeData;
|
||||
MSR_IA32_PLATFORM_ID_REGISTER PlatformIdMsr;
|
||||
UINT32 ProcessorFlags;
|
||||
|
||||
if (CpuMpData->MicrocodePatchRegionSize == 0) {
|
||||
//
|
||||
@@ -67,7 +70,7 @@ MicrocodeDetect (
|
||||
}
|
||||
|
||||
CurrentRevision = GetCurrentMicrocodeSignature ();
|
||||
if (CurrentRevision != 0) {
|
||||
if (CurrentRevision != 0 && !IsBspCallIn) {
|
||||
//
|
||||
// Skip loading microcode if it has been loaded successfully
|
||||
//
|
||||
@@ -87,6 +90,19 @@ MicrocodeDetect (
|
||||
PlatformIdMsr.Uint64 = AsmReadMsr64 (MSR_IA32_PLATFORM_ID);
|
||||
PlatformId = (UINT8) PlatformIdMsr.Bits.PlatformId;
|
||||
|
||||
//
|
||||
// Check whether AP has same processor with BSP.
|
||||
// If yes, direct use microcode info saved by BSP.
|
||||
//
|
||||
if (!IsBspCallIn) {
|
||||
if ((CpuMpData->ProcessorSignature == Eax.Uint32) &&
|
||||
(CpuMpData->ProcessorFlags & (1 << PlatformId)) != 0) {
|
||||
MicrocodeData = (VOID *)(UINTN) CpuMpData->MicrocodeDataAddress;
|
||||
LatestRevision = CpuMpData->MicrocodeRevision;
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
|
||||
LatestRevision = 0;
|
||||
MicrocodeData = NULL;
|
||||
MicrocodeEnd = (UINTN) (CpuMpData->MicrocodePatchAddress + CpuMpData->MicrocodePatchRegionSize);
|
||||
@@ -117,6 +133,7 @@ MicrocodeDetect (
|
||||
}
|
||||
if (CheckSum32 == 0) {
|
||||
CorrectMicrocode = TRUE;
|
||||
ProcessorFlags = MicrocodeEntryPoint->ProcessorFlags;
|
||||
}
|
||||
} else if ((MicrocodeEntryPoint->DataSize != 0) &&
|
||||
(MicrocodeEntryPoint->UpdateRevision > LatestRevision)) {
|
||||
@@ -151,6 +168,7 @@ MicrocodeDetect (
|
||||
// Find one
|
||||
//
|
||||
CorrectMicrocode = TRUE;
|
||||
ProcessorFlags = ExtendedTable->ProcessorFlag;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -188,6 +206,7 @@ MicrocodeDetect (
|
||||
MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + TotalSize);
|
||||
} while (((UINTN) MicrocodeEntryPoint < MicrocodeEnd));
|
||||
|
||||
Done:
|
||||
if (LatestRevision > CurrentRevision) {
|
||||
//
|
||||
// BIOS only authenticate updates that contain a numerically larger revision
|
||||
@@ -211,4 +230,16 @@ MicrocodeDetect (
|
||||
ReleaseSpinLock(&CpuMpData->MpLock);
|
||||
}
|
||||
}
|
||||
|
||||
if (IsBspCallIn && (LatestRevision != 0)) {
|
||||
//
|
||||
// Save BSP processor info and microcode info for later AP use.
|
||||
//
|
||||
CpuMpData->ProcessorSignature = Eax.Uint32;
|
||||
CpuMpData->ProcessorFlags = ProcessorFlags;
|
||||
CpuMpData->MicrocodeDataAddress = (UINTN) MicrocodeData;
|
||||
CpuMpData->MicrocodeRevision = LatestRevision;
|
||||
DEBUG ((DEBUG_INFO, "BSP Microcode:: signature [0x%08x], ProcessorFlags [0x%08x], \
|
||||
MicroData [0x%08x], Revision [0x%08x]\n", Eax.Uint32, ProcessorFlags, (UINTN) MicrocodeData, LatestRevision));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user