From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by mx.groups.io with SMTP id smtpd.web12.6637.1582079462337134751 for ; Tue, 18 Feb 2020 18:31:02 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 134.134.136.20, mailfrom: ray.ni@intel.com) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 18 Feb 2020 18:31:01 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,458,1574150400"; d="scan'208";a="282974278" Received: from fmsmsx103.amr.corp.intel.com ([10.18.124.201]) by FMSMGA003.fm.intel.com with ESMTP; 18 Feb 2020 18:31:01 -0800 Received: from fmsmsx601.amr.corp.intel.com (10.18.126.81) by FMSMSX103.amr.corp.intel.com (10.18.124.201) with Microsoft SMTP Server (TLS) id 14.3.439.0; Tue, 18 Feb 2020 18:31:00 -0800 Received: from fmsmsx601.amr.corp.intel.com (10.18.126.81) by fmsmsx601.amr.corp.intel.com (10.18.126.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Tue, 18 Feb 2020 18:31:00 -0800 Received: from shsmsx103.ccr.corp.intel.com (10.239.4.69) by fmsmsx601.amr.corp.intel.com (10.18.126.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) id 15.1.1713.5 via Frontend Transport; Tue, 18 Feb 2020 18:30:59 -0800 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.5]) by SHSMSX103.ccr.corp.intel.com ([169.254.4.196]) with mapi id 14.03.0439.000; Wed, 19 Feb 2020 10:30:57 +0800 From: "Ni, Ray" To: "Fu, Siyuan" , "devel@edk2.groups.io" CC: "Kinney, Michael D" , "Chaganty, Rangasai V" Subject: Re: [PATCH v5] IntelSiliconPkg: FIT based shadow microcode PPI support. Thread-Topic: [PATCH v5] IntelSiliconPkg: FIT based shadow microcode PPI support. Thread-Index: AQHV5TO5wKdfnQrH0kyeS1PkhFkvO6ghydPg Date: Wed, 19 Feb 2020 02:30:56 +0000 Message-ID: <734D49CCEBEEF84792F5B80ED585239D5C44414F@SHSMSX104.ccr.corp.intel.com> References: <2f87cb365f721e89057a5f2eb598bb1221c73ddd.1581903801.git.siyuan.fu@intel.com> In-Reply-To: <2f87cb365f721e89057a5f2eb598bb1221c73ddd.1581903801.git.siyuan.fu@intel.com> Accept-Language: en-US, zh-CN X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-version: 11.2.0.6 dlp-reaction: no-action x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Return-Path: ray.ni@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable 1. EFIAPI is missing for ShadowMicrocode() 2. What's the reason of creating a separate function ShadowMicrocodePatchBy= Fit ()? Is that because you think this PEIM may support other uCode load me= chanism than FIT? If no, can you merge the *ByFit() to ShadowMicrocode()? 3. "Invalid FIT point" -> "Invalid FIT pointer" 4. According to FIT spec, I think you missed three additional checks on the= FIT Header: a). Just one Type 0 entry in FIT b). If C_V is set, FIT table checksum must be 0. c). Version should be 0x0100. More checks can make sure that we are visiting the real FIT. Because fr= om the spec, we have no other way to know whether a FIT really exists from = data not from FIT itself. > -----Original Message----- > From: Fu, Siyuan > Sent: Monday, February 17, 2020 9:44 AM > To: devel@edk2.groups.io > Cc: Kinney, Michael D ; Ni, Ray ; Chaganty, Rangasai V > > Subject: [PATCH v5] IntelSiliconPkg: FIT based shadow microcode PPI suppo= rt. >=20 > V5 Changes: > Add FIT address check to see if it's in valid firmware region. > V4 Changes: > Adjust EDKII_MICROCODE_SHADOW_INFO_HOB structure definition for > better alignment and understanding. > Add EFI_MICROCODE_STORAGE_TYPE_FLASH_CONTEXT structure definition. > Fix a typo in EFI_MICROCODE_STORAGE_TYPE_FLASH_GUID. > Merge ShadowMicrocodePei.h header into c file. > Correct file header description and copy right year. > V3 Changes: > Remove the feature PCD PcdCpuShadowMicrocodeByFit because the > whole FIT microcode shadow code is moved to this PEIM so platform > could disable this feature by not include PEIM now. > V2 Changes: > Rename EDKII_PEI_CPU_MICROCODE_ID to EDKII_PEI_MICROCODE_CPU_ID. >=20 > This patch adds a platform PEIM for FIT based shadow microcode PPI > support. A detailed design doc can be found here: > https://edk2.groups.io/g/devel/files/Designs/2020/0214/Support%20 > the%202nd%20Microcode%20FV%20Flash%20Region.pdf >=20 > TEST: Tested on FIT enabled platform. > BZ: https://tianocore.acgmultimedia.com/show_bug.cgi?id=3D2449 >=20 > Cc: Michael D Kinney > Cc: Ray Ni > Cc: Rangasai V Chaganty > Signed-off-by: Siyuan Fu > --- > .../ShadowMicrocode/ShadowMicrocodePei.c | 446 ++++++++++++++++++ > .../ShadowMicrocode/ShadowMicrocodePei.inf | 43 ++ > .../Include/Guid/MicrocodeShadowInfoHob.h | 64 +++ > .../Intel/IntelSiliconPkg/IntelSiliconPkg.dec | 8 +- > .../Intel/IntelSiliconPkg/IntelSiliconPkg.dsc | 3 +- > 5 files changed, 562 insertions(+), 2 deletions(-) > create mode 100644 Silicon/Intel/IntelSiliconPkg/Feature/ShadowMicrocode= /ShadowMicrocodePei.c > create mode 100644 Silicon/Intel/IntelSiliconPkg/Feature/ShadowMicrocode= /ShadowMicrocodePei.inf > create mode 100644 Silicon/Intel/IntelSiliconPkg/Include/Guid/MicrocodeS= hadowInfoHob.h >=20 > diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/ShadowMicrocode/Shadow= MicrocodePei.c > b/Silicon/Intel/IntelSiliconPkg/Feature/ShadowMicrocode/ShadowMicrocodePe= i.c > new file mode 100644 > index 0000000000..e130f61fb0 > --- /dev/null > +++ b/Silicon/Intel/IntelSiliconPkg/Feature/ShadowMicrocode/ShadowMicroco= dePei.c > @@ -0,0 +1,446 @@ > +/** @file > + FIT based microcode shadow PEIM. > + > +Copyright (c) 2020, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +// > +// Data structure for microcode patch information > +// > +typedef struct { > + UINTN Address; > + UINTN Size; > +} MICROCODE_PATCH_INFO; > + > +/** > + Shadow microcode update patches to memory. > + > + The function is used for shadowing microcode update patches to a conti= nuous memory. > + It shall allocate memory buffer and only shadow the microcode patches = for those > + processors specified by MicrocodeCpuId array. The checksum verificatio= n may be > + skiped in this function so the caller must perform checksum verificati= on before > + using the microcode patches in returned memory buffer. > + > + @param[in] This The PPI instance pointer. > + @param[in] CpuIdCount Number of elements in MicrocodeCpuId = array. > + @param[in] MicrocodeCpuId A pointer to an array of EDKII_PEI_MI= CROCODE_CPU_ID > + structures. > + @param[out] BufferSize Pointer to receive the total size of = Buffer. > + @param[out] Buffer Pointer to receive address of allocat= ed memory > + with microcode patches data in it. > + > + @retval EFI_SUCCESS The microcode has been shadowed to me= mory. > + @retval EFI_OUT_OF_RESOURCES The operation fails due to lack of re= sources. > + > +**/ > +EFI_STATUS > +ShadowMicrocode ( > + IN EDKII_PEI_SHADOW_MICROCODE_PPI *This, > + IN UINTN CpuIdCount, > + IN EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId, > + OUT UINTN *BufferSize, > + OUT VOID **Buffer > + ); > + > + > +EDKII_PEI_SHADOW_MICROCODE_PPI mPeiShadowMicrocodePpi =3D { > + ShadowMicrocode > +}; > + > + > +EFI_PEI_PPI_DESCRIPTOR mPeiShadowMicrocodePpiList[] =3D { > + { > + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, > + &gEdkiiPeiShadowMicrocodePpiGuid, > + &mPeiShadowMicrocodePpi > + } > +}; > + > +/** > + Determine if a microcode patch matchs the specific processor signature= and flag. > + > + @param[in] CpuIdCount Number of elements in MicrocodeCpuId= array. > + @param[in] MicrocodeCpuId A pointer to an array of EDKII_PEI_M= ICROCODE_CPU_ID > + structures. > + @param[in] ProcessorSignature The processor signature field value > + supported by a microcode patch. > + @param[in] ProcessorFlags The prcessor flags field value suppo= rted by > + a microcode patch. > + > + @retval TRUE The specified microcode patch will be loaded. > + @retval FALSE The specified microcode patch will not be loaded. > +**/ > +BOOLEAN > +IsProcessorMatchedMicrocodePatch ( > + IN UINTN CpuIdCount, > + IN EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId, > + IN UINT32 ProcessorSignature, > + IN UINT32 ProcessorFlags > + ) > +{ > + UINTN Index; > + > + for (Index =3D 0; Index < CpuIdCount; Index++) { > + if ((ProcessorSignature =3D=3D MicrocodeCpuId[Index].ProcessorSignat= ure) && > + (ProcessorFlags & (1 << MicrocodeCpuId[Index].PlatformId)) !=3D = 0) { > + return TRUE; > + } > + } > + > + return FALSE; > +} > + > +/** > + Check the 'ProcessorSignature' and 'ProcessorFlags' of the microcode > + patch header with the CPUID and PlatformID of the processors within > + system to decide if it will be copied into memory. > + > + @param[in] CpuIdCount Number of elements in MicrocodeCpuId= array. > + @param[in] MicrocodeCpuId A pointer to an array of EDKII_PEI_M= ICROCODE_CPU_ID > + structures. > + @param[in] MicrocodeEntryPoint The pointer to the microcode patch h= eader. > + > + @retval TRUE The specified microcode patch need to be loaded. > + @retval FALSE The specified microcode patch dosen't need to be load= ed. > +**/ > +BOOLEAN > +IsMicrocodePatchNeedLoad ( > + IN UINTN CpuIdCount, > + IN EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId, > + CPU_MICROCODE_HEADER *MicrocodeEntryPoint > + ) > +{ > + BOOLEAN NeedLoad; > + UINTN DataSize; > + UINTN TotalSize; > + CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader; > + UINT32 ExtendedTableCount; > + CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable; > + UINTN Index; > + > + // > + // Check the 'ProcessorSignature' and 'ProcessorFlags' in microcode pa= tch header. > + // > + NeedLoad =3D IsProcessorMatchedMicrocodePatch ( > + CpuIdCount, > + MicrocodeCpuId, > + MicrocodeEntryPoint->ProcessorSignature.Uint32, > + MicrocodeEntryPoint->ProcessorFlags > + ); > + > + // > + // If the Extended Signature Table exists, check if the processor is i= n the > + // support list > + // > + DataSize =3D MicrocodeEntryPoint->DataSize; > + TotalSize =3D (DataSize =3D=3D 0) ? 2048 : MicrocodeEntryPoint->TotalS= ize; > + if ((!NeedLoad) && (DataSize !=3D 0) && > + (TotalSize - DataSize > sizeof (CPU_MICROCODE_HEADER) + > + sizeof (CPU_MICROCODE_EXTENDED_TABLE_HEADE= R))) { > + ExtendedTableHeader =3D (CPU_MICROCODE_EXTENDED_TABLE_HEADER *) ((UI= NT8 *) (MicrocodeEntryPoint) > + + DataSize + sizeof (CPU_MICROCODE_HEADER)); > + ExtendedTableCount =3D ExtendedTableHeader->ExtendedSignatureCount; > + ExtendedTable =3D (CPU_MICROCODE_EXTENDED_TABLE *) (ExtendedTa= bleHeader + 1); > + > + for (Index =3D 0; Index < ExtendedTableCount; Index ++) { > + // > + // Check the 'ProcessorSignature' and 'ProcessorFlag' of the Exten= ded > + // Signature Table entry with the CPUID and PlatformID of the proc= essors > + // within system to decide if it will be copied into memory > + // > + NeedLoad =3D IsProcessorMatchedMicrocodePatch ( > + CpuIdCount, > + MicrocodeCpuId, > + ExtendedTable->ProcessorSignature.Uint32, > + ExtendedTable->ProcessorFlag > + ); > + if (NeedLoad) { > + break; > + } > + ExtendedTable ++; > + } > + } > + > + return NeedLoad; > +} > + > +/** > + Actual worker function that shadows the required microcode patches int= o memory. > + > + @param[in] Patches The pointer to an array of informati= on on > + the microcode patches that will be l= oaded > + into memory. > + @param[in] PatchCount The number of microcode patches that= will > + be loaded into memory. > + @param[in] TotalLoadSize The total size of all the microcode = patches > + to be loaded. > + @param[out] BufferSize Pointer to receive the total size of= Buffer. > + @param[out] Buffer Pointer to receive address of alloca= ted memory > + with microcode patches data in it. > +**/ > +VOID > +ShadowMicrocodePatchWorker ( > + IN MICROCODE_PATCH_INFO *Patches, > + IN UINTN PatchCount, > + IN UINTN TotalLoadSize, > + OUT UINTN *BufferSize, > + OUT VOID **Buffer > + ) > +{ > + UINTN Index; > + VOID *MicrocodePatchInRam; > + UINT8 *Walker; > + EDKII_MICROCODE_SHADOW_INFO_HOB *MicrocodeShadowHob; > + UINTN HobDataLength; > + UINT64 *MicrocodeAddressInMemory; > + EFI_MICROCODE_STORAGE_TYPE_FLASH_CONTEXT *Flashcontext; > + > + ASSERT ((Patches !=3D NULL) && (PatchCount !=3D 0)); > + > + // > + // Init microcode shadow info HOB content. > + // > + HobDataLength =3D sizeof (EDKII_MICROCODE_SHADOW_INFO_HOB) + > + sizeof (UINT64) * PatchCount * 2; > + MicrocodeShadowHob =3D AllocatePool (HobDataLength); > + if (MicrocodeShadowHob =3D=3D NULL) { > + ASSERT (FALSE); > + return; > + } > + MicrocodeShadowHob->MicrocodeCount =3D PatchCount; > + CopyGuid ( > + &MicrocodeShadowHob->StorageType, > + &gEdkiiMicrocodeStorageTypeFlashGuid > + ); > + MicrocodeAddressInMemory =3D (UINT64 *) (MicrocodeShadowHob + 1); > + Flashcontext =3D (EFI_MICROCODE_STORAGE_TYPE_FLASH_CONTEXT *) (Microco= deAddressInMemory + PatchCount); > + > + // > + // Allocate memory for microcode shadow operation. > + // > + MicrocodePatchInRam =3D AllocatePages (EFI_SIZE_TO_PAGES (TotalLoadSiz= e)); > + if (MicrocodePatchInRam =3D=3D NULL) { > + ASSERT (FALSE); > + return; > + } > + > + // > + // Shadow all the required microcode patches into memory > + // > + for (Walker =3D MicrocodePatchInRam, Index =3D 0; Index < PatchCount; = Index++) { > + CopyMem ( > + Walker, > + (VOID *) Patches[Index].Address, > + Patches[Index].Size > + ); > + MicrocodeAddressInMemory[Index] =3D (UINT64) Walker; > + Flashcontext->MicrocodeAddressInFlash[Index] =3D (UINT64) Patches[I= ndex].Address; > + Walker +=3D Patches[Index].Size; > + } > + > + // > + // Update the microcode patch related fields in CpuMpData > + // > + *Buffer =3D (VOID *) (UINTN) MicrocodePatchInRam; > + *BufferSize =3D TotalLoadSize; > + > + BuildGuidDataHob ( > + &gEdkiiMicrocodeShadowInfoHobGuid, > + MicrocodeShadowHob, > + HobDataLength > + ); > + > + DEBUG (( > + DEBUG_INFO, > + "%a: Required microcode patches have been loaded at 0x%lx, with size= 0x%lx.\n", > + __FUNCTION__, *Buffer, *BufferSize > + )); > + > + return; > +} > + > +/** > + Shadow the required microcode patches data into memory according > + to FIT microcode entry. > + > +**/ > +EFI_STATUS > +ShadowMicrocodePatchByFit ( > + IN UINTN CpuIdCount, > + IN EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId, > + OUT UINTN *BufferSize, > + OUT VOID **Buffer > + ) > +{ > + UINT64 FitPointer; > + UINT64 FitEnding; > + FIRMWARE_INTERFACE_TABLE_ENTRY *FitEntry; > + UINT32 EntryNum; > + UINT32 Index; > + MICROCODE_PATCH_INFO *PatchInfoBuffer; > + UINTN MaxPatchNumber; > + CPU_MICROCODE_HEADER *MicrocodeEntryPoint; > + UINTN PatchCount; > + UINTN TotalSize; > + UINTN TotalLoadSize; > + > + FitPointer =3D *(UINT64 *) (UINTN) FIT_POINTER_ADDRESS; > + > + // > + // The entire FIT table must reside with in the firmware address range > + // of (4GB-16MB) to (4GB-40h). > + // > + if ((FitPointer < (SIZE_4GB - SIZE_16MB)) || (FitPointer >=3D (SIZE_4G= B - 0x40))) { > + // > + // Invalid FIT address, treat it as no FIT table. > + // > + DEBUG ((DEBUG_ERROR, "Error: Invalid FIT point 0x%p.\n", FitPointer)= ); > + return EFI_NOT_FOUND; > + } > + 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 header, treat it as no FIT table. > + // > + DEBUG ((DEBUG_ERROR, "Error: Invalid FIT header.\n")); > + return EFI_NOT_FOUND; > + } > + EntryNum =3D *(UINT32 *)(&FitEntry[0].Size[0]) & 0xFFFFFF; > + FitEnding =3D FitPointer + sizeof (FIRMWARE_INTERFACE_TABLE_ENTRY) * E= ntryNum; > + if (FitEnding > (SIZE_4GB - 0x40)) { > + // > + // Invalid FIT ending address, treat it as no FIT table. > + // > + DEBUG ((DEBUG_ERROR, "Error: FIT table exceeds valid range.\n")); > + return EFI_NOT_FOUND; > + } > + > + // > + // Calculate microcode entry number > + // > + MaxPatchNumber =3D 0; > + for (Index =3D 0; Index < EntryNum; Index++) { > + if (FitEntry[Index].Type =3D=3D FIT_TYPE_01_MICROCODE) { > + MaxPatchNumber++; > + } > + } > + if (MaxPatchNumber =3D=3D 0) { > + return EFI_NOT_FOUND; > + } > + > + PatchInfoBuffer =3D AllocatePool (MaxPatchNumber * sizeof (MICROCODE_P= ATCH_INFO)); > + if (PatchInfoBuffer =3D=3D NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + // > + // Fill up microcode patch info buffer according to FIT table. > + // > + PatchCount =3D 0; > + TotalLoadSize =3D 0; > + for (Index =3D 0; Index < EntryNum; Index++) { > + if (FitEntry[Index].Type =3D=3D FIT_TYPE_01_MICROCODE) { > + MicrocodeEntryPoint =3D (CPU_MICROCODE_HEADER *) (UINTN) FitEntry[= Index].Address; > + TotalSize =3D (MicrocodeEntryPoint->DataSize =3D=3D 0) ? 2048 : Mi= crocodeEntryPoint->TotalSize; > + if (IsMicrocodePatchNeedLoad (CpuIdCount, MicrocodeCpuId, Microcod= eEntryPoint)) { > + PatchInfoBuffer[PatchCount].Address =3D (UINTN) MicrocodeEnt= ryPoint; > + PatchInfoBuffer[PatchCount].Size =3D TotalSize; > + TotalLoadSize +=3D TotalSize; > + PatchCount++; > + } > + } > + } > + > + if (PatchCount !=3D 0) { > + DEBUG (( > + DEBUG_INFO, > + "%a: 0x%x microcode patches will be loaded into memory, with size = 0x%x.\n", > + __FUNCTION__, PatchCount, TotalLoadSize > + )); > + > + ShadowMicrocodePatchWorker (PatchInfoBuffer, PatchCount, TotalLoadSi= ze, BufferSize, Buffer); > + } > + > + FreePool (PatchInfoBuffer); > + return EFI_SUCCESS; > +} > + > + > +/** > + Shadow microcode update patches to memory. > + > + The function is used for shadowing microcode update patches to a conti= nuous memory. > + It shall allocate memory buffer and only shadow the microcode patches = for those > + processors specified by MicrocodeCpuId array. The checksum verificatio= n may be > + skiped in this function so the caller must perform checksum verificati= on before > + using the microcode patches in returned memory buffer. > + > + @param[in] This The PPI instance pointer. > + @param[in] CpuIdCount Number of elements in MicrocodeCpuId = array. > + @param[in] MicrocodeCpuId A pointer to an array of EDKII_PEI_MI= CROCODE_CPU_ID > + structures. > + @param[out] BufferSize Pointer to receive the total size of = Buffer. > + @param[out] Buffer Pointer to receive address of allocat= ed memory > + with microcode patches data in it. > + > + @retval EFI_SUCCESS The microcode has been shadowed to me= mory. > + @retval EFI_OUT_OF_RESOURCES The operation fails due to lack of re= sources. > + > +**/ > +EFI_STATUS > +ShadowMicrocode ( > + IN EDKII_PEI_SHADOW_MICROCODE_PPI *This, > + IN UINTN CpuIdCount, > + IN EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId, > + OUT UINTN *BufferSize, > + OUT VOID **Buffer > + ) > +{ > + if (BufferSize =3D=3D NULL || Buffer =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + return ShadowMicrocodePatchByFit (CpuIdCount, MicrocodeCpuId, BufferSi= ze, Buffer); > +} > + > + > +/** > + Platform Init PEI module entry point > + > + @param[in] FileHandle Not used. > + @param[in] PeiServices General purpose services available to= every PEIM. > + > + @retval EFI_SUCCESS The function completes successfully > + @retval EFI_OUT_OF_RESOURCES Insufficient resources to create data= base > +**/ > +EFI_STATUS > +EFIAPI > +ShadowMicrocodePeimInit ( > + IN EFI_PEI_FILE_HANDLE FileHandle, > + IN CONST EFI_PEI_SERVICES **PeiServices > + ) > +{ > + EFI_STATUS Status; > + > + // > + // Install EDKII Shadow Microcode PPI > + // > + Status =3D PeiServicesInstallPpi(mPeiShadowMicrocodePpiList); > + ASSERT_EFI_ERROR (Status); > + > + return Status; > +} > diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/ShadowMicrocode/Shadow= MicrocodePei.inf > b/Silicon/Intel/IntelSiliconPkg/Feature/ShadowMicrocode/ShadowMicrocodePe= i.inf > new file mode 100644 > index 0000000000..019400ab31 > --- /dev/null > +++ b/Silicon/Intel/IntelSiliconPkg/Feature/ShadowMicrocode/ShadowMicroco= dePei.inf > @@ -0,0 +1,43 @@ > +### @file > +# FIT based microcode shadow PEIM. > +# > +# Copyright (c) 2020, Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +### > + > +[Defines] > + INF_VERSION =3D 0x00010017 > + BASE_NAME =3D ShadowMicrocodePei > + FILE_GUID =3D 8af4cf68-ebe4-4b21-a008-0cb3da277be= 5 > + VERSION_STRING =3D 1.0 > + MODULE_TYPE =3D PEIM > + ENTRY_POINT =3D ShadowMicrocodePeimInit > + > +[Sources] > + ShadowMicrocodePei.c > + > +[LibraryClasses] > + PeimEntryPoint > + DebugLib > + MemoryAllocationLib > + BaseMemoryLib > + HobLib > + PeiServicesLib > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + UefiCpuPkg/UefiCpuPkg.dec > + IntelSiliconPkg/IntelSiliconPkg.dec > + > +[Ppis] > + gEdkiiPeiShadowMicrocodePpiGuid ## PRODUCES > + > +[Guids] > + gEdkiiMicrocodeShadowInfoHobGuid > + gEdkiiMicrocodeStorageTypeFlashGuid > + > +[Depex] > + TRUE > diff --git a/Silicon/Intel/IntelSiliconPkg/Include/Guid/MicrocodeShadowIn= foHob.h > b/Silicon/Intel/IntelSiliconPkg/Include/Guid/MicrocodeShadowInfoHob.h > new file mode 100644 > index 0000000000..d1a9d79a51 > --- /dev/null > +++ b/Silicon/Intel/IntelSiliconPkg/Include/Guid/MicrocodeShadowInfoHob.h > @@ -0,0 +1,64 @@ > +/** @file > + The definition for Microcode Shadow Info Hob. > + > + Copyright (c) 2019, Intel Corporation. All rights reserved.
> + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > + > +#ifndef _MICROCODE_SHADOW_INFO_HOB_H_ > +#define _MICROCODE_SHADOW_INFO_HOB_H_ > + > +/// > +/// The Global ID of a GUIDed HOB used to pass microcode shadow info to = DXE Driver. > +/// > +#define EDKII_MICROCODE_SHADOW_INFO_HOB_GUID \ > + { \ > + 0x658903f9, 0xda66, 0x460d, { 0x8b, 0xb0, 0x9d, 0x2d, 0xdf, 0x65, 0x= 44, 0x59 } \ > + } > + > +extern EFI_GUID gEdkiiMicrocodeShadowInfoHobGuid; > + > +typedef struct { > + // > + // An EFI_GUID that defines the contents of StorageContext. > + // > + GUID StorageType; > + // > + // Number of the microcode patches which have been > + // relocated to memory. > + // > + UINT64 MicrocodeCount; > + // > + // An array with MicrocodeCount elements that stores > + // the shadowed microcode patch address in memory. > + // > + UINT64 MicrocodeAddrInMemory[]; > + // > + // A buffer which contains details about the storage information > + // specific to StorageType. > + // > + // UINT8 StorageContext[]; > +} EDKII_MICROCODE_SHADOW_INFO_HOB; > + > +// > +// An EDKII_MICROCODE_SHADOW_INFO_HOB with StorageType set to below GUID= will have > +// the StorageContext of a EFI_MICROCODE_STORAGE_TYPE_FLASH_CONTEXT stru= cutre. > +// > +#define EFI_MICROCODE_STORAGE_TYPE_FLASH_GUID \ > + { \ > + 0x2cba01b3, 0xd391, 0x4598, { 0x8d, 0x89, 0xb7, 0xfc, 0x39, 0x22, 0x= fd, 0x71 } \ > + } > + > +extern EFI_GUID gEdkiiMicrocodeStorageTypeFlashGuid; > + > +typedef struct { > + // > + // An array with MicrocodeCount elements that stores the original > + // microcode patch address on flash. The address is placed in same > + // order as the microcode patches in MicrocodeAddrInMemory. > + // > + UINT64 MicrocodeAddressInFlash[]; > +} EFI_MICROCODE_STORAGE_TYPE_FLASH_CONTEXT; > + > +#endif > diff --git a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec b/Silicon/= Intel/IntelSiliconPkg/IntelSiliconPkg.dec > index 22ebf19c4e..3c49fb289c 100644 > --- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec > +++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec > @@ -3,7 +3,7 @@ > # > # This package provides common open source Intel silicon modules. > # > -# Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.
> +# Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.
> # SPDX-License-Identifier: BSD-2-Clause-Patent > # > ## > @@ -48,6 +48,12 @@ > ## HOB GUID to get memory information after MRC is done. The hob data = will be used to set the PMR ranges > gVtdPmrInfoDataHobGuid =3D {0x6fb61645, 0xf168, 0x46be, { 0x80, 0xec, = 0xb5, 0x02, 0x38, 0x5e, 0xe7, 0xe7 } } >=20 > + ## Include/Guid/MicrocodeShadowInfoHob.h > + gEdkiiMicrocodeShadowInfoHobGuid =3D { 0x658903f9, 0xda66, 0x460d, { 0= x8b, 0xb0, 0x9d, 0x2d, 0xdf, 0x65, 0x44, 0x59 } } > + > + ## Include/Guid/MicrocodeShadowInfoHob.h > + gEdkiiMicrocodeStorageTypeFlashGuid =3D { 0x2cba01b3, 0xd391, 0x4598, = { 0x8d, 0x89, 0xb7, 0xfc, 0x39, 0x22, 0xfd, 0x71 } } > + > [Ppis] > gEdkiiVTdInfoPpiGuid =3D { 0x8a59fcb3, 0xf191, 0x400c, { 0x97, 0x67, 0= x67, 0xaf, 0x2b, 0x25, 0x68, 0x4a } } >=20 > diff --git a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc b/Silicon/= Intel/IntelSiliconPkg/IntelSiliconPkg.dsc > index 0a6509d8b3..f995883691 100644 > --- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc > +++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc > @@ -1,7 +1,7 @@ > ## @file > # This package provides common open source Intel silicon modules. > # > -# Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.
> +# Copyright (c) 2017 - 2020, Intel Corporation. All rights reserved.
> # > # SPDX-License-Identifier: BSD-2-Clause-Patent > # > @@ -84,6 +84,7 @@ > IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSa= mplePei.inf > IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.= inf > IntelSiliconPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/Mi= crocodeFlashAccessLibNull.inf > + IntelSiliconPkg/Feature/ShadowMicrocode/ShadowMicrocodePei.inf > IntelSiliconPkg/Library/PeiDxeSmmBootMediaLib/PeiFirmwareBootMediaLib.= inf > IntelSiliconPkg/Library/PeiDxeSmmBootMediaLib/DxeSmmFirmwareBootMediaL= ib.inf >=20 > -- > 2.19.1.windows.1