]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/RegisterCpuFeaturesLib/CpuFeaturesInitialize.c
UefiCpuPkg/CpuFeature: reduce time complexty to calc CpuInfo.First
[mirror_edk2.git] / UefiCpuPkg / Library / RegisterCpuFeaturesLib / CpuFeaturesInitialize.c
index ba052732a86c324ededa82610f817f3fa1b0b701..57511c4efa7c3ec189240bf26f8e5ff58963fad3 100644 (file)
@@ -105,7 +105,10 @@ CpuInitDataInitialize (
   EFI_CPU_PHYSICAL_LOCATION            *Location;\r
   UINT32                               PackageIndex;\r
   UINT32                               CoreIndex;\r
-  UINT32                               First;\r
+  UINTN                                Pages;\r
+  UINT32                               FirstPackage;\r
+  UINT32                               *FirstCore;\r
+  UINT32                               *FirstThread;\r
   ACPI_CPU_DATA                        *AcpiCpuData;\r
   CPU_STATUS_INFORMATION               *CpuStatus;\r
   UINT32                               *ThreadCountPerPackage;\r
@@ -237,74 +240,69 @@ CpuInitDataInitialize (
 \r
   //\r
   // Initialize CpuFeaturesData->InitOrder[].CpuInfo.First\r
+  // Use AllocatePages () instead of AllocatePool () because pool cannot be freed in PEI phase but page can.\r
   //\r
+  Pages     = EFI_SIZE_TO_PAGES (CpuStatus->PackageCount * sizeof (UINT32) + CpuStatus->PackageCount * CpuStatus->MaxCoreCount * sizeof (UINT32));\r
+  FirstCore = AllocatePages (Pages);\r
+  ASSERT (FirstCore != NULL);\r
+  FirstThread  = FirstCore + CpuStatus->PackageCount;\r
 \r
   //\r
-  // Set First.Package for each thread belonging to the first package.\r
+  // Set FirstPackage, FirstCore[], FirstThread[] to maximum package ID, core ID, thread ID.\r
   //\r
-  First = MAX_UINT32;\r
+  FirstPackage = MAX_UINT32;\r
+  SetMem32 (FirstCore,   CpuStatus->PackageCount * sizeof (UINT32), MAX_UINT32);\r
+  SetMem32 (FirstThread, CpuStatus->PackageCount * CpuStatus->MaxCoreCount * sizeof (UINT32), MAX_UINT32);\r
+\r
   for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {\r
     Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location;\r
-    First = MIN (Location->Package, First);\r
+\r
+    //\r
+    // Save the minimum package ID in the platform.\r
+    //\r
+    FirstPackage                 = MIN (Location->Package, FirstPackage);\r
+\r
+    //\r
+    // Save the minimum core ID per package.\r
+    //\r
+    FirstCore[Location->Package] = MIN (Location->Core, FirstCore[Location->Package]);\r
+\r
+    //\r
+    // Save the minimum thread ID per core.\r
+    //\r
+    FirstThread[Location->Package * CpuStatus->MaxCoreCount + Location->Core] = MIN (\r
+      Location->Thread,\r
+      FirstThread[Location->Package * CpuStatus->MaxCoreCount + Location->Core]\r
+    );\r
   }\r
+\r
+  //\r
+  // Update the First field.\r
+  //\r
   for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {\r
     Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location;\r
-    if (Location->Package == First) {\r
+\r
+    if (Location->Package == FirstPackage) {\r
       CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Package = 1;\r
     }\r
-  }\r
 \r
-  //\r
-  // Set First.Die/Tile/Module for each thread assuming:\r
-  //  single Die under each package, single Tile under each Die, single Module under each Tile\r
-  //\r
-  for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {\r
+    //\r
+    // Set First.Die/Tile/Module for each thread assuming:\r
+    //  single Die under each package, single Tile under each Die, single Module under each Tile\r
+    //\r
     CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Die = 1;\r
     CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Tile = 1;\r
     CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Module = 1;\r
-  }\r
 \r
-  for (PackageIndex = 0; PackageIndex < CpuStatus->PackageCount; PackageIndex++) {\r
-    //\r
-    // Set First.Core for each thread in the first core of each package.\r
-    //\r
-    First = MAX_UINT32;\r
-    for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {\r
-      Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location;\r
-      if (Location->Package == PackageIndex) {\r
-        First = MIN (Location->Core, First);\r
-      }\r
+    if (Location->Core == FirstCore[Location->Package]) {\r
+      CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Core = 1;\r
     }\r
-\r
-    for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {\r
-      Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location;\r
-      if (Location->Package == PackageIndex && Location->Core == First) {\r
-        CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Core = 1;\r
-      }\r
+    if (Location->Thread == FirstThread[Location->Package * CpuStatus->MaxCoreCount + Location->Core]) {\r
+      CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Thread = 1;\r
     }\r
   }\r
 \r
-  for (PackageIndex = 0; PackageIndex < CpuStatus->PackageCount; PackageIndex++) {\r
-    for (CoreIndex = 0; CoreIndex < CpuStatus->MaxCoreCount; CoreIndex++) {\r
-      //\r
-      // Set First.Thread for the first thread of each core.\r
-      //\r
-      First = MAX_UINT32;\r
-      for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {\r
-        Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location;\r
-        if (Location->Package == PackageIndex && Location->Core == CoreIndex) {\r
-          First = MIN (Location->Thread, First);\r
-        }\r
-      }\r
-\r
-      for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {\r
-        Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location;\r
-        if (Location->Package == PackageIndex && Location->Core == CoreIndex && Location->Thread == First) {\r
-          CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Thread = 1;\r
-        }\r
-      }\r
-    }\r
-  }\r
+  FreePages (FirstCore, Pages);\r
 }\r
 \r
 /**\r