/** @file\r
CPU Register Table Library functions.\r
\r
- Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ Copyright (c) 2017 - 2021, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include "RegisterCpuFeatures.h"\r
\r
-/**\r
- Checks if two CPU feature bit masks are equal.\r
-\r
- @param[in] FirstFeatureMask The first input CPU feature bit mask\r
- @param[in] SecondFeatureMask The second input CPU feature bit mask\r
-\r
- @retval TRUE Two CPU feature bit masks are equal.\r
- @retval FALSE Two CPU feature bit masks are not equal.\r
-**/\r
-BOOLEAN\r
-IsCpuFeatureMatch (\r
- IN UINT8 *FirstFeatureMask,\r
- IN UINT8 *SecondFeatureMask\r
- )\r
-{\r
- UINTN BitMaskSize;\r
-\r
- BitMaskSize = PcdGetSize (PcdCpuFeaturesSupport);\r
- if (CompareMem (FirstFeatureMask, SecondFeatureMask, BitMaskSize) == 0) {\r
- return TRUE;\r
- } else {\r
- return FALSE;\r
- }\r
-}\r
-\r
/**\r
Function that uses DEBUG() macros to display the contents of a a CPU feature bit mask.\r
\r
@param[in] FeatureMask A pointer to the CPU feature bit mask.\r
+ @param[in] BitMaskSize CPU feature bits mask buffer size.\r
+\r
**/\r
VOID\r
DumpCpuFeatureMask (\r
- IN UINT8 *FeatureMask\r
+ IN UINT8 *FeatureMask,\r
+ IN UINT32 BitMaskSize\r
)\r
{\r
- UINTN Index;\r
- UINT8 *Data8;\r
- UINTN BitMaskSize;\r
+ UINTN Index;\r
+ UINT8 *Data8;\r
\r
- BitMaskSize = PcdGetSize (PcdCpuFeaturesSupport);\r
- Data8 = (UINT8 *) FeatureMask;\r
+ Data8 = (UINT8 *)FeatureMask;\r
for (Index = 0; Index < BitMaskSize; Index++) {\r
DEBUG ((DEBUG_INFO, " %02x ", *Data8++));\r
}\r
+\r
DEBUG ((DEBUG_INFO, "\n"));\r
}\r
\r
Dump CPU feature name or CPU feature bit mask.\r
\r
@param[in] CpuFeature Pointer to CPU_FEATURES_ENTRY\r
+ @param[in] BitMaskSize CPU feature bits mask buffer size.\r
+\r
**/\r
VOID\r
DumpCpuFeature (\r
- IN CPU_FEATURES_ENTRY *CpuFeature\r
+ IN CPU_FEATURES_ENTRY *CpuFeature,\r
+ IN UINT32 BitMaskSize\r
)\r
{\r
-\r
if (CpuFeature->FeatureName != NULL) {\r
DEBUG ((DEBUG_INFO, "FeatureName: %a\n", CpuFeature->FeatureName));\r
} else {\r
DEBUG ((DEBUG_INFO, "FeatureMask = "));\r
- DumpCpuFeatureMask (CpuFeature->FeatureMask);\r
+ DumpCpuFeatureMask (CpuFeature->FeatureMask, BitMaskSize);\r
}\r
}\r
\r
**/\r
BOOLEAN\r
IsBitMaskMatchCheck (\r
- IN UINT8 *FeatureMask,\r
- IN UINT8 *DependentBitMask\r
+ IN UINT8 *FeatureMask,\r
+ IN UINT8 *DependentBitMask\r
)\r
{\r
- UINTN Index;\r
- UINTN BitMaskSize;\r
- UINT8 *Data1;\r
- UINT8 *Data2;\r
+ UINTN Index;\r
+ UINT8 *Data1;\r
+ UINT8 *Data2;\r
+ CPU_FEATURES_DATA *CpuFeaturesData;\r
\r
- BitMaskSize = PcdGetSize (PcdCpuFeaturesSupport);\r
+ CpuFeaturesData = GetCpuFeaturesData ();\r
\r
Data1 = FeatureMask;\r
Data2 = DependentBitMask;\r
- for (Index = 0; Index < BitMaskSize; Index++) {\r
+ for (Index = 0; Index < CpuFeaturesData->BitMaskSize; Index++) {\r
if (((*(Data1++)) & (*(Data2++))) != 0) {\r
return TRUE;\r
}\r
}\r
+\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Try to find the specify cpu featuren in former/after feature list.\r
+\r
+ @param[in] FeatureList Pointer to dependent CPU feature list\r
+ @param[in] CurrentEntry Pointer to current CPU feature entry.\r
+ @param[in] SearchFormer Find in former feature or after features.\r
+ @param[in] FeatureMask Pointer to CPU feature bit mask\r
+\r
+ @retval TRUE The feature bit mask is in dependent CPU feature bit mask buffer.\r
+ @retval FALSE The feature bit mask is not in dependent CPU feature bit mask buffer.\r
+**/\r
+BOOLEAN\r
+FindSpecifyFeature (\r
+ IN LIST_ENTRY *FeatureList,\r
+ IN LIST_ENTRY *CurrentEntry,\r
+ IN BOOLEAN SearchFormer,\r
+ IN UINT8 *FeatureMask\r
+ )\r
+{\r
+ CPU_FEATURES_ENTRY *CpuFeature;\r
+ LIST_ENTRY *NextEntry;\r
+\r
+ //\r
+ // Check whether exist the not neighborhood entry first.\r
+ // If not exist, return FALSE means not found status.\r
+ //\r
+ if (SearchFormer) {\r
+ NextEntry = CurrentEntry->BackLink;\r
+ if (IsNull (FeatureList, NextEntry)) {\r
+ return FALSE;\r
+ }\r
+\r
+ NextEntry = NextEntry->BackLink;\r
+ if (IsNull (FeatureList, NextEntry)) {\r
+ return FALSE;\r
+ }\r
+\r
+ NextEntry = CurrentEntry->BackLink->BackLink;\r
+ } else {\r
+ NextEntry = CurrentEntry->ForwardLink;\r
+ if (IsNull (FeatureList, NextEntry)) {\r
+ return FALSE;\r
+ }\r
+\r
+ NextEntry = NextEntry->ForwardLink;\r
+ if (IsNull (FeatureList, NextEntry)) {\r
+ return FALSE;\r
+ }\r
+\r
+ NextEntry = CurrentEntry->ForwardLink->ForwardLink;\r
+ }\r
+\r
+ while (!IsNull (FeatureList, NextEntry)) {\r
+ CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (NextEntry);\r
+\r
+ if (IsBitMaskMatchCheck (FeatureMask, CpuFeature->FeatureMask)) {\r
+ return TRUE;\r
+ }\r
+\r
+ if (SearchFormer) {\r
+ NextEntry = NextEntry->BackLink;\r
+ } else {\r
+ NextEntry = NextEntry->ForwardLink;\r
+ }\r
+ }\r
+\r
return FALSE;\r
}\r
\r
/**\r
Return feature dependence result.\r
\r
- @param[in] CpuFeature Pointer to CPU feature.\r
- @param[in] Before Check before dependence or after.\r
+ @param[in] CpuFeature Pointer to CPU feature.\r
+ @param[in] Before Check before dependence or after.\r
+ @param[in] NextCpuFeatureMask Pointer to next CPU feature Mask.\r
\r
@retval return the dependence result.\r
**/\r
CPU_FEATURE_DEPENDENCE_TYPE\r
DetectFeatureScope (\r
- IN CPU_FEATURES_ENTRY *CpuFeature,\r
- IN BOOLEAN Before\r
+ IN CPU_FEATURES_ENTRY *CpuFeature,\r
+ IN BOOLEAN Before,\r
+ IN UINT8 *NextCpuFeatureMask\r
)\r
{\r
+ //\r
+ // if need to check before type dependence but the feature after current feature is not\r
+ // exist, means this before type dependence not valid, just return NoneDepType.\r
+ // Just like Feature A has a dependence of feature B, but Feature B not installed, so\r
+ // Feature A maybe insert to the last entry of the list. In this case, for below code,\r
+ // Featrure A has depend of feature B, but it is the last entry of the list, so the\r
+ // NextCpuFeatureMask is NULL, so the dependence for feature A here is useless and code\r
+ // just return NoneDepType.\r
+ //\r
+ if (NextCpuFeatureMask == NULL) {\r
+ return NoneDepType;\r
+ }\r
+\r
if (Before) {\r
- if (CpuFeature->PackageBeforeFeatureBitMask != NULL) {\r
+ if ((CpuFeature->PackageBeforeFeatureBitMask != NULL) &&\r
+ IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->PackageBeforeFeatureBitMask))\r
+ {\r
return PackageDepType;\r
}\r
\r
- if (CpuFeature->CoreBeforeFeatureBitMask != NULL) {\r
+ if ((CpuFeature->CoreBeforeFeatureBitMask != NULL) &&\r
+ IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->CoreBeforeFeatureBitMask))\r
+ {\r
return CoreDepType;\r
}\r
\r
- if (CpuFeature->BeforeFeatureBitMask != NULL) {\r
+ if ((CpuFeature->ThreadBeforeFeatureBitMask != NULL) &&\r
+ IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->ThreadBeforeFeatureBitMask))\r
+ {\r
return ThreadDepType;\r
}\r
\r
return NoneDepType;\r
}\r
\r
- if (CpuFeature->PackageAfterFeatureBitMask != NULL) {\r
+ if ((CpuFeature->PackageAfterFeatureBitMask != NULL) &&\r
+ IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->PackageAfterFeatureBitMask))\r
+ {\r
return PackageDepType;\r
}\r
\r
- if (CpuFeature->CoreAfterFeatureBitMask != NULL) {\r
+ if ((CpuFeature->CoreAfterFeatureBitMask != NULL) &&\r
+ IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->CoreAfterFeatureBitMask))\r
+ {\r
return CoreDepType;\r
}\r
\r
- if (CpuFeature->AfterFeatureBitMask != NULL) {\r
+ if ((CpuFeature->ThreadAfterFeatureBitMask != NULL) &&\r
+ IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->ThreadAfterFeatureBitMask))\r
+ {\r
return ThreadDepType;\r
}\r
\r
}\r
\r
/**\r
- Clear dependence for the specified type.\r
+ Return feature dependence result.\r
\r
- @param[in] CpuFeature Cpu feature need to clear.\r
- @param[in] Before Before or after dependence relationship.\r
+ @param[in] CpuFeature Pointer to CPU feature.\r
+ @param[in] Before Check before dependence or after.\r
+ @param[in] FeatureList Pointer to CPU feature list.\r
\r
+ @retval return the dependence result.\r
**/\r
-VOID\r
-ClearFeatureScope (\r
- IN CPU_FEATURES_ENTRY *CpuFeature,\r
- IN BOOLEAN Before\r
+CPU_FEATURE_DEPENDENCE_TYPE\r
+DetectNoneNeighborhoodFeatureScope (\r
+ IN CPU_FEATURES_ENTRY *CpuFeature,\r
+ IN BOOLEAN Before,\r
+ IN LIST_ENTRY *FeatureList\r
)\r
{\r
if (Before) {\r
- if (CpuFeature->BeforeFeatureBitMask != NULL) {\r
- FreePool (CpuFeature->BeforeFeatureBitMask);\r
- CpuFeature->BeforeFeatureBitMask = NULL;\r
- }\r
- if (CpuFeature->CoreBeforeFeatureBitMask != NULL) {\r
- FreePool (CpuFeature->CoreBeforeFeatureBitMask);\r
- CpuFeature->CoreBeforeFeatureBitMask = NULL;\r
- }\r
- if (CpuFeature->PackageBeforeFeatureBitMask != NULL) {\r
- FreePool (CpuFeature->PackageBeforeFeatureBitMask);\r
- CpuFeature->PackageBeforeFeatureBitMask = NULL;\r
- }\r
- } else {\r
- if (CpuFeature->PackageAfterFeatureBitMask != NULL) {\r
- FreePool (CpuFeature->PackageAfterFeatureBitMask);\r
- CpuFeature->PackageAfterFeatureBitMask = NULL;\r
+ if ((CpuFeature->PackageBeforeFeatureBitMask != NULL) &&\r
+ FindSpecifyFeature (FeatureList, &CpuFeature->Link, FALSE, CpuFeature->PackageBeforeFeatureBitMask))\r
+ {\r
+ return PackageDepType;\r
}\r
- if (CpuFeature->CoreAfterFeatureBitMask != NULL) {\r
- FreePool (CpuFeature->CoreAfterFeatureBitMask);\r
- CpuFeature->CoreAfterFeatureBitMask = NULL;\r
+\r
+ if ((CpuFeature->CoreBeforeFeatureBitMask != NULL) &&\r
+ FindSpecifyFeature (FeatureList, &CpuFeature->Link, FALSE, CpuFeature->CoreBeforeFeatureBitMask))\r
+ {\r
+ return CoreDepType;\r
}\r
- if (CpuFeature->AfterFeatureBitMask != NULL) {\r
- FreePool (CpuFeature->AfterFeatureBitMask);\r
- CpuFeature->AfterFeatureBitMask = NULL;\r
+\r
+ if ((CpuFeature->ThreadBeforeFeatureBitMask != NULL) &&\r
+ FindSpecifyFeature (FeatureList, &CpuFeature->Link, FALSE, CpuFeature->ThreadBeforeFeatureBitMask))\r
+ {\r
+ return ThreadDepType;\r
}\r
+\r
+ return NoneDepType;\r
}\r
+\r
+ if ((CpuFeature->PackageAfterFeatureBitMask != NULL) &&\r
+ FindSpecifyFeature (FeatureList, &CpuFeature->Link, TRUE, CpuFeature->PackageAfterFeatureBitMask))\r
+ {\r
+ return PackageDepType;\r
+ }\r
+\r
+ if ((CpuFeature->CoreAfterFeatureBitMask != NULL) &&\r
+ FindSpecifyFeature (FeatureList, &CpuFeature->Link, TRUE, CpuFeature->CoreAfterFeatureBitMask))\r
+ {\r
+ return CoreDepType;\r
+ }\r
+\r
+ if ((CpuFeature->ThreadAfterFeatureBitMask != NULL) &&\r
+ FindSpecifyFeature (FeatureList, &CpuFeature->Link, TRUE, CpuFeature->ThreadAfterFeatureBitMask))\r
+ {\r
+ return ThreadDepType;\r
+ }\r
+\r
+ return NoneDepType;\r
}\r
\r
/**\r
\r
@param[in, out] PreviousFeature CPU feature current before the find one.\r
@param[in, out] CurrentFeature Cpu feature need to adjust.\r
+ @param[in] FindFeature Cpu feature which current feature depends.\r
@param[in] Before Before or after dependence relationship.\r
\r
@retval TRUE means the current feature dependence has been adjusted.\r
**/\r
BOOLEAN\r
AdjustFeaturesDependence (\r
- IN OUT CPU_FEATURES_ENTRY *PreviousFeature,\r
- IN OUT CPU_FEATURES_ENTRY *CurrentFeature,\r
- IN BOOLEAN Before\r
+ IN OUT CPU_FEATURES_ENTRY *PreviousFeature,\r
+ IN OUT CPU_FEATURES_ENTRY *CurrentFeature,\r
+ IN CPU_FEATURES_ENTRY *FindFeature,\r
+ IN BOOLEAN Before\r
)\r
{\r
- CPU_FEATURE_DEPENDENCE_TYPE PreDependType;\r
- CPU_FEATURE_DEPENDENCE_TYPE CurrentDependType;\r
+ CPU_FEATURE_DEPENDENCE_TYPE PreDependType;\r
+ CPU_FEATURE_DEPENDENCE_TYPE CurrentDependType;\r
\r
- PreDependType = DetectFeatureScope(PreviousFeature, Before);\r
- CurrentDependType = DetectFeatureScope(CurrentFeature, Before);\r
+ PreDependType = DetectFeatureScope (PreviousFeature, Before, FindFeature->FeatureMask);\r
+ CurrentDependType = DetectFeatureScope (CurrentFeature, Before, FindFeature->FeatureMask);\r
\r
//\r
// If previous feature has no dependence with the find featue.\r
// processors and clear the dependence for the other one.\r
//\r
if (PreDependType >= CurrentDependType) {\r
- ClearFeatureScope (CurrentFeature, Before);\r
return TRUE;\r
} else {\r
- ClearFeatureScope (PreviousFeature, Before);\r
return FALSE;\r
}\r
}\r
**/\r
VOID\r
AdjustEntry (\r
- IN LIST_ENTRY *FeatureList,\r
- IN OUT LIST_ENTRY *FindEntry,\r
- IN OUT LIST_ENTRY *CurrentEntry,\r
- IN BOOLEAN Before\r
+ IN LIST_ENTRY *FeatureList,\r
+ IN OUT LIST_ENTRY *FindEntry,\r
+ IN OUT LIST_ENTRY *CurrentEntry,\r
+ IN BOOLEAN Before\r
)\r
{\r
- LIST_ENTRY *PreviousEntry;\r
- CPU_FEATURES_ENTRY *PreviousFeature;\r
- CPU_FEATURES_ENTRY *CurrentFeature;\r
+ LIST_ENTRY *PreviousEntry;\r
+ CPU_FEATURES_ENTRY *PreviousFeature;\r
+ CPU_FEATURES_ENTRY *CurrentFeature;\r
+ CPU_FEATURES_ENTRY *FindFeature;\r
\r
//\r
// For CPU feature which has core or package type dependence, later code need to insert\r
//\r
if (Before) {\r
PreviousEntry = GetPreviousNode (FeatureList, FindEntry);\r
- } else {\r\r
+ } else {\r
PreviousEntry = GetNextNode (FeatureList, FindEntry);\r
}\r
\r
- CurrentFeature = CPU_FEATURE_ENTRY_FROM_LINK (CurrentEntry);\r
+ CurrentFeature = CPU_FEATURE_ENTRY_FROM_LINK (CurrentEntry);\r
RemoveEntryList (CurrentEntry);\r
\r
if (IsNull (FeatureList, PreviousEntry)) {\r
// If exist the previous or next entry, need to check it before insert curent entry.\r
//\r
PreviousFeature = CPU_FEATURE_ENTRY_FROM_LINK (PreviousEntry);\r
+ FindFeature = CPU_FEATURE_ENTRY_FROM_LINK (FindEntry);\r
\r
- if (AdjustFeaturesDependence (PreviousFeature, CurrentFeature, Before)) {\r
+ if (AdjustFeaturesDependence (PreviousFeature, CurrentFeature, FindFeature, Before)) {\r
//\r
// Return TRUE means current feature dependence has been cleared and the previous\r
// feature dependence has been kept and used. So insert current feature before (or after)\r
}\r
}\r
}\r
-}\r\r
+}\r
\r
/**\r
Checks and adjusts current CPU features per dependency relationship.\r
**/\r
BOOLEAN\r
InsertToBeforeEntry (\r
- IN LIST_ENTRY *FeatureList,\r
- IN LIST_ENTRY *CurrentEntry,\r
- IN UINT8 *FeatureMask\r
+ IN LIST_ENTRY *FeatureList,\r
+ IN LIST_ENTRY *CurrentEntry,\r
+ IN UINT8 *FeatureMask\r
)\r
{\r
- LIST_ENTRY *CheckEntry;\r
- CPU_FEATURES_ENTRY *CheckFeature;\r
- BOOLEAN Swapped;\r
+ LIST_ENTRY *CheckEntry;\r
+ CPU_FEATURES_ENTRY *CheckFeature;\r
+ BOOLEAN Swapped;\r
\r
Swapped = FALSE;\r
\r
Swapped = TRUE;\r
break;\r
}\r
+\r
CheckEntry = CheckEntry->ForwardLink;\r
}\r
\r
**/\r
BOOLEAN\r
InsertToAfterEntry (\r
- IN LIST_ENTRY *FeatureList,\r
- IN LIST_ENTRY *CurrentEntry,\r
- IN UINT8 *FeatureMask\r
+ IN LIST_ENTRY *FeatureList,\r
+ IN LIST_ENTRY *CurrentEntry,\r
+ IN UINT8 *FeatureMask\r
)\r
{\r
- LIST_ENTRY *CheckEntry;\r
- CPU_FEATURES_ENTRY *CheckFeature;\r
- BOOLEAN Swapped;\r
+ LIST_ENTRY *CheckEntry;\r
+ CPU_FEATURES_ENTRY *CheckFeature;\r
+ BOOLEAN Swapped;\r
\r
Swapped = FALSE;\r
\r
Swapped = TRUE;\r
break;\r
}\r
+\r
CheckEntry = CheckEntry->ForwardLink;\r
}\r
\r
**/\r
VOID\r
CheckCpuFeaturesDependency (\r
- IN LIST_ENTRY *FeatureList\r
+ IN LIST_ENTRY *FeatureList\r
)\r
{\r
- LIST_ENTRY *CurrentEntry;\r
- CPU_FEATURES_ENTRY *CpuFeature;\r
- LIST_ENTRY *CheckEntry;\r
- CPU_FEATURES_ENTRY *CheckFeature;\r
- BOOLEAN Swapped;\r
- LIST_ENTRY *TempEntry;\r
- LIST_ENTRY *NextEntry;\r
+ LIST_ENTRY *CurrentEntry;\r
+ CPU_FEATURES_ENTRY *CpuFeature;\r
+ LIST_ENTRY *CheckEntry;\r
+ CPU_FEATURES_ENTRY *CheckFeature;\r
+ BOOLEAN Swapped;\r
+ LIST_ENTRY *TempEntry;\r
+ LIST_ENTRY *NextEntry;\r
\r
CurrentEntry = GetFirstNode (FeatureList);\r
while (!IsNull (FeatureList, CurrentEntry)) {\r
- Swapped = FALSE;\r
+ Swapped = FALSE;\r
CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (CurrentEntry);\r
- NextEntry = CurrentEntry->ForwardLink;\r
+ NextEntry = CurrentEntry->ForwardLink;\r
if (CpuFeature->BeforeAll) {\r
//\r
// Check all features dispatched before this entry\r
Swapped = TRUE;\r
break;\r
}\r
+\r
CheckEntry = CheckEntry->ForwardLink;\r
}\r
+\r
if (Swapped) {\r
CurrentEntry = NextEntry;\r
continue;\r
RemoveEntryList (CurrentEntry);\r
InsertHeadList (CheckEntry, CurrentEntry);\r
CurrentEntry = TempEntry;\r
- Swapped = TRUE;\r
+ Swapped = TRUE;\r
break;\r
}\r
+\r
CheckEntry = CheckEntry->ForwardLink;\r
}\r
+\r
if (Swapped) {\r
CurrentEntry = NextEntry;\r
continue;\r
}\r
}\r
\r
- if (CpuFeature->BeforeFeatureBitMask != NULL) {\r
- Swapped = InsertToBeforeEntry (FeatureList, CurrentEntry, CpuFeature->BeforeFeatureBitMask);\r
+ if (CpuFeature->ThreadBeforeFeatureBitMask != NULL) {\r
+ Swapped = InsertToBeforeEntry (FeatureList, CurrentEntry, CpuFeature->ThreadBeforeFeatureBitMask);\r
if (Swapped) {\r
- CurrentEntry = NextEntry;\r
continue;\r
}\r
}\r
\r
- if (CpuFeature->AfterFeatureBitMask != NULL) {\r
- Swapped = InsertToAfterEntry (FeatureList, CurrentEntry, CpuFeature->AfterFeatureBitMask);\r
+ if (CpuFeature->ThreadAfterFeatureBitMask != NULL) {\r
+ Swapped = InsertToAfterEntry (FeatureList, CurrentEntry, CpuFeature->ThreadAfterFeatureBitMask);\r
if (Swapped) {\r
- CurrentEntry = NextEntry;\r
continue;\r
}\r
}\r
if (CpuFeature->CoreBeforeFeatureBitMask != NULL) {\r
Swapped = InsertToBeforeEntry (FeatureList, CurrentEntry, CpuFeature->CoreBeforeFeatureBitMask);\r
if (Swapped) {\r
- CurrentEntry = NextEntry;\r
continue;\r
}\r
}\r
if (CpuFeature->CoreAfterFeatureBitMask != NULL) {\r
Swapped = InsertToAfterEntry (FeatureList, CurrentEntry, CpuFeature->CoreAfterFeatureBitMask);\r
if (Swapped) {\r
- CurrentEntry = NextEntry;\r
continue;\r
}\r
}\r
if (CpuFeature->PackageBeforeFeatureBitMask != NULL) {\r
Swapped = InsertToBeforeEntry (FeatureList, CurrentEntry, CpuFeature->PackageBeforeFeatureBitMask);\r
if (Swapped) {\r
- CurrentEntry = NextEntry;\r
continue;\r
}\r
}\r
if (CpuFeature->PackageAfterFeatureBitMask != NULL) {\r
Swapped = InsertToAfterEntry (FeatureList, CurrentEntry, CpuFeature->PackageAfterFeatureBitMask);\r
if (Swapped) {\r
- CurrentEntry = NextEntry;\r
continue;\r
}\r
}\r
/**\r
Worker function to register CPU Feature.\r
\r
+ @param[in] CpuFeaturesData Pointer to CPU feature data structure.\r
@param[in] CpuFeature Pointer to CPU feature entry\r
\r
@retval RETURN_SUCCESS The CPU feature was successfully registered.\r
**/\r
RETURN_STATUS\r
RegisterCpuFeatureWorker (\r
- IN CPU_FEATURES_ENTRY *CpuFeature\r
+ IN CPU_FEATURES_DATA *CpuFeaturesData,\r
+ IN CPU_FEATURES_ENTRY *CpuFeature\r
)\r
{\r
- EFI_STATUS Status;\r
- CPU_FEATURES_DATA *CpuFeaturesData;\r
- CPU_FEATURES_ENTRY *CpuFeatureEntry;\r
- LIST_ENTRY *Entry;\r
- UINTN BitMaskSize;\r
- BOOLEAN FeatureExist;\r
+ EFI_STATUS Status;\r
+ CPU_FEATURES_ENTRY *CpuFeatureEntry;\r
+ LIST_ENTRY *Entry;\r
+ BOOLEAN FeatureExist;\r
\r
- BitMaskSize = PcdGetSize (PcdCpuFeaturesSupport);\r
- CpuFeaturesData = GetCpuFeaturesData ();\r
- if (CpuFeaturesData->FeaturesCount == 0) {\r
- InitializeListHead (&CpuFeaturesData->FeatureList);\r
- InitializeSpinLock (&CpuFeaturesData->CpuFlags.MemoryMappedLock);\r
- InitializeSpinLock (&CpuFeaturesData->CpuFlags.ConsoleLogLock);\r
- CpuFeaturesData->BitMaskSize = (UINT32) BitMaskSize;\r
- }\r
- ASSERT (CpuFeaturesData->BitMaskSize == BitMaskSize);\r
-\r
- FeatureExist = FALSE;\r
+ FeatureExist = FALSE;\r
CpuFeatureEntry = NULL;\r
- Entry = GetFirstNode (&CpuFeaturesData->FeatureList);\r
+ Entry = GetFirstNode (&CpuFeaturesData->FeatureList);\r
while (!IsNull (&CpuFeaturesData->FeatureList, Entry)) {\r
CpuFeatureEntry = CPU_FEATURE_ENTRY_FROM_LINK (Entry);\r
- if (IsCpuFeatureMatch (CpuFeature->FeatureMask, CpuFeatureEntry->FeatureMask)) {\r
+ if (CompareMem (CpuFeature->FeatureMask, CpuFeatureEntry->FeatureMask, CpuFeaturesData->BitMaskSize) == 0) {\r
//\r
// If this feature already registered\r
//\r
FeatureExist = TRUE;\r
break;\r
}\r
+\r
Entry = Entry->ForwardLink;\r
}\r
\r
if (!FeatureExist) {\r
DEBUG ((DEBUG_INFO, "[NEW] "));\r
- DumpCpuFeature (CpuFeature);\r
+ DumpCpuFeature (CpuFeature, CpuFeaturesData->BitMaskSize);\r
InsertTailList (&CpuFeaturesData->FeatureList, &CpuFeature->Link);\r
CpuFeaturesData->FeaturesCount++;\r
} else {\r
DEBUG ((DEBUG_INFO, "[OVERRIDE] "));\r
- DumpCpuFeature (CpuFeature);\r
+ DumpCpuFeature (CpuFeature, CpuFeaturesData->BitMaskSize);\r
ASSERT (CpuFeatureEntry != NULL);\r
//\r
// Overwrite original parameters of CPU feature\r
if (CpuFeature->GetConfigDataFunc != NULL) {\r
CpuFeatureEntry->GetConfigDataFunc = CpuFeature->GetConfigDataFunc;\r
}\r
+\r
if (CpuFeature->SupportFunc != NULL) {\r
CpuFeatureEntry->SupportFunc = CpuFeature->SupportFunc;\r
}\r
+\r
if (CpuFeature->InitializeFunc != NULL) {\r
CpuFeatureEntry->InitializeFunc = CpuFeature->InitializeFunc;\r
}\r
+\r
if (CpuFeature->FeatureName != NULL) {\r
if (CpuFeatureEntry->FeatureName == NULL) {\r
CpuFeatureEntry->FeatureName = AllocatePool (CPU_FEATURE_NAME_SIZE);\r
ASSERT (CpuFeatureEntry->FeatureName != NULL);\r
}\r
+\r
Status = AsciiStrCpyS (CpuFeatureEntry->FeatureName, CPU_FEATURE_NAME_SIZE, CpuFeature->FeatureName);\r
ASSERT_EFI_ERROR (Status);\r
FreePool (CpuFeature->FeatureName);\r
}\r
- if (CpuFeature->BeforeFeatureBitMask != NULL) {\r
- if (CpuFeatureEntry->BeforeFeatureBitMask != NULL) {\r
- FreePool (CpuFeatureEntry->BeforeFeatureBitMask);\r
+\r
+ if (CpuFeature->ThreadBeforeFeatureBitMask != NULL) {\r
+ if (CpuFeatureEntry->ThreadBeforeFeatureBitMask != NULL) {\r
+ FreePool (CpuFeatureEntry->ThreadBeforeFeatureBitMask);\r
}\r
- CpuFeatureEntry->BeforeFeatureBitMask = CpuFeature->BeforeFeatureBitMask;\r
+\r
+ CpuFeatureEntry->ThreadBeforeFeatureBitMask = CpuFeature->ThreadBeforeFeatureBitMask;\r
}\r
- if (CpuFeature->AfterFeatureBitMask != NULL) {\r
- if (CpuFeatureEntry->AfterFeatureBitMask != NULL) {\r
- FreePool (CpuFeatureEntry->AfterFeatureBitMask);\r
+\r
+ if (CpuFeature->ThreadAfterFeatureBitMask != NULL) {\r
+ if (CpuFeatureEntry->ThreadAfterFeatureBitMask != NULL) {\r
+ FreePool (CpuFeatureEntry->ThreadAfterFeatureBitMask);\r
}\r
- CpuFeatureEntry->AfterFeatureBitMask = CpuFeature->AfterFeatureBitMask;\r
+\r
+ CpuFeatureEntry->ThreadAfterFeatureBitMask = CpuFeature->ThreadAfterFeatureBitMask;\r
}\r
+\r
if (CpuFeature->CoreBeforeFeatureBitMask != NULL) {\r
if (CpuFeatureEntry->CoreBeforeFeatureBitMask != NULL) {\r
FreePool (CpuFeatureEntry->CoreBeforeFeatureBitMask);\r
}\r
+\r
CpuFeatureEntry->CoreBeforeFeatureBitMask = CpuFeature->CoreBeforeFeatureBitMask;\r
}\r
+\r
if (CpuFeature->CoreAfterFeatureBitMask != NULL) {\r
if (CpuFeatureEntry->CoreAfterFeatureBitMask != NULL) {\r
FreePool (CpuFeatureEntry->CoreAfterFeatureBitMask);\r
}\r
+\r
CpuFeatureEntry->CoreAfterFeatureBitMask = CpuFeature->CoreAfterFeatureBitMask;\r
}\r
+\r
if (CpuFeature->PackageBeforeFeatureBitMask != NULL) {\r
if (CpuFeatureEntry->PackageBeforeFeatureBitMask != NULL) {\r
FreePool (CpuFeatureEntry->PackageBeforeFeatureBitMask);\r
}\r
+\r
CpuFeatureEntry->PackageBeforeFeatureBitMask = CpuFeature->PackageBeforeFeatureBitMask;\r
}\r
+\r
if (CpuFeature->PackageAfterFeatureBitMask != NULL) {\r
if (CpuFeatureEntry->PackageAfterFeatureBitMask != NULL) {\r
FreePool (CpuFeatureEntry->PackageAfterFeatureBitMask);\r
}\r
+\r
CpuFeatureEntry->PackageAfterFeatureBitMask = CpuFeature->PackageAfterFeatureBitMask;\r
}\r
\r
FreePool (CpuFeature->FeatureMask);\r
FreePool (CpuFeature);\r
}\r
+\r
//\r
// Verify CPU features dependency can change CPU feature order\r
//\r
**/\r
VOID\r
SetCpuFeaturesBitMask (\r
- IN UINT8 **FeaturesBitMask,\r
- IN UINT32 Feature,\r
- IN UINTN BitMaskSize\r
+ IN UINT8 **FeaturesBitMask,\r
+ IN UINT32 Feature,\r
+ IN UINTN BitMaskSize\r
)\r
{\r
- UINT8 *CpuFeaturesBitMask;\r
+ UINT8 *CpuFeaturesBitMask;\r
\r
ASSERT (FeaturesBitMask != NULL);\r
CpuFeaturesBitMask = *FeaturesBitMask;\r
}\r
\r
CpuFeaturesBitMask += (Feature / 8);\r
- *CpuFeaturesBitMask |= (UINT8) (1 << (Feature % 8));\r
+ *CpuFeaturesBitMask |= (UINT8)(1 << (Feature % 8));\r
}\r
\r
/**\r
RETURN_STATUS\r
EFIAPI\r
RegisterCpuFeature (\r
- IN CHAR8 *FeatureName, OPTIONAL\r
- IN CPU_FEATURE_GET_CONFIG_DATA GetConfigDataFunc, OPTIONAL\r
- IN CPU_FEATURE_SUPPORT SupportFunc, OPTIONAL\r
- IN CPU_FEATURE_INITIALIZE InitializeFunc, OPTIONAL\r
+ IN CHAR8 *FeatureName OPTIONAL,\r
+ IN CPU_FEATURE_GET_CONFIG_DATA GetConfigDataFunc OPTIONAL,\r
+ IN CPU_FEATURE_SUPPORT SupportFunc OPTIONAL,\r
+ IN CPU_FEATURE_INITIALIZE InitializeFunc OPTIONAL,\r
...\r
)\r
{\r
- EFI_STATUS Status;\r
- VA_LIST Marker;\r
- UINT32 Feature;\r
- UINTN BitMaskSize;\r
- CPU_FEATURES_ENTRY *CpuFeature;\r
- UINT8 *FeatureMask;\r
- UINT8 *BeforeFeatureBitMask;\r
- UINT8 *AfterFeatureBitMask;\r
- UINT8 *CoreBeforeFeatureBitMask;\r
- UINT8 *CoreAfterFeatureBitMask;\r
- UINT8 *PackageBeforeFeatureBitMask;\r
- UINT8 *PackageAfterFeatureBitMask;\r
- BOOLEAN BeforeAll;\r
- BOOLEAN AfterAll;\r
+ EFI_STATUS Status;\r
+ VA_LIST Marker;\r
+ UINT32 Feature;\r
+ CPU_FEATURES_ENTRY *CpuFeature;\r
+ UINT8 *FeatureMask;\r
+ UINT8 *ThreadBeforeFeatureBitMask;\r
+ UINT8 *ThreadAfterFeatureBitMask;\r
+ UINT8 *CoreBeforeFeatureBitMask;\r
+ UINT8 *CoreAfterFeatureBitMask;\r
+ UINT8 *PackageBeforeFeatureBitMask;\r
+ UINT8 *PackageAfterFeatureBitMask;\r
+ BOOLEAN BeforeAll;\r
+ BOOLEAN AfterAll;\r
+ CPU_FEATURES_DATA *CpuFeaturesData;\r
\r
FeatureMask = NULL;\r
- BeforeFeatureBitMask = NULL;\r
- AfterFeatureBitMask = NULL;\r
+ ThreadBeforeFeatureBitMask = NULL;\r
+ ThreadAfterFeatureBitMask = NULL;\r
CoreBeforeFeatureBitMask = NULL;\r
CoreAfterFeatureBitMask = NULL;\r
PackageBeforeFeatureBitMask = NULL;\r
PackageAfterFeatureBitMask = NULL;\r
- BeforeAll = FALSE;\r
- AfterAll = FALSE;\r
+ BeforeAll = FALSE;\r
+ AfterAll = FALSE;\r
\r
- BitMaskSize = PcdGetSize (PcdCpuFeaturesSupport);\r
+ CpuFeaturesData = GetCpuFeaturesData ();\r
+ if (CpuFeaturesData->FeaturesCount == 0) {\r
+ InitializeListHead (&CpuFeaturesData->FeatureList);\r
+ InitializeSpinLock (&CpuFeaturesData->CpuFlags.MemoryMappedLock);\r
+ //\r
+ // Code assumes below three PCDs have PCD same buffer size.\r
+ //\r
+ ASSERT (PcdGetSize (PcdCpuFeaturesSetting) == PcdGetSize (PcdCpuFeaturesCapability));\r
+ ASSERT (PcdGetSize (PcdCpuFeaturesSetting) == PcdGetSize (PcdCpuFeaturesSupport));\r
+ CpuFeaturesData->BitMaskSize = (UINT32)PcdGetSize (PcdCpuFeaturesSetting);\r
+ }\r
\r
VA_START (Marker, InitializeFunc);\r
Feature = VA_ARG (Marker, UINT32);\r
while (Feature != CPU_FEATURE_END) {\r
- ASSERT ((Feature & (CPU_FEATURE_BEFORE | CPU_FEATURE_AFTER))\r
- != (CPU_FEATURE_BEFORE | CPU_FEATURE_AFTER));\r
- ASSERT ((Feature & (CPU_FEATURE_BEFORE_ALL | CPU_FEATURE_AFTER_ALL))\r
- != (CPU_FEATURE_BEFORE_ALL | CPU_FEATURE_AFTER_ALL));\r
- ASSERT ((Feature & (CPU_FEATURE_CORE_BEFORE | CPU_FEATURE_CORE_AFTER))\r
- != (CPU_FEATURE_CORE_BEFORE | CPU_FEATURE_CORE_AFTER));\r
- ASSERT ((Feature & (CPU_FEATURE_PACKAGE_BEFORE | CPU_FEATURE_PACKAGE_AFTER))\r
- != (CPU_FEATURE_PACKAGE_BEFORE | CPU_FEATURE_PACKAGE_AFTER));\r
- if (Feature < CPU_FEATURE_BEFORE) {\r
+ //\r
+ // It's invalid to require a feature is before AND after all other features.\r
+ //\r
+ ASSERT (\r
+ (Feature & (CPU_FEATURE_BEFORE_ALL | CPU_FEATURE_AFTER_ALL))\r
+ != (CPU_FEATURE_BEFORE_ALL | CPU_FEATURE_AFTER_ALL)\r
+ );\r
+\r
+ //\r
+ // It's invalid to require feature A is before AND after before feature B,\r
+ // either in thread level, core level or package level.\r
+ //\r
+ ASSERT (\r
+ (Feature & (CPU_FEATURE_THREAD_BEFORE | CPU_FEATURE_THREAD_AFTER))\r
+ != (CPU_FEATURE_THREAD_BEFORE | CPU_FEATURE_THREAD_AFTER)\r
+ );\r
+ ASSERT (\r
+ (Feature & (CPU_FEATURE_CORE_BEFORE | CPU_FEATURE_CORE_AFTER))\r
+ != (CPU_FEATURE_CORE_BEFORE | CPU_FEATURE_CORE_AFTER)\r
+ );\r
+ ASSERT (\r
+ (Feature & (CPU_FEATURE_PACKAGE_BEFORE | CPU_FEATURE_PACKAGE_AFTER))\r
+ != (CPU_FEATURE_PACKAGE_BEFORE | CPU_FEATURE_PACKAGE_AFTER)\r
+ );\r
+ if (Feature < CPU_FEATURE_THREAD_BEFORE) {\r
BeforeAll = ((Feature & CPU_FEATURE_BEFORE_ALL) != 0) ? TRUE : FALSE;\r
AfterAll = ((Feature & CPU_FEATURE_AFTER_ALL) != 0) ? TRUE : FALSE;\r
Feature &= ~(CPU_FEATURE_BEFORE_ALL | CPU_FEATURE_AFTER_ALL);\r
ASSERT (FeatureMask == NULL);\r
- SetCpuFeaturesBitMask (&FeatureMask, Feature, BitMaskSize);\r
- } else if ((Feature & CPU_FEATURE_BEFORE) != 0) {\r
- SetCpuFeaturesBitMask (&BeforeFeatureBitMask, Feature & ~CPU_FEATURE_BEFORE, BitMaskSize);\r
- } else if ((Feature & CPU_FEATURE_AFTER) != 0) {\r
- SetCpuFeaturesBitMask (&AfterFeatureBitMask, Feature & ~CPU_FEATURE_AFTER, BitMaskSize);\r
+ SetCpuFeaturesBitMask (&FeatureMask, Feature, CpuFeaturesData->BitMaskSize);\r
+ } else if ((Feature & CPU_FEATURE_THREAD_BEFORE) != 0) {\r
+ SetCpuFeaturesBitMask (&ThreadBeforeFeatureBitMask, Feature & ~CPU_FEATURE_THREAD_BEFORE, CpuFeaturesData->BitMaskSize);\r
+ } else if ((Feature & CPU_FEATURE_THREAD_AFTER) != 0) {\r
+ SetCpuFeaturesBitMask (&ThreadAfterFeatureBitMask, Feature & ~CPU_FEATURE_THREAD_AFTER, CpuFeaturesData->BitMaskSize);\r
} else if ((Feature & CPU_FEATURE_CORE_BEFORE) != 0) {\r
- SetCpuFeaturesBitMask (&CoreBeforeFeatureBitMask, Feature & ~CPU_FEATURE_CORE_BEFORE, BitMaskSize);\r
+ SetCpuFeaturesBitMask (&CoreBeforeFeatureBitMask, Feature & ~CPU_FEATURE_CORE_BEFORE, CpuFeaturesData->BitMaskSize);\r
} else if ((Feature & CPU_FEATURE_CORE_AFTER) != 0) {\r
- SetCpuFeaturesBitMask (&CoreAfterFeatureBitMask, Feature & ~CPU_FEATURE_CORE_AFTER, BitMaskSize);\r
+ SetCpuFeaturesBitMask (&CoreAfterFeatureBitMask, Feature & ~CPU_FEATURE_CORE_AFTER, CpuFeaturesData->BitMaskSize);\r
} else if ((Feature & CPU_FEATURE_PACKAGE_BEFORE) != 0) {\r
- SetCpuFeaturesBitMask (&PackageBeforeFeatureBitMask, Feature & ~CPU_FEATURE_PACKAGE_BEFORE, BitMaskSize);\r
+ SetCpuFeaturesBitMask (&PackageBeforeFeatureBitMask, Feature & ~CPU_FEATURE_PACKAGE_BEFORE, CpuFeaturesData->BitMaskSize);\r
} else if ((Feature & CPU_FEATURE_PACKAGE_AFTER) != 0) {\r
- SetCpuFeaturesBitMask (&PackageAfterFeatureBitMask, Feature & ~CPU_FEATURE_PACKAGE_AFTER, BitMaskSize);\r
+ SetCpuFeaturesBitMask (&PackageAfterFeatureBitMask, Feature & ~CPU_FEATURE_PACKAGE_AFTER, CpuFeaturesData->BitMaskSize);\r
}\r
+\r
Feature = VA_ARG (Marker, UINT32);\r
}\r
+\r
VA_END (Marker);\r
\r
CpuFeature = AllocateZeroPool (sizeof (CPU_FEATURES_ENTRY));\r
ASSERT (CpuFeature != NULL);\r
CpuFeature->Signature = CPU_FEATURE_ENTRY_SIGNATURE;\r
CpuFeature->FeatureMask = FeatureMask;\r
- CpuFeature->BeforeFeatureBitMask = BeforeFeatureBitMask;\r
- CpuFeature->AfterFeatureBitMask = AfterFeatureBitMask;\r
+ CpuFeature->ThreadBeforeFeatureBitMask = ThreadBeforeFeatureBitMask;\r
+ CpuFeature->ThreadAfterFeatureBitMask = ThreadAfterFeatureBitMask;\r
CpuFeature->CoreBeforeFeatureBitMask = CoreBeforeFeatureBitMask;\r
CpuFeature->CoreAfterFeatureBitMask = CoreAfterFeatureBitMask;\r
CpuFeature->PackageBeforeFeatureBitMask = PackageBeforeFeatureBitMask;\r
CpuFeature->SupportFunc = SupportFunc;\r
CpuFeature->InitializeFunc = InitializeFunc;\r
if (FeatureName != NULL) {\r
- CpuFeature->FeatureName = AllocatePool (CPU_FEATURE_NAME_SIZE);\r
+ CpuFeature->FeatureName = AllocatePool (CPU_FEATURE_NAME_SIZE);\r
ASSERT (CpuFeature->FeatureName != NULL);\r
Status = AsciiStrCpyS (CpuFeature->FeatureName, CPU_FEATURE_NAME_SIZE, FeatureName);\r
ASSERT_EFI_ERROR (Status);\r
}\r
\r
- Status = RegisterCpuFeatureWorker (CpuFeature);\r
+ Status = RegisterCpuFeatureWorker (CpuFeaturesData, CpuFeature);\r
ASSERT_EFI_ERROR (Status);\r
\r
return RETURN_SUCCESS;\r
VOID\r
)\r
{\r
- EFI_STATUS Status;\r
- UINTN NumberOfCpus;\r
- UINTN NumberOfEnabledProcessors;\r
- ACPI_CPU_DATA *AcpiCpuData;\r
- UINTN TableSize;\r
- CPU_REGISTER_TABLE *RegisterTable;\r
- UINTN Index;\r
- EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;\r
-\r
- AcpiCpuData = (ACPI_CPU_DATA *) (UINTN) PcdGet64 (PcdCpuS3DataAddress);\r
- if (AcpiCpuData != NULL) {\r
- return AcpiCpuData;\r
- }\r
+ EFI_STATUS Status;\r
+ UINTN NumberOfCpus;\r
+ UINTN NumberOfEnabledProcessors;\r
+ ACPI_CPU_DATA *AcpiCpuData;\r
+ UINTN TableSize;\r
+ CPU_REGISTER_TABLE *RegisterTable;\r
+ UINTN Index;\r
+ EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;\r
+\r
+ AcpiCpuData = (ACPI_CPU_DATA *)(UINTN)PcdGet64 (PcdCpuS3DataAddress);\r
+ if (AcpiCpuData == NULL) {\r
+ AcpiCpuData = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (ACPI_CPU_DATA)));\r
+ ASSERT (AcpiCpuData != NULL);\r
+ ZeroMem (AcpiCpuData, sizeof (ACPI_CPU_DATA));\r
\r
- AcpiCpuData = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (ACPI_CPU_DATA)));\r
- ASSERT (AcpiCpuData != NULL);\r
+ //\r
+ // Set PcdCpuS3DataAddress to the base address of the ACPI_CPU_DATA structure\r
+ //\r
+ Status = PcdSet64S (PcdCpuS3DataAddress, (UINT64)(UINTN)AcpiCpuData);\r
+ ASSERT_EFI_ERROR (Status);\r
\r
- //\r
- // Set PcdCpuS3DataAddress to the base address of the ACPI_CPU_DATA structure\r
- //\r
- Status = PcdSet64S (PcdCpuS3DataAddress, (UINT64)(UINTN)AcpiCpuData);\r
- ASSERT_EFI_ERROR (Status);\r
+ GetNumberOfProcessor (&NumberOfCpus, &NumberOfEnabledProcessors);\r
+ AcpiCpuData->NumberOfCpus = (UINT32)NumberOfCpus;\r
+ }\r
\r
- GetNumberOfProcessor (&NumberOfCpus, &NumberOfEnabledProcessors);\r
- AcpiCpuData->NumberOfCpus = (UINT32)NumberOfCpus;\r
+ if ((AcpiCpuData->CpuFeatureInitData.RegisterTable == 0) ||\r
+ (AcpiCpuData->CpuFeatureInitData.PreSmmInitRegisterTable == 0))\r
+ {\r
+ //\r
+ // Allocate buffer for empty RegisterTable and PreSmmInitRegisterTable for all CPUs\r
+ //\r
+ NumberOfCpus = AcpiCpuData->NumberOfCpus;\r
+ TableSize = 2 * NumberOfCpus * sizeof (CPU_REGISTER_TABLE);\r
+ RegisterTable = AllocatePages (EFI_SIZE_TO_PAGES (TableSize));\r
+ ASSERT (RegisterTable != NULL);\r
\r
- //\r
- // Allocate buffer for empty RegisterTable and PreSmmInitRegisterTable for all CPUs\r
- //\r
- TableSize = 2 * NumberOfCpus * sizeof (CPU_REGISTER_TABLE);\r
- RegisterTable = AllocatePages (EFI_SIZE_TO_PAGES (TableSize));\r
- ASSERT (RegisterTable != NULL);\r
+ for (Index = 0; Index < NumberOfCpus; Index++) {\r
+ Status = GetProcessorInformation (Index, &ProcessorInfoBuffer);\r
+ ASSERT_EFI_ERROR (Status);\r
\r
- for (Index = 0; Index < NumberOfCpus; Index++) {\r
- Status = GetProcessorInformation (Index, &ProcessorInfoBuffer);\r
- ASSERT_EFI_ERROR (Status);\r
+ RegisterTable[Index].InitialApicId = (UINT32)ProcessorInfoBuffer.ProcessorId;\r
+ RegisterTable[Index].TableLength = 0;\r
+ RegisterTable[Index].AllocatedSize = 0;\r
+ RegisterTable[Index].RegisterTableEntry = 0;\r
+\r
+ RegisterTable[NumberOfCpus + Index].InitialApicId = (UINT32)ProcessorInfoBuffer.ProcessorId;\r
+ RegisterTable[NumberOfCpus + Index].TableLength = 0;\r
+ RegisterTable[NumberOfCpus + Index].AllocatedSize = 0;\r
+ RegisterTable[NumberOfCpus + Index].RegisterTableEntry = 0;\r
+ }\r
\r
- RegisterTable[Index].InitialApicId = (UINT32)ProcessorInfoBuffer.ProcessorId;\r
- RegisterTable[Index].TableLength = 0;\r
- RegisterTable[Index].AllocatedSize = 0;\r
- RegisterTable[Index].RegisterTableEntry = 0;\r
+ if (AcpiCpuData->CpuFeatureInitData.RegisterTable == 0) {\r
+ AcpiCpuData->CpuFeatureInitData.RegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)RegisterTable;\r
+ }\r
\r
- RegisterTable[NumberOfCpus + Index].InitialApicId = (UINT32)ProcessorInfoBuffer.ProcessorId;\r
- RegisterTable[NumberOfCpus + Index].TableLength = 0;\r
- RegisterTable[NumberOfCpus + Index].AllocatedSize = 0;\r
- RegisterTable[NumberOfCpus + Index].RegisterTableEntry = 0;\r
+ if (AcpiCpuData->CpuFeatureInitData.PreSmmInitRegisterTable == 0) {\r
+ AcpiCpuData->CpuFeatureInitData.PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)(RegisterTable + NumberOfCpus);\r
+ }\r
}\r
- AcpiCpuData->RegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)RegisterTable;\r
- AcpiCpuData->PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)(RegisterTable + NumberOfCpus);\r
\r
return AcpiCpuData;\r
}\r
STATIC\r
VOID\r
EnlargeRegisterTable (\r
- IN OUT CPU_REGISTER_TABLE *RegisterTable\r
+ IN OUT CPU_REGISTER_TABLE *RegisterTable\r
)\r
{\r
EFI_PHYSICAL_ADDRESS Address;\r
UINTN UsedPages;\r
\r
UsedPages = RegisterTable->AllocatedSize / EFI_PAGE_SIZE;\r
- Address = (UINTN)AllocatePages (UsedPages + 1);\r
+ Address = (UINTN)AllocatePages (UsedPages + 1);\r
ASSERT (Address != 0);\r
\r
//\r
//\r
if (RegisterTable->AllocatedSize > 0) {\r
CopyMem (\r
- (VOID *) (UINTN) Address,\r
- (VOID *) (UINTN) RegisterTable->RegisterTableEntry,\r
+ (VOID *)(UINTN)Address,\r
+ (VOID *)(UINTN)RegisterTable->RegisterTableEntry,\r
RegisterTable->AllocatedSize\r
);\r
\r
@param[in] ValidBitStart Start of the bit section\r
@param[in] ValidBitLength Length of the bit section\r
@param[in] Value Value to write\r
+ @param[in] TestThenWrite Whether need to test current Value before writing.\r
+\r
**/\r
VOID\r
CpuRegisterTableWriteWorker (\r
- IN BOOLEAN PreSmmFlag,\r
- IN UINTN ProcessorNumber,\r
- IN REGISTER_TYPE RegisterType,\r
- IN UINT64 Index,\r
- IN UINT8 ValidBitStart,\r
- IN UINT8 ValidBitLength,\r
- IN UINT64 Value\r
+ IN BOOLEAN PreSmmFlag,\r
+ IN UINTN ProcessorNumber,\r
+ IN REGISTER_TYPE RegisterType,\r
+ IN UINT64 Index,\r
+ IN UINT8 ValidBitStart,\r
+ IN UINT8 ValidBitLength,\r
+ IN UINT64 Value,\r
+ IN BOOLEAN TestThenWrite\r
)\r
{\r
- CPU_FEATURES_DATA *CpuFeaturesData;\r
- ACPI_CPU_DATA *AcpiCpuData;\r
- CPU_REGISTER_TABLE *RegisterTable;\r
- CPU_REGISTER_TABLE_ENTRY *RegisterTableEntry;\r
+ CPU_FEATURES_DATA *CpuFeaturesData;\r
+ ACPI_CPU_DATA *AcpiCpuData;\r
+ CPU_REGISTER_TABLE *RegisterTable;\r
+ CPU_REGISTER_TABLE_ENTRY *RegisterTableEntry;\r
\r
CpuFeaturesData = GetCpuFeaturesData ();\r
if (CpuFeaturesData->RegisterTable == NULL) {\r
AcpiCpuData = GetAcpiCpuData ();\r
- ASSERT ((AcpiCpuData != NULL) && (AcpiCpuData->RegisterTable != 0));\r
- CpuFeaturesData->RegisterTable = (CPU_REGISTER_TABLE *) (UINTN) AcpiCpuData->RegisterTable;\r
- CpuFeaturesData->PreSmmRegisterTable = (CPU_REGISTER_TABLE *) (UINTN) AcpiCpuData->PreSmmInitRegisterTable;\r
+ ASSERT ((AcpiCpuData != NULL) && (AcpiCpuData->CpuFeatureInitData.RegisterTable != 0));\r
+ CpuFeaturesData->RegisterTable = (CPU_REGISTER_TABLE *)(UINTN)AcpiCpuData->CpuFeatureInitData.RegisterTable;\r
+ CpuFeaturesData->PreSmmRegisterTable = (CPU_REGISTER_TABLE *)(UINTN)AcpiCpuData->CpuFeatureInitData.PreSmmInitRegisterTable;\r
}\r
\r
if (PreSmmFlag) {\r
//\r
// Append entry in the register table.\r
//\r
- RegisterTableEntry = (CPU_REGISTER_TABLE_ENTRY *) (UINTN) RegisterTable->RegisterTableEntry;\r
+ RegisterTableEntry = (CPU_REGISTER_TABLE_ENTRY *)(UINTN)RegisterTable->RegisterTableEntry;\r
RegisterTableEntry[RegisterTable->TableLength].RegisterType = RegisterType;\r
- RegisterTableEntry[RegisterTable->TableLength].Index = (UINT32) Index;\r
- RegisterTableEntry[RegisterTable->TableLength].HighIndex = (UINT32) RShiftU64 (Index, 32);\r
+ RegisterTableEntry[RegisterTable->TableLength].Index = (UINT32)Index;\r
+ RegisterTableEntry[RegisterTable->TableLength].HighIndex = (UINT32)RShiftU64 (Index, 32);\r
RegisterTableEntry[RegisterTable->TableLength].ValidBitStart = ValidBitStart;\r
RegisterTableEntry[RegisterTable->TableLength].ValidBitLength = ValidBitLength;\r
RegisterTableEntry[RegisterTable->TableLength].Value = Value;\r
+ RegisterTableEntry[RegisterTable->TableLength].TestThenWrite = TestThenWrite;\r
\r
RegisterTable->TableLength++;\r
}\r
VOID\r
EFIAPI\r
CpuRegisterTableWrite (\r
- IN UINTN ProcessorNumber,\r
- IN REGISTER_TYPE RegisterType,\r
- IN UINT64 Index,\r
- IN UINT64 ValueMask,\r
- IN UINT64 Value\r
+ IN UINTN ProcessorNumber,\r
+ IN REGISTER_TYPE RegisterType,\r
+ IN UINT64 Index,\r
+ IN UINT64 ValueMask,\r
+ IN UINT64 Value\r
+ )\r
+{\r
+ UINT8 Start;\r
+ UINT8 End;\r
+ UINT8 Length;\r
+\r
+ Start = (UINT8)LowBitSet64 (ValueMask);\r
+ End = (UINT8)HighBitSet64 (ValueMask);\r
+ Length = End - Start + 1;\r
+ CpuRegisterTableWriteWorker (FALSE, ProcessorNumber, RegisterType, Index, Start, Length, Value, FALSE);\r
+}\r
+\r
+/**\r
+ Adds an entry in specified register table.\r
+\r
+ This function adds an entry in specified register table, with given register type,\r
+ register index, bit section and value.\r
+\r
+ @param[in] ProcessorNumber The index of the CPU to add a register table entry\r
+ @param[in] RegisterType Type of the register to program\r
+ @param[in] Index Index of the register to program\r
+ @param[in] ValueMask Mask of bits in register to write\r
+ @param[in] Value Value to write\r
+\r
+ @note This service could be called by BSP only.\r
+**/\r
+VOID\r
+EFIAPI\r
+CpuRegisterTableTestThenWrite (\r
+ IN UINTN ProcessorNumber,\r
+ IN REGISTER_TYPE RegisterType,\r
+ IN UINT64 Index,\r
+ IN UINT64 ValueMask,\r
+ IN UINT64 Value\r
)\r
{\r
- UINT8 Start;\r
- UINT8 End;\r
- UINT8 Length;\r
+ UINT8 Start;\r
+ UINT8 End;\r
+ UINT8 Length;\r
\r
- Start = (UINT8)LowBitSet64 (ValueMask);\r
+ Start = (UINT8)LowBitSet64 (ValueMask);\r
End = (UINT8)HighBitSet64 (ValueMask);\r
Length = End - Start + 1;\r
- CpuRegisterTableWriteWorker (FALSE, ProcessorNumber, RegisterType, Index, Start, Length, Value);\r
+ CpuRegisterTableWriteWorker (FALSE, ProcessorNumber, RegisterType, Index, Start, Length, Value, TRUE);\r
}\r
\r
/**\r
VOID\r
EFIAPI\r
PreSmmCpuRegisterTableWrite (\r
- IN UINTN ProcessorNumber,\r
- IN REGISTER_TYPE RegisterType,\r
- IN UINT64 Index,\r
- IN UINT64 ValueMask,\r
- IN UINT64 Value\r
+ IN UINTN ProcessorNumber,\r
+ IN REGISTER_TYPE RegisterType,\r
+ IN UINT64 Index,\r
+ IN UINT64 ValueMask,\r
+ IN UINT64 Value\r
)\r
{\r
UINT8 Start;\r
UINT8 End;\r
UINT8 Length;\r
\r
- Start = (UINT8)LowBitSet64 (ValueMask);\r
+ Start = (UINT8)LowBitSet64 (ValueMask);\r
End = (UINT8)HighBitSet64 (ValueMask);\r
Length = End - Start + 1;\r
- CpuRegisterTableWriteWorker (TRUE, ProcessorNumber, RegisterType, Index, Start, Length, Value);\r
+ CpuRegisterTableWriteWorker (TRUE, ProcessorNumber, RegisterType, Index, Start, Length, Value, FALSE);\r
}\r
\r
/**\r
@param[in] CpuBitMaskSize The size of CPU feature bit mask buffer\r
@param[in] Feature The bit number of the CPU feature\r
\r
- @retval TRUE The CPU feature is set in PcdCpuFeaturesSupport.\r
- @retval FALSE The CPU feature is not set in PcdCpuFeaturesSupport.\r
+ @retval TRUE The CPU feature is set in CpuBitMask.\r
+ @retval FALSE The CPU feature is not set in CpuBitMask.\r
\r
**/\r
BOOLEAN\r
IsCpuFeatureSetInCpuPcd (\r
- IN UINT8 *CpuBitMask,\r
- IN UINTN CpuBitMaskSize,\r
- IN UINT32 Feature\r
+ IN UINT8 *CpuBitMask,\r
+ IN UINTN CpuBitMaskSize,\r
+ IN UINT32 Feature\r
)\r
{\r
if ((Feature >> 3) >= CpuBitMaskSize) {\r
return FALSE;\r
}\r
+\r
return ((*(CpuBitMask + (Feature >> 3)) & (1 << (Feature & 0x07))) != 0);\r
}\r
\r
BOOLEAN\r
EFIAPI\r
IsCpuFeatureSupported (\r
- IN UINT32 Feature\r
+ IN UINT32 Feature\r
)\r
{\r
return IsCpuFeatureSetInCpuPcd (\r
BOOLEAN\r
EFIAPI\r
IsCpuFeatureInSetting (\r
- IN UINT32 Feature\r
+ IN UINT32 Feature\r
)\r
{\r
return IsCpuFeatureSetInCpuPcd (\r
);\r
}\r
\r
-/**\r
- Determines if a CPU feature is set in PcdCpuFeaturesCapability bit mask.\r
-\r
- @param[in] Feature The bit number of the CPU feature to check in the PCD\r
- PcdCpuFeaturesCapability\r
-\r
- @retval TRUE The CPU feature is set in PcdCpuFeaturesCapability.\r
- @retval FALSE The CPU feature is not set in PcdCpuFeaturesCapability.\r
-\r
- @note This service could be called by BSP only.\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-IsCpuFeatureCapability (\r
- IN UINT32 Feature\r
- )\r
-{\r
- return IsCpuFeatureSetInCpuPcd (\r
- (UINT8 *)PcdGetPtr (PcdCpuFeaturesCapability),\r
- PcdGetSize (PcdCpuFeaturesCapability),\r
- Feature\r
- );\r
-\r
-}\r
-\r
-/**\r
- Determines if a CPU feature is set in PcdCpuFeaturesUserConfiguration bit mask.\r
-\r
- @param[in] Feature The bit number of the CPU feature to check in the PCD\r
- PcdCpuFeaturesUserConfiguration\r
-\r
- @retval TRUE The CPU feature is set in PcdCpuFeaturesUserConfiguration.\r
- @retval FALSE The CPU feature is not set in PcdCpuFeaturesUserConfiguration.\r
-\r
- @note This service could be called by BSP only.\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-IsCpuFeatureUserConfiguration (\r
- IN UINT32 Feature\r
- )\r
-{\r
- return IsCpuFeatureSetInCpuPcd (\r
- (UINT8 *)PcdGetPtr (PcdCpuFeaturesUserConfiguration),\r
- PcdGetSize (PcdCpuFeaturesUserConfiguration),\r
- Feature\r
- );\r
-\r
-}\r
-\r
/**\r
Switches to assigned BSP after CPU features initialization.\r
\r
VOID\r
EFIAPI\r
SwitchBspAfterFeaturesInitialize (\r
- IN UINTN ProcessorNumber\r
+ IN UINTN ProcessorNumber\r
)\r
{\r
- CPU_FEATURES_DATA *CpuFeaturesData;\r
+ CPU_FEATURES_DATA *CpuFeaturesData;\r
\r
- CpuFeaturesData = GetCpuFeaturesData ();\r
+ CpuFeaturesData = GetCpuFeaturesData ();\r
CpuFeaturesData->BspNumber = ProcessorNumber;\r
}\r
-\r