From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by ml01.01.org (Postfix) with ESMTP id D611A1A1E5A for ; Fri, 29 Jul 2016 11:15:36 -0700 (PDT) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga103.jf.intel.com with ESMTP; 29 Jul 2016 11:15:38 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.28,440,1464678000"; d="scan'208";a="1016339113" Received: from jfan12-desk.ccr.corp.intel.com ([10.239.9.5]) by fmsmga001.fm.intel.com with ESMTP; 29 Jul 2016 11:15:35 -0700 From: Jeff Fan To: edk2-devel@ml01.01.org Cc: Michael Kinney , Feng Tian , Giri P Mudusuru , Laszlo Ersek Date: Sat, 30 Jul 2016 02:14:41 +0800 Message-Id: <1469816112-8200-16-git-send-email-jeff.fan@intel.com> X-Mailer: git-send-email 2.7.4.windows.1 In-Reply-To: <1469816112-8200-1-git-send-email-jeff.fan@intel.com> References: <1469816112-8200-1-git-send-email-jeff.fan@intel.com> Subject: [Patch v4 15/46] UefiCpuPkg/MpInitLib: Add MicrocodeDetect() and load microcode on BSP X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 29 Jul 2016 18:15:37 -0000 v4: 1. ProcessorSignature is updated to CPU_MICROCODE_PROCESSOR_SIGNATURE instead of UINT32. Cc: Michael Kinney Cc: Feng Tian Cc: Giri P Mudusuru Cc: Laszlo Ersek Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jeff Fan --- 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 a455896..42713f0 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -212,5 +212,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