]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/RegisterCpuFeaturesLib/CpuFeaturesInitialize.c
UefiCpuPkg/Feature: Support different thread count per core
[mirror_edk2.git] / UefiCpuPkg / Library / RegisterCpuFeaturesLib / CpuFeaturesInitialize.c
index 5c673fa8cf417d1202a92b91115745d914112879..d4a576385f0fcb5653806e5b22d937e7af2ed202 100644 (file)
@@ -103,14 +103,13 @@ CpuInitDataInitialize (
   UINT32                               Package;\r
   UINT32                               Thread;\r
   EFI_CPU_PHYSICAL_LOCATION            *Location;\r
-  BOOLEAN                              *CoresVisited;\r
-  UINTN                                Index;\r
   UINT32                               PackageIndex;\r
   UINT32                               CoreIndex;\r
   UINT32                               First;\r
   ACPI_CPU_DATA                        *AcpiCpuData;\r
   CPU_STATUS_INFORMATION               *CpuStatus;\r
-  UINT32                               *ValidCoreCountPerPackage;\r
+  UINT32                               *ThreadCountPerPackage;\r
+  UINT8                                *ThreadCountPerCore;\r
   UINTN                                NumberOfCpus;\r
   UINTN                                NumberOfEnabledProcessors;\r
 \r
@@ -202,35 +201,32 @@ CpuInitDataInitialize (
   //\r
   // Collect valid core count in each package because not all cores are valid.\r
   //\r
-  ValidCoreCountPerPackage= AllocateZeroPool (sizeof (UINT32) * CpuStatus->PackageCount);\r
-  ASSERT (ValidCoreCountPerPackage != 0);\r
-  CpuStatus->ValidCoreCountPerPackage = (EFI_PHYSICAL_ADDRESS)(UINTN)ValidCoreCountPerPackage;\r
-  CoresVisited = AllocatePool (sizeof (BOOLEAN) * CpuStatus->MaxCoreCount);\r
-  ASSERT (CoresVisited != NULL);\r
-\r
-  for (Index = 0; Index < CpuStatus->PackageCount; Index ++ ) {\r
-    ZeroMem (CoresVisited, sizeof (BOOLEAN) * CpuStatus->MaxCoreCount);\r
-    //\r
-    // Collect valid cores in Current package.\r
-    //\r
-    for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {\r
-      Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location;\r
-      if (Location->Package == Index && !CoresVisited[Location->Core] ) {\r
-        //\r
-        // The ValidCores position for Location->Core is valid.\r
-        // The possible values in ValidCores[Index] are 0 or 1.\r
-        // FALSE means no valid threads in this Core.\r
-        // TRUE means have valid threads in this core, no matter the thead count is 1 or more.\r
-        //\r
-        CoresVisited[Location->Core] = TRUE;\r
-        ValidCoreCountPerPackage[Index]++;\r
-      }\r
-    }\r
+  ThreadCountPerPackage = AllocateZeroPool (sizeof (UINT32) * CpuStatus->PackageCount);\r
+  ASSERT (ThreadCountPerPackage != NULL);\r
+  CpuStatus->ThreadCountPerPackage = (EFI_PHYSICAL_ADDRESS)(UINTN)ThreadCountPerPackage;\r
+\r
+  ThreadCountPerCore = AllocateZeroPool (sizeof (UINT8) * CpuStatus->PackageCount * CpuStatus->MaxCoreCount);\r
+  ASSERT (ThreadCountPerCore != NULL);\r
+  CpuStatus->ThreadCountPerCore = (EFI_PHYSICAL_ADDRESS)(UINTN)ThreadCountPerCore;\r
+\r
+  for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {\r
+    Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location;\r
+    ThreadCountPerPackage[Location->Package]++;\r
+    ThreadCountPerCore[Location->Package * CpuStatus->MaxCoreCount + Location->Core]++;\r
   }\r
-  FreePool (CoresVisited);\r
 \r
-  for (Index = 0; Index <= Package; Index++) {\r
-    DEBUG ((DEBUG_INFO, "Package: %d, Valid Core : %d\n", Index, ValidCoreCountPerPackage[Index]));\r
+  for (PackageIndex = 0; PackageIndex < CpuStatus->PackageCount; PackageIndex++) {\r
+    if (ThreadCountPerPackage[PackageIndex] != 0) {\r
+      DEBUG ((DEBUG_INFO, "P%02d: Thread Count = %d\n", PackageIndex, ThreadCountPerPackage[PackageIndex]));\r
+      for (CoreIndex = 0; CoreIndex < CpuStatus->MaxCoreCount; CoreIndex++) {\r
+        if (ThreadCountPerCore[PackageIndex * CpuStatus->MaxCoreCount + CoreIndex] != 0) {\r
+          DEBUG ((\r
+            DEBUG_INFO, "  P%02d C%04d, Thread Count = %d\n", PackageIndex, CoreIndex,\r
+            ThreadCountPerCore[PackageIndex * CpuStatus->MaxCoreCount + CoreIndex]\r
+            ));\r
+        }\r
+      }\r
+    }\r
   }\r
 \r
   CpuFeaturesData->CpuFlags.CoreSemaphoreCount = AllocateZeroPool (sizeof (UINT32) * CpuStatus->PackageCount * CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount);\r
@@ -894,11 +890,11 @@ ProgramProcessorRegister (
   CPU_REGISTER_TABLE_ENTRY  *RegisterTableEntryHead;\r
   volatile UINT32           *SemaphorePtr;\r
   UINT32                    FirstThread;\r
-  UINT32                    PackageThreadsCount;\r
   UINT32                    CurrentThread;\r
+  UINT32                    CurrentCore;\r
   UINTN                     ProcessorIndex;\r
-  UINTN                     ValidThreadCount;\r
-  UINT32                    *ValidCoreCountPerPackage;\r
+  UINT32                    *ThreadCountPerPackage;\r
+  UINT8                     *ThreadCountPerCore;\r
   EFI_STATUS                Status;\r
   UINT64                    CurrentValue;\r
 \r
@@ -1029,28 +1025,44 @@ ProgramProcessorRegister (
       switch (RegisterTableEntry->Value) {\r
       case CoreDepType:\r
         SemaphorePtr = CpuFlags->CoreSemaphoreCount;\r
+        ThreadCountPerCore = (UINT8 *)(UINTN)CpuStatus->ThreadCountPerCore;\r
+\r
+        CurrentCore = ApLocation->Package * CpuStatus->MaxCoreCount + ApLocation->Core;\r
         //\r
         // Get Offset info for the first thread in the core which current thread belongs to.\r
         //\r
-        FirstThread = (ApLocation->Package * CpuStatus->MaxCoreCount + ApLocation->Core) * CpuStatus->MaxThreadCount;\r
+        FirstThread   = CurrentCore * CpuStatus->MaxThreadCount;\r
         CurrentThread = FirstThread + ApLocation->Thread;\r
+\r
         //\r
-        // First Notify all threads in current Core that this thread has ready.\r
+        // Different cores may have different valid threads in them. If driver maintail clearly\r
+        // thread index in different cores, the logic will be much complicated.\r
+        // Here driver just simply records the max thread number in all cores and use it as expect\r
+        // thread number for all cores.\r
+        // In below two steps logic, first current thread will Release semaphore for each thread\r
+        // in current core. Maybe some threads are not valid in this core, but driver don't\r
+        // care. Second, driver will let current thread wait semaphore for all valid threads in\r
+        // current core. Because only the valid threads will do release semaphore for this\r
+        // thread, driver here only need to wait the valid thread count.\r
+        //\r
+\r
+        //\r
+        // First Notify ALL THREADs in current Core that this thread is ready.\r
         //\r
         for (ProcessorIndex = 0; ProcessorIndex < CpuStatus->MaxThreadCount; ProcessorIndex ++) {\r
-          LibReleaseSemaphore ((UINT32 *) &SemaphorePtr[FirstThread + ProcessorIndex]);\r
+          LibReleaseSemaphore (&SemaphorePtr[FirstThread + ProcessorIndex]);\r
         }\r
         //\r
-        // Second, check whether all valid threads in current core have ready.\r
+        // Second, check whether all VALID THREADs (not all threads) in current core are ready.\r
         //\r
-        for (ProcessorIndex = 0; ProcessorIndex < CpuStatus->MaxThreadCount; ProcessorIndex ++) {\r
+        for (ProcessorIndex = 0; ProcessorIndex < ThreadCountPerCore[CurrentCore]; ProcessorIndex ++) {\r
           LibWaitForSemaphore (&SemaphorePtr[CurrentThread]);\r
         }\r
         break;\r
 \r
       case PackageDepType:\r
         SemaphorePtr = CpuFlags->PackageSemaphoreCount;\r
-        ValidCoreCountPerPackage = (UINT32 *)(UINTN)CpuStatus->ValidCoreCountPerPackage;\r
+        ThreadCountPerPackage = (UINT32 *)(UINTN)CpuStatus->ThreadCountPerPackage;\r
         //\r
         // Get Offset info for the first thread in the package which current thread belongs to.\r
         //\r
@@ -1058,18 +1070,13 @@ ProgramProcessorRegister (
         //\r
         // Get the possible threads count for current package.\r
         //\r
-        PackageThreadsCount = CpuStatus->MaxThreadCount * CpuStatus->MaxCoreCount;\r
         CurrentThread = FirstThread + CpuStatus->MaxThreadCount * ApLocation->Core + ApLocation->Thread;\r
-        //\r
-        // Get the valid thread count for current package.\r
-        //\r
-        ValidThreadCount = CpuStatus->MaxThreadCount * ValidCoreCountPerPackage[ApLocation->Package];\r
 \r
         //\r
-        // Different packages may have different valid cores in them. If driver maintail clearly\r
-        // cores number in different packages, the logic will be much complicated.\r
-        // Here driver just simply records the max core number in all packages and use it as expect\r
-        // core number for all packages.\r
+        // Different packages may have different valid threads in them. If driver maintail clearly\r
+        // thread index in different packages, the logic will be much complicated.\r
+        // Here driver just simply records the max thread number in all packages and use it as expect\r
+        // thread number for all packages.\r
         // In below two steps logic, first current thread will Release semaphore for each thread\r
         // in current package. Maybe some threads are not valid in this package, but driver don't\r
         // care. Second, driver will let current thread wait semaphore for all valid threads in\r
@@ -1078,15 +1085,15 @@ ProgramProcessorRegister (
         //\r
 \r
         //\r
-        // First Notify ALL THREADS in current package that this thread has ready.\r
+        // First Notify ALL THREADS in current package that this thread is ready.\r
         //\r
-        for (ProcessorIndex = 0; ProcessorIndex < PackageThreadsCount ; ProcessorIndex ++) {\r
-          LibReleaseSemaphore ((UINT32 *) &SemaphorePtr[FirstThread + ProcessorIndex]);\r
+        for (ProcessorIndex = 0; ProcessorIndex < CpuStatus->MaxThreadCount * CpuStatus->MaxCoreCount; ProcessorIndex ++) {\r
+          LibReleaseSemaphore (&SemaphorePtr[FirstThread + ProcessorIndex]);\r
         }\r
         //\r
-        // Second, check whether VALID THREADS (not all threads) in current package have ready.\r
+        // Second, check whether VALID THREADS (not all threads) in current package are ready.\r
         //\r
-        for (ProcessorIndex = 0; ProcessorIndex < ValidThreadCount; ProcessorIndex ++) {\r
+        for (ProcessorIndex = 0; ProcessorIndex < ThreadCountPerPackage[ApLocation->Package]; ProcessorIndex ++) {\r
           LibWaitForSemaphore (&SemaphorePtr[CurrentThread]);\r
         }\r
         break;\r