From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.151; helo=mga17.intel.com; envelope-from=jiewen.yao@intel.com; receiver=edk2-devel@lists.01.org Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) (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 C80A1203BEA4B for ; Thu, 3 May 2018 23:05:40 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 03 May 2018 23:05:40 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,361,1520924400"; d="scan'208";a="36764114" Received: from fmsmsx106.amr.corp.intel.com ([10.18.124.204]) by fmsmga007.fm.intel.com with ESMTP; 03 May 2018 23:05:40 -0700 Received: from fmsmsx101.amr.corp.intel.com (10.18.124.199) by FMSMSX106.amr.corp.intel.com (10.18.124.204) with Microsoft SMTP Server (TLS) id 14.3.319.2; Thu, 3 May 2018 23:05:40 -0700 Received: from shsmsx152.ccr.corp.intel.com (10.239.6.52) by fmsmsx101.amr.corp.intel.com (10.18.124.199) with Microsoft SMTP Server (TLS) id 14.3.319.2; Thu, 3 May 2018 23:05:39 -0700 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.79]) by SHSMSX152.ccr.corp.intel.com ([169.254.6.6]) with mapi id 14.03.0319.002; Fri, 4 May 2018 14:05:37 +0800 From: "Yao, Jiewen" To: "Zeng, Star" , "edk2-devel@lists.01.org" Thread-Topic: [PATCH V2] IntelSiliconPkg MicrocodeUpdateDxe: Honor FIT table Thread-Index: AQHT3gCcs30sckNZcUyA60i+Yawwn6QfH8Qw Date: Fri, 4 May 2018 06:05:36 +0000 Message-ID: <74D8A39837DF1E4DA445A8C0B3885C503AB8D821@shsmsx102.ccr.corp.intel.com> References: <1524817211-46772-1-git-send-email-star.zeng@intel.com> In-Reply-To: <1524817211-46772-1-git-send-email-star.zeng@intel.com> Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiYTEzMmNjOWItMDIwYi00M2I2LWIwZTgtM2ZiNmNlNDVjMWI1IiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjIuNS4xOCIsIlRydXN0ZWRMYWJlbEhhc2giOiI3ZjI4M3VPMzVtYmNkb2NcL1RhdzZpbU9qYnBobnl0Wkx5N0t0cVlYbjEzVTNhYU15akVQOU8xTTNBcTl6R3NQTSJ9 x-ctpclassification: CTP_NT dlp-product: dlpe-windows dlp-version: 11.0.200.100 dlp-reaction: no-action x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH V2] IntelSiliconPkg MicrocodeUpdateDxe: Honor FIT table X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 04 May 2018 06:05:41 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Jiewen.yao@intel.com > -----Original Message----- > From: Zeng, Star > Sent: Friday, April 27, 2018 1:20 AM > To: edk2-devel@lists.01.org > Cc: Zeng, Star ; Yao, Jiewen > Subject: [PATCH V2] IntelSiliconPkg MicrocodeUpdateDxe: Honor FIT table >=20 > It is the second step for > https://bugzilla.tianocore.org/show_bug.cgi?id=3D540. >=20 > V2: Use error handling instead of ASSERT for FIT table checking result. >=20 > Cc: Jiewen Yao > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Star Zeng > --- > .../Capsule/MicrocodeUpdateDxe/MicrocodeFmp.c | 251 > +++++++++++++- > .../Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.c | 363 > +++++++++++++++++++-- > .../Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.h | 13 +- > .../MicrocodeUpdateDxe/MicrocodeUpdateDxe.inf | 3 +- > 4 files changed, 601 insertions(+), 29 deletions(-) >=20 > diff --git > a/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeFmp.c > b/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeFmp.c > index ef5e630caf01..bc1387b3dddd 100644 > --- a/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeFmp.c > +++ b/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeFmp.c > @@ -272,7 +272,7 @@ FmpSetImage ( > } >=20 > Status =3D MicrocodeWrite(MicrocodeFmpPrivate, (VOID *)Image, ImageSiz= e, > &MicrocodeFmpPrivate->LastAttempt.LastAttemptVersion, > &MicrocodeFmpPrivate->LastAttempt.LastAttemptStatus, AbortReason); > - DEBUG((DEBUG_INFO, "SetImage - LastAttemp Version - 0x%x, State - > 0x%x\n", MicrocodeFmpPrivate->LastAttempt.LastAttemptVersion, > MicrocodeFmpPrivate->LastAttempt.LastAttemptStatus)); > + DEBUG((DEBUG_INFO, "SetImage - LastAttempt Version - 0x%x, Status - > 0x%x\n", MicrocodeFmpPrivate->LastAttempt.LastAttemptVersion, > MicrocodeFmpPrivate->LastAttempt.LastAttemptStatus)); > VarStatus =3D gRT->SetVariable( > MICROCODE_FMP_LAST_ATTEMPT_VARIABLE_NAME, > &gEfiCallerIdGuid, > @@ -280,7 +280,7 @@ FmpSetImage ( > sizeof(MicrocodeFmpPrivate->LastAttempt), > &MicrocodeFmpPrivate->LastAttempt > ); > - DEBUG((DEBUG_INFO, "SetLastAttemp - %r\n", VarStatus)); > + DEBUG((DEBUG_INFO, "SetLastAttempt - %r\n", VarStatus)); >=20 > if (!EFI_ERROR(Status)) { > InitializeMicrocodeDescriptor(MicrocodeFmpPrivate); > @@ -415,6 +415,212 @@ FmpSetPackageInfo ( > } >=20 > /** > + Sort FIT microcode entries based upon MicrocodeEntryPoint, from low to > high. > + > + @param[in] MicrocodeFmpPrivate private data structure to be initialize= d. > + > +**/ > +VOID > +SortFitMicrocodeInfo ( > + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate > + ) > +{ > + FIT_MICROCODE_INFO *FitMicrocodeEntry; > + FIT_MICROCODE_INFO *NextFitMicrocodeEntry; > + FIT_MICROCODE_INFO TempFitMicrocodeEntry; > + FIT_MICROCODE_INFO *FitMicrocodeEntryEnd; > + > + FitMicrocodeEntry =3D MicrocodeFmpPrivate->FitMicrocodeInfo; > + NextFitMicrocodeEntry =3D FitMicrocodeEntry + 1; > + FitMicrocodeEntryEnd =3D MicrocodeFmpPrivate->FitMicrocodeInfo + > MicrocodeFmpPrivate->FitMicrocodeEntryCount; > + while (FitMicrocodeEntry < FitMicrocodeEntryEnd) { > + while (NextFitMicrocodeEntry < FitMicrocodeEntryEnd) { > + if (FitMicrocodeEntry->MicrocodeEntryPoint > > NextFitMicrocodeEntry->MicrocodeEntryPoint) { > + CopyMem (&TempFitMicrocodeEntry, FitMicrocodeEntry, sizeof > (FIT_MICROCODE_INFO)); > + CopyMem (FitMicrocodeEntry, NextFitMicrocodeEntry, sizeof > (FIT_MICROCODE_INFO)); > + CopyMem (NextFitMicrocodeEntry, &TempFitMicrocodeEntry, sizeof > (FIT_MICROCODE_INFO)); > + } > + > + NextFitMicrocodeEntry =3D NextFitMicrocodeEntry + 1; > + } > + > + FitMicrocodeEntry =3D FitMicrocodeEntry + 1; > + NextFitMicrocodeEntry =3D FitMicrocodeEntry + 1; > + } > +} > + > +/** > + Initialize FIT microcode information. > + > + @param[in] MicrocodeFmpPrivate private data structure to be initialize= d. > + > + @return EFI_SUCCESS FIT microcode information is initialized= . > + @return EFI_OUT_OF_RESOURCES No enough resource for the > initialization. > + @return EFI_DEVICE_ERROR There is something wrong in FIT > microcode entry. > +**/ > +EFI_STATUS > +InitializeFitMicrocodeInfo ( > + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate > + ) > +{ > + UINT64 FitPointer; > + FIRMWARE_INTERFACE_TABLE_ENTRY *FitEntry; > + UINT32 EntryNum; > + UINT32 MicrocodeEntryNum; > + UINT32 Index; > + UINTN Address; > + VOID *MicrocodePatchAddress; > + UINTN MicrocodePatchRegionSize; > + FIT_MICROCODE_INFO *FitMicrocodeInfo; > + FIT_MICROCODE_INFO *FitMicrocodeInfoNext; > + CPU_MICROCODE_HEADER *MicrocodeEntryPoint; > + CPU_MICROCODE_HEADER *MicrocodeEntryPointNext; > + UINTN FitMicrocodeIndex; > + MICROCODE_INFO *MicrocodeInfo; > + UINTN MicrocodeIndex; > + > + if (MicrocodeFmpPrivate->FitMicrocodeInfo !=3D NULL) { > + FreePool (MicrocodeFmpPrivate->FitMicrocodeInfo); > + MicrocodeFmpPrivate->FitMicrocodeInfo =3D NULL; > + MicrocodeFmpPrivate->FitMicrocodeEntryCount =3D 0; > + } > + > + FitPointer =3D *(UINT64 *) (UINTN) FIT_POINTER_ADDRESS; > + if ((FitPointer =3D=3D 0) || > + (FitPointer =3D=3D 0xFFFFFFFFFFFFFFFF) || > + (FitPointer =3D=3D 0xEEEEEEEEEEEEEEEE)) { > + // > + // No FIT table. > + // > + return EFI_SUCCESS; > + } > + FitEntry =3D (FIRMWARE_INTERFACE_TABLE_ENTRY *) (UINTN) FitPointer; > + if ((FitEntry[0].Type !=3D FIT_TYPE_00_HEADER) || > + (FitEntry[0].Address !=3D FIT_TYPE_00_SIGNATURE)) { > + // > + // Invalid FIT table, treat it as no FIT table. > + // > + return EFI_SUCCESS; > + } > + > + EntryNum =3D *(UINT32 *)(&FitEntry[0].Size[0]) & 0xFFFFFF; > + > + // > + // Calculate microcode entry number. > + // > + MicrocodeEntryNum =3D 0; > + for (Index =3D 0; Index < EntryNum; Index++) { > + if (FitEntry[Index].Type =3D=3D FIT_TYPE_01_MICROCODE) { > + MicrocodeEntryNum++; > + } > + } > + if (MicrocodeEntryNum =3D=3D 0) { > + // > + // No FIT microcode entry. > + // > + return EFI_SUCCESS; > + } > + > + // > + // Allocate buffer. > + // > + MicrocodeFmpPrivate->FitMicrocodeInfo =3D AllocateZeroPool > (MicrocodeEntryNum * sizeof (FIT_MICROCODE_INFO)); > + if (MicrocodeFmpPrivate->FitMicrocodeInfo =3D=3D NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + MicrocodeFmpPrivate->FitMicrocodeEntryCount =3D MicrocodeEntryNum; > + > + MicrocodePatchAddress =3D MicrocodeFmpPrivate->MicrocodePatchAddress; > + MicrocodePatchRegionSize =3D > MicrocodeFmpPrivate->MicrocodePatchRegionSize; > + > + // > + // Collect microcode entry info. > + // > + MicrocodeEntryNum =3D 0; > + for (Index =3D 0; Index < EntryNum; Index++) { > + if (FitEntry[Index].Type =3D=3D FIT_TYPE_01_MICROCODE) { > + Address =3D (UINTN) FitEntry[Index].Address; > + if ((Address < (UINTN) MicrocodePatchAddress) || > + (Address >=3D ((UINTN) MicrocodePatchAddress + > MicrocodePatchRegionSize))) { > + DEBUG (( > + DEBUG_ERROR, > + "InitializeFitMicrocodeInfo - Address (0x%x) is not in Microco= de > Region\n", > + Address > + )); > + goto ErrorExit; > + } > + FitMicrocodeInfo =3D > &MicrocodeFmpPrivate->FitMicrocodeInfo[MicrocodeEntryNum]; > + FitMicrocodeInfo->MicrocodeEntryPoint =3D (CPU_MICROCODE_HEADER > *) Address; > + if ((*(UINT32 *) Address) =3D=3D 0xFFFFFFFF) { > + // > + // It is the empty slot as long as the first dword is 0xFFFF_FFF= F. > + // > + FitMicrocodeInfo->Empty =3D TRUE; > + } else { > + FitMicrocodeInfo->Empty =3D FALSE; > + } > + MicrocodeEntryNum++; > + } > + } > + > + // > + // Every microcode should have a FIT microcode entry. > + // > + for (MicrocodeIndex =3D 0; MicrocodeIndex < > MicrocodeFmpPrivate->DescriptorCount; MicrocodeIndex++) { > + MicrocodeInfo =3D > &MicrocodeFmpPrivate->MicrocodeInfo[MicrocodeIndex]; > + for (FitMicrocodeIndex =3D 0; FitMicrocodeIndex < > MicrocodeFmpPrivate->FitMicrocodeEntryCount; FitMicrocodeIndex++) { > + FitMicrocodeInfo =3D > &MicrocodeFmpPrivate->FitMicrocodeInfo[FitMicrocodeIndex]; > + if (MicrocodeInfo->MicrocodeEntryPoint =3D=3D > FitMicrocodeInfo->MicrocodeEntryPoint) { > + FitMicrocodeInfo->TotalSize =3D MicrocodeInfo->TotalSize; > + FitMicrocodeInfo->InUse =3D MicrocodeInfo->InUse; > + break; > + } > + } > + if (FitMicrocodeIndex >=3D MicrocodeFmpPrivate->FitMicrocodeEntryCou= nt) > { > + DEBUG (( > + DEBUG_ERROR, > + "InitializeFitMicrocodeInfo - There is no FIT microcode entry fo= r > Microcode (0x%x)\n", > + MicrocodeInfo->MicrocodeEntryPoint > + )); > + goto ErrorExit; > + } > + } > + > + SortFitMicrocodeInfo (MicrocodeFmpPrivate); > + > + // > + // Check overlap. > + // > + for (FitMicrocodeIndex =3D 0; FitMicrocodeIndex < > MicrocodeFmpPrivate->FitMicrocodeEntryCount - 1; FitMicrocodeIndex++) { > + FitMicrocodeInfo =3D > &MicrocodeFmpPrivate->FitMicrocodeInfo[FitMicrocodeIndex]; > + MicrocodeEntryPoint =3D FitMicrocodeInfo->MicrocodeEntryPoint; > + FitMicrocodeInfoNext =3D > &MicrocodeFmpPrivate->FitMicrocodeInfo[FitMicrocodeIndex + 1]; > + MicrocodeEntryPointNext =3D FitMicrocodeInfoNext->MicrocodeEntryPoin= t; > + if ((MicrocodeEntryPoint >=3D MicrocodeEntryPointNext) || > + ((FitMicrocodeInfo->TotalSize !=3D 0) && > + ((UINTN) MicrocodeEntryPoint + FitMicrocodeInfo->TotalSize) > > + (UINTN) MicrocodeEntryPointNext)) { > + DEBUG (( > + DEBUG_ERROR, > + "InitializeFitMicrocodeInfo - There is overlap between FIT micro= code > entries (0x%x 0x%x)\n", > + MicrocodeEntryPoint, > + MicrocodeEntryPointNext > + )); > + goto ErrorExit; > + } > + } > + > + return EFI_SUCCESS; > + > +ErrorExit: > + FreePool (MicrocodeFmpPrivate->FitMicrocodeInfo); > + MicrocodeFmpPrivate->FitMicrocodeInfo =3D NULL; > + MicrocodeFmpPrivate->FitMicrocodeEntryCount =3D 0; > + return EFI_DEVICE_ERROR; > +} > + > +/** > Initialize Processor Microcode Index. >=20 > @param[in] MicrocodeFmpPrivate private data structure to be initialize= d. > @@ -460,14 +666,16 @@ InitializedProcessorMicrocodeIndex ( >=20 > @param[in] MicrocodeFmpPrivate private data structure to be initialize= d. >=20 > - @return EFI_SUCCESS Microcode Descriptor is initialized. > + @return EFI_SUCCESS Microcode Descriptor is initialized. > + @return EFI_OUT_OF_RESOURCES No enough resource for the > initialization. > **/ > EFI_STATUS > InitializeMicrocodeDescriptor ( > IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate > ) > { > - UINT8 CurrentMicrocodeCount; > + EFI_STATUS Status; > + UINT8 CurrentMicrocodeCount; >=20 > CurrentMicrocodeCount =3D (UINT8)GetMicrocodeInfo (MicrocodeFmpPrivate= , > 0, NULL, NULL); >=20 > @@ -496,6 +704,7 @@ InitializeMicrocodeDescriptor ( > if (MicrocodeFmpPrivate->MicrocodeInfo =3D=3D NULL) { > MicrocodeFmpPrivate->MicrocodeInfo =3D > AllocateZeroPool(MicrocodeFmpPrivate->DescriptorCount * > sizeof(MICROCODE_INFO)); > if (MicrocodeFmpPrivate->MicrocodeInfo =3D=3D NULL) { > + FreePool (MicrocodeFmpPrivate->ImageDescriptor); > return EFI_OUT_OF_RESOURCES; > } > } > @@ -505,6 +714,14 @@ InitializeMicrocodeDescriptor ( >=20 > InitializedProcessorMicrocodeIndex (MicrocodeFmpPrivate); >=20 > + Status =3D InitializeFitMicrocodeInfo (MicrocodeFmpPrivate); > + if (EFI_ERROR(Status)) { > + FreePool (MicrocodeFmpPrivate->ImageDescriptor); > + FreePool (MicrocodeFmpPrivate->MicrocodeInfo); > + DEBUG((DEBUG_ERROR, "InitializeFitMicrocodeInfo - %r\n", Status)); > + return Status; > + } > + > return EFI_SUCCESS; > } >=20 > @@ -513,7 +730,8 @@ InitializeMicrocodeDescriptor ( >=20 > @param[in] MicrocodeFmpPrivate private data structure to be initialize= d. >=20 > - @return EFI_SUCCESS private data is initialized. > + @return EFI_SUCCESS Processor information is initialized. > + @return EFI_OUT_OF_RESOURCES No enough resource for the > initialization. > **/ > EFI_STATUS > InitializeProcessorInfo ( > @@ -583,6 +801,7 @@ DumpPrivateInfo ( > PROCESSOR_INFO *ProcessorInfo; > MICROCODE_INFO *MicrocodeInfo; > EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageDescriptor; > + FIT_MICROCODE_INFO *FitMicrocodeInfo; >=20 > DEBUG ((DEBUG_INFO, "ProcessorInfo:\n")); > DEBUG ((DEBUG_INFO, " ProcessorCount - 0x%x\n", > MicrocodeFmpPrivate->ProcessorCount)); > @@ -635,6 +854,23 @@ DumpPrivateInfo ( > DEBUG((DEBUG_VERBOSE, " LastAttemptStatus - 0x%x\n", > ImageDescriptor[Index].LastAttemptStatus)); > DEBUG((DEBUG_VERBOSE, " HardwareInstance - > 0x%lx\n", ImageDescriptor[Index].HardwareInstance)); > } > + > + if (MicrocodeFmpPrivate->FitMicrocodeInfo !=3D NULL) { > + DEBUG ((DEBUG_INFO, "FitMicrocodeInfo:\n")); > + FitMicrocodeInfo =3D MicrocodeFmpPrivate->FitMicrocodeInfo; > + DEBUG ((DEBUG_INFO, " FitMicrocodeEntryCount - 0x%x\n", > MicrocodeFmpPrivate->FitMicrocodeEntryCount)); > + for (Index =3D 0; Index < MicrocodeFmpPrivate->FitMicrocodeEntryCoun= t; > Index++) { > + DEBUG (( > + DEBUG_INFO, > + " FitMicrocodeInfo[0x%x] - 0x%08x, 0x%08x, (0x%x, 0x%x)\n", > + Index, > + FitMicrocodeInfo[Index].MicrocodeEntryPoint, > + FitMicrocodeInfo[Index].TotalSize, > + FitMicrocodeInfo[Index].InUse, > + FitMicrocodeInfo[Index].Empty > + )); > + } > + } > } >=20 > /** > @@ -671,8 +907,8 @@ InitializePrivateData ( > &VarSize, > &MicrocodeFmpPrivate->LastAttempt > ); > - DEBUG((DEBUG_INFO, "GetLastAttemp - %r\n", VarStatus)); > - DEBUG((DEBUG_INFO, "GetLastAttemp Version - 0x%x, State - 0x%x\n", > MicrocodeFmpPrivate->LastAttempt.LastAttemptVersion, > MicrocodeFmpPrivate->LastAttempt.LastAttemptStatus)); > + DEBUG((DEBUG_INFO, "GetLastAttempt - %r\n", VarStatus)); > + DEBUG((DEBUG_INFO, "GetLastAttempt Version - 0x%x, State - 0x%x\n", > MicrocodeFmpPrivate->LastAttempt.LastAttemptVersion, > MicrocodeFmpPrivate->LastAttempt.LastAttemptStatus)); >=20 > Result =3D > GetMicrocodeRegion(&MicrocodeFmpPrivate->MicrocodePatchAddress, > &MicrocodeFmpPrivate->MicrocodePatchRegionSize); > if (!Result) { > @@ -688,6 +924,7 @@ InitializePrivateData ( >=20 > Status =3D InitializeMicrocodeDescriptor(MicrocodeFmpPrivate); > if (EFI_ERROR(Status)) { > + FreePool (MicrocodeFmpPrivate->ProcessorInfo); > DEBUG((DEBUG_ERROR, "InitializeMicrocodeDescriptor - %r\n", Status))= ; > return Status; > } > diff --git > a/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.c > b/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.c > index 2cb0adbc44d5..9098712c2fc8 100644 > --- a/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.= c > +++ > b/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.c > @@ -368,7 +368,7 @@ GetMatchedProcessor ( > On output, the index of target > CPU which matches the Microcode. >=20 > @retval EFI_SUCCESS The Microcode image passes > verification. > - @retval EFI_VOLUME_CORRUPTED The Microcode image is corrupt. > + @retval EFI_VOLUME_CORRUPTED The Microcode image is > corrupted. > @retval EFI_INCOMPATIBLE_VERSION The Microcode image version is > incorrect. > @retval EFI_UNSUPPORTED The Microcode ProcessorSignature > or ProcessorFlags is incorrect. > @retval EFI_SECURITY_VIOLATION The Microcode image fails to load. > @@ -550,7 +550,7 @@ VerifyMicrocode ( > } > *LastAttemptStatus =3D > LAST_ATTEMPT_STATUS_ERROR_INCORRECT_VERSION; > if (AbortReason !=3D NULL) { > - *AbortReason =3D > AllocateCopyPool(sizeof(L"UnsupportedProcessSignature/ProcessorFlags"), > L"UnsupportedProcessSignature/ProcessorFlags"); > + *AbortReason =3D > AllocateCopyPool(sizeof(L"UnsupportedProcessorSignature/ProcessorFlags"), > L"UnsupportedProcessorSignature/ProcessorFlags"); > } > return EFI_UNSUPPORTED; > } > @@ -623,6 +623,124 @@ GetNextMicrocode ( > } >=20 > /** > + Get next FIT Microcode entrypoint. > + > + @param[in] MicrocodeFmpPrivate The Microcode driver private > data > + @param[in] MicrocodeEntryPoint Current Microcode entrypoint > + > + @return next FIT Microcode entrypoint. > +**/ > +CPU_MICROCODE_HEADER * > +GetNextFitMicrocode ( > + IN MICROCODE_FMP_PRIVATE_DATA > *MicrocodeFmpPrivate, > + IN CPU_MICROCODE_HEADER *MicrocodeEntryPoint > + ) > +{ > + UINTN Index; > + > + for (Index =3D 0; Index < MicrocodeFmpPrivate->FitMicrocodeEntryCount; > Index++) { > + if (MicrocodeEntryPoint =3D=3D > MicrocodeFmpPrivate->FitMicrocodeInfo[Index].MicrocodeEntryPoint) { > + if (Index =3D=3D (UINTN) MicrocodeFmpPrivate->FitMicrocodeEntryCou= nt - > 1) { > + // it is last one > + return NULL; > + } else { > + // return next one > + return MicrocodeFmpPrivate->FitMicrocodeInfo[Index + > 1].MicrocodeEntryPoint; > + } > + } > + } > + > + ASSERT(FALSE); > + return NULL; > +} > + > +/** > + Find empty FIT Microcode entrypoint. > + > + @param[in] MicrocodeFmpPrivate The Microcode driver private > data > + @param[in] ImageSize The size of Microcode image > buffer in bytes. > + @param[out] AvailableSize Available size of the empty FIT > Microcode entrypoint. > + > + @return Empty FIT Microcode entrypoint. > +**/ > +CPU_MICROCODE_HEADER * > +FindEmptyFitMicrocode ( > + IN MICROCODE_FMP_PRIVATE_DATA > *MicrocodeFmpPrivate, > + IN UINTN ImageSize, > + OUT UINTN *AvailableSize > + ) > +{ > + UINTN Index; > + CPU_MICROCODE_HEADER *MicrocodeEntryPoint; > + CPU_MICROCODE_HEADER > *NextMicrocodeEntryPoint; > + VOID *MicrocodePatchAddress; > + UINTN MicrocodePatchRegionSize; > + > + MicrocodePatchAddress =3D MicrocodeFmpPrivate->MicrocodePatchAddress; > + MicrocodePatchRegionSize =3D > MicrocodeFmpPrivate->MicrocodePatchRegionSize; > + > + for (Index =3D 0; Index < MicrocodeFmpPrivate->FitMicrocodeEntryCount; > Index++) { > + if (MicrocodeFmpPrivate->FitMicrocodeInfo[Index].Empty) { > + MicrocodeEntryPoint =3D > MicrocodeFmpPrivate->FitMicrocodeInfo[Index].MicrocodeEntryPoint; > + NextMicrocodeEntryPoint =3D GetNextFitMicrocode > (MicrocodeFmpPrivate, MicrocodeEntryPoint); > + if (NextMicrocodeEntryPoint !=3D NULL) { > + *AvailableSize =3D (UINTN) NextMicrocodeEntryPoint - (UINTN) > MicrocodeEntryPoint; > + } else { > + *AvailableSize =3D (UINTN) MicrocodePatchAddress + > MicrocodePatchRegionSize - (UINTN) MicrocodeEntryPoint; > + } > + if (*AvailableSize >=3D ImageSize) { > + return MicrocodeEntryPoint; > + } > + } > + } > + > + return NULL; > +} > + > +/** > + Find unused FIT Microcode entrypoint. > + > + @param[in] MicrocodeFmpPrivate The Microcode driver private > data > + @param[in] ImageSize The size of Microcode image > buffer in bytes. > + @param[out] AvailableSize Available size of the unused FI= T > Microcode entrypoint. > + > + @return Unused FIT Microcode entrypoint. > +**/ > +CPU_MICROCODE_HEADER * > +FindUnusedFitMicrocode ( > + IN MICROCODE_FMP_PRIVATE_DATA > *MicrocodeFmpPrivate, > + IN UINTN ImageSize, > + OUT UINTN *AvailableSize > + ) > +{ > + UINTN Index; > + CPU_MICROCODE_HEADER *MicrocodeEntryPoint; > + CPU_MICROCODE_HEADER > *NextMicrocodeEntryPoint; > + VOID *MicrocodePatchAddress; > + UINTN MicrocodePatchRegionSize; > + > + MicrocodePatchAddress =3D MicrocodeFmpPrivate->MicrocodePatchAddress; > + MicrocodePatchRegionSize =3D > MicrocodeFmpPrivate->MicrocodePatchRegionSize; > + > + for (Index =3D 0; Index < MicrocodeFmpPrivate->FitMicrocodeEntryCount; > Index++) { > + if (!MicrocodeFmpPrivate->FitMicrocodeInfo[Index].InUse) { > + MicrocodeEntryPoint =3D > MicrocodeFmpPrivate->FitMicrocodeInfo[Index].MicrocodeEntryPoint; > + NextMicrocodeEntryPoint =3D GetNextFitMicrocode > (MicrocodeFmpPrivate, MicrocodeEntryPoint); > + if (NextMicrocodeEntryPoint !=3D NULL) { > + *AvailableSize =3D (UINTN) NextMicrocodeEntryPoint - (UINTN) > MicrocodeEntryPoint; > + } else { > + *AvailableSize =3D (UINTN) MicrocodePatchAddress + > MicrocodePatchRegionSize - (UINTN) MicrocodeEntryPoint; > + } > + if (*AvailableSize >=3D ImageSize) { > + return MicrocodeEntryPoint; > + } > + } > + } > + > + return NULL; > +} > + > +/** > Get current Microcode used region size. >=20 > @param[in] MicrocodeFmpPrivate The Microcode driver private > data > @@ -666,7 +784,7 @@ UpdateMicrocode ( >=20 > DEBUG((DEBUG_INFO, "PlatformUpdate:")); > DEBUG((DEBUG_INFO, " Address - 0x%lx,", Address)); > - DEBUG((DEBUG_INFO, " Legnth - 0x%x\n", ImageSize)); > + DEBUG((DEBUG_INFO, " Length - 0x%x\n", ImageSize)); >=20 > Status =3D MicrocodeFlashWrite ( > Address, > @@ -682,6 +800,201 @@ UpdateMicrocode ( > } >=20 > /** > + Update Microcode flash region with FIT. > + > + @param[in] MicrocodeFmpPrivate The Microcode driver private > data > + @param[in] TargetMicrocodeEntryPoint Target Microcode entrypoint to > be updated > + @param[in] Image The Microcode image buffer. > + @param[in] ImageSize The size of Microcode image > buffer in bytes. > + @param[out] LastAttemptStatus The last attempt status, which > will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. > + > + @retval EFI_SUCCESS The Microcode image is written. > + @retval EFI_WRITE_PROTECTED The flash device is read only. > +**/ > +EFI_STATUS > +UpdateMicrocodeFlashRegionWithFit ( > + IN MICROCODE_FMP_PRIVATE_DATA > *MicrocodeFmpPrivate, > + IN CPU_MICROCODE_HEADER > *TargetMicrocodeEntryPoint, > + IN VOID *Image, > + IN UINTN ImageSize, > + OUT UINT32 *LastAttemptStatus > + ) > +{ > + VOID *MicrocodePatchAddress; > + UINTN MicrocodePatchRegionSize; > + UINTN TargetTotalSize; > + EFI_STATUS Status; > + VOID > *MicrocodePatchScratchBuffer; > + UINT8 *ScratchBufferPtr; > + UINTN ScratchBufferSize; > + UINTN RestSize; > + UINTN AvailableSize; > + VOID *NextMicrocodeEntryPoint; > + VOID *EmptyFitMicrocodeEntry; > + VOID *UnusedFitMicrocodeEntry; > + > + DEBUG((DEBUG_INFO, "UpdateMicrocodeFlashRegionWithFit: Image - 0x%x, > size - 0x%x\n", Image, ImageSize)); > + > + MicrocodePatchAddress =3D MicrocodeFmpPrivate->MicrocodePatchAddress; > + MicrocodePatchRegionSize =3D > MicrocodeFmpPrivate->MicrocodePatchRegionSize; > + > + MicrocodePatchScratchBuffer =3D AllocateZeroPool > (MicrocodePatchRegionSize); > + if (MicrocodePatchScratchBuffer =3D=3D NULL) { > + DEBUG((DEBUG_ERROR, "Fail to allocate Microcode Scratch buffer\n")); > + *LastAttemptStatus =3D > LAST_ATTEMPT_STATUS_ERROR_INSUFFICIENT_RESOURCES; > + return EFI_OUT_OF_RESOURCES; > + } > + ScratchBufferPtr =3D MicrocodePatchScratchBuffer; > + ScratchBufferSize =3D 0; > + > + // > + // Target data collection > + // > + TargetTotalSize =3D 0; > + AvailableSize =3D 0; > + if (TargetMicrocodeEntryPoint !=3D NULL) { > + if (TargetMicrocodeEntryPoint->DataSize =3D=3D 0) { > + TargetTotalSize =3D 2048; > + } else { > + TargetTotalSize =3D TargetMicrocodeEntryPoint->TotalSize; > + } > + DEBUG((DEBUG_INFO, " TargetTotalSize - 0x%x\n", TargetTotalSize)); > + NextMicrocodeEntryPoint =3D GetNextFitMicrocode (MicrocodeFmpPrivate= , > TargetMicrocodeEntryPoint); > + DEBUG((DEBUG_INFO, " NextMicrocodeEntryPoint - 0x%x\n", > NextMicrocodeEntryPoint)); > + if (NextMicrocodeEntryPoint !=3D NULL) { > + ASSERT ((UINTN) NextMicrocodeEntryPoint >=3D ((UINTN) > TargetMicrocodeEntryPoint + TargetTotalSize)); > + AvailableSize =3D (UINTN) NextMicrocodeEntryPoint - (UINTN) > TargetMicrocodeEntryPoint; > + } else { > + AvailableSize =3D (UINTN) MicrocodePatchAddress + > MicrocodePatchRegionSize - (UINTN) TargetMicrocodeEntryPoint; > + } > + DEBUG((DEBUG_INFO, " AvailableSize - 0x%x\n", AvailableSize)); > + ASSERT (AvailableSize >=3D TargetTotalSize); > + } > + // > + // Total Size means the Microcode size. > + // Available Size means the Microcode size plus the pad till (1) next > Microcode or (2) the end. > + // > + // (1) > + // +------+-----------+-----+------+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D+ > + // | MCU1 | Microcode | PAD | MCU2 | Empty | > + // +------+-----------+-----+------+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D+ > + // | TotalSize | > + // |<-AvailableSize->| > + // > + // (2) > + // +------+-----------+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D+ > + // | MCU | Microcode | Empty | > + // +------+-----------+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D+ > + // | TotalSize | > + // |<- AvailableSize ->| > + // > + > + // > + // Update based on policy > + // > + > + // > + // 1. If there is enough space to update old one in situ, replace old = microcode > in situ. > + // > + if (AvailableSize >=3D ImageSize) { > + DEBUG((DEBUG_INFO, "Replace old microcode in situ\n")); > + // > + // +------+------------+------+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D+ > + // |Other | Old Image | ... | Empty | > + // +------+------------+------+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D+ > + // > + // +------+---------+--+------+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D+ > + // |Other |New Image|FF| ... | Empty | > + // +------+---------+--+------+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D+ > + // > + // 1.1. Copy new image > + CopyMem (ScratchBufferPtr, Image, ImageSize); > + ScratchBufferSize +=3D ImageSize; > + ScratchBufferPtr =3D (UINT8 *)MicrocodePatchScratchBuffer + > ScratchBufferSize; > + // 1.2. Pad 0xFF > + RestSize =3D AvailableSize - ImageSize; > + if (RestSize > 0) { > + SetMem (ScratchBufferPtr, RestSize, 0xFF); > + ScratchBufferSize +=3D RestSize; > + ScratchBufferPtr =3D (UINT8 *)MicrocodePatchScratchBuffer + > ScratchBufferSize; > + } > + Status =3D UpdateMicrocode((UINTN)TargetMicrocodeEntryPoint, > MicrocodePatchScratchBuffer, ScratchBufferSize, LastAttemptStatus); > + return Status; > + } > + > + // > + // 2. If there is empty FIT microcode entry with enough space, use it. > + // > + EmptyFitMicrocodeEntry =3D FindEmptyFitMicrocode (MicrocodeFmpPrivate, > ImageSize, &AvailableSize); > + if (EmptyFitMicrocodeEntry !=3D NULL) { > + DEBUG((DEBUG_INFO, "Use empty FIT microcode entry\n")); > + // 2.1. Copy new image > + CopyMem (ScratchBufferPtr, Image, ImageSize); > + ScratchBufferSize +=3D ImageSize; > + ScratchBufferPtr =3D (UINT8 *)MicrocodePatchScratchBuffer + > ScratchBufferSize; > + // 2.2. Pad 0xFF > + RestSize =3D AvailableSize - ImageSize; > + if (RestSize > 0) { > + SetMem (ScratchBufferPtr, RestSize, 0xFF); > + ScratchBufferSize +=3D RestSize; > + ScratchBufferPtr =3D (UINT8 *)MicrocodePatchScratchBuffer + > ScratchBufferSize; > + } > + Status =3D UpdateMicrocode ((UINTN) EmptyFitMicrocodeEntry, > MicrocodePatchScratchBuffer, ScratchBufferSize, LastAttemptStatus); > + if (!EFI_ERROR (Status) && (TargetMicrocodeEntryPoint !=3D NULL)) { > + // > + // Empty old microcode. > + // > + ScratchBufferPtr =3D MicrocodePatchScratchBuffer; > + SetMem (ScratchBufferPtr, TargetTotalSize, 0xFF); > + ScratchBufferSize =3D TargetTotalSize; > + ScratchBufferPtr =3D (UINT8 *) MicrocodePatchScratchBuffer + > ScratchBufferSize; > + UpdateMicrocode ((UINTN) TargetMicrocodeEntryPoint, > MicrocodePatchScratchBuffer, ScratchBufferSize, LastAttemptStatus); > + } > + return Status; > + } > + > + // > + // 3. If there is unused microcode entry with enough space, use it. > + // > + UnusedFitMicrocodeEntry =3D FindUnusedFitMicrocode > (MicrocodeFmpPrivate, ImageSize, &AvailableSize); > + if (UnusedFitMicrocodeEntry !=3D NULL) { > + DEBUG((DEBUG_INFO, "Use unused FIT microcode entry\n")); > + // 3.1. Copy new image > + CopyMem (ScratchBufferPtr, Image, ImageSize); > + ScratchBufferSize +=3D ImageSize; > + ScratchBufferPtr =3D (UINT8 *)MicrocodePatchScratchBuffer + > ScratchBufferSize; > + // 3.2. Pad 0xFF > + RestSize =3D AvailableSize - ImageSize; > + if (RestSize > 0) { > + SetMem (ScratchBufferPtr, RestSize, 0xFF); > + ScratchBufferSize +=3D RestSize; > + ScratchBufferPtr =3D (UINT8 *)MicrocodePatchScratchBuffer + > ScratchBufferSize; > + } > + Status =3D UpdateMicrocode ((UINTN) UnusedFitMicrocodeEntry, > MicrocodePatchScratchBuffer, ScratchBufferSize, LastAttemptStatus); > + if (!EFI_ERROR (Status) && (TargetMicrocodeEntryPoint !=3D NULL)) { > + // > + // Empty old microcode. > + // > + ScratchBufferPtr =3D MicrocodePatchScratchBuffer; > + SetMem (ScratchBufferPtr, TargetTotalSize, 0xFF); > + ScratchBufferSize =3D TargetTotalSize; > + ScratchBufferPtr =3D (UINT8 *) MicrocodePatchScratchBuffer + > ScratchBufferSize; > + UpdateMicrocode ((UINTN) TargetMicrocodeEntryPoint, > MicrocodePatchScratchBuffer, ScratchBufferSize, LastAttemptStatus); > + } > + return Status; > + } > + > + // > + // 4. No usable FIT microcode entry. > + // > + DEBUG((DEBUG_ERROR, "No usable FIT microcode entry\n")); > + *LastAttemptStatus =3D > LAST_ATTEMPT_STATUS_ERROR_INSUFFICIENT_RESOURCES; > + Status =3D EFI_OUT_OF_RESOURCES; > + > + return Status; > +} > + > +/** > Update Microcode flash region. >=20 > @param[in] MicrocodeFmpPrivate The Microcode driver private > data > @@ -753,8 +1066,8 @@ UpdateMicrocodeFlashRegion ( > AvailableSize =3D (UINTN)MicrocodePatchAddress + > MicrocodePatchRegionSize - (UINTN)TargetMicrocodeEntryPoint; > } > DEBUG((DEBUG_INFO, " AvailableSize - 0x%x\n", AvailableSize)); > + ASSERT (AvailableSize >=3D TargetTotalSize); > } > - ASSERT (AvailableSize >=3D TargetTotalSize); > UsedRegionSize =3D > GetCurrentMicrocodeUsedRegionSize(MicrocodeFmpPrivate); > DEBUG((DEBUG_INFO, " UsedRegionSize - 0x%x\n", UsedRegionSize)); > ASSERT (UsedRegionSize >=3D TargetTotalSize); > @@ -762,8 +1075,8 @@ UpdateMicrocodeFlashRegion ( > ASSERT ((UINTN)MicrocodePatchAddress + UsedRegionSize >=3D > ((UINTN)TargetMicrocodeEntryPoint + TargetTotalSize)); > } > // > - // Total Size means the Microcode data size. > - // Available Size means the Microcode data size plus the pad till (1) = next > Microcode or (2) the end. > + // Total Size means the Microcode size. > + // Available Size means the Microcode size plus the pad till (1) next > Microcode or (2) the end. > // > // (1) > // +------+-----------+-----+------+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D+ > @@ -793,11 +1106,11 @@ UpdateMicrocodeFlashRegion ( > DEBUG((DEBUG_INFO, "Replace old microcode in situ\n")); > // > // +------+------------+------+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D+ > - // |Other1| Old Image |Other2| Empty | > + // |Other | Old Image | ... | Empty | > // +------+------------+------+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D+ > // > // +------+---------+--+------+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D+ > - // |Other1|New Image|FF|Other2| Empty | > + // |Other |New Image|FF| ... | Empty | > // +------+---------+--+------+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D+ > // > // 1.1. Copy new image > @@ -835,11 +1148,11 @@ UpdateMicrocodeFlashRegion ( > DEBUG((DEBUG_INFO, "Reorg and replace old microcode\n")); > // > // +------+------------+------+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D+ > - // |Other1| Old Image |Other2| Empty | > + // |Other | Old Image | ... | Empty | > // +------+------------+------+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D+ > // > // +------+---------------+------+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D+ > - // |Other1| New Image |Other2| Empty | > + // |Other | New Image | ... | Empty | > // +------+---------------+------+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D+ > // > // 2.1. Copy new image > @@ -849,7 +1162,7 @@ UpdateMicrocodeFlashRegion ( > // 2.2. Copy rest images after the old image. > if (NextMicrocodeEntryPoint !=3D 0) { > RestSize =3D (UINTN)MicrocodePatchAddress + UsedRegionSize - > ((UINTN)NextMicrocodeEntryPoint); > - CopyMem (ScratchBufferPtr, (UINT8 *)TargetMicrocodeEntryPoint + > TargetTotalSize, RestSize); > + CopyMem (ScratchBufferPtr, NextMicrocodeEntryPoint, RestSize); > ScratchBufferSize +=3D RestSize; > ScratchBufferPtr =3D (UINT8 *)MicrocodePatchScratchBuffer + > ScratchBufferSize; > } > @@ -932,7 +1245,7 @@ UpdateMicrocodeFlashRegion ( > call to FreePool(). >=20 > @retval EFI_SUCCESS The Microcode image is written. > - @retval EFI_VOLUME_CORRUPTED The Microcode image is corrupt. > + @retval EFI_VOLUME_CORRUPTED The Microcode image is > corrupted. > @retval EFI_INCOMPATIBLE_VERSION The Microcode image version is > incorrect. > @retval EFI_SECURITY_VIOLATION The Microcode image fails to load. > @retval EFI_WRITE_PROTECTED The flash device is read only. > @@ -963,7 +1276,6 @@ MicrocodeWrite ( > return EFI_OUT_OF_RESOURCES; > } >=20 > - *LastAttemptVersion =3D ((CPU_MICROCODE_HEADER > *)Image)->UpdateRevision; > TargetCpuIndex =3D (UINTN)-1; > Status =3D VerifyMicrocode(MicrocodeFmpPrivate, AlignedImage, ImageSiz= e, > TRUE, LastAttemptStatus, AbortReason, &TargetCpuIndex); > if (EFI_ERROR(Status)) { > @@ -972,6 +1284,7 @@ MicrocodeWrite ( > return Status; > } > DEBUG((DEBUG_INFO, "Pass VerifyMicrocode\n")); > + *LastAttemptVersion =3D ((CPU_MICROCODE_HEADER > *)Image)->UpdateRevision; >=20 > DEBUG((DEBUG_INFO, " TargetCpuIndex - 0x%x\n", TargetCpuIndex)); > ASSERT (TargetCpuIndex < MicrocodeFmpPrivate->ProcessorCount); > @@ -985,13 +1298,23 @@ MicrocodeWrite ( > } > DEBUG((DEBUG_INFO, " TargetMicrocodeEntryPoint - 0x%x\n", > TargetMicrocodeEntryPoint)); >=20 > - Status =3D UpdateMicrocodeFlashRegion( > - MicrocodeFmpPrivate, > - TargetMicrocodeEntryPoint, > - AlignedImage, > - ImageSize, > - LastAttemptStatus > - ); > + if (MicrocodeFmpPrivate->FitMicrocodeInfo !=3D NULL) { > + Status =3D UpdateMicrocodeFlashRegionWithFit ( > + MicrocodeFmpPrivate, > + TargetMicrocodeEntryPoint, > + AlignedImage, > + ImageSize, > + LastAttemptStatus > + ); > + } else { > + Status =3D UpdateMicrocodeFlashRegion ( > + MicrocodeFmpPrivate, > + TargetMicrocodeEntryPoint, > + AlignedImage, > + ImageSize, > + LastAttemptStatus > + ); > + } >=20 > FreePool(AlignedImage); >=20 > diff --git > a/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.h > b/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.h > index 4442032eb6b6..3f92c517a91c 100644 > --- a/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.= h > +++ > b/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.h > @@ -20,6 +20,8 @@ > #include > #include >=20 > +#include > + > #include > #include >=20 > @@ -58,6 +60,13 @@ typedef struct { > } MICROCODE_INFO; >=20 > typedef struct { > + CPU_MICROCODE_HEADER *MicrocodeEntryPoint; > + UINTN TotalSize; > + BOOLEAN InUse; > + BOOLEAN Empty; > +} FIT_MICROCODE_INFO; > + > +typedef struct { > UINTN CpuIndex; > UINT32 ProcessorSignature; > UINT8 PlatformId; > @@ -86,11 +95,13 @@ struct _MICROCODE_FMP_PRIVATE_DATA { > UINTN BspIndex; > UINTN ProcessorCount; > PROCESSOR_INFO *ProcessorInfo; > + UINT32 FitMicrocodeEntryCount; > + FIT_MICROCODE_INFO *FitMicrocodeInfo; > }; >=20 > typedef struct _MICROCODE_FMP_PRIVATE_DATA > MICROCODE_FMP_PRIVATE_DATA; >=20 > -#define MICROCODE_FMP_LAST_ATTEMPT_VARIABLE_NAME > L"MicrocodeLastAttempVar" > +#define MICROCODE_FMP_LAST_ATTEMPT_VARIABLE_NAME > L"MicrocodeLastAttemptVar" >=20 > /** > Returns a pointer to the MICROCODE_FMP_PRIVATE_DATA structure from > the input a as Fmp. > diff --git > a/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.i > nf > b/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.i > nf > index dbc90857a0a5..24f06c23d404 100644 > --- > a/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.i > nf > +++ > b/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.i > nf > @@ -3,7 +3,7 @@ > # > # Produce FMP instance to update Microcode. > # > -# Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved. > +# Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved. > # This program and the accompanying materials > # are licensed and made available under the terms and conditions of the= BSD > License > # which accompanies this distribution. The full text of the license ma= y be > found at > @@ -65,6 +65,7 @@ [Pcd] >=20 > [Depex] > gEfiVariableArchProtocolGuid AND > + gEfiVariableWriteArchProtocolGuid AND > gEfiMpServiceProtocolGuid >=20 > [UserExtensions.TianoCore."ExtraFiles"] > -- > 2.7.0.windows.1