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
MSR_IA32_PLATFORM_ID_REGISTER PlatformIdMsr;\r
UINT32 ProcessorFlags;\r
UINT32 ThreadId;\r
+ BOOLEAN IsBspCallIn;\r
\r
//\r
// set ProcessorFlags to suppress incorrect compiler/analyzer warnings\r
}\r
\r
CurrentRevision = GetCurrentMicrocodeSignature ();\r
+ IsBspCallIn = (ProcessorNumber == (UINTN)CpuMpData->BspNumber) ? TRUE : FALSE;\r
if (CurrentRevision != 0 && !IsBspCallIn) {\r
//\r
// Skip loading microcode if it has been loaded successfully\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
)\r
{\r
CPU_MP_DATA *CpuMpData;\r
+ UINTN ProcessorNumber;\r
+ EFI_STATUS Status;\r
\r
CpuMpData = (CPU_MP_DATA *) Buffer;\r
+ Status = GetProcessorNumber (CpuMpData, &ProcessorNumber);\r
+ ASSERT_EFI_ERROR (Status);\r
//\r
// Load microcode on AP\r
//\r
- MicrocodeDetect (CpuMpData, FALSE);\r
+ MicrocodeDetect (CpuMpData, ProcessorNumber);\r
//\r
// Sync BSP's MTRR table to AP\r
//\r
//\r
// Detect and apply Microcode on BSP\r
//\r
- MicrocodeDetect (CpuMpData, TRUE);\r
+ MicrocodeDetect (CpuMpData, CpuMpData->BspNumber);\r
//\r
// Store BSP's MTRR setting\r
//\r
EFI_EVENT WaitEvent;\r
UINT32 ProcessorSignature;\r
UINT8 PlatformId;\r
+ UINT64 MicrocodeEntryAddr;\r
} CPU_AP_DATA;\r
\r
//\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] 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
/**\r
VOID\r
);\r
\r
+/**\r
+ Find the current Processor number by APIC ID.\r
+\r
+ @param[in] CpuMpData Pointer to PEI CPU MP Data\r
+ @param[out] ProcessorNumber Return the pocessor number found\r
+\r
+ @retval EFI_SUCCESS ProcessorNumber is found and returned.\r
+ @retval EFI_NOT_FOUND ProcessorNumber is not found.\r
+**/\r
+EFI_STATUS\r
+GetProcessorNumber (\r
+ IN CPU_MP_DATA *CpuMpData,\r
+ OUT UINTN *ProcessorNumber\r
+ );\r
+\r
#endif\r
\r
\r
[Guids]\r
gEdkiiS3SmmInitDoneGuid\r
+ gEdkiiMicrocodePatchHobGuid\r
#include "MpLib.h"\r
#include <Library/PeiServicesLib.h>\r
#include <Guid/S3SmmInitDone.h>\r
+#include <Guid/MicrocodePatchHob.h>\r
\r
/**\r
S3 SMM Init Done notification function.\r
{\r
}\r
\r
+/**\r
+ Build the microcode patch HOB that contains the base address and size of the\r
+ microcode patch stored in the memory.\r
+\r
+ @param[in] CpuMpData Pointer to the CPU_MP_DATA structure.\r
+\r
+**/\r
+VOID\r
+BuildMicrocodeCacheHob (\r
+ IN CPU_MP_DATA *CpuMpData\r
+ )\r
+{\r
+ EDKII_MICROCODE_PATCH_HOB *MicrocodeHob;\r
+ UINTN HobDataLength;\r
+ UINT32 Index;\r
+\r
+ HobDataLength = sizeof (EDKII_MICROCODE_PATCH_HOB) +\r
+ sizeof (UINT64) * CpuMpData->CpuCount;\r
+\r
+ MicrocodeHob = AllocatePool (HobDataLength);\r
+ if (MicrocodeHob == NULL) {\r
+ ASSERT (FALSE);\r
+ return;\r
+ }\r
+\r
+ //\r
+ // Store the information of the memory region that holds the microcode patches.\r
+ //\r
+ MicrocodeHob->MicrocodePatchAddress = CpuMpData->MicrocodePatchAddress;\r
+ MicrocodeHob->MicrocodePatchRegionSize = CpuMpData->MicrocodePatchRegionSize;\r
+\r
+ //\r
+ // Store the detected microcode patch for each processor as well.\r
+ //\r
+ MicrocodeHob->ProcessorCount = CpuMpData->CpuCount;\r
+ for (Index = 0; Index < CpuMpData->CpuCount; Index++) {\r
+ if (CpuMpData->CpuData[Index].MicrocodeEntryAddr != 0) {\r
+ MicrocodeHob->ProcessorSpecificPatchOffset[Index] =\r
+ CpuMpData->CpuData[Index].MicrocodeEntryAddr - CpuMpData->MicrocodePatchAddress;\r
+ } else {\r
+ MicrocodeHob->ProcessorSpecificPatchOffset[Index] = MAX_UINT64;\r
+ }\r
+ }\r
+\r
+ BuildGuidDataHob (\r
+ &gEdkiiMicrocodePatchHobGuid,\r
+ MicrocodeHob,\r
+ HobDataLength\r
+ );\r
+\r
+ return;\r
+}\r
+\r
/**\r
Initialize global data for MP support.\r
\r
{\r
EFI_STATUS Status;\r
\r
+ BuildMicrocodeCacheHob (CpuMpData);\r
SaveCpuMpData (CpuMpData);\r
\r
///\r