--- /dev/null
+/** @file\r
+ This file declares EDKII Shadow Microcode PPI.\r
+\r
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef __PPI_SHADOW_MICROCODE_H__\r
+#define __PPI_SHADOW_MICROCODE_H__\r
+\r
+#define EDKII_PEI_SHADOW_MICROCODE_PPI_GUID \\r
+ { \\r
+ 0x430f6965, 0x9a69, 0x41c5, { 0x93, 0xed, 0x8b, 0xf0, 0x64, 0x35, 0xc1, 0xc6 } \\r
+ }\r
+\r
+typedef struct _EDKII_PEI_SHADOW_MICROCODE_PPI EDKII_PEI_SHADOW_MICROCODE_PPI;\r
+\r
+typedef struct {\r
+ UINT32 ProcessorSignature;\r
+ UINT8 PlatformId;\r
+} EDKII_PEI_MICROCODE_CPU_ID;\r
+\r
+/**\r
+ Shadow microcode update patches to memory.\r
+\r
+ The function is used for shadowing microcode update patches to a continuous memory.\r
+ It shall allocate memory buffer and only shadow the microcode patches for those\r
+ processors specified by MicrocodeCpuId array. The checksum verification may be\r
+ skiped in this function so the caller must perform checksum verification before\r
+ using the microcode patches in returned memory buffer.\r
+\r
+ @param[in] This The PPI instance pointer.\r
+ @param[in] CpuIdCount Number of elements in MicrocodeCpuId array.\r
+ @param[in] MicrocodeCpuId A pointer to an array of EDKII_PEI_MICROCODE_CPU_ID\r
+ structures.\r
+ @param[out] BufferSize Pointer to receive the total size of Buffer.\r
+ @param[out] Buffer Pointer to receive address of allocated memory\r
+ with microcode patches data in it.\r
+\r
+ @retval EFI_SUCCESS The microcode has been shadowed to memory.\r
+ @retval EFI_OUT_OF_RESOURCES The operation fails due to lack of resources.\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EDKII_PEI_SHADOW_MICROCODE) (\r
+ IN EDKII_PEI_SHADOW_MICROCODE_PPI *This,\r
+ IN UINTN CpuIdCount,\r
+ IN EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId,\r
+ OUT UINTN *BufferSize,\r
+ OUT VOID **Buffer\r
+ );\r
+\r
+///\r
+/// This PPI is installed by some platform or chipset-specific PEIM that\r
+/// abstracts handling microcode shadow support.\r
+///\r
+struct _EDKII_PEI_SHADOW_MICROCODE_PPI {\r
+ EDKII_PEI_SHADOW_MICROCODE ShadowMicrocode;\r
+};\r
+\r
+extern EFI_GUID gEdkiiPeiShadowMicrocodePpiGuid;\r
+\r
+#endif\r
+\r
gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONSUMES\r
gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode ## CONSUMES\r
gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate ## SOMETIMES_CONSUMES\r
- gUefiCpuPkgTokenSpaceGuid.PcdCpuShadowMicrocodeByFit ## CONSUMES\r
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES\r
\r
/** @file\r
MP initialize support functions for DXE phase.\r
\r
- Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
return Status;\r
}\r
+\r
+/**\r
+ This funtion will try to invoke platform specific microcode shadow logic to\r
+ relocate microcode update patches into memory.\r
+\r
+ @param[in] CpuMpData The pointer to CPU MP Data structure.\r
+\r
+ @retval EFI_SUCCESS Shadow microcode success.\r
+ @retval EFI_OUT_OF_RESOURCES No enough resource to complete the operation.\r
+ @retval EFI_UNSUPPORTED Can't find platform specific microcode shadow\r
+ PPI/Protocol.\r
+**/\r
+EFI_STATUS\r
+PlatformShadowMicrocode (\r
+ IN OUT CPU_MP_DATA *CpuMpData\r
+ )\r
+{\r
+ //\r
+ // There is no DXE version of platform shadow microcode protocol so far.\r
+ // A platform which only uses DxeMpInitLib instance could only supports\r
+ // the PCD based microcode shadowing.\r
+ //\r
+ return EFI_UNSUPPORTED;\r
+}\r
return;\r
}\r
\r
-/**\r
- Shadow the required microcode patches data into memory according to FIT microcode entry.\r
-\r
- @param[in, out] CpuMpData The pointer to CPU MP Data structure.\r
-\r
- @return EFI_SUCCESS Microcode patch is shadowed into memory.\r
- @return EFI_UNSUPPORTED FIT based microcode shadowing is not supported.\r
- @return EFI_OUT_OF_RESOURCES No enough memory resource.\r
- @return EFI_NOT_FOUND There is something wrong in FIT microcode entry.\r
-\r
-**/\r
-EFI_STATUS\r
-ShadowMicrocodePatchByFit (\r
- IN OUT CPU_MP_DATA *CpuMpData\r
- )\r
-{\r
- UINT64 FitPointer;\r
- FIRMWARE_INTERFACE_TABLE_ENTRY *FitEntry;\r
- UINT32 EntryNum;\r
- UINT32 Index;\r
- MICROCODE_PATCH_INFO *PatchInfoBuffer;\r
- UINTN MaxPatchNumber;\r
- CPU_MICROCODE_HEADER *MicrocodeEntryPoint;\r
- UINTN PatchCount;\r
- UINTN TotalSize;\r
- UINTN TotalLoadSize;\r
-\r
- if (!FeaturePcdGet (PcdCpuShadowMicrocodeByFit)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- FitPointer = *(UINT64 *) (UINTN) FIT_POINTER_ADDRESS;\r
- if ((FitPointer == 0) ||\r
- (FitPointer == 0xFFFFFFFFFFFFFFFF) ||\r
- (FitPointer == 0xEEEEEEEEEEEEEEEE)) {\r
- //\r
- // No FIT table.\r
- //\r
- ASSERT (FALSE);\r
- return EFI_NOT_FOUND;\r
- }\r
- FitEntry = (FIRMWARE_INTERFACE_TABLE_ENTRY *) (UINTN) FitPointer;\r
- if ((FitEntry[0].Type != FIT_TYPE_00_HEADER) ||\r
- (FitEntry[0].Address != FIT_TYPE_00_SIGNATURE)) {\r
- //\r
- // Invalid FIT table, treat it as no FIT table.\r
- //\r
- ASSERT (FALSE);\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- EntryNum = *(UINT32 *)(&FitEntry[0].Size[0]) & 0xFFFFFF;\r
-\r
- //\r
- // Calculate microcode entry number\r
- //\r
- MaxPatchNumber = 0;\r
- for (Index = 0; Index < EntryNum; Index++) {\r
- if (FitEntry[Index].Type == FIT_TYPE_01_MICROCODE) {\r
- MaxPatchNumber++;\r
- }\r
- }\r
- if (MaxPatchNumber == 0) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- PatchInfoBuffer = AllocatePool (MaxPatchNumber * sizeof (MICROCODE_PATCH_INFO));\r
- if (PatchInfoBuffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Fill up microcode patch info buffer according to FIT table.\r
- //\r
- PatchCount = 0;\r
- TotalLoadSize = 0;\r
- for (Index = 0; Index < EntryNum; Index++) {\r
- if (FitEntry[Index].Type == FIT_TYPE_01_MICROCODE) {\r
- MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (UINTN) FitEntry[Index].Address;\r
- TotalSize = (MicrocodeEntryPoint->DataSize == 0) ? 2048 : MicrocodeEntryPoint->TotalSize;\r
- if (IsMicrocodePatchNeedLoad (CpuMpData, MicrocodeEntryPoint)) {\r
- PatchInfoBuffer[PatchCount].Address = (UINTN) MicrocodeEntryPoint;\r
- PatchInfoBuffer[PatchCount].Size = TotalSize;\r
- TotalLoadSize += TotalSize;\r
- PatchCount++;\r
- }\r
- }\r
- }\r
-\r
- if (PatchCount != 0) {\r
- DEBUG ((\r
- DEBUG_INFO,\r
- "%a: 0x%x microcode patches will be loaded into memory, with size 0x%x.\n",\r
- __FUNCTION__, PatchCount, TotalLoadSize\r
- ));\r
-\r
- ShadowMicrocodePatchWorker (CpuMpData, PatchInfoBuffer, PatchCount, TotalLoadSize);\r
- }\r
-\r
- FreePool (PatchInfoBuffer);\r
- return EFI_SUCCESS;\r
-}\r
-\r
/**\r
Shadow the required microcode patches data into memory.\r
\r
{\r
EFI_STATUS Status;\r
\r
- Status = ShadowMicrocodePatchByFit (CpuMpData);\r
+ Status = PlatformShadowMicrocode (CpuMpData);\r
if (EFI_ERROR (Status)) {\r
ShadowMicrocodePatchByPcd (CpuMpData);\r
}\r
\r
#include <Guid/MicrocodePatchHob.h>\r
\r
-#include <IndustryStandard/FirmwareInterfaceTable.h>\r
-\r
-\r
#define WAKEUP_AP_SIGNAL SIGNATURE_32 ('S', 'T', 'A', 'P')\r
\r
#define CPU_INIT_MP_LIB_HOB_GUID \\r
OUT UINTN *ProcessorNumber\r
);\r
\r
+/**\r
+ This funtion will try to invoke platform specific microcode shadow logic to\r
+ relocate microcode update patches into memory.\r
+\r
+ @param[in] CpuMpData The pointer to CPU MP Data structure.\r
+\r
+ @retval EFI_SUCCESS Shadow microcode success.\r
+ @retval EFI_OUT_OF_RESOURCES No enough resource to complete the operation.\r
+ @retval EFI_UNSUPPORTED Can't find platform specific microcode shadow\r
+ PPI/Protocol.\r
+**/\r
+EFI_STATUS\r
+PlatformShadowMicrocode (\r
+ IN OUT CPU_MP_DATA *CpuMpData\r
+ );\r
+\r
#endif\r
\r
gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONSUMES\r
gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode ## CONSUMES\r
gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate ## SOMETIMES_CONSUMES\r
- gUefiCpuPkgTokenSpaceGuid.PcdCpuShadowMicrocodeByFit ## CONSUMES\r
+\r
+[Ppis]\r
+ gEdkiiPeiShadowMicrocodePpiGuid ## SOMETIMES_CONSUMES\r
\r
[Guids]\r
gEdkiiS3SmmInitDoneGuid\r
#include "MpLib.h"\r
#include <Library/PeiServicesLib.h>\r
#include <Guid/S3SmmInitDone.h>\r
+#include <Ppi/ShadowMicrocode.h>\r
\r
/**\r
S3 SMM Init Done notification function.\r
return EnableDisableApWorker (ProcessorNumber, EnableAP, HealthFlag);\r
}\r
\r
+/**\r
+ This funtion will try to invoke platform specific microcode shadow logic to\r
+ relocate microcode update patches into memory.\r
+\r
+ @param[in] CpuMpData The pointer to CPU MP Data structure.\r
\r
+ @retval EFI_SUCCESS Shadow microcode success.\r
+ @retval EFI_OUT_OF_RESOURCES No enough resource to complete the operation.\r
+ @retval EFI_UNSUPPORTED Can't find platform specific microcode shadow\r
+ PPI/Protocol.\r
+**/\r
+EFI_STATUS\r
+PlatformShadowMicrocode (\r
+ IN OUT CPU_MP_DATA *CpuMpData\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EDKII_PEI_SHADOW_MICROCODE_PPI *ShadowMicrocodePpi;\r
+ UINTN CpuCount;\r
+ EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId;\r
+ UINTN Index;\r
+ UINTN BufferSize;\r
+ VOID *Buffer;\r
+\r
+ Status = PeiServicesLocatePpi (\r
+ &gEdkiiPeiShadowMicrocodePpiGuid,\r
+ 0,\r
+ NULL,\r
+ (VOID **) &ShadowMicrocodePpi\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ CpuCount = CpuMpData->CpuCount;\r
+ MicrocodeCpuId = (EDKII_PEI_MICROCODE_CPU_ID *) AllocateZeroPool (sizeof (EDKII_PEI_MICROCODE_CPU_ID) * CpuCount);\r
+ if (MicrocodeCpuId == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ for (Index = 0; Index < CpuMpData->CpuCount; Index++) {\r
+ MicrocodeCpuId[Index].ProcessorSignature = CpuMpData->CpuData[Index].ProcessorSignature;\r
+ MicrocodeCpuId[Index].PlatformId = CpuMpData->CpuData[Index].PlatformId;\r
+ }\r
+\r
+ Status = ShadowMicrocodePpi->ShadowMicrocode (\r
+ ShadowMicrocodePpi,\r
+ CpuCount,\r
+ MicrocodeCpuId,\r
+ &BufferSize,\r
+ &Buffer\r
+ );\r
+ FreePool (MicrocodeCpuId);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ CpuMpData->MicrocodePatchAddress = (UINTN) Buffer;\r
+ CpuMpData->MicrocodePatchRegionSize = BufferSize;\r
+\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "%a: Required microcode patches have been loaded at 0x%lx, with size 0x%lx.\n",\r
+ __FUNCTION__, CpuMpData->MicrocodePatchAddress, CpuMpData->MicrocodePatchRegionSize\r
+ ));\r
+\r
+ return EFI_SUCCESS;\r
+}\r
## @file UefiCpuPkg.dec\r
# This Package provides UEFI compatible CPU modules and libraries.\r
#\r
-# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.<BR>\r
#\r
# SPDX-License-Identifier: BSD-2-Clause-Patent\r
#\r
[Ppis]\r
gEdkiiPeiMpServices2PpiGuid = { 0x5cb9cb3d, 0x31a4, 0x480c, { 0x94, 0x98, 0x29, 0xd2, 0x69, 0xba, 0xcf, 0xba}}\r
\r
+ ## Include/Ppi/ShadowMicrocode.h\r
+ gEdkiiPeiShadowMicrocodePpiGuid = { 0x430f6965, 0x9a69, 0x41c5, { 0x93, 0xed, 0x8b, 0xf0, 0x64, 0x35, 0xc1, 0xc6 }}\r
+\r
[PcdsFeatureFlag]\r
## Indicates if SMM Profile will be enabled.\r
# If enabled, instruction executions in and data accesses to memory outside of SMRAM will be logged.\r
# @Prompt Lock SMM Feature Control MSR.\r
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmFeatureControlMsrLock|TRUE|BOOLEAN|0x3213210B\r
\r
- ## Indicates if FIT based microcode shadowing will be enabled.<BR><BR>\r
- # TRUE - FIT base microcode shadowing will be enabled.<BR>\r
- # FALSE - FIT base microcode shadowing will be disabled.<BR>\r
- # @Prompt FIT based microcode shadowing.\r
- gUefiCpuPkgTokenSpaceGuid.PcdCpuShadowMicrocodeByFit|FALSE|BOOLEAN|0x3213210D\r
-\r
[PcdsFixedAtBuild]\r
## List of exception vectors which need switching stack.\r
# This PCD will only take into effect if PcdCpuStackGuard is enabled.\r
"TRUE - locked.<BR>\n"\r
"FALSE - unlocked.<BR>"\r
\r
-#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuShadowMicrocodeByFit_PROMPT #language en-US "FIT based microcode shadowing"\r
-\r
-#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuShadowMicrocodeByFit_HELP #language en-US "Indicates if FIT based microcode shadowing will be enabled.<BR><BR>\n"\r
- "TRUE - FIT base microcode shadowing will be enabled.<BR>\n"\r
- "FALSE - FIT base microcode shadowing will be disabled.<BR>"\r
-\r
#string STR_gUefiCpuPkgTokenSpaceGuid_PcdPeiTemporaryRamStackSize_PROMPT #language en-US "Stack size in the temporary RAM"\r
\r
#string STR_gUefiCpuPkgTokenSpaceGuid_PcdPeiTemporaryRamStackSize_HELP #language en-US "Specifies stack size in the temporary RAM. 0 means half of TemporaryRamSize."\r