[Patch v5 15/48] UefiCpuPkg/MpInitLib: Add MicrocodeDetect() and load microcode on BSP


Jeff Fan <jeff.fan@...>
 

v4:
1. ProcessorSignature is updated to CPU_MICROCODE_PROCESSOR_SIGNATURE
instead of UINT32.

Cc: Michael Kinney <michael.d.kinney@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Cc: Giri P Mudusuru <giri.p.mudusuru@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <jeff.fan@intel.com>
---
UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 1 +
.../{CpuMpPei => Library/MpInitLib}/Microcode.c | 77 +++++++++++-----------
UefiCpuPkg/Library/MpInitLib/MpLib.c | 5 ++
UefiCpuPkg/Library/MpInitLib/MpLib.h | 10 +++
UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 1 +
5 files changed, 57 insertions(+), 37 deletions(-)
copy UefiCpuPkg/{CpuMpPei => Library/MpInitLib}/Microcode.c (68%)

diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
index e9a2725..03a8994 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -39,6 +39,7 @@ [Sources.common]
DxeMpLib.c
MpLib.c
MpLib.h
+ Microcode.c

[Packages]
MdePkg/MdePkg.dec
diff --git a/UefiCpuPkg/CpuMpPei/Microcode.c b/UefiCpuPkg/Library/MpInitLib/Microcode.c
similarity index 68%
copy from UefiCpuPkg/CpuMpPei/Microcode.c
copy to UefiCpuPkg/Library/MpInitLib/Microcode.c
index 4fe6f2d..0fd8e8c 100644
--- a/UefiCpuPkg/CpuMpPei/Microcode.c
+++ b/UefiCpuPkg/Library/MpInitLib/Microcode.c
@@ -12,56 +12,55 @@

**/

-#include "CpuMpPei.h"
+#include "MpLib.h"

/**
Get microcode update signature of currently loaded microcode update.

@return Microcode signature.
-
**/
UINT32
GetCurrentMicrocodeSignature (
VOID
)
{
- UINT64 Signature;
+ MSR_IA32_BIOS_SIGN_ID_REGISTER BiosSignIdMsr;

- AsmWriteMsr64 (EFI_MSR_IA32_BIOS_SIGN_ID, 0);
+ AsmWriteMsr64 (MSR_IA32_BIOS_SIGN_ID, 0);
AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL);
- Signature = AsmReadMsr64 (EFI_MSR_IA32_BIOS_SIGN_ID);
- return (UINT32) RShiftU64 (Signature, 32);
+ BiosSignIdMsr.Uint64 = AsmReadMsr64 (MSR_IA32_BIOS_SIGN_ID);
+ return BiosSignIdMsr.Bits.MicrocodeUpdateSignature;
}

/**
Detect whether specified processor can find matching microcode patch and load it.

- @param PeiCpuMpData Pointer to PEI CPU MP Data
+ @param[in] PeiCpuMpData Pointer to PEI CPU MP Data
**/
VOID
MicrocodeDetect (
- IN PEI_CPU_MP_DATA *PeiCpuMpData
+ IN CPU_MP_DATA *CpuMpData
)
{
UINT64 MicrocodePatchAddress;
UINT64 MicrocodePatchRegionSize;
UINT32 ExtendedTableLength;
UINT32 ExtendedTableCount;
- EFI_CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable;
- EFI_CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader;
- EFI_CPU_MICROCODE_HEADER *MicrocodeEntryPoint;
+ CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable;
+ CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader;
+ CPU_MICROCODE_HEADER *MicrocodeEntryPoint;
UINTN MicrocodeEnd;
UINTN Index;
UINT8 PlatformId;
- UINT32 RegEax;
+ CPUID_VERSION_INFO_EAX Eax;
UINT32 CurrentRevision;
UINT32 LatestRevision;
UINTN TotalSize;
UINT32 CheckSum32;
BOOLEAN CorrectMicrocode;
- MICROCODE_INFO MicrocodeInfo;
+ VOID *MicrocodeData;
+ MSR_IA32_PLATFORM_ID_REGISTER PlatformIdMsr;

- ZeroMem (&MicrocodeInfo, sizeof (MICROCODE_INFO));
MicrocodePatchAddress = PcdGet64 (PcdCpuMicrocodePatchAddress);
MicrocodePatchRegionSize = PcdGet64 (PcdCpuMicrocodePatchRegionSize);
if (MicrocodePatchRegionSize == 0) {
@@ -82,18 +81,19 @@ MicrocodeDetect (
ExtendedTableLength = 0;
//
// Here data of CPUID leafs have not been collected into context buffer, so
- // GetProcessorCpuid() cannot be used here to retrieve CPUID data.
+ // GetProcessorCpuid() cannot be used here to retrieve sCPUID data.
//
- AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, NULL);
+ AsmCpuid (CPUID_VERSION_INFO, &Eax.Uint32, NULL, NULL, NULL);

//
// The index of platform information resides in bits 50:52 of MSR IA32_PLATFORM_ID
//
- PlatformId = (UINT8) AsmMsrBitFieldRead64 (EFI_MSR_IA32_PLATFORM_ID, 50, 52);
+ PlatformIdMsr.Uint64 = AsmReadMsr64 (MSR_IA32_PLATFORM_ID);
+ PlatformId = (UINT8) PlatformIdMsr.Bits.PlatformId;

LatestRevision = 0;
MicrocodeEnd = (UINTN) (MicrocodePatchAddress + MicrocodePatchRegionSize);
- MicrocodeEntryPoint = (EFI_CPU_MICROCODE_HEADER *) (UINTN) MicrocodePatchAddress;
+ MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (UINTN) MicrocodePatchAddress;
do {
//
// Check if the microcode is for the Cpu and the version is newer
@@ -106,44 +106,49 @@ MicrocodeDetect (
// because the padding data should not include 0x00000001 and it should be the repeated
// byte format (like 0xXYXYXYXY....).
//
- if (MicrocodeEntryPoint->ProcessorId == RegEax &&
+ if (MicrocodeEntryPoint->ProcessorSignature.Uint32 == Eax.Uint32 &&
MicrocodeEntryPoint->UpdateRevision > LatestRevision &&
(MicrocodeEntryPoint->ProcessorFlags & (1 << PlatformId))
) {
if (MicrocodeEntryPoint->DataSize == 0) {
- CheckSum32 = CalculateSum32 ((UINT32 *)MicrocodeEntryPoint, 2048);
+ CheckSum32 = CalculateSum32 ((UINT32 *) MicrocodeEntryPoint, 2048);
} else {
- CheckSum32 = CalculateSum32 ((UINT32 *)MicrocodeEntryPoint, MicrocodeEntryPoint->DataSize + sizeof(EFI_CPU_MICROCODE_HEADER));
+ CheckSum32 = CalculateSum32 (
+ (UINT32 *) MicrocodeEntryPoint,
+ MicrocodeEntryPoint->DataSize + sizeof (CPU_MICROCODE_HEADER)
+ );
}
if (CheckSum32 == 0) {
CorrectMicrocode = TRUE;
}
} else if ((MicrocodeEntryPoint->DataSize != 0) &&
(MicrocodeEntryPoint->UpdateRevision > LatestRevision)) {
- ExtendedTableLength = MicrocodeEntryPoint->TotalSize - (MicrocodeEntryPoint->DataSize + sizeof (EFI_CPU_MICROCODE_HEADER));
+ ExtendedTableLength = MicrocodeEntryPoint->TotalSize - (MicrocodeEntryPoint->DataSize +
+ sizeof (CPU_MICROCODE_HEADER));
if (ExtendedTableLength != 0) {
//
// Extended Table exist, check if the CPU in support list
//
- ExtendedTableHeader = (EFI_CPU_MICROCODE_EXTENDED_TABLE_HEADER *)((UINT8 *)(MicrocodeEntryPoint) + MicrocodeEntryPoint->DataSize + sizeof (EFI_CPU_MICROCODE_HEADER));
+ ExtendedTableHeader = (CPU_MICROCODE_EXTENDED_TABLE_HEADER *) ((UINT8 *) (MicrocodeEntryPoint)
+ + MicrocodeEntryPoint->DataSize + sizeof (CPU_MICROCODE_HEADER));
//
// Calculate Extended Checksum
//
if ((ExtendedTableLength % 4) == 0) {
- CheckSum32 = CalculateSum32 ((UINT32 *)ExtendedTableHeader, ExtendedTableLength);
+ CheckSum32 = CalculateSum32 ((UINT32 *) ExtendedTableHeader, ExtendedTableLength);
if (CheckSum32 == 0) {
//
// Checksum correct
//
ExtendedTableCount = ExtendedTableHeader->ExtendedSignatureCount;
- ExtendedTable = (EFI_CPU_MICROCODE_EXTENDED_TABLE *)(ExtendedTableHeader + 1);
+ ExtendedTable = (CPU_MICROCODE_EXTENDED_TABLE *) (ExtendedTableHeader + 1);
for (Index = 0; Index < ExtendedTableCount; Index ++) {
- CheckSum32 = CalculateSum32 ((UINT32 *)ExtendedTable, sizeof(EFI_CPU_MICROCODE_EXTENDED_TABLE));
+ CheckSum32 = CalculateSum32 ((UINT32 *) ExtendedTable, sizeof(CPU_MICROCODE_EXTENDED_TABLE));
if (CheckSum32 == 0) {
//
// Verify Header
//
- if ((ExtendedTable->ProcessorSignature == RegEax) &&
+ if ((ExtendedTable->ProcessorSignature.Uint32 == Eax.Uint32) &&
(ExtendedTable->ProcessorFlag & (1 << PlatformId)) ) {
//
// Find one
@@ -166,7 +171,7 @@ MicrocodeDetect (
// alignment value should be larger than 1-KByte. We could skip SIZE_1KB padding data to
// find the next possible microcode patch header.
//
- MicrocodeEntryPoint = (EFI_CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + SIZE_1KB);
+ MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + SIZE_1KB);
continue;
}
//
@@ -180,12 +185,10 @@ MicrocodeDetect (

if (CorrectMicrocode) {
LatestRevision = MicrocodeEntryPoint->UpdateRevision;
- MicrocodeInfo.MicrocodeData = (VOID *)((UINTN)MicrocodeEntryPoint + sizeof (EFI_CPU_MICROCODE_HEADER));
- MicrocodeInfo.MicrocodeSize = TotalSize;
- MicrocodeInfo.ProcessorId = RegEax;
+ MicrocodeData = (VOID *) ((UINTN) MicrocodeEntryPoint + sizeof (CPU_MICROCODE_HEADER));
}

- MicrocodeEntryPoint = (EFI_CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + TotalSize);
+ MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + TotalSize);
} while (((UINTN) MicrocodeEntryPoint < MicrocodeEnd));

if (LatestRevision > CurrentRevision) {
@@ -196,18 +199,18 @@ MicrocodeDetect (
// revision equal to zero.
//
AsmWriteMsr64 (
- EFI_MSR_IA32_BIOS_UPDT_TRIG,
- (UINT64) (UINTN) MicrocodeInfo.MicrocodeData
- );
+ MSR_IA32_BIOS_UPDT_TRIG,
+ (UINT64) (UINTN) MicrocodeData
+ );
//
// Get and check new microcode signature
//
CurrentRevision = GetCurrentMicrocodeSignature ();
if (CurrentRevision != LatestRevision) {
- AcquireSpinLock(&PeiCpuMpData->MpLock);
+ AcquireSpinLock(&CpuMpData->MpLock);
DEBUG ((EFI_D_ERROR, "Updated microcode signature [0x%08x] does not match \
loaded microcode signature [0x%08x]\n", CurrentRevision, LatestRevision));
- ReleaseSpinLock(&PeiCpuMpData->MpLock);
+ ReleaseSpinLock(&CpuMpData->MpLock);
}
}
}
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 0832228..7384f5d 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -294,6 +294,11 @@ MpInitLibInitialize (
CpuMpData->CpuData[Index].StartupApSignal =
(UINT32 *)(MonitorBuffer + MonitorFilterSize * Index);
}
+ //
+ // Load Microcode on BSP
+ //
+ MicrocodeDetect (CpuMpData);
+ //
// Store BSP's MTRR setting
//
MtrrGetAllMtrrs (&CpuMpData->MtrrTable);
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index ca8bd44..625d061 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -232,5 +232,15 @@ AsmGetAddressMap (
OUT MP_ASSEMBLY_ADDRESS_MAP *AddressMap
);

+/**
+ Detect whether specified processor can find matching microcode patch and load it.
+
+ @param[in] PeiCpuMpData Pointer to PEI CPU MP Data
+**/
+VOID
+MicrocodeDetect (
+ IN CPU_MP_DATA *CpuMpData
+ );
+
#endif

diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
index c195a38..0c6873d 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
@@ -39,6 +39,7 @@ [Sources.common]
PeiMpLib.c
MpLib.c
MpLib.h
+ Microcode.c

[Packages]
MdePkg/MdePkg.dec
--
2.7.4.windows.1