/** @file\r
Implementation of loading microcode on processors.\r
\r
- Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
It does not guarantee that the data has not been modified.\r
CPU has its own mechanism to verify Microcode Binary part.\r
\r
- @param[in] CpuMpData The pointer to CPU MP Data structure.\r
- @param[in] IsBspCallIn Indicate whether the caller is BSP or not.\r
+ @param[in] CpuMpData The pointer to CPU MP Data structure.\r
+ @param[in] ProcessorNumber The handle number of the processor. The range is\r
+ from 0 to the total number of logical processors\r
+ minus 1.\r
**/\r
VOID\r
MicrocodeDetect (\r
IN CPU_MP_DATA *CpuMpData,\r
- IN BOOLEAN IsBspCallIn\r
+ IN UINTN ProcessorNumber\r
)\r
{\r
UINT32 ExtendedTableLength;\r
UINTN Index;\r
UINT8 PlatformId;\r
CPUID_VERSION_INFO_EAX Eax;\r
+ CPU_AP_DATA *CpuData;\r
UINT32 CurrentRevision;\r
UINT32 LatestRevision;\r
UINTN TotalSize;\r
UINT32 InCompleteCheckSum32;\r
BOOLEAN CorrectMicrocode;\r
VOID *MicrocodeData;\r
- MSR_IA32_PLATFORM_ID_REGISTER PlatformIdMsr;\r
- UINT32 ProcessorFlags;\r
UINT32 ThreadId;\r
-\r
- //\r
- // set ProcessorFlags to suppress incorrect compiler/analyzer warnings\r
- //\r
- ProcessorFlags = 0;\r
+ BOOLEAN IsBspCallIn;\r
\r
if (CpuMpData->MicrocodePatchRegionSize == 0) {\r
//\r
}\r
\r
CurrentRevision = GetCurrentMicrocodeSignature ();\r
- if (CurrentRevision != 0 && !IsBspCallIn) {\r
- //\r
- // Skip loading microcode if it has been loaded successfully\r
- //\r
- return;\r
- }\r
+ IsBspCallIn = (ProcessorNumber == (UINTN)CpuMpData->BspNumber) ? TRUE : FALSE;\r
\r
GetProcessorLocationByApicId (GetInitialApicId (), NULL, NULL, &ThreadId);\r
if (ThreadId != 0) {\r
}\r
\r
ExtendedTableLength = 0;\r
- //\r
- // Here data of CPUID leafs have not been collected into context buffer, so\r
- // GetProcessorCpuid() cannot be used here to retrieve CPUID data.\r
- //\r
- AsmCpuid (CPUID_VERSION_INFO, &Eax.Uint32, NULL, NULL, NULL);\r
-\r
- //\r
- // The index of platform information resides in bits 50:52 of MSR IA32_PLATFORM_ID\r
- //\r
- PlatformIdMsr.Uint64 = AsmReadMsr64 (MSR_IA32_PLATFORM_ID);\r
- PlatformId = (UINT8) PlatformIdMsr.Bits.PlatformId;\r
+ Eax.Uint32 = CpuMpData->CpuData[ProcessorNumber].ProcessorSignature;\r
+ PlatformId = CpuMpData->CpuData[ProcessorNumber].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
+ // Get the CPU data for BSP\r
+ //\r
+ CpuData = &(CpuMpData->CpuData[CpuMpData->BspNumber]);\r
+ if ((CpuData->ProcessorSignature == Eax.Uint32) &&\r
+ (CpuData->PlatformId == PlatformId) &&\r
+ (CpuData->MicrocodeEntryAddr != 0)) {\r
+ MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *)(UINTN) CpuData->MicrocodeEntryAddr;\r
+ MicrocodeData = (VOID *) (MicrocodeEntryPoint + 1);\r
+ LatestRevision = MicrocodeEntryPoint->UpdateRevision;\r
+ goto Done;\r
}\r
}\r
\r
CheckSum32 += MicrocodeEntryPoint->Checksum;\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
} while (((UINTN) MicrocodeEntryPoint < MicrocodeEnd));\r
\r
Done:\r
+ if (LatestRevision != 0) {\r
+ //\r
+ // Save the detected microcode patch entry address (including the\r
+ // microcode patch header) for each processor.\r
+ // It will be used when building the microcode patch cache HOB.\r
+ //\r
+ CpuMpData->CpuData[ProcessorNumber].MicrocodeEntryAddr =\r
+ (UINTN) MicrocodeData - sizeof (CPU_MICROCODE_HEADER);\r
+ }\r
+\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
\r
/**\r
Patches[Index].Size\r
);\r
\r
- //\r
- // Zero-fill the padding area\r
- // Please note that AlignedSize will be no less than Size\r
- //\r
- ZeroMem (\r
- Walker + Patches[Index].Size,\r
- Patches[Index].AlignedSize - Patches[Index].Size\r
- );\r
-\r
- Walker += Patches[Index].AlignedSize;\r
+ Walker += Patches[Index].Size;\r
}\r
\r
//\r
//\r
// Store the information of this microcode patch\r
//\r
- if (TotalSize > ALIGN_VALUE (TotalSize, SIZE_1KB) ||\r
- ALIGN_VALUE (TotalSize, SIZE_1KB) > MAX_UINTN - TotalLoadSize) {\r
- goto OnExit;\r
- }\r
- PatchInfoBuffer[PatchCount - 1].Address = (UINTN) MicrocodeEntryPoint;\r
- PatchInfoBuffer[PatchCount - 1].Size = TotalSize;\r
- PatchInfoBuffer[PatchCount - 1].AlignedSize = ALIGN_VALUE (TotalSize, SIZE_1KB);\r
- TotalLoadSize += PatchInfoBuffer[PatchCount - 1].AlignedSize;\r
+ PatchInfoBuffer[PatchCount - 1].Address = (UINTN) MicrocodeEntryPoint;\r
+ PatchInfoBuffer[PatchCount - 1].Size = TotalSize;\r
+ TotalLoadSize += TotalSize;\r
}\r
\r
//\r