]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/RegisterCpuFeaturesLib/CpuFeaturesInitialize.c
UefiCpuPkg: Refactor initialization of CPU features during S3 resume
[mirror_edk2.git] / UefiCpuPkg / Library / RegisterCpuFeaturesLib / CpuFeaturesInitialize.c
index 63bc50a55fe979ff06dc15f04411d80eda92653f..6e2ab7951821b76444b1597e015c9770e7d39053 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   CPU Features Initialize functions.\r
 \r
-  Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2017 - 2021, Intel Corporation. All rights reserved.<BR>\r
   SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
@@ -103,11 +103,16 @@ 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
+  UINTN                                Pages;\r
+  UINT32                               FirstPackage;\r
+  UINT32                               *FirstCore;\r
+  UINT32                               *FirstThread;\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
@@ -124,8 +129,9 @@ CpuInitDataInitialize (
 \r
   GetNumberOfProcessor (&NumberOfCpus, &NumberOfEnabledProcessors);\r
 \r
-  CpuFeaturesData->InitOrder = AllocateZeroPool (sizeof (CPU_FEATURES_INIT_ORDER) * NumberOfCpus);\r
+  CpuFeaturesData->InitOrder = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (CPU_FEATURES_INIT_ORDER) * NumberOfCpus));\r
   ASSERT (CpuFeaturesData->InitOrder != NULL);\r
+  ZeroMem (CpuFeaturesData->InitOrder, sizeof (CPU_FEATURES_INIT_ORDER) * NumberOfCpus);\r
 \r
   //\r
   // Collect CPU Features information\r
@@ -146,10 +152,10 @@ CpuInitDataInitialize (
   ASSERT (AcpiCpuData != NULL);\r
   CpuFeaturesData->AcpiCpuData= AcpiCpuData;\r
 \r
-  CpuStatus = &AcpiCpuData->CpuStatus;\r
+  CpuStatus = &AcpiCpuData->CpuFeatureInitData.CpuStatus;\r
   Location = AllocateZeroPool (sizeof (EFI_CPU_PHYSICAL_LOCATION) * NumberOfCpus);\r
   ASSERT (Location != NULL);\r
-  AcpiCpuData->ApLocation = (EFI_PHYSICAL_ADDRESS)(UINTN)Location;\r
+  AcpiCpuData->CpuFeatureInitData.ApLocation = (EFI_PHYSICAL_ADDRESS)(UINTN)Location;\r
 \r
   for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {\r
     InitOrder = &CpuFeaturesData->InitOrder[ProcessorNumber];\r
@@ -199,41 +205,104 @@ 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
   ASSERT (CpuFeaturesData->CpuFlags.CoreSemaphoreCount != NULL);\r
   CpuFeaturesData->CpuFlags.PackageSemaphoreCount = AllocateZeroPool (sizeof (UINT32) * CpuStatus->PackageCount * CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount);\r
   ASSERT (CpuFeaturesData->CpuFlags.PackageSemaphoreCount != NULL);\r
+\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 FirstPackage, FirstCore[], FirstThread[] to maximum package ID, core ID, thread ID.\r
+  //\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
+\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
+\r
+    if (Location->Package == FirstPackage) {\r
+      CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Package = 1;\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
+    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
+    if (Location->Core == FirstCore[Location->Package]) {\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
+  FreePages (FirstCore, Pages);\r
 }\r
 \r
 /**\r
@@ -430,8 +499,8 @@ DumpRegisterTableOnProcessor (
       DEBUG ((\r
         DebugPrintErrorLevel,\r
         "Processor: %04d: Index %04d, MSR  : %08x, Bit Start: %02d, Bit Length: %02d, Value: %016lx\r\n",\r
-        ProcessorNumber,\r
-        FeatureIndex,\r
+        (UINT32) ProcessorNumber,\r
+        (UINT32) FeatureIndex,\r
         RegisterTableEntry->Index,\r
         RegisterTableEntry->ValidBitStart,\r
         RegisterTableEntry->ValidBitLength,\r
@@ -442,8 +511,8 @@ DumpRegisterTableOnProcessor (
       DEBUG ((\r
         DebugPrintErrorLevel,\r
         "Processor: %04d: Index %04d, CR   : %08x, Bit Start: %02d, Bit Length: %02d, Value: %016lx\r\n",\r
-        ProcessorNumber,\r
-        FeatureIndex,\r
+        (UINT32) ProcessorNumber,\r
+        (UINT32) FeatureIndex,\r
         RegisterTableEntry->Index,\r
         RegisterTableEntry->ValidBitStart,\r
         RegisterTableEntry->ValidBitLength,\r
@@ -453,9 +522,9 @@ DumpRegisterTableOnProcessor (
     case MemoryMapped:\r
       DEBUG ((\r
         DebugPrintErrorLevel,\r
-        "Processor: %04d: Index %04d, MMIO : %08lx, Bit Start: %02d, Bit Length: %02d, Value: %016lx\r\n",\r
-        ProcessorNumber,\r
-        FeatureIndex,\r
+        "Processor: %04d: Index %04d, MMIO : %016lx, Bit Start: %02d, Bit Length: %02d, Value: %016lx\r\n",\r
+        (UINT32) ProcessorNumber,\r
+        (UINT32) FeatureIndex,\r
         RegisterTableEntry->Index | LShiftU64 (RegisterTableEntry->HighIndex, 32),\r
         RegisterTableEntry->ValidBitStart,\r
         RegisterTableEntry->ValidBitLength,\r
@@ -465,9 +534,9 @@ DumpRegisterTableOnProcessor (
     case CacheControl:\r
       DEBUG ((\r
         DebugPrintErrorLevel,\r
-        "Processor: %04d: Index %04d, CACHE: %08lx, Bit Start: %02d, Bit Length: %02d, Value: %016lx\r\n",\r
-        ProcessorNumber,\r
-        FeatureIndex,\r
+        "Processor: %04d: Index %04d, CACHE: %08x, Bit Start: %02d, Bit Length: %02d, Value: %016lx\r\n",\r
+        (UINT32) ProcessorNumber,\r
+        (UINT32) FeatureIndex,\r
         RegisterTableEntry->Index,\r
         RegisterTableEntry->ValidBitStart,\r
         RegisterTableEntry->ValidBitLength,\r
@@ -478,8 +547,8 @@ DumpRegisterTableOnProcessor (
       DEBUG ((\r
         DebugPrintErrorLevel,\r
         "Processor: %04d: Index %04d, SEMAP: %s\r\n",\r
-        ProcessorNumber,\r
-        FeatureIndex,\r
+        (UINT32) ProcessorNumber,\r
+        (UINT32) FeatureIndex,\r
         mDependTypeStr[MIN ((UINT32)RegisterTableEntry->Value, InvalidDepType)]\r
         ));\r
       break;\r
@@ -820,12 +889,13 @@ 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
   //\r
   // Traverse Register Table of this logical processor\r
@@ -848,7 +918,16 @@ ProgramProcessorRegister (
       if (EFI_ERROR (Status)) {\r
         break;\r
       }\r
-\r
+      if (RegisterTableEntry->TestThenWrite) {\r
+        CurrentValue = BitFieldRead64 (\r
+                         Value,\r
+                         RegisterTableEntry->ValidBitStart,\r
+                         RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1\r
+                         );\r
+        if (CurrentValue == RegisterTableEntry->Value) {\r
+          break;\r
+        }\r
+      }\r
       Value = (UINTN) BitFieldWrite64 (\r
                         Value,\r
                         RegisterTableEntry->ValidBitStart,\r
@@ -857,10 +936,29 @@ ProgramProcessorRegister (
                         );\r
       ReadWriteCr (RegisterTableEntry->Index, FALSE, &Value);\r
       break;\r
+\r
     //\r
     // The specified register is Model Specific Register\r
     //\r
     case Msr:\r
+      if (RegisterTableEntry->TestThenWrite) {\r
+        Value = (UINTN)AsmReadMsr64 (RegisterTableEntry->Index);\r
+        if (RegisterTableEntry->ValidBitLength >= 64) {\r
+          if (Value == RegisterTableEntry->Value) {\r
+            break;\r
+          }\r
+        } else {\r
+          CurrentValue = BitFieldRead64 (\r
+                           Value,\r
+                           RegisterTableEntry->ValidBitStart,\r
+                           RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1\r
+                           );\r
+          if (CurrentValue == RegisterTableEntry->Value) {\r
+            break;\r
+          }\r
+        }\r
+      }\r
+\r
       if (RegisterTableEntry->ValidBitLength >= 64) {\r
         //\r
         // If length is not less than 64 bits, then directly write without reading\r
@@ -926,28 +1024,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
+        // 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 has ready.\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
@@ -955,18 +1069,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
@@ -975,15 +1084,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
@@ -1022,7 +1131,7 @@ SetProcessorRegister (
   CpuFeaturesData = (CPU_FEATURES_DATA *) Buffer;\r
   AcpiCpuData = CpuFeaturesData->AcpiCpuData;\r
 \r
-  RegisterTables = (CPU_REGISTER_TABLE *)(UINTN)AcpiCpuData->RegisterTable;\r
+  RegisterTables = (CPU_REGISTER_TABLE *)(UINTN)AcpiCpuData->CpuFeatureInitData.RegisterTable;\r
 \r
   InitApicId = GetInitialApicId ();\r
   RegisterTable = NULL;\r
@@ -1038,8 +1147,8 @@ SetProcessorRegister (
 \r
   ProgramProcessorRegister (\r
     RegisterTable,\r
-    (EFI_CPU_PHYSICAL_LOCATION *)(UINTN)AcpiCpuData->ApLocation + ProcIndex,\r
-    &AcpiCpuData->CpuStatus,\r
+    (EFI_CPU_PHYSICAL_LOCATION *)(UINTN)AcpiCpuData->CpuFeatureInitData.ApLocation + ProcIndex,\r
+    &AcpiCpuData->CpuFeatureInitData.CpuStatus,\r
     &CpuFeaturesData->CpuFlags\r
     );\r
 }\r