]> git.proxmox.com Git - mirror_edk2.git/commitdiff
UefiCpuPkg: Add MicrocodeLib for loading microcode
authorRay Ni <ray.ni@intel.com>
Thu, 1 Apr 2021 10:32:23 +0000 (18:32 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Fri, 9 Apr 2021 01:43:18 +0000 (01:43 +0000)
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3303
Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
UefiCpuPkg/Include/Library/MicrocodeLib.h [new file with mode: 0644]
UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.c [new file with mode: 0644]
UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf [new file with mode: 0644]
UefiCpuPkg/UefiCpuPkg.dec
UefiCpuPkg/UefiCpuPkg.dsc

diff --git a/UefiCpuPkg/Include/Library/MicrocodeLib.h b/UefiCpuPkg/Include/Library/MicrocodeLib.h
new file mode 100644 (file)
index 0000000..f14d56b
--- /dev/null
@@ -0,0 +1,120 @@
+/** @file\r
+  Public include file for Microcode library.\r
+\r
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef MICROCODE_LIB_H_\r
+#define MICROCODE_LIB_H_\r
+\r
+#include <Register/Intel/Microcode.h>\r
+#include <Ppi/ShadowMicrocode.h>\r
+\r
+/**\r
+  Get microcode update signature of currently loaded microcode update.\r
+\r
+  @return  Microcode signature.\r
+**/\r
+UINT32\r
+EFIAPI\r
+GetProcessorMicrocodeSignature (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Get the processor signature and platform ID for current processor.\r
+\r
+  @param MicrocodeCpuId  Return the processor signature and platform ID.\r
+**/\r
+VOID\r
+EFIAPI\r
+GetProcessorMicrocodeCpuId (\r
+  EDKII_PEI_MICROCODE_CPU_ID  *MicrocodeCpuId\r
+  );\r
+\r
+/**\r
+  Return the total size of the microcode entry.\r
+\r
+  Logic follows pseudo code in SDM as below:\r
+\r
+     N = 512\r
+     If (Update.DataSize != 00000000H)\r
+       N = Update.TotalSize / 4\r
+\r
+  If Microcode is NULL, then ASSERT.\r
+\r
+  @param Microcode  Pointer to the microcode entry.\r
+\r
+  @return The microcode total size.\r
+**/\r
+UINT32\r
+EFIAPI\r
+GetMicrocodeLength (\r
+  IN CPU_MICROCODE_HEADER *Microcode\r
+  );\r
+\r
+/**\r
+  Load the microcode to the processor.\r
+\r
+  If Microcode is NULL, then ASSERT.\r
+\r
+  @param Microcode  Pointer to the microcode entry.\r
+**/\r
+VOID\r
+EFIAPI\r
+LoadMicrocode (\r
+  IN CPU_MICROCODE_HEADER *Microcode\r
+  );\r
+\r
+/**\r
+  Detect whether specified processor can find matching microcode patch and load it.\r
+\r
+  Microcode format is as below:\r
+  +----------------------------------------+-------------------------------------------------+\r
+  |          CPU_MICROCODE_HEADER          |                                                 |\r
+  +----------------------------------------+                                                 V\r
+  |              Update Data               |                                               CPU_MICROCODE_HEADER.Checksum\r
+  +----------------------------------------+-------+                                         ^\r
+  |  CPU_MICROCODE_EXTENDED_TABLE_HEADER   |       |                                         |\r
+  +----------------------------------------+       V                                         |\r
+  |      CPU_MICROCODE_EXTENDED_TABLE[0]   |  CPU_MICROCODE_EXTENDED_TABLE_HEADER.Checksum   |\r
+  |      CPU_MICROCODE_EXTENDED_TABLE[1]   |       ^                                         |\r
+  |                   ...                  |       |                                         |\r
+  +----------------------------------------+-------+-----------------------------------------+\r
+\r
+  There may by multiple CPU_MICROCODE_EXTENDED_TABLE in this format.\r
+  The count of CPU_MICROCODE_EXTENDED_TABLE is indicated by ExtendedSignatureCount\r
+  of CPU_MICROCODE_EXTENDED_TABLE_HEADER structure.\r
+\r
+  If Microcode is NULL, then ASSERT.\r
+\r
+  @param Microcode            Pointer to a microcode entry.\r
+  @param MicrocodeLength      The total length of the microcode entry.\r
+  @param MinimumRevision      The microcode whose revision <= MinimumRevision is treated as invalid.\r
+                              Caller can supply value get from GetProcessorMicrocodeSignature() to check\r
+                              whether the microcode is newer than loaded one.\r
+                              Caller can supply 0 to treat any revision (except 0) microcode as valid.\r
+  @param MicrocodeCpuIds      Pointer to an array of processor signature and platform ID that represents\r
+                              a set of processors.\r
+                              Caller can supply zero-element array to skip the processor signature and\r
+                              platform ID check.\r
+  @param MicrocodeCpuIdCount  The number of elements in MicrocodeCpuIds.\r
+  @param VerifyChecksum       FALSE to skip all the checksum verifications.\r
+\r
+  @retval TRUE  The microcode is valid.\r
+  @retval FALSE The microcode is invalid.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+IsValidMicrocode (\r
+  IN CPU_MICROCODE_HEADER       *Microcode,\r
+  IN UINTN                      MicrocodeLength,\r
+  IN UINT32                     MinimumRevision,\r
+  IN EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuIds,\r
+  IN UINTN                      MicrocodeCpuIdCount,\r
+  IN BOOLEAN                    VerifyChecksum\r
+  );\r
+\r
+#endif\r
diff --git a/UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.c b/UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.c
new file mode 100644 (file)
index 0000000..03a43fd
--- /dev/null
@@ -0,0 +1,322 @@
+/** @file\r
+  Implementation of MicrocodeLib.\r
+\r
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Uefi/UefiBaseType.h>\r
+#include <Register/Intel/Cpuid.h>\r
+#include <Register/Intel/ArchitecturalMsr.h>\r
+#include <Register/Intel/Microcode.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Ppi/ShadowMicrocode.h>\r
+\r
+/**\r
+  Get microcode update signature of currently loaded microcode update.\r
+\r
+  @return  Microcode signature.\r
+**/\r
+UINT32\r
+EFIAPI\r
+GetProcessorMicrocodeSignature (\r
+  VOID\r
+  )\r
+{\r
+  MSR_IA32_BIOS_SIGN_ID_REGISTER   BiosSignIdMsr;\r
+\r
+  AsmWriteMsr64 (MSR_IA32_BIOS_SIGN_ID, 0);\r
+  AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL);\r
+  BiosSignIdMsr.Uint64 = AsmReadMsr64 (MSR_IA32_BIOS_SIGN_ID);\r
+  return BiosSignIdMsr.Bits.MicrocodeUpdateSignature;\r
+}\r
+\r
+/**\r
+  Get the processor signature and platform ID for current processor.\r
+\r
+  @param MicrocodeCpuId  Return the processor signature and platform ID.\r
+**/\r
+VOID\r
+EFIAPI\r
+GetProcessorMicrocodeCpuId (\r
+  EDKII_PEI_MICROCODE_CPU_ID  *MicrocodeCpuId\r
+  )\r
+{\r
+  MSR_IA32_PLATFORM_ID_REGISTER PlatformIdMsr;\r
+\r
+  ASSERT (MicrocodeCpuId != NULL);\r
+\r
+  PlatformIdMsr.Uint64 = AsmReadMsr64 (MSR_IA32_PLATFORM_ID);\r
+  MicrocodeCpuId->PlatformId = (UINT8) PlatformIdMsr.Bits.PlatformId;\r
+  AsmCpuid (CPUID_VERSION_INFO, &MicrocodeCpuId->ProcessorSignature, NULL, NULL, NULL);\r
+}\r
+\r
+/**\r
+  Return the total size of the microcode entry.\r
+\r
+  Logic follows pseudo code in SDM as below:\r
+\r
+     N = 512\r
+     If (Update.DataSize != 00000000H)\r
+       N = Update.TotalSize / 4\r
+\r
+  If Microcode is NULL, then ASSERT.\r
+\r
+  @param Microcode  Pointer to the microcode entry.\r
+\r
+  @return The microcode total size.\r
+**/\r
+UINT32\r
+EFIAPI\r
+GetMicrocodeLength (\r
+  IN CPU_MICROCODE_HEADER *Microcode\r
+  )\r
+{\r
+  UINT32   TotalSize;\r
+\r
+  ASSERT (Microcode != NULL);\r
+\r
+  TotalSize = 2048;\r
+  if (Microcode->DataSize != 0) {\r
+    TotalSize = Microcode->TotalSize;\r
+  }\r
+  return TotalSize;\r
+}\r
+\r
+/**\r
+  Load the microcode to the processor.\r
+\r
+  If Microcode is NULL, then ASSERT.\r
+\r
+  @param Microcode  Pointer to the microcode entry.\r
+**/\r
+VOID\r
+EFIAPI\r
+LoadMicrocode (\r
+  IN CPU_MICROCODE_HEADER *Microcode\r
+  )\r
+{\r
+  ASSERT (Microcode != NULL);\r
+\r
+  AsmWriteMsr64 (MSR_IA32_BIOS_UPDT_TRIG, (UINT64) (UINTN) (Microcode + 1));\r
+}\r
+\r
+/**\r
+  Determine if a microcode patch matchs the specific processor signature and flag.\r
+\r
+  @param[in]  ProcessorSignature    The processor signature field value in a\r
+                                    microcode patch.\r
+  @param[in]  ProcessorFlags        The processor flags field value in a\r
+                                    microcode patch.\r
+  @param[in]  MicrocodeCpuId        A pointer to an array of EDKII_PEI_MICROCODE_CPU_ID\r
+                                    structures.\r
+  @param[in]  MicrocodeCpuIdCount   Number of elements in MicrocodeCpuId array.\r
+\r
+  @retval TRUE     The specified microcode patch matches to one of the MicrocodeCpuId.\r
+  @retval FALSE    The specified microcode patch doesn't match to any of the MicrocodeCpuId.\r
+**/\r
+BOOLEAN\r
+IsProcessorMatchedMicrocode (\r
+  IN UINT32                           ProcessorSignature,\r
+  IN UINT32                           ProcessorFlags,\r
+  IN EDKII_PEI_MICROCODE_CPU_ID       *MicrocodeCpuId,\r
+  IN UINTN                            MicrocodeCpuIdCount\r
+  )\r
+{\r
+  UINTN          Index;\r
+\r
+  if (MicrocodeCpuIdCount == 0) {\r
+    return TRUE;\r
+  }\r
+\r
+  for (Index = 0; Index < MicrocodeCpuIdCount; Index++) {\r
+    if ((ProcessorSignature == MicrocodeCpuId[Index].ProcessorSignature) &&\r
+        (ProcessorFlags & (1 << MicrocodeCpuId[Index].PlatformId)) != 0) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Detect whether specified processor can find matching microcode patch and load it.\r
+\r
+  Microcode format is as below:\r
+  +----------------------------------------+-------------------------------------------------+\r
+  |          CPU_MICROCODE_HEADER          |                                                 |\r
+  +----------------------------------------+                                                 V\r
+  |              Update Data               |                                               CPU_MICROCODE_HEADER.Checksum\r
+  +----------------------------------------+-------+                                         ^\r
+  |  CPU_MICROCODE_EXTENDED_TABLE_HEADER   |       |                                         |\r
+  +----------------------------------------+       V                                         |\r
+  |      CPU_MICROCODE_EXTENDED_TABLE[0]   |  CPU_MICROCODE_EXTENDED_TABLE_HEADER.Checksum   |\r
+  |      CPU_MICROCODE_EXTENDED_TABLE[1]   |       ^                                         |\r
+  |                   ...                  |       |                                         |\r
+  +----------------------------------------+-------+-----------------------------------------+\r
+\r
+  There may by multiple CPU_MICROCODE_EXTENDED_TABLE in this format.\r
+  The count of CPU_MICROCODE_EXTENDED_TABLE is indicated by ExtendedSignatureCount\r
+  of CPU_MICROCODE_EXTENDED_TABLE_HEADER structure.\r
+\r
+  If Microcode is NULL, then ASSERT.\r
+\r
+  @param Microcode            Pointer to a microcode entry.\r
+  @param MicrocodeLength      The total length of the microcode entry.\r
+  @param MinimumRevision      The microcode whose revision <= MinimumRevision is treated as invalid.\r
+                              Caller can supply value get from GetProcessorMicrocodeSignature() to check\r
+                              whether the microcode is newer than loaded one.\r
+                              Caller can supply 0 to treat any revision (except 0) microcode as valid.\r
+  @param MicrocodeCpuIds      Pointer to an array of processor signature and platform ID that represents\r
+                              a set of processors.\r
+                              Caller can supply zero-element array to skip the processor signature and\r
+                              platform ID check.\r
+  @param MicrocodeCpuIdCount  The number of elements in MicrocodeCpuIds.\r
+  @param VerifyChecksum       FALSE to skip all the checksum verifications.\r
+\r
+  @retval TRUE  The microcode is valid.\r
+  @retval FALSE The microcode is invalid.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+IsValidMicrocode (\r
+  IN CPU_MICROCODE_HEADER       *Microcode,\r
+  IN UINTN                      MicrocodeLength,\r
+  IN UINT32                     MinimumRevision,\r
+  IN EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuIds,\r
+  IN UINTN                      MicrocodeCpuIdCount,\r
+  IN BOOLEAN                    VerifyChecksum\r
+  )\r
+{\r
+  UINTN                                   Index;\r
+  UINT32                                  DataSize;\r
+  UINT32                                  TotalSize;\r
+  CPU_MICROCODE_EXTENDED_TABLE            *ExtendedTable;\r
+  CPU_MICROCODE_EXTENDED_TABLE_HEADER     *ExtendedTableHeader;\r
+  UINT32                                  ExtendedTableLength;\r
+  UINT32                                  Sum32;\r
+  BOOLEAN                                 Match;\r
+\r
+  ASSERT (Microcode != NULL);\r
+\r
+  //\r
+  // It's invalid when:\r
+  //   the input microcode buffer is so small that even cannot contain the header.\r
+  //   the input microcode buffer is so large that exceeds MAX_ADDRESS.\r
+  //\r
+  if ((MicrocodeLength < sizeof (CPU_MICROCODE_HEADER)) || (MicrocodeLength > (MAX_ADDRESS - (UINTN) Microcode))) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Per SDM, HeaderVersion and LoaderRevision should both be 1.\r
+  //\r
+  if ((Microcode->HeaderVersion != 1) || (Microcode->LoaderRevision != 1)) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // The microcode revision should be larger than the minimum revision.\r
+  //\r
+  if (Microcode->UpdateRevision <= MinimumRevision) {\r
+    return FALSE;\r
+  }\r
+\r
+  DataSize = Microcode->DataSize;\r
+  if (DataSize == 0) {\r
+    DataSize = 2000;\r
+  }\r
+\r
+  //\r
+  // Per SDM, DataSize should be multiple of DWORDs.\r
+  //\r
+  if ((DataSize % 4) != 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  TotalSize = GetMicrocodeLength (Microcode);\r
+\r
+  //\r
+  // Check whether the whole microcode is within the buffer.\r
+  // TotalSize should be multiple of 1024.\r
+  //\r
+  if (((TotalSize % SIZE_1KB) != 0) || (TotalSize > MicrocodeLength)) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // The summation of all DWORDs in microcode should be zero.\r
+  //\r
+  if (VerifyChecksum && (CalculateSum32 ((UINT32 *) Microcode, TotalSize) != 0)) {\r
+    return FALSE;\r
+  }\r
+\r
+  Sum32 = Microcode->ProcessorSignature.Uint32 + Microcode->ProcessorFlags + Microcode->Checksum;\r
+\r
+  //\r
+  // Check the processor signature and platform ID in the primary header.\r
+  //\r
+  Match = IsProcessorMatchedMicrocode (\r
+            Microcode->ProcessorSignature.Uint32,\r
+            Microcode->ProcessorFlags,\r
+            MicrocodeCpuIds,\r
+            MicrocodeCpuIdCount\r
+            );\r
+  if (Match) {\r
+    return TRUE;\r
+  }\r
+\r
+  ExtendedTableLength = TotalSize - (DataSize + sizeof (CPU_MICROCODE_HEADER));\r
+  if ((ExtendedTableLength < sizeof (CPU_MICROCODE_EXTENDED_TABLE_HEADER)) || ((ExtendedTableLength % 4) != 0)) {\r
+    return FALSE;\r
+  }\r
+  //\r
+  // Extended Table exist, check if the CPU in support list\r
+  //\r
+  ExtendedTableHeader = (CPU_MICROCODE_EXTENDED_TABLE_HEADER *) ((UINTN) (Microcode + 1) + DataSize);\r
+  if (ExtendedTableHeader->ExtendedSignatureCount > MAX_UINT32 / sizeof (CPU_MICROCODE_EXTENDED_TABLE)) {\r
+    return FALSE;\r
+  }\r
+  if (ExtendedTableHeader->ExtendedSignatureCount * sizeof (CPU_MICROCODE_EXTENDED_TABLE)\r
+      > ExtendedTableLength - sizeof (CPU_MICROCODE_EXTENDED_TABLE_HEADER)) {\r
+    return FALSE;\r
+  }\r
+  //\r
+  // Check the extended table checksum\r
+  //\r
+  if (VerifyChecksum && (CalculateSum32 ((UINT32 *) ExtendedTableHeader, ExtendedTableLength) != 0)) {\r
+    return FALSE;\r
+  }\r
+\r
+  ExtendedTable = (CPU_MICROCODE_EXTENDED_TABLE *) (ExtendedTableHeader + 1);\r
+  for (Index = 0; Index < ExtendedTableHeader->ExtendedSignatureCount; Index ++) {\r
+    if (VerifyChecksum &&\r
+        (ExtendedTable[Index].ProcessorSignature.Uint32 + ExtendedTable[Index].ProcessorFlag\r
+        + ExtendedTable[Index].Checksum != Sum32)) {\r
+      //\r
+      // The extended table entry is valid when the summation of Processor Signature, Processor Flags\r
+      // and Checksum equal to the coresponding summation from primary header. Because:\r
+      //    CalculateSum32 (Header + Update Binary) == 0\r
+      //    CalculateSum32 (Header + Update Binary)\r
+      //        - (Header.ProcessorSignature + Header.ProcessorFlag + Header.Checksum)\r
+      //        + (Extended.ProcessorSignature + Extended.ProcessorFlag + Extended.Checksum) == 0\r
+      // So,\r
+      //    (Header.ProcessorSignature + Header.ProcessorFlag + Header.Checksum)\r
+      //     == (Extended.ProcessorSignature + Extended.ProcessorFlag + Extended.Checksum)\r
+      //\r
+      continue;\r
+    }\r
+    Match = IsProcessorMatchedMicrocode (\r
+              ExtendedTable[Index].ProcessorSignature.Uint32,\r
+              ExtendedTable[Index].ProcessorFlag,\r
+              MicrocodeCpuIds,\r
+              MicrocodeCpuIdCount\r
+              );\r
+    if (Match) {\r
+      return TRUE;\r
+    }\r
+  }\r
+  return FALSE;\r
+}\r
diff --git a/UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf b/UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf
new file mode 100644 (file)
index 0000000..c6f8f52
--- /dev/null
@@ -0,0 +1,32 @@
+##  @file\r
+#   Library for microcode verification and load.\r
+#\r
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010006\r
+  BASE_NAME                      = MicrocodeLib\r
+  FILE_GUID                      = EB8C72BC-8A48-4F80-996B-E52F68416D57\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = MicrocodeLib\r
+\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 EBC\r
+#\r
+\r
+[Sources.common]\r
+  MicrocodeLib.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  UefiCpuPkg/UefiCpuPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  DebugLib\r
index a639ce5412e49e7766f9ca38421a5b4dcc247a6e..62acb291f3099d14bf192ffaeeed891972e6eb96 100644 (file)
@@ -1,7 +1,7 @@
 ## @file  UefiCpuPkg.dec\r
 # This Package provides UEFI compatible CPU modules and libraries.\r
 #\r
-# Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>\r
 #\r
 # SPDX-License-Identifier: BSD-2-Clause-Patent\r
 #\r
@@ -59,6 +59,9 @@
   ##  @libraryclass  Provides function to get CPU cache information.\r
   CpuCacheInfoLib|Include/Library/CpuCacheInfoLib.h\r
 \r
+  ##  @libraryclass  Provides function for loading microcode.\r
+  MicrocodeLib|Include/Library/MicrocodeLib.h\r
+\r
 [Guids]\r
   gUefiCpuPkgTokenSpaceGuid      = { 0xac05bf33, 0x995a, 0x4ed4, { 0xaa, 0xb8, 0xef, 0x7a, 0xe8, 0xf, 0x5c, 0xb0 }}\r
   gMsegSmramGuid                 = { 0x5802bce4, 0xeeee, 0x4e33, { 0xa1, 0x30, 0xeb, 0xad, 0x27, 0xf0, 0xe4, 0x39 }}\r
index c16cf8d1b96d61369849d60bb2a7c687f072af7e..699c91626bd87594caff2ac35b605cedc758f64d 100644 (file)
@@ -60,6 +60,7 @@
   PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf\r
   TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf\r
   VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf\r
+  MicrocodeLib|UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf\r
 \r
 [LibraryClasses.common.SEC]\r
   PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf\r
   UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf\r
   UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf\r
   UefiCpuPkg/Library/MpInitLibUp/MpInitLibUp.inf\r
+  UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf\r
   UefiCpuPkg/Library/MtrrLib/MtrrLib.inf\r
   UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf\r
   UefiCpuPkg/Library/RegisterCpuFeaturesLib/PeiRegisterCpuFeaturesLib.inf\r