]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MpInitLib/Microcode.c
MdePkg: Add header file for Firmware Interface Table specification.
[mirror_edk2.git] / UefiCpuPkg / Library / MpInitLib / Microcode.c
index 330fd99623347ef172542b9bceaa708cd29ef424..8f4d4da40c76f5b1beab32af3c47e9389ea22585 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Implementation of loading microcode on processors.\r
 \r
-  Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.<BR>\r
   SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
@@ -65,13 +65,15 @@ GetCurrentMicrocodeSignature (
          It does not guarantee that the data has not been modified.\r
          CPU has its own mechanism to verify Microcode Binary part.\r
 \r
-  @param[in]  CpuMpData    The pointer to CPU MP Data structure.\r
-  @param[in]  IsBspCallIn  Indicate whether the caller is BSP or not.\r
+  @param[in]  CpuMpData        The pointer to CPU MP Data structure.\r
+  @param[in]  ProcessorNumber  The handle number of the processor. The range is\r
+                               from 0 to the total number of logical processors\r
+                               minus 1.\r
 **/\r
 VOID\r
 MicrocodeDetect (\r
   IN CPU_MP_DATA             *CpuMpData,\r
-  IN BOOLEAN                 IsBspCallIn\r
+  IN UINTN                   ProcessorNumber\r
   )\r
 {\r
   UINT32                                  ExtendedTableLength;\r
@@ -83,6 +85,7 @@ MicrocodeDetect (
   UINTN                                   Index;\r
   UINT8                                   PlatformId;\r
   CPUID_VERSION_INFO_EAX                  Eax;\r
+  CPU_AP_DATA                             *CpuData;\r
   UINT32                                  CurrentRevision;\r
   UINT32                                  LatestRevision;\r
   UINTN                                   TotalSize;\r
@@ -90,14 +93,8 @@ MicrocodeDetect (
   UINT32                                  InCompleteCheckSum32;\r
   BOOLEAN                                 CorrectMicrocode;\r
   VOID                                    *MicrocodeData;\r
-  MSR_IA32_PLATFORM_ID_REGISTER           PlatformIdMsr;\r
-  UINT32                                  ProcessorFlags;\r
   UINT32                                  ThreadId;\r
-\r
-  //\r
-  // set ProcessorFlags to suppress incorrect compiler/analyzer warnings\r
-  //\r
-  ProcessorFlags = 0;\r
+  BOOLEAN                                 IsBspCallIn;\r
 \r
   if (CpuMpData->MicrocodePatchRegionSize == 0) {\r
     //\r
@@ -107,12 +104,7 @@ MicrocodeDetect (
   }\r
 \r
   CurrentRevision = GetCurrentMicrocodeSignature ();\r
-  if (CurrentRevision != 0 && !IsBspCallIn) {\r
-    //\r
-    // Skip loading microcode if it has been loaded successfully\r
-    //\r
-    return;\r
-  }\r
+  IsBspCallIn     = (ProcessorNumber == (UINTN)CpuMpData->BspNumber) ? TRUE : FALSE;\r
 \r
   GetProcessorLocationByApicId (GetInitialApicId (), NULL, NULL, &ThreadId);\r
   if (ThreadId != 0) {\r
@@ -123,28 +115,25 @@ MicrocodeDetect (
   }\r
 \r
   ExtendedTableLength = 0;\r
-  //\r
-  // Here data of CPUID leafs have not been collected into context buffer, so\r
-  // GetProcessorCpuid() cannot be used here to retrieve CPUID data.\r
-  //\r
-  AsmCpuid (CPUID_VERSION_INFO, &Eax.Uint32, NULL, NULL, NULL);\r
-\r
-  //\r
-  // The index of platform information resides in bits 50:52 of MSR IA32_PLATFORM_ID\r
-  //\r
-  PlatformIdMsr.Uint64 = AsmReadMsr64 (MSR_IA32_PLATFORM_ID);\r
-  PlatformId = (UINT8) PlatformIdMsr.Bits.PlatformId;\r
+  Eax.Uint32 = CpuMpData->CpuData[ProcessorNumber].ProcessorSignature;\r
+  PlatformId = CpuMpData->CpuData[ProcessorNumber].PlatformId;\r
 \r
   //\r
   // Check whether AP has same processor with BSP.\r
   // If yes, direct use microcode info saved by BSP.\r
   //\r
   if (!IsBspCallIn) {\r
-    if ((CpuMpData->ProcessorSignature == Eax.Uint32) &&\r
-        (CpuMpData->ProcessorFlags & (1 << PlatformId)) != 0) {\r
-        MicrocodeData = (VOID *)(UINTN) CpuMpData->MicrocodeDataAddress;\r
-        LatestRevision = CpuMpData->MicrocodeRevision;\r
-        goto Done;\r
+    //\r
+    // Get the CPU data for BSP\r
+    //\r
+    CpuData = &(CpuMpData->CpuData[CpuMpData->BspNumber]);\r
+    if ((CpuData->ProcessorSignature == Eax.Uint32) &&\r
+        (CpuData->PlatformId == PlatformId) &&\r
+        (CpuData->MicrocodeEntryAddr != 0)) {\r
+      MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *)(UINTN) CpuData->MicrocodeEntryAddr;\r
+      MicrocodeData       = (VOID *) (MicrocodeEntryPoint + 1);\r
+      LatestRevision      = MicrocodeEntryPoint->UpdateRevision;\r
+      goto Done;\r
     }\r
   }\r
 \r
@@ -212,7 +201,6 @@ MicrocodeDetect (
         CheckSum32 += MicrocodeEntryPoint->Checksum;\r
         if (CheckSum32 == 0) {\r
           CorrectMicrocode = TRUE;\r
-          ProcessorFlags = MicrocodeEntryPoint->ProcessorFlags;\r
         }\r
       } else if ((MicrocodeEntryPoint->DataSize != 0) &&\r
                  (MicrocodeEntryPoint->UpdateRevision > LatestRevision)) {\r
@@ -256,7 +244,6 @@ MicrocodeDetect (
                     // Find one\r
                     //\r
                     CorrectMicrocode = TRUE;\r
-                    ProcessorFlags = ExtendedTable->ProcessorFlag;\r
                     break;\r
                   }\r
                 }\r
@@ -295,6 +282,16 @@ MicrocodeDetect (
   } while (((UINTN) MicrocodeEntryPoint < MicrocodeEnd));\r
 \r
 Done:\r
+  if (LatestRevision != 0) {\r
+    //\r
+    // Save the detected microcode patch entry address (including the\r
+    // microcode patch header) for each processor.\r
+    // It will be used when building the microcode patch cache HOB.\r
+    //\r
+    CpuMpData->CpuData[ProcessorNumber].MicrocodeEntryAddr =\r
+      (UINTN) MicrocodeData -  sizeof (CPU_MICROCODE_HEADER);\r
+  }\r
+\r
   if (LatestRevision > CurrentRevision) {\r
     //\r
     // BIOS only authenticate updates that contain a numerically larger revision\r
@@ -318,18 +315,6 @@ Done:
       ReleaseSpinLock(&CpuMpData->MpLock);\r
     }\r
   }\r
-\r
-  if (IsBspCallIn && (LatestRevision != 0)) {\r
-    //\r
-    // Save BSP processor info and microcode info for later AP use.\r
-    //\r
-    CpuMpData->ProcessorSignature   = Eax.Uint32;\r
-    CpuMpData->ProcessorFlags       = ProcessorFlags;\r
-    CpuMpData->MicrocodeDataAddress = (UINTN) MicrocodeData;\r
-    CpuMpData->MicrocodeRevision    = LatestRevision;\r
-    DEBUG ((DEBUG_INFO, "BSP Microcode:: signature [0x%08x], ProcessorFlags [0x%08x], \\r
-       MicroData [0x%08x], Revision [0x%08x]\n", Eax.Uint32, ProcessorFlags, (UINTN) MicrocodeData, LatestRevision));\r
-  }\r
 }\r
 \r
 /**\r
@@ -406,16 +391,7 @@ LoadMicrocodePatchWorker (
       Patches[Index].Size\r
       );\r
 \r
-    //\r
-    // Zero-fill the padding area\r
-    // Please note that AlignedSize will be no less than Size\r
-    //\r
-    ZeroMem (\r
-      Walker + Patches[Index].Size,\r
-      Patches[Index].AlignedSize - Patches[Index].Size\r
-      );\r
-\r
-    Walker += Patches[Index].AlignedSize;\r
+    Walker += Patches[Index].Size;\r
   }\r
 \r
   //\r
@@ -587,14 +563,9 @@ LoadMicrocodePatch (
       //\r
       // Store the information of this microcode patch\r
       //\r
-      if (TotalSize > ALIGN_VALUE (TotalSize, SIZE_1KB) ||\r
-          ALIGN_VALUE (TotalSize, SIZE_1KB) > MAX_UINTN - TotalLoadSize) {\r
-        goto OnExit;\r
-      }\r
-      PatchInfoBuffer[PatchCount - 1].Address     = (UINTN) MicrocodeEntryPoint;\r
-      PatchInfoBuffer[PatchCount - 1].Size        = TotalSize;\r
-      PatchInfoBuffer[PatchCount - 1].AlignedSize = ALIGN_VALUE (TotalSize, SIZE_1KB);\r
-      TotalLoadSize += PatchInfoBuffer[PatchCount - 1].AlignedSize;\r
+      PatchInfoBuffer[PatchCount - 1].Address = (UINTN) MicrocodeEntryPoint;\r
+      PatchInfoBuffer[PatchCount - 1].Size    = TotalSize;\r
+      TotalLoadSize += TotalSize;\r
     }\r
 \r
     //\r