]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/CpuMpPei/Microcode.c
UefiCpuPkg/CpuMpPei: Consume MpInitLib to produce CPU MP PPI services
[mirror_edk2.git] / UefiCpuPkg / CpuMpPei / Microcode.c
index 70e149be877262973e67fd36cd990f432a23a037..4fe6f2d8db40d2ed91eb6ecacefb3bc5b51e36de 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Implementation of loading microcode on processors.\r
 \r
-  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
@@ -36,10 +36,11 @@ GetCurrentMicrocodeSignature (
 /**\r
   Detect whether specified processor can find matching microcode patch and load it.\r
 \r
+  @param PeiCpuMpData        Pointer to PEI CPU MP Data\r
 **/\r
 VOID\r
 MicrocodeDetect (\r
-  VOID\r
+  IN PEI_CPU_MP_DATA            *PeiCpuMpData\r
   )\r
 {\r
   UINT64                                  MicrocodePatchAddress;\r
@@ -53,11 +54,11 @@ MicrocodeDetect (
   UINTN                                   Index;\r
   UINT8                                   PlatformId;\r
   UINT32                                  RegEax;\r
+  UINT32                                  CurrentRevision;\r
   UINT32                                  LatestRevision;\r
   UINTN                                   TotalSize;\r
   UINT32                                  CheckSum32;\r
   BOOLEAN                                 CorrectMicrocode;\r
-  INT32                                   CurrentSignature;\r
   MICROCODE_INFO                          MicrocodeInfo;\r
 \r
   ZeroMem (&MicrocodeInfo, sizeof (MICROCODE_INFO));\r
@@ -70,6 +71,14 @@ MicrocodeDetect (
     return;\r
   }\r
 \r
+  CurrentRevision = GetCurrentMicrocodeSignature ();\r
+  if (CurrentRevision != 0) {\r
+    //\r
+    // Skip loading microcode if it has been loaded successfully\r
+    //\r
+    return;\r
+  }\r
+\r
   ExtendedTableLength = 0;\r
   //\r
   // Here data of CPUID leafs have not been collected into context buffer, so\r
@@ -94,7 +103,7 @@ MicrocodeDetect (
     if (MicrocodeEntryPoint->HeaderVersion == 0x1) {\r
       //\r
       // It is the microcode header. It is not the padding data between microcode patches\r
-      // becasue the padding data should not include 0x00000001 and it should be the repeated\r
+      // because the padding data should not include 0x00000001 and it should be the repeated\r
       // byte format (like 0xXYXYXYXY....).\r
       //\r
       if (MicrocodeEntryPoint->ProcessorId == RegEax &&\r
@@ -179,22 +188,26 @@ MicrocodeDetect (
     MicrocodeEntryPoint = (EFI_CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + TotalSize);\r
   } while (((UINTN) MicrocodeEntryPoint < MicrocodeEnd));\r
 \r
-  if (LatestRevision > 0) {\r
+  if (LatestRevision > CurrentRevision) {\r
     //\r
-    // Get microcode update signature of currently loaded microcode update\r
+    // BIOS only authenticate updates that contain a numerically larger revision\r
+    // than the currently loaded revision, where Current Signature < New Update\r
+    // Revision. A processor with no loaded update is considered to have a\r
+    // revision equal to zero.\r
     //\r
-    CurrentSignature = GetCurrentMicrocodeSignature ();\r
+    AsmWriteMsr64 (\r
+      EFI_MSR_IA32_BIOS_UPDT_TRIG,\r
+      (UINT64) (UINTN) MicrocodeInfo.MicrocodeData\r
+      );\r
     //\r
-    // If no microcode update has been loaded, then trigger microcode load.\r
+    // Get and check new microcode signature\r
     //\r
-    if (CurrentSignature == 0) {\r
-      AsmWriteMsr64 (\r
-        EFI_MSR_IA32_BIOS_UPDT_TRIG,\r
-        (UINT64) (UINTN) MicrocodeInfo.MicrocodeData\r
-        );\r
-      MicrocodeInfo.Load = TRUE;\r
-    } else {\r
-      MicrocodeInfo.Load = FALSE;\r
+    CurrentRevision = GetCurrentMicrocodeSignature ();\r
+    if (CurrentRevision != LatestRevision) {\r
+      AcquireSpinLock(&PeiCpuMpData->MpLock);\r
+      DEBUG ((EFI_D_ERROR, "Updated microcode signature [0x%08x] does not match \\r
+                loaded microcode signature [0x%08x]\n", CurrentRevision, LatestRevision));\r
+      ReleaseSpinLock(&PeiCpuMpData->MpLock);\r
     }\r
   }\r
 }\r