summaryrefslogtreecommitdiffstats
path: root/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
diff options
context:
space:
mode:
Diffstat (limited to 'UefiCpuPkg/Library/MpInitLib/PeiMpLib.c')
-rw-r--r--UefiCpuPkg/Library/MpInitLib/PeiMpLib.c68
1 files changed, 68 insertions, 0 deletions
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;
+}