UefiCpuPkg/MpInitLib: Use BSP uCode for APs if possible.
authorEric Dong <eric.dong@intel.com>
Wed, 11 Jul 2018 11:07:28 +0000 (19:07 +0800)
committerEric Dong <eric.dong@intel.com>
Wed, 18 Jul 2018 04:43:30 +0000 (12:43 +0800)
Search uCode costs much time, if AP has same processor type
with BSP, AP can use BSP saved uCode info to get better performance.

This change enables this solution.

Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Eric Dong <eric.dong@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
UefiCpuPkg/Library/MpInitLib/Microcode.c
UefiCpuPkg/Library/MpInitLib/MpLib.c
UefiCpuPkg/Library/MpInitLib/MpLib.h

index e47f9f4..30ceaa4 100644 (file)
@@ -35,11 +35,13 @@ GetCurrentMicrocodeSignature (
 /**\r
   Detect whether specified processor can find matching microcode patch and load it.\r
 \r
-  @param[in]  CpuMpData  The pointer to CPU MP Data structure.\r
+  @param[in]  CpuMpData    The pointer to CPU MP Data structure.\r
+  @param[in]  IsBspCallIn  Indicate whether the caller is BSP or not.\r
 **/\r
 VOID\r
 MicrocodeDetect (\r
-  IN CPU_MP_DATA             *CpuMpData\r
+  IN CPU_MP_DATA             *CpuMpData,\r
+  IN BOOLEAN                 IsBspCallIn\r
   )\r
 {\r
   UINT32                                  ExtendedTableLength;\r
@@ -58,6 +60,7 @@ MicrocodeDetect (
   BOOLEAN                                 CorrectMicrocode;\r
   VOID                                    *MicrocodeData;\r
   MSR_IA32_PLATFORM_ID_REGISTER           PlatformIdMsr;\r
+  UINT32                                  ProcessorFlags;\r
 \r
   if (CpuMpData->MicrocodePatchRegionSize == 0) {\r
     //\r
@@ -67,7 +70,7 @@ MicrocodeDetect (
   }\r
 \r
   CurrentRevision = GetCurrentMicrocodeSignature ();\r
-  if (CurrentRevision != 0) {\r
+  if (CurrentRevision != 0 && !IsBspCallIn) {\r
     //\r
     // Skip loading microcode if it has been loaded successfully\r
     //\r
@@ -87,6 +90,19 @@ MicrocodeDetect (
   PlatformIdMsr.Uint64 = AsmReadMsr64 (MSR_IA32_PLATFORM_ID);\r
   PlatformId = (UINT8) PlatformIdMsr.Bits.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
+  }\r
+\r
   LatestRevision = 0;\r
   MicrocodeData  = NULL;\r
   MicrocodeEnd = (UINTN) (CpuMpData->MicrocodePatchAddress + CpuMpData->MicrocodePatchRegionSize);\r
@@ -117,6 +133,7 @@ MicrocodeDetect (
         }\r
         if (CheckSum32 == 0) {\r
           CorrectMicrocode = TRUE;\r
+          ProcessorFlags = MicrocodeEntryPoint->ProcessorFlags;\r
         }\r
       } else if ((MicrocodeEntryPoint->DataSize != 0) &&\r
                  (MicrocodeEntryPoint->UpdateRevision > LatestRevision)) {\r
@@ -151,6 +168,7 @@ MicrocodeDetect (
                     // Find one\r
                     //\r
                     CorrectMicrocode = TRUE;\r
+                    ProcessorFlags = ExtendedTable->ProcessorFlag;\r
                     break;\r
                   }\r
                 }\r
@@ -188,6 +206,7 @@ MicrocodeDetect (
     MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + TotalSize);\r
   } while (((UINTN) MicrocodeEntryPoint < MicrocodeEnd));\r
 \r
+Done:\r
   if (LatestRevision > CurrentRevision) {\r
     //\r
     // BIOS only authenticate updates that contain a numerically larger revision\r
@@ -211,4 +230,16 @@ MicrocodeDetect (
       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
index d8b56f1..722db2a 100644 (file)
@@ -410,7 +410,7 @@ ApInitializeSync (
   //\r
   // Load microcode on AP\r
   //\r
-  MicrocodeDetect (CpuMpData);\r
+  MicrocodeDetect (CpuMpData, FALSE);\r
   //\r
   // Sync BSP's MTRR table to AP\r
   //\r
@@ -1658,7 +1658,7 @@ MpInitLibInitialize (
   //\r
   // Load Microcode on BSP\r
   //\r
-  MicrocodeDetect (CpuMpData);\r
+  MicrocodeDetect (CpuMpData, TRUE);\r
   //\r
   // Store BSP's MTRR setting\r
   //\r
index 9aedb52..6958080 100644 (file)
@@ -245,6 +245,11 @@ struct _CPU_MP_DATA {
   BOOLEAN                        TimerInterruptState;\r
   UINT64                         MicrocodePatchAddress;\r
   UINT64                         MicrocodePatchRegionSize;\r
+\r
+  UINT32                         ProcessorSignature;\r
+  UINT32                         ProcessorFlags;\r
+  UINT64                         MicrocodeDataAddress;\r
+  UINT32                         MicrocodeRevision;\r
 };\r
 \r
 extern EFI_GUID mCpuInitMpLibHobGuid;\r
@@ -546,11 +551,13 @@ CheckAndUpdateApsStatus (
 /**\r
   Detect whether specified processor can find matching microcode patch and load it.\r
 \r
-  @param[in]  CpuMpData  The pointer to CPU MP Data structure.\r
+  @param[in]  CpuMpData    The pointer to CPU MP Data structure.\r
+  @param[in]  IsBspCallIn  Indicate whether the caller is BSP or not.\r
 **/\r
 VOID\r
 MicrocodeDetect (\r
-  IN CPU_MP_DATA             *CpuMpData\r
+  IN CPU_MP_DATA             *CpuMpData,\r
+  IN BOOLEAN                 IsBspCallIn\r
   );\r
 \r
 /**\r