summaryrefslogtreecommitdiffstats
path: root/UefiCpuPkg/Library
diff options
context:
space:
mode:
authorSiyuan Fu <siyuan.fu@intel.com>2020-02-11 21:30:48 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2020-02-14 04:31:18 +0000
commitc788c2b1ade657e01a63001e8fee621001404af7 (patch)
tree0c5376783cf05454937971adeb312aeb70762407 /UefiCpuPkg/Library
parent534fcb84decdd613cc35309f24e7b792b1928809 (diff)
downloadedk2-c788c2b1ade657e01a63001e8fee621001404af7.tar.gz
edk2-c788c2b1ade657e01a63001e8fee621001404af7.tar.bz2
edk2-c788c2b1ade657e01a63001e8fee621001404af7.zip
UefiCpuPkg: Remove FIT based microcode shadow logic from MpInitLib.
Commit c7c964b and dd01704 add header file for FIT table and update MpInitLib to support FIT based microcode shadow operation. There are comments that FIT is Intel specific specification instead of industry standard, which should not be placed in EDK2 MdePkg and UefiCpuPkg. So this patch adds a platform PPI for the microcode shadow logic, and remove the FIT related code from EDK2. The FIT based microcode shadow support will be implemented as a new platform PEIM in IntelSiliconPkg in edk2-platforms. This patch doesn't provide a DXE version shadow microcode protocol, a platform which only uses DxeMpInitLib instance only supports PCD based microcode shadowing. 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 TEST: Tested on FIT enabled platform. BZ: https://tianocore.acgmultimedia.com/show_bug.cgi?id=2449 Cc: Eric Dong <eric.dong@intel.com> Cc: Ray Ni <ray.ni@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Signed-off-by: Siyuan Fu <siyuan.fu@intel.com> Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Ray Ni <ray.ni@intel.com> Acked-by: Laszlo Ersek <lersek@redhat.com>
Diffstat (limited to 'UefiCpuPkg/Library')
-rw-r--r--UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf1
-rw-r--r--UefiCpuPkg/Library/MpInitLib/DxeMpLib.c26
-rw-r--r--UefiCpuPkg/Library/MpInitLib/Microcode.c105
-rw-r--r--UefiCpuPkg/Library/MpInitLib/MpLib.h19
-rw-r--r--UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf4
-rw-r--r--UefiCpuPkg/Library/MpInitLib/PeiMpLib.c68
6 files changed, 113 insertions, 110 deletions
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
index 9e6cce0895..45aaa179ff 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -69,6 +69,5 @@
gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate ## SOMETIMES_CONSUMES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuShadowMicrocodeByFit ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index b17e287bbf..a987c32109 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -1,7 +1,7 @@
/** @file
MP initialize support functions for DXE phase.
- Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -816,3 +816,27 @@ MpInitLibEnableDisableAP (
return Status;
}
+
+/**
+ This funtion will try to invoke platform specific microcode shadow logic to
+ relocate microcode update patches into memory.
+
+ @param[in] CpuMpData The pointer to CPU MP Data structure.
+
+ @retval EFI_SUCCESS Shadow microcode success.
+ @retval EFI_OUT_OF_RESOURCES No enough resource to complete the operation.
+ @retval EFI_UNSUPPORTED Can't find platform specific microcode shadow
+ PPI/Protocol.
+**/
+EFI_STATUS
+PlatformShadowMicrocode (
+ IN OUT CPU_MP_DATA *CpuMpData
+ )
+{
+ //
+ // There is no DXE version of platform shadow microcode protocol so far.
+ // A platform which only uses DxeMpInitLib instance could only supports
+ // the PCD based microcode shadowing.
+ //
+ return EFI_UNSUPPORTED;
+}
diff --git a/UefiCpuPkg/Library/MpInitLib/Microcode.c b/UefiCpuPkg/Library/MpInitLib/Microcode.c
index 67e214d463..15629591e2 100644
--- a/UefiCpuPkg/Library/MpInitLib/Microcode.c
+++ b/UefiCpuPkg/Library/MpInitLib/Microcode.c
@@ -620,109 +620,6 @@ OnExit:
}
/**
- Shadow the required microcode patches data into memory according to FIT microcode entry.
-
- @param[in, out] CpuMpData The pointer to CPU MP Data structure.
-
- @return EFI_SUCCESS Microcode patch is shadowed into memory.
- @return EFI_UNSUPPORTED FIT based microcode shadowing is not supported.
- @return EFI_OUT_OF_RESOURCES No enough memory resource.
- @return EFI_NOT_FOUND There is something wrong in FIT microcode entry.
-
-**/
-EFI_STATUS
-ShadowMicrocodePatchByFit (
- IN OUT CPU_MP_DATA *CpuMpData
- )
-{
- UINT64 FitPointer;
- 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;
-
- if (!FeaturePcdGet (PcdCpuShadowMicrocodeByFit)) {
- return EFI_UNSUPPORTED;
- }
-
- FitPointer = *(UINT64 *) (UINTN) FIT_POINTER_ADDRESS;
- if ((FitPointer == 0) ||
- (FitPointer == 0xFFFFFFFFFFFFFFFF) ||
- (FitPointer == 0xEEEEEEEEEEEEEEEE)) {
- //
- // No FIT table.
- //
- ASSERT (FALSE);
- return EFI_NOT_FOUND;
- }
- FitEntry = (FIRMWARE_INTERFACE_TABLE_ENTRY *) (UINTN) FitPointer;
- if ((FitEntry[0].Type != FIT_TYPE_00_HEADER) ||
- (FitEntry[0].Address != FIT_TYPE_00_SIGNATURE)) {
- //
- // Invalid FIT table, treat it as no FIT table.
- //
- ASSERT (FALSE);
- return EFI_NOT_FOUND;
- }
-
- EntryNum = *(UINT32 *)(&FitEntry[0].Size[0]) & 0xFFFFFF;
-
- //
- // Calculate microcode entry number
- //
- MaxPatchNumber = 0;
- for (Index = 0; Index < EntryNum; Index++) {
- if (FitEntry[Index].Type == FIT_TYPE_01_MICROCODE) {
- MaxPatchNumber++;
- }
- }
- if (MaxPatchNumber == 0) {
- return EFI_NOT_FOUND;
- }
-
- PatchInfoBuffer = AllocatePool (MaxPatchNumber * sizeof (MICROCODE_PATCH_INFO));
- if (PatchInfoBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Fill up microcode patch info buffer according to FIT table.
- //
- PatchCount = 0;
- TotalLoadSize = 0;
- for (Index = 0; Index < EntryNum; Index++) {
- if (FitEntry[Index].Type == FIT_TYPE_01_MICROCODE) {
- MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (UINTN) FitEntry[Index].Address;
- TotalSize = (MicrocodeEntryPoint->DataSize == 0) ? 2048 : MicrocodeEntryPoint->TotalSize;
- if (IsMicrocodePatchNeedLoad (CpuMpData, MicrocodeEntryPoint)) {
- PatchInfoBuffer[PatchCount].Address = (UINTN) MicrocodeEntryPoint;
- PatchInfoBuffer[PatchCount].Size = TotalSize;
- TotalLoadSize += TotalSize;
- PatchCount++;
- }
- }
- }
-
- if (PatchCount != 0) {
- DEBUG ((
- DEBUG_INFO,
- "%a: 0x%x microcode patches will be loaded into memory, with size 0x%x.\n",
- __FUNCTION__, PatchCount, TotalLoadSize
- ));
-
- ShadowMicrocodePatchWorker (CpuMpData, PatchInfoBuffer, PatchCount, TotalLoadSize);
- }
-
- FreePool (PatchInfoBuffer);
- return EFI_SUCCESS;
-}
-
-/**
Shadow the required microcode patches data into memory.
@param[in, out] CpuMpData The pointer to CPU MP Data structure.
@@ -734,7 +631,7 @@ ShadowMicrocodeUpdatePatch (
{
EFI_STATUS Status;
- Status = ShadowMicrocodePatchByFit (CpuMpData);
+ Status = PlatformShadowMicrocode (CpuMpData);
if (EFI_ERROR (Status)) {
ShadowMicrocodePatchByPcd (CpuMpData);
}
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index a6eab5f3d7..455cb3f09a 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -31,9 +31,6 @@
#include <Guid/MicrocodePatchHob.h>
-#include <IndustryStandard/FirmwareInterfaceTable.h>
-
-
#define WAKEUP_AP_SIGNAL SIGNATURE_32 ('S', 'T', 'A', 'P')
#define CPU_INIT_MP_LIB_HOB_GUID \
@@ -657,5 +654,21 @@ GetProcessorNumber (
OUT UINTN *ProcessorNumber
);
+/**
+ This funtion will try to invoke platform specific microcode shadow logic to
+ relocate microcode update patches into memory.
+
+ @param[in] CpuMpData The pointer to CPU MP Data structure.
+
+ @retval EFI_SUCCESS Shadow microcode success.
+ @retval EFI_OUT_OF_RESOURCES No enough resource to complete the operation.
+ @retval EFI_UNSUPPORTED Can't find platform specific microcode shadow
+ PPI/Protocol.
+**/
+EFI_STATUS
+PlatformShadowMicrocode (
+ IN OUT CPU_MP_DATA *CpuMpData
+ );
+
#endif
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
index 555125a7c5..d78d328b42 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
@@ -60,7 +60,9 @@
gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate ## SOMETIMES_CONSUMES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuShadowMicrocodeByFit ## CONSUMES
+
+[Ppis]
+ gEdkiiPeiShadowMicrocodePpiGuid ## SOMETIMES_CONSUMES
[Guids]
gEdkiiS3SmmInitDoneGuid
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
index 6ecbed39ec..17b60903c5 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
@@ -9,6 +9,7 @@
#include "MpLib.h"
#include <Library/PeiServicesLib.h>
#include <Guid/S3SmmInitDone.h>
+#include <Ppi/ShadowMicrocode.h>
/**
S3 SMM Init Done notification function.
@@ -639,4 +640,71 @@ MpInitLibEnableDisableAP (
return EnableDisableApWorker (ProcessorNumber, EnableAP, HealthFlag);
}
+/**
+ This funtion will try to invoke platform specific microcode shadow logic to
+ relocate microcode update patches into memory.
+
+ @param[in] CpuMpData The pointer to CPU MP Data structure.
+ @retval EFI_SUCCESS Shadow microcode success.
+ @retval EFI_OUT_OF_RESOURCES No enough resource to complete the operation.
+ @retval EFI_UNSUPPORTED Can't find platform specific microcode shadow
+ PPI/Protocol.
+**/
+EFI_STATUS
+PlatformShadowMicrocode (
+ IN OUT CPU_MP_DATA *CpuMpData
+ )
+{
+ EFI_STATUS Status;
+ EDKII_PEI_SHADOW_MICROCODE_PPI *ShadowMicrocodePpi;
+ UINTN CpuCount;
+ EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId;
+ UINTN Index;
+ UINTN BufferSize;
+ VOID *Buffer;
+
+ Status = PeiServicesLocatePpi (
+ &gEdkiiPeiShadowMicrocodePpiGuid,
+ 0,
+ NULL,
+ (VOID **) &ShadowMicrocodePpi
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ CpuCount = CpuMpData->CpuCount;
+ MicrocodeCpuId = (EDKII_PEI_MICROCODE_CPU_ID *) AllocateZeroPool (sizeof (EDKII_PEI_MICROCODE_CPU_ID) * CpuCount);
+ if (MicrocodeCpuId == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ for (Index = 0; Index < CpuMpData->CpuCount; Index++) {
+ MicrocodeCpuId[Index].ProcessorSignature = CpuMpData->CpuData[Index].ProcessorSignature;
+ MicrocodeCpuId[Index].PlatformId = CpuMpData->CpuData[Index].PlatformId;
+ }
+
+ Status = ShadowMicrocodePpi->ShadowMicrocode (
+ ShadowMicrocodePpi,
+ CpuCount,
+ MicrocodeCpuId,
+ &BufferSize,
+ &Buffer
+ );
+ FreePool (MicrocodeCpuId);
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ CpuMpData->MicrocodePatchAddress = (UINTN) Buffer;
+ CpuMpData->MicrocodePatchRegionSize = BufferSize;
+
+ DEBUG ((
+ DEBUG_INFO,
+ "%a: Required microcode patches have been loaded at 0x%lx, with size 0x%lx.\n",
+ __FUNCTION__, CpuMpData->MicrocodePatchAddress, CpuMpData->MicrocodePatchRegionSize
+ ));
+
+ return EFI_SUCCESS;
+}