From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 1A469818F0 for ; Tue, 27 Dec 2016 17:41:09 -0800 (PST) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP; 27 Dec 2016 17:41:08 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.33,419,1477983600"; d="scan'208";a="1087294322" Received: from fmsmsx103.amr.corp.intel.com ([10.18.124.201]) by fmsmga001.fm.intel.com with ESMTP; 27 Dec 2016 17:41:08 -0800 Received: from fmsmsx151.amr.corp.intel.com (10.18.125.4) by FMSMSX103.amr.corp.intel.com (10.18.124.201) with Microsoft SMTP Server (TLS) id 14.3.248.2; Tue, 27 Dec 2016 17:41:08 -0800 Received: from shsmsx103.ccr.corp.intel.com (10.239.4.69) by FMSMSX151.amr.corp.intel.com (10.18.125.4) with Microsoft SMTP Server (TLS) id 14.3.248.2; Tue, 27 Dec 2016 17:41:01 -0800 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.88]) by SHSMSX103.ccr.corp.intel.com ([10.239.4.69]) with mapi id 14.03.0248.002; Wed, 28 Dec 2016 09:41:00 +0800 From: "Fan, Jeff" To: "Yao, Jiewen" , "edk2-devel@lists.01.org" CC: "Zeng, Star" Thread-Topic: [PATCH 2/2] UefiCpuPkg/MicrocodeUpdate: Add MP support. Thread-Index: AQHSYBX4ULZIcuK9FU6FTA0Fj7Af7qEclccg Date: Wed, 28 Dec 2016 01:40:59 +0000 Message-ID: <542CF652F8836A4AB8DBFAAD40ED192A4C5061B7@shsmsx102.ccr.corp.intel.com> References: <1482825026-3224-1-git-send-email-jiewen.yao@intel.com> <1482825026-3224-3-git-send-email-jiewen.yao@intel.com> In-Reply-To: <1482825026-3224-3-git-send-email-jiewen.yao@intel.com> Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiMDNmNmI4MDAtY2ZiZC00ZGNiLWI2MTUtNTAxY2JiYTI2NmRiIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX0lDIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE1LjkuNi42IiwiVHJ1c3RlZExhYmVsSGFzaCI6IitFdm55YnpmM3c4VDdcL1I3NXVHcmNPZVczZWJYOEFMc0FTT3Ztb3g5Zm1rPSJ9 x-ctpclassification: CTP_IC x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH 2/2] UefiCpuPkg/MicrocodeUpdate: Add MP support. 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: Wed, 28 Dec 2016 01:41:09 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Jeff Fan -----Original Message----- From: Yao, Jiewen=20 Sent: Tuesday, December 27, 2016 3:50 PM To: edk2-devel@lists.01.org Cc: Fan, Jeff; Zeng, Star Subject: [PATCH 2/2] UefiCpuPkg/MicrocodeUpdate: Add MP support. Support the case that BSP and AP are using different Microcode. The previous logic validates new MCU on BSP only. The enhanced logic will validate MCU on every BSP and AP. As long as one processor loads the MCU successfully, it will be updated. Cc: Jeff Fan Cc: Star Zeng Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiewen Yao --- UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeFmp.c | 182= +++++++++++ UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.c | 344= +++++++++++--------- UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.h | 71= +++- UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.inf | 4= +- 4 files changed, 451 insertions(+), 150 deletions(-) diff --git a/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeFmp.c b= /UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeFmp.c index 97f2f35..242167e 100644 --- a/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeFmp.c +++ b/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeFmp.c @@ -414,6 +414,47 @@ FmpSetPackageInfo ( } =20 /** + Initialize Processor Microcode Index. + + @param[in] MicrocodeFmpPrivate private data structure to be initialized. +**/ +VOID +InitializedProcessorMicrocodeIndex ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate + ) +{ + UINTN CpuIndex; + UINTN MicrocodeIndex; + UINTN TargetCpuIndex; + UINT32 AttemptStatus; + EFI_STATUS Status; + + for (CpuIndex =3D 0; CpuIndex < MicrocodeFmpPrivate->ProcessorCount; Cpu= Index++) { + if (MicrocodeFmpPrivate->ProcessorInfo[CpuIndex].MicrocodeIndex !=3D (= UINTN)-1) { + continue; + } + for (MicrocodeIndex =3D 0; MicrocodeIndex < MicrocodeFmpPrivate->Descr= iptorCount; MicrocodeIndex++) { + if (!MicrocodeFmpPrivate->MicrocodeInfo[MicrocodeIndex].InUse) { + continue; + } + TargetCpuIndex =3D CpuIndex; + Status =3D VerifyMicrocode( + MicrocodeFmpPrivate, + MicrocodeFmpPrivate->MicrocodeInfo[MicrocodeIndex].Microc= odeEntryPoint, + MicrocodeFmpPrivate->MicrocodeInfo[MicrocodeIndex].TotalS= ize, + FALSE, + &AttemptStatus, + NULL, + &TargetCpuIndex + ); + if (!EFI_ERROR(Status)) { + MicrocodeFmpPrivate->ProcessorInfo[CpuIndex].MicrocodeIndex =3D Mi= crocodeIndex; + } + } + } +} + +/** Initialize Microcode Descriptor. =20 @param[in] MicrocodeFmpPrivate private data structure to be initialized. @@ -461,10 +502,139 @@ InitializeMicrocodeDescriptor ( CurrentMicrocodeCount =3D (UINT8)GetMicrocodeInfo (MicrocodeFmpPrivate, = MicrocodeFmpPrivate->DescriptorCount, MicrocodeFmpPrivate->ImageDescriptor,= MicrocodeFmpPrivate->MicrocodeInfo); ASSERT(CurrentMicrocodeCount =3D=3D MicrocodeFmpPrivate->DescriptorCount= ); =20 + InitializedProcessorMicrocodeIndex (MicrocodeFmpPrivate); + + return EFI_SUCCESS; +} + +/** + Initialize MicrocodeFmpDriver multiprocessor information. + + @param[in] MicrocodeFmpPrivate private data structure to be initialized. + + @return EFI_SUCCESS private data is initialized. +**/ +EFI_STATUS +InitializeProcessorInfo ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate + ) +{ + EFI_STATUS Status; + EFI_MP_SERVICES_PROTOCOL *MpService; + UINTN NumberOfProcessors; + UINTN NumberOfEnabledProcessors; + UINTN Index; + UINTN BspIndex; + + Status =3D gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID= =20 + **)&MpService); ASSERT_EFI_ERROR(Status); + + MicrocodeFmpPrivate->MpService =3D MpService; =20 + MicrocodeFmpPrivate->ProcessorCount =3D 0; =20 + MicrocodeFmpPrivate->ProcessorInfo =3D NULL; + + Status =3D MpService->GetNumberOfProcessors (MpService,=20 + &NumberOfProcessors, &NumberOfEnabledProcessors); =20 + ASSERT_EFI_ERROR(Status); MicrocodeFmpPrivate->ProcessorCount =3D=20 + NumberOfProcessors; + + Status =3D MpService->WhoAmI (MpService, &BspIndex); =20 + ASSERT_EFI_ERROR(Status); MicrocodeFmpPrivate->BspIndex =3D BspIndex; + + MicrocodeFmpPrivate->ProcessorInfo =3D AllocateZeroPool=20 + (sizeof(PROCESSOR_INFO) * MicrocodeFmpPrivate->ProcessorCount); + if (MicrocodeFmpPrivate->ProcessorInfo =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + for (Index =3D 0; Index < NumberOfProcessors; Index++) { + MicrocodeFmpPrivate->ProcessorInfo[Index].CpuIndex =3D Index; + MicrocodeFmpPrivate->ProcessorInfo[Index].MicrocodeIndex =3D (UINTN)-1= ; + if (Index =3D=3D BspIndex) { + CollectProcessorInfo (&MicrocodeFmpPrivate->ProcessorInfo[Index]); + } else { + Status =3D MpService->StartupThisAP ( + MpService, + CollectProcessorInfo, + Index, + NULL, + 0, + &MicrocodeFmpPrivate->ProcessorInfo[Index], + NULL + ); + ASSERT_EFI_ERROR(Status); + } + } + return EFI_SUCCESS; } =20 /** + Dump private information. +**/ +VOID +DumpPrivateInfo ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate + ) +{ + UINTN Index; + PROCESSOR_INFO *ProcessorInfo; + MICROCODE_INFO *MicrocodeInfo; + EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageDescriptor; + + DEBUG ((DEBUG_INFO, "ProcessorInfo:\n")); DEBUG ((DEBUG_INFO, " =20 + ProcessorCount - 0x%x\n", MicrocodeFmpPrivate->ProcessorCount)); + DEBUG ((DEBUG_INFO, " BspIndex - 0x%x\n",=20 + MicrocodeFmpPrivate->BspIndex)); + + ProcessorInfo =3D MicrocodeFmpPrivate->ProcessorInfo; + for (Index =3D 0; Index < MicrocodeFmpPrivate->ProcessorCount; Index++) = { + DEBUG (( + DEBUG_INFO, + " ProcessorInfo[0x%x] - 0x%08x, 0x%02x, 0x%08x, (0x%x)\n", + ProcessorInfo[Index].CpuIndex, + ProcessorInfo[Index].ProcessorSignature, + ProcessorInfo[Index].PlatformId, + ProcessorInfo[Index].MicrocodeRevision, + ProcessorInfo[Index].MicrocodeIndex + )); + } + + DEBUG ((DEBUG_INFO, "MicrocodeInfo:\n")); MicrocodeInfo =3D=20 + MicrocodeFmpPrivate->MicrocodeInfo; + DEBUG ((DEBUG_INFO, " MicrocodeRegion - 0x%x - 0x%x\n",=20 + MicrocodeFmpPrivate->MicrocodePatchAddress,=20 + MicrocodeFmpPrivate->MicrocodePatchRegionSize)); + DEBUG ((DEBUG_INFO, " MicrocodeCount - 0x%x\n",=20 + MicrocodeFmpPrivate->DescriptorCount)); + for (Index =3D 0; Index < MicrocodeFmpPrivate->DescriptorCount; Index++)= { + DEBUG (( + DEBUG_INFO, + " MicrocodeInfo[0x%x] - 0x%08x, 0x%08x, (0x%x)\n", + Index, + MicrocodeInfo[Index].MicrocodeEntryPoint, + MicrocodeInfo[Index].TotalSize, + MicrocodeInfo[Index].InUse + )); + } + + ImageDescriptor =3D MicrocodeFmpPrivate->ImageDescriptor; + DEBUG ((DEBUG_VERBOSE, "ImageDescriptor:\n")); + for (Index =3D 0; Index < MicrocodeFmpPrivate->DescriptorCount; Index++)= { + DEBUG((DEBUG_VERBOSE, " ImageDescriptor (%d)\n", Index)); + DEBUG((DEBUG_VERBOSE, " ImageIndex - 0x%x\n", Imag= eDescriptor[Index].ImageIndex)); + DEBUG((DEBUG_VERBOSE, " ImageTypeId - %g\n", &Image= Descriptor[Index].ImageTypeId)); + DEBUG((DEBUG_VERBOSE, " ImageId - 0x%lx\n", Ima= geDescriptor[Index].ImageId)); + DEBUG((DEBUG_VERBOSE, " ImageIdName - %s\n", ImageD= escriptor[Index].ImageIdName)); + DEBUG((DEBUG_VERBOSE, " Version - 0x%x\n", Imag= eDescriptor[Index].Version)); + DEBUG((DEBUG_VERBOSE, " VersionName - %s\n", ImageD= escriptor[Index].VersionName)); + DEBUG((DEBUG_VERBOSE, " Size - 0x%x\n", Imag= eDescriptor[Index].Size)); + DEBUG((DEBUG_VERBOSE, " AttributesSupported - 0x%lx\n", Ima= geDescriptor[Index].AttributesSupported)); + DEBUG((DEBUG_VERBOSE, " AttributesSetting - 0x%lx\n", Ima= geDescriptor[Index].AttributesSetting)); + DEBUG((DEBUG_VERBOSE, " Compatibilities - 0x%lx\n", Ima= geDescriptor[Index].Compatibilities)); + DEBUG((DEBUG_VERBOSE, " LowestSupportedImageVersion - 0x%x\n", Imag= eDescriptor[Index].LowestSupportedImageVersion)); + DEBUG((DEBUG_VERBOSE, " LastAttemptVersion - 0x%x\n", Imag= eDescriptor[Index].LastAttemptVersion)); + DEBUG((DEBUG_VERBOSE, " LastAttemptStatus - 0x%x\n", Imag= eDescriptor[Index].LastAttemptStatus)); + DEBUG((DEBUG_VERBOSE, " HardwareInstance - 0x%lx\n", Ima= geDescriptor[Index].HardwareInstance)); + } +} + +/** Initialize MicrocodeFmpDriver private data structure. =20 @param[in] MicrocodeFmpPrivate private data structure to be initialized. @@ -507,7 +677,19 @@ InitializePrivateData ( return EFI_NOT_FOUND; } =20 + Status =3D InitializeProcessorInfo (MicrocodeFmpPrivate); if=20 + (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "InitializeProcessorInfo - %r\n", Status)); + return Status; + } + Status =3D InitializeMicrocodeDescriptor(MicrocodeFmpPrivate); + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "InitializeMicrocodeDescriptor - %r\n", Status)); + return Status; + } + + DumpPrivateInfo (MicrocodeFmpPrivate); =20 return Status; } diff --git a/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.= c b/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.c index 46739ba..e26bcdc 100644 --- a/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.c +++ b/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.c @@ -21,36 +21,6 @@ =20 #include "MicrocodeUpdate.h" =20 - -/** - Verify Microcode. - - Caution: This function may receive untrusted input. - - @param[in] Image The Microcode image buffer. - @param[in] ImageSize The size of Microcode image buffer in byt= es. - @param[in] TryLoad Try to load Microcode or not. - @param[out] LastAttemptStatus The last attempt status, which will be re= corded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. - @param[out] AbortReason A pointer to a pointer to a null-terminat= ed string providing more - details for the aborted operation. The bu= ffer is allocated by this function - with AllocatePool(), and it is the caller= 's responsibility to free it with a - call to FreePool(). - - @retval EFI_SUCCESS The Microcode image passes verificatio= n. - @retval EFI_VOLUME_CORRUPTED The Microcode image is corrupt. - @retval EFI_INCOMPATIBLE_VERSION The Microcode image version is incorre= ct. - @retval EFI_UNSUPPORTED The Microcode ProcessorSignature or Pr= ocessorFlags is incorrect. - @retval EFI_SECURITY_VIOLATION The Microcode image fails to load. -**/ -EFI_STATUS -VerifyMicrocode ( - IN VOID *Image, - IN UINTN ImageSize, - IN BOOLEAN TryLoad, - OUT UINT32 *LastAttemptStatus, - OUT CHAR16 **AbortReason - ); - /** Get Microcode Region. =20 @@ -144,46 +114,92 @@ LoadMicrocode ( } =20 /** - If the Microcode is used by current processor. + Load Microcode on an Application Processor. + The function prototype for invoking a function on an Application Process= or. + + @param[in,out] Buffer The pointer to private data buffer. +**/ +VOID +EFIAPI +MicrocodeLoadAp ( + IN OUT VOID *Buffer + ) +{ + MICROCODE_LOAD_BUFFER *MicrocodeLoadBuffer; + + MicrocodeLoadBuffer =3D Buffer; + MicrocodeLoadBuffer->Revision =3D LoadMicrocode=20 +(MicrocodeLoadBuffer->Address); } + +/** + Load new Microcode on this processor =20 - @param[in] MicrocodeEntryPoint The Microcode buffer + @param[in] MicrocodeFmpPrivate The Microcode driver private data + @param[in] CpuIndex The index of the processor. + @param[in] Address The address of new Microcode. + + @return Loaded Microcode signature. =20 - @retval TRUE The Microcode is used by current processor. - @retval FALSE The Microcode is NOT used by current processor. **/ -BOOLEAN -IsMicrocodeInUse ( - IN CPU_MICROCODE_HEADER *MicrocodeEntryPoint +UINT32 +LoadMicrocodeOnThis ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, + IN UINTN CpuIndex, + IN UINT64 Address ) { - UINT32 AttemptStatus; - UINTN TotalSize; - EFI_STATUS Status; + EFI_STATUS Status; + EFI_MP_SERVICES_PROTOCOL *MpService; + MICROCODE_LOAD_BUFFER MicrocodeLoadBuffer; =20 - if (MicrocodeEntryPoint->HeaderVersion =3D=3D 0x1 && MicrocodeEntryPoint= ->LoaderRevision =3D=3D 0x1) { - // - // It is the microcode header. It is not the padding data between micr= ocode patches - // becasue the padding data should not include 0x00000001 and it shoul= d be the repeated - // byte format (like 0xXYXYXYXY....). - // - if (MicrocodeEntryPoint->DataSize =3D=3D 0) { - TotalSize =3D 2048; - } else { - TotalSize =3D MicrocodeEntryPoint->TotalSize; - } - Status =3D VerifyMicrocode(MicrocodeEntryPoint, TotalSize, FALSE, &Att= emptStatus, NULL); - if (!EFI_ERROR(Status)) { - return TRUE; - } + if (CpuIndex =3D=3D MicrocodeFmpPrivate->BspIndex) { + return LoadMicrocode (Address); + } else { + MpService =3D MicrocodeFmpPrivate->MpService; + MicrocodeLoadBuffer.Address =3D Address; + MicrocodeLoadBuffer.Revision =3D 0; + Status =3D MpService->StartupThisAP ( + MpService, + MicrocodeLoadAp, + CpuIndex, + NULL, + 0, + &MicrocodeLoadBuffer, + NULL + ); + ASSERT_EFI_ERROR(Status); + return MicrocodeLoadBuffer.Revision; } - return FALSE; +} + +/** + Collect processor information. + The function prototype for invoking a function on an Application Process= or. + + @param[in,out] Buffer The pointer to private data buffer. +**/ +VOID +EFIAPI +CollectProcessorInfo ( + IN OUT VOID *Buffer + ) +{ + PROCESSOR_INFO *ProcessorInfo; + + ProcessorInfo =3D Buffer; + ProcessorInfo->ProcessorSignature =3D GetCurrentProcessorSignature(); =20 + ProcessorInfo->PlatformId =3D GetCurrentPlatformId(); =20 + ProcessorInfo->MicrocodeRevision =3D GetCurrentMicrocodeSignature(); } =20 /** Get current Microcode information. =20 - NOTE: The DescriptorCount/ImageDescriptor/MicrocodeInfo in MicrocodeFmpP= rivate - are not avaiable in this function. + The ProcessorInformation (BspIndex/ProcessorCount/ProcessorInfo) + in MicrocodeFmpPrivate must be initialized. + + The MicrocodeInformation=20 + (DescriptorCount/ImageDescriptor/MicrocodeInfo) + in MicrocodeFmpPrivate may not be avaiable in this function. =20 @param[in] MicrocodeFmpPrivate The Microcode driver private dat= a @param[in] DescriptorCount The count of Microcode ImageDesc= riptor allocated. @@ -208,6 +224,9 @@ GetMicrocodeInfo ( UINTN Count; UINT64 ImageAttributes; BOOLEAN IsInUse; + EFI_STATUS Status; + UINT32 AttemptStatus; + UINTN TargetCpuIndex; =20 MicrocodePatchAddress =3D MicrocodeFmpPrivate->MicrocodePatchAddress; MicrocodePatchRegionSize =3D MicrocodeFmpPrivate->MicrocodePatchRegionSi= ze; @@ -231,7 +250,15 @@ GetMicrocodeInfo ( TotalSize =3D MicrocodeEntryPoint->TotalSize; } =20 - IsInUse =3D IsMicrocodeInUse (MicrocodeEntryPoint); + TargetCpuIndex =3D (UINTN)-1; + Status =3D VerifyMicrocode(MicrocodeFmpPrivate, MicrocodeEntryPoint,= TotalSize, FALSE, &AttemptStatus, NULL, &TargetCpuIndex); + if (!EFI_ERROR(Status)) { + IsInUse =3D TRUE; + ASSERT (TargetCpuIndex < MicrocodeFmpPrivate->ProcessorCount); + MicrocodeFmpPrivate->ProcessorInfo[TargetCpuIndex].MicrocodeIndex = =3D Count; + } else { + IsInUse =3D FALSE; + } =20 if (ImageDescriptor !=3D NULL && DescriptorCount > Count) { ImageDescriptor[Count].ImageIndex =3D (UINT8)(Count + 1); @@ -283,= 18 +310,62 @@ GetMicrocodeInfo ( } =20 /** + Return matched processor information. + + @param[in] MicrocodeFmpPrivate The Microcode driver private data + @param[in] ProcessorSignature The processor signature to be mat= ched + @param[in] ProcessorFlags The processor flags to be matched + @param[in, out] TargetCpuIndex On input, the index of target CPU= which tries to match the Microcode. (UINTN)-1 means to try all. + On output, the index of target CP= U which matches the Microcode. + + @return matched processor information. +**/ +PROCESSOR_INFO * +GetMatchedProcessor ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, + IN UINT32 ProcessorSignature, + IN UINT32 ProcessorFlags, + IN OUT UINTN *TargetCpuIndex + ) +{ + UINTN Index; + + if (*TargetCpuIndex !=3D (UINTN)-1) { + Index =3D *TargetCpuIndex; + if ((ProcessorSignature =3D=3D MicrocodeFmpPrivate->ProcessorInfo[Inde= x].ProcessorSignature) && + ((ProcessorFlags & (1 << MicrocodeFmpPrivate->ProcessorInfo[Index]= .PlatformId)) !=3D 0)) { + return &MicrocodeFmpPrivate->ProcessorInfo[Index]; + } else { + return NULL; + } + } + + for (Index =3D 0; Index < MicrocodeFmpPrivate->ProcessorCount; Index++) = { + if ((ProcessorSignature =3D=3D MicrocodeFmpPrivate->ProcessorInfo[Inde= x].ProcessorSignature) && + ((ProcessorFlags & (1 << MicrocodeFmpPrivate->ProcessorInfo[Index]= .PlatformId)) !=3D 0)) { + *TargetCpuIndex =3D Index; + return &MicrocodeFmpPrivate->ProcessorInfo[Index]; + } + } + return NULL; +} + +/** Verify Microcode. =20 Caution: This function may receive untrusted input. =20 - @param[in] Image The Microcode image buffer. - @param[in] ImageSize The size of Microcode image buffer in byt= es. - @param[in] TryLoad Try to load Microcode or not. - @param[out] LastAttemptStatus The last attempt status, which will be re= corded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. - @param[out] AbortReason A pointer to a pointer to a null-terminat= ed string providing more - details for the aborted operation. The bu= ffer is allocated by this function - with AllocatePool(), and it is the caller= 's responsibility to free it with a - call to FreePool(). + @param[in] MicrocodeFmpPrivate The Microcode driver private data + @param[in] Image The Microcode image buffer. + @param[in] ImageSize The size of Microcode image buffe= r in bytes. + @param[in] TryLoad Try to load Microcode or not. + @param[out] LastAttemptStatus The last attempt status, which wi= ll be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. + @param[out] AbortReason A pointer to a pointer to a null-= terminated string providing more + details for the aborted operation= . The buffer is allocated by this function + with AllocatePool(), and it is th= e caller's responsibility to free it with a + call to FreePool(). + @param[in, out] TargetCpuIndex On input, the index of target CPU= which tries to match the Microcode. (UINTN)-1 means to try all. + On output, the index of target CP= U which matches the Microcode. =20 @retval EFI_SUCCESS The Microcode image passes verificatio= n. @retval EFI_VOLUME_CORRUPTED The Microcode image is corrupt. @@ -304,11 +375,13 @@ GetMicrocodeInfo ( **/ EFI_STATUS VerifyMicrocode = ( - IN VOID *Image, - IN UINTN ImageSize, - IN BOOLEAN TryLoad, - OUT UINT32 *LastAttemptStatus, - OUT CHAR16 **AbortReason + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, + IN VOID *Image, + IN UINTN ImageSize, + IN BOOLEAN TryLoad, + OUT UINT32 *LastAttemptStatus, + OUT CHAR16 **AbortReason, OPTIONAL + IN OUT UINTN *TargetCpuIndex ) { UINTN Index; @@ -316,8 +389,7 @@ VerifyMicrocode ( UINTN TotalSize; UINTN DataSize; UINT32 CurrentRevision; - UINT32 CurrentProcessorSignature; - UINT8 CurrentPlatformId; + PROCESSOR_INFO *ProcessorInfo; UINT32 CheckSum32; UINTN ExtendedTableLength; UINT32 ExtendedTableCount; @@ -409,11 +481,10 @@ VerifyMicrocode ( // // Check ProcessorSignature/ProcessorFlags // - CorrectMicrocode =3D FALSE; - CurrentProcessorSignature =3D GetCurrentProcessorSignature(); - CurrentPlatformId =3D GetCurrentPlatformId(); - if ((MicrocodeEntryPoint->ProcessorSignature.Uint32 !=3D CurrentProcesso= rSignature) || - ((MicrocodeEntryPoint->ProcessorFlags & (1 << CurrentPlatformId)) = =3D=3D 0)) { + + ProcessorInfo =3D GetMatchedProcessor (MicrocodeFmpPrivate,=20 + MicrocodeEntryPoint->ProcessorSignature.Uint32, MicrocodeEntryPoint->Proc= essorFlags, TargetCpuIndex); if (ProcessorInfo =3D=3D NULL) { + CorrectMicrocode =3D FALSE; ExtendedTableLength =3D TotalSize - (DataSize + sizeof(CPU_MICROCODE_H= EADER)); if (ExtendedTableLength !=3D 0) { // @@ -438,8 +509,8 @@ VerifyMicrocode ( // // Verify Header // - if ((ExtendedTable->ProcessorSignature.Uint32 =3D=3D Curre= ntProcessorSignature) && - (ExtendedTable->ProcessorFlag & (1 << CurrentPlatformI= d))) { + ProcessorInfo =3D GetMatchedProcessor (MicrocodeFmpPrivate= , ExtendedTable->ProcessorSignature.Uint32, ExtendedTable->ProcessorFlag, T= argetCpuIndex); + if (ProcessorInfo !=3D NULL) { // // Find one // @@ -459,11 +530,7 @@ VerifyMicrocode ( } *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_ERROR_INCORRECT_VERSION; if (AbortReason !=3D NULL) { - if (MicrocodeEntryPoint->ProcessorSignature.Uint32 !=3D CurrentPro= cessorSignature) { - *AbortReason =3D AllocateCopyPool(sizeof(L"UnsupportedProcessSig= nature"), L"UnsupportedProcessSignature"); - } else { - *AbortReason =3D AllocateCopyPool(sizeof(L"UnsupportedProcessorF= lags"), L"UnsupportedProcessorFlags"); - } + *AbortReason =3D=20 + AllocateCopyPool(sizeof(L"UnsupportedProcessSignature/ProcessorFlags") + , L"UnsupportedProcessSignature/ProcessorFlags"); } return EFI_UNSUPPORTED; } @@ -472,7 +539,7 @@ VerifyMicrocode ( // // Check UpdateRevision // - CurrentRevision =3D GetCurrentMicrocodeSignature(); + CurrentRevision =3D ProcessorInfo->MicrocodeRevision; if (MicrocodeEntryPoint->UpdateRevision < CurrentRevision) { if (TryLoad) { DEBUG((DEBUG_ERROR, "VerifyMicrocode - fail on UpdateRevision\n")); = @@ -488,7 +555,7 @@ VerifyMicrocode ( // try load MCU // if (TryLoad) { - CurrentRevision =3D LoadMicrocode((UINTN)MicrocodeEntryPoint + sizeof(= CPU_MICROCODE_HEADER)); + CurrentRevision =3D LoadMicrocodeOnThis(MicrocodeFmpPrivate,=20 + ProcessorInfo->CpuIndex, (UINTN)MicrocodeEntryPoint +=20 + sizeof(CPU_MICROCODE_HEADER)); if (MicrocodeEntryPoint->UpdateRevision !=3D CurrentRevision) { DEBUG((DEBUG_ERROR, "VerifyMicrocode - fail on LoadMicrocode\n")); *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_ERROR_AUTH_ERROR; @@ -503,31 +570,6 @@ VerifyMicrocode ( } =20 /** - Get current Microcode in used. - - @param[in] MicrocodeFmpPrivate The Microcode driver private data - - @return current Microcode in used. -**/ -VOID * -GetCurrentMicrocodeInUse ( - IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate - ) -{ - UINTN Index; - - for (Index =3D 0; Index < MicrocodeFmpPrivate->DescriptorCount; Index++)= { - if (!MicrocodeFmpPrivate->MicrocodeInfo[Index].InUse) { - continue; - } - if (IsMicrocodeInUse (MicrocodeFmpPrivate->MicrocodeInfo[Index].Microc= odeEntryPoint)) { - return MicrocodeFmpPrivate->MicrocodeInfo[Index].MicrocodeEntryPoint= ; - } - } - return NULL; -} - -/** Get next Microcode entrypoint. =20 @param[in] MicrocodeFmpPrivate The Microcode driver private data @@ -622,7 +664,7 @@ UpdateMicrocode ( Update Microcode flash region. =20 @param[in] MicrocodeFmpPrivate The Microcode driver private data - @param[in] CurrentMicrocodeEntryPoint Current Microcode entrypoint + @param[in] TargetMicrocodeEntryPoint Target Microcode entrypoint to=20 + be updated @param[in] Image The Microcode image buffer. @param[in] ImageSize The size of Microcode image buffe= r in bytes. @param[out] LastAttemptStatus The last attempt status, which wi= ll be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. @@ -633,7 +675,7 @@ UpdateMicrocode ( EFI_STATUS UpdateMicrocodeFlashRegion ( IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, - IN CPU_MICROCODE_HEADER *CurrentMicrocodeEntryPoint, + IN CPU_MICROCODE_HEADER *TargetMicrocodeEntryPoint, IN VOID *Image, IN UINTN ImageSize, OUT UINT32 *LastAttemptStatus @@ -641,7 +683,7 @@ UpdateMicrocodeFlashRegion ( { VOID *MicrocodePatchAddress; UINTN MicrocodePatchRegionSize; - UINTN CurrentTotalSize; + UINTN TargetTotalSize; UINTN UsedRegionSize; EFI_STATUS Status; VOID *MicrocodePatchScratchBuffer; @@ -669,34 +711,34 @@ UpdateMicrocodeFlashRegion ( ScratchBufferSize =3D 0; =20 // - // Current data collection + // Target data collection // - CurrentTotalSize =3D 0; + TargetTotalSize =3D 0; AvailableSize =3D 0; NextMicrocodeEntryPoint =3D NULL; - if (CurrentMicrocodeEntryPoint !=3D NULL) { - if (CurrentMicrocodeEntryPoint->DataSize =3D=3D 0) { - CurrentTotalSize =3D 2048; + if (TargetMicrocodeEntryPoint !=3D NULL) { + if (TargetMicrocodeEntryPoint->DataSize =3D=3D 0) { + TargetTotalSize =3D 2048; } else { - CurrentTotalSize =3D CurrentMicrocodeEntryPoint->TotalSize; + TargetTotalSize =3D TargetMicrocodeEntryPoint->TotalSize; } - DEBUG((DEBUG_INFO, " CurrentTotalSize - 0x%x\n", CurrentTotalSize)); - NextMicrocodeEntryPoint =3D GetNextMicrocode(MicrocodeFmpPrivate, Curr= entMicrocodeEntryPoint); + DEBUG((DEBUG_INFO, " TargetTotalSize - 0x%x\n", TargetTotalSize)); + NextMicrocodeEntryPoint =3D GetNextMicrocode(MicrocodeFmpPrivate,=20 + TargetMicrocodeEntryPoint); DEBUG((DEBUG_INFO, " NextMicrocodeEntryPoint - 0x%x\n", NextMicrocode= EntryPoint)); if (NextMicrocodeEntryPoint !=3D NULL) { - ASSERT ((UINTN)NextMicrocodeEntryPoint >=3D ((UINTN)CurrentMicrocode= EntryPoint + CurrentTotalSize)); - AvailableSize =3D (UINTN)NextMicrocodeEntryPoint - (UINTN)CurrentMic= rocodeEntryPoint; + ASSERT ((UINTN)NextMicrocodeEntryPoint >=3D ((UINTN)TargetMicrocodeE= ntryPoint + TargetTotalSize)); + AvailableSize =3D (UINTN)NextMicrocodeEntryPoint -=20 + (UINTN)TargetMicrocodeEntryPoint; } else { - AvailableSize =3D (UINTN)MicrocodePatchAddress + MicrocodePatchRegio= nSize - (UINTN)CurrentMicrocodeEntryPoint; + AvailableSize =3D (UINTN)MicrocodePatchAddress +=20 + MicrocodePatchRegionSize - (UINTN)TargetMicrocodeEntryPoint; } DEBUG((DEBUG_INFO, " AvailableSize - 0x%x\n", AvailableSize)); } - ASSERT (AvailableSize >=3D CurrentTotalSize); + ASSERT (AvailableSize >=3D TargetTotalSize); UsedRegionSize =3D GetCurrentMicrocodeUsedRegionSize(MicrocodeFmpPrivate= ); DEBUG((DEBUG_INFO, " UsedRegionSize - 0x%x\n", UsedRegionSize)); - ASSERT (UsedRegionSize >=3D CurrentTotalSize); - if (CurrentMicrocodeEntryPoint !=3D NULL) { - ASSERT ((UINTN)MicrocodePatchAddress + UsedRegionSize >=3D ((UINTN)Cur= rentMicrocodeEntryPoint + CurrentTotalSize)); + ASSERT (UsedRegionSize >=3D TargetTotalSize); if=20 + (TargetMicrocodeEntryPoint !=3D NULL) { + ASSERT ((UINTN)MicrocodePatchAddress + UsedRegionSize >=3D=20 + ((UINTN)TargetMicrocodeEntryPoint + TargetTotalSize)); } // // Total Size means the Microcode data size. @@ -748,15 +790,15 @@ UpdateMicrocodeFlashRegion ( ScratchBufferSize +=3D RestSize; ScratchBufferPtr =3D (UINT8 *)ScratchBufferPtr + ScratchBufferSize; } - Status =3D UpdateMicrocode((UINTN)CurrentMicrocodeEntryPoint, Microcod= ePatchScratchBuffer, ScratchBufferSize, LastAttemptStatus); + Status =3D UpdateMicrocode((UINTN)TargetMicrocodeEntryPoint,=20 + MicrocodePatchScratchBuffer, ScratchBufferSize, LastAttemptStatus); return Status; } =20 // // 2. If there is enough space to remove old one and add new one, reorg = and replace old microcode. // - if (MicrocodePatchRegionSize - (UsedRegionSize - CurrentTotalSize) >=3D = ImageSize) { - if (CurrentMicrocodeEntryPoint =3D=3D NULL) { + if (MicrocodePatchRegionSize - (UsedRegionSize - TargetTotalSize) >=3D I= mageSize) { + if (TargetMicrocodeEntryPoint =3D=3D NULL) { DEBUG((DEBUG_INFO, "Append new microcode\n")); // // +------+------------+------+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D+ @@ -786,11 +828,11 @@ UpdateMicrocodeFlashRegion ( // 2.2. Copy rest images after the old image. if (NextMicrocodeEntryPoint !=3D 0) { RestSize =3D (UINTN)MicrocodePatchAddress + UsedRegionSize - ((UIN= TN)NextMicrocodeEntryPoint); - CopyMem (ScratchBufferPtr, (UINT8 *)CurrentMicrocodeEntryPoint + C= urrentTotalSize, RestSize); + CopyMem (ScratchBufferPtr, (UINT8 *)TargetMicrocodeEntryPoint +=20 + TargetTotalSize, RestSize); ScratchBufferSize +=3D RestSize; ScratchBufferPtr =3D (UINT8 *)ScratchBufferPtr + ScratchBufferSize= ; } - Status =3D UpdateMicrocode((UINTN)CurrentMicrocodeEntryPoint, Microc= odePatchScratchBuffer, ScratchBufferSize, LastAttemptStatus); + Status =3D UpdateMicrocode((UINTN)TargetMicrocodeEntryPoint,=20 + MicrocodePatchScratchBuffer, ScratchBufferSize, LastAttemptStatus); } return Status; } @@ -823,7 +865,7 @@ UpdateMicrocodeFlashRegion ( if (!MicrocodeInfo[Index].InUse) { continue; } - if (MicrocodeInfo[Index].MicrocodeEntryPoint =3D=3D CurrentMicrocode= EntryPoint) { + if (MicrocodeInfo[Index].MicrocodeEntryPoint =3D=3D=20 + TargetMicrocodeEntryPoint) { continue; } if (MicrocodeInfo[Index].TotalSize <=3D MicrocodePatchRegionSize - S= cratchBufferSize) { @@ -886,14 +928,9 @@ MicrocodeWrite ( { EFI_STATUS Status; VOID *AlignedImage; - CPU_MICROCODE_HEADER *CurrentMicrocodeEntryPoint; - - // - // We must get Current MicrocodeEntrypoint *before* VerifyMicrocode, - // because the MicrocodeSignature might be updated in VerifyMicrocode. - // - CurrentMicrocodeEntryPoint =3D GetCurrentMicrocodeInUse(MicrocodeFmpPriv= ate); - DEBUG((DEBUG_INFO, " CurrentMicrocodeEntryPoint - 0x%x\n", CurrentMicro= codeEntryPoint)); + CPU_MICROCODE_HEADER *TargetMicrocodeEntryPoint; + UINTN TargetCpuIndex; + UINTN TargetMicrcodeIndex; =20 // // MCU must be 16 bytes aligned @@ -906,7 +943,8 @@ MicrocodeWrite ( } =20 *LastAttemptVersion =3D ((CPU_MICROCODE_HEADER *)Image)->UpdateRevision; - Status =3D VerifyMicrocode(AlignedImage, ImageSize, TRUE, LastAttemptSta= tus, AbortReason); + TargetCpuIndex =3D (UINTN)-1; + Status =3D VerifyMicrocode(MicrocodeFmpPrivate, AlignedImage,=20 + ImageSize, TRUE, LastAttemptStatus, AbortReason, &TargetCpuIndex); if (EFI_ERROR(Status)) { DEBUG((DEBUG_ERROR, "Fail to verify Microcode Region\n")); FreePool(AlignedImage); @@ -914,9 +952,21 @@ MicrocodeWrite ( } DEBUG((DEBUG_INFO, "Pass VerifyMicrocode\n")); =20 + DEBUG((DEBUG_INFO, " TargetCpuIndex - 0x%x\n", TargetCpuIndex)); =20 + ASSERT (TargetCpuIndex < MicrocodeFmpPrivate->ProcessorCount); + TargetMicrcodeIndex =3D=20 + MicrocodeFmpPrivate->ProcessorInfo[TargetCpuIndex].MicrocodeIndex; + DEBUG((DEBUG_INFO, " TargetMicrcodeIndex - 0x%x\n",=20 + TargetMicrcodeIndex)); if (TargetMicrcodeIndex !=3D (UINTN)-1) { + ASSERT (TargetMicrcodeIndex < MicrocodeFmpPrivate->DescriptorCount); + TargetMicrocodeEntryPoint =3D=20 + MicrocodeFmpPrivate->MicrocodeInfo[TargetMicrcodeIndex].MicrocodeEntry + Point; + } else { + TargetMicrocodeEntryPoint =3D NULL; + } + DEBUG((DEBUG_INFO, " TargetMicrocodeEntryPoint - 0x%x\n",=20 + TargetMicrocodeEntryPoint)); + Status =3D UpdateMicrocodeFlashRegion( MicrocodeFmpPrivate, - CurrentMicrocodeEntryPoint, + TargetMicrocodeEntryPoint, AlignedImage, ImageSize, LastAttemptStatus diff --git a/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.= h b/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.h index b4d1bac..3d9bf85 100644 --- a/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.h +++ b/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.h @@ -21,6 +21,7 @@ #include =20 #include +#include =20 #include #include @@ -56,6 +57,19 @@ typedef struct { BOOLEAN InUse; } MICROCODE_INFO; =20 +typedef struct { + UINTN CpuIndex; + UINT32 ProcessorSignature; + UINT8 PlatformId; + UINT32 MicrocodeRevision; + UINTN MicrocodeIndex; +} PROCESSOR_INFO; + +typedef struct { + UINT64 Address; + UINT32 Revision; +} MICROCODE_LOAD_BUFFER; + struct _MICROCODE_FMP_PRIVATE_DATA { UINT32 Signature; EFI_FIRMWARE_MANAGEMENT_PROTOCOL Fmp; @@ -68,6 +82,10 @@ struct _MICROCODE_FMP_PRIVATE_DATA { UINT32 PackageVersion; CHAR16 *PackageVersionName; MICROCODE_FMP_LAST_ATTEMPT_VARIABLE LastAttempt; + EFI_MP_SERVICES_PROTOCOL *MpService; + UINTN BspIndex; + UINTN ProcessorCount; + PROCESSOR_INFO *ProcessorInfo; }; =20 typedef struct _MICROCODE_FMP_PRIVATE_DATA MICROCODE_FMP_PRIVATE_DATA; @@= -108,10 +126,25 @@ GetMicrocodeRegion ( ); =20 /** + Collect processor information. + The function prototype for invoking a function on an Application Process= or. + + @param[in,out] Buffer The pointer to private data buffer. +**/ +VOID +EFIAPI +CollectProcessorInfo ( + IN OUT VOID *Buffer + ); + +/** Get current Microcode information. =20 - NOTE: The DescriptorCount/ImageDescriptor/MicrocodeInfo in MicrocodeFmpP= rivate - are not avaiable in this function. + The ProcessorInformation (BspIndex/ProcessorCount/ProcessorInfo) + in MicrocodeFmpPrivate must be initialized. + + The MicrocodeInformation=20 + (DescriptorCount/ImageDescriptor/MicrocodeInfo) + in MicrocodeFmpPrivate may not be avaiable in this function. =20 @param[in] MicrocodeFmpPrivate The Microcode driver private dat= a @param[in] DescriptorCount The count of Microcode ImageDesc= riptor allocated. @@ -129,6 +162,40 @@ GetMicrocodeInfo ( ); =20 /** + Verify Microcode. + + Caution: This function may receive untrusted input. + + @param[in] MicrocodeFmpPrivate The Microcode driver private data + @param[in] Image The Microcode image buffer. + @param[in] ImageSize The size of Microcode image buffe= r in bytes. + @param[in] TryLoad Try to load Microcode or not. + @param[out] LastAttemptStatus The last attempt status, which wi= ll be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. + @param[out] AbortReason A pointer to a pointer to a null-= terminated string providing more + details for the aborted operation= . The buffer is allocated by this function + with AllocatePool(), and it is th= e caller's responsibility to free it with a + call to FreePool(). + @param[in, out] TargetCpuIndex On input, the index of target CPU= which tries to match the Microcode. (UINTN)-1 means to try all. + On output, the index of target CP= U which matches the Microcode. + + @retval EFI_SUCCESS The Microcode image passes verificatio= n. + @retval EFI_VOLUME_CORRUPTED The Microcode image is corrupt. + @retval EFI_INCOMPATIBLE_VERSION The Microcode image version is incorre= ct. + @retval EFI_UNSUPPORTED The Microcode ProcessorSignature or Pr= ocessorFlags is incorrect. + @retval EFI_SECURITY_VIOLATION The Microcode image fails to load. +**/ +EFI_STATUS +VerifyMicrocode ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, + IN VOID *Image, + IN UINTN ImageSize, + IN BOOLEAN TryLoad, + OUT UINT32 *LastAttemptStatus, + OUT CHAR16 **AbortReason, OPTIONAL + IN OUT UINTN *TargetCpuIndex OPTIONAL + ); + +/** Write Microcode. =20 @param[in] MicrocodeFmpPrivate The Microcode driver private data diff --git a/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateD= xe.inf b/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.i= nf index 7aae348..55797cf 100644 --- a/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.inf +++ b/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.i +++ nf @@ -56,13 +56,15 @@ =20 [Protocols] gEfiFirmwareManagementProtocolGuid ## PRODUCES + gEfiMpServiceProtocolGuid ## CONSUMES =20 [Pcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress ## CONS= UMES gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONS= UMES =20 [Depex] - gEfiVariableArchProtocolGuid + gEfiVariableArchProtocolGuid AND + gEfiMpServiceProtocolGuid =20 [UserExtensions.TianoCore."ExtraFiles"] MicrocodeUpdateDxeExtra.uni -- 2.7.4.windows.1