2 CPU Features Initialize functions.
4 Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "RegisterCpuFeatures.h"
18 Worker function to save PcdCpuFeaturesCapability.
20 @param[in] SupportedFeatureMask The pointer to CPU feature bits mask buffer
24 IN UINT8
*SupportedFeatureMask
30 BitMaskSize
= PcdGetSize (PcdCpuFeaturesCapability
);
31 Status
= PcdSetPtrS (PcdCpuFeaturesCapability
, &BitMaskSize
, SupportedFeatureMask
);
32 ASSERT_EFI_ERROR (Status
);
36 Worker function to save PcdCpuFeaturesSetting.
38 @param[in] SupportedFeatureMask The pointer to CPU feature bits mask buffer
42 IN UINT8
*SupportedFeatureMask
48 BitMaskSize
= PcdGetSize (PcdCpuFeaturesSetting
);
49 Status
= PcdSetPtrS (PcdCpuFeaturesSetting
, &BitMaskSize
, SupportedFeatureMask
);
50 ASSERT_EFI_ERROR (Status
);
54 Worker function to get PcdCpuFeaturesSupport.
56 @return The pointer to CPU feature bits mask buffer.
64 UINT8
*SupportBitMask
;
66 BitMaskSize
= PcdGetSize (PcdCpuFeaturesSupport
);
67 SupportBitMask
= AllocateZeroPool (BitMaskSize
);
68 ASSERT (SupportBitMask
!= NULL
);
69 SupportBitMask
= (UINT8
*) PcdGetPtr (PcdCpuFeaturesSupport
);
71 return SupportBitMask
;
75 Worker function to get PcdCpuFeaturesUserConfiguration.
77 @return The pointer to CPU feature bits mask buffer.
80 GetConfigurationPcds (
85 UINT8
*SupportBitMask
;
87 BitMaskSize
= PcdGetSize (PcdCpuFeaturesUserConfiguration
);
88 SupportBitMask
= AllocateZeroPool (BitMaskSize
);
89 ASSERT (SupportBitMask
!= NULL
);
90 SupportBitMask
= (UINT8
*) PcdGetPtr (PcdCpuFeaturesUserConfiguration
);
92 return SupportBitMask
;
96 Collects CPU type and feature information.
98 @param[in, out] CpuInfo The pointer to CPU feature information
102 IN OUT REGISTER_CPU_FEATURE_INFORMATION
*CpuInfo
105 CPUID_VERSION_INFO_EAX Eax
;
106 CPUID_VERSION_INFO_ECX Ecx
;
107 CPUID_VERSION_INFO_EDX Edx
;
108 UINT32 DisplayedFamily
;
109 UINT32 DisplayedModel
;
111 AsmCpuid (CPUID_VERSION_INFO
, &Eax
.Uint32
, NULL
, &Ecx
.Uint32
, &Edx
.Uint32
);
113 DisplayedFamily
= Eax
.Bits
.FamilyId
;
114 if (Eax
.Bits
.FamilyId
== 0x0F) {
115 DisplayedFamily
|= (Eax
.Bits
.ExtendedFamilyId
<< 4);
118 DisplayedModel
= Eax
.Bits
.Model
;
119 if (Eax
.Bits
.FamilyId
== 0x06 || Eax
.Bits
.FamilyId
== 0x0f) {
120 DisplayedModel
|= (Eax
.Bits
.ExtendedModelId
<< 4);
123 CpuInfo
->DisplayFamily
= DisplayedFamily
;
124 CpuInfo
->DisplayModel
= DisplayedModel
;
125 CpuInfo
->SteppingId
= Eax
.Bits
.SteppingId
;
126 CpuInfo
->ProcessorType
= Eax
.Bits
.ProcessorType
;
127 CpuInfo
->CpuIdVersionInfoEcx
.Uint32
= Ecx
.Uint32
;
128 CpuInfo
->CpuIdVersionInfoEdx
.Uint32
= Edx
.Uint32
;
132 Prepares for private data used for CPU features.
134 @param[in] NumberOfCpus Number of processor in system
137 CpuInitDataInitialize (
138 IN UINTN NumberOfCpus
142 UINTN ProcessorNumber
;
143 EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer
;
144 CPU_FEATURES_ENTRY
*CpuFeature
;
145 CPU_FEATURES_INIT_ORDER
*InitOrder
;
146 CPU_FEATURES_DATA
*CpuFeaturesData
;
149 CpuFeaturesData
= GetCpuFeaturesData ();
150 CpuFeaturesData
->InitOrder
= AllocateZeroPool (sizeof (CPU_FEATURES_INIT_ORDER
) * NumberOfCpus
);
151 ASSERT (CpuFeaturesData
->InitOrder
!= NULL
);
152 CpuFeaturesData
->BitMaskSize
= PcdGetSize (PcdCpuFeaturesSupport
);
155 // Collect CPU Features information
157 Entry
= GetFirstNode (&CpuFeaturesData
->FeatureList
);
158 while (!IsNull (&CpuFeaturesData
->FeatureList
, Entry
)) {
159 CpuFeature
= CPU_FEATURE_ENTRY_FROM_LINK (Entry
);
160 ASSERT (CpuFeature
->InitializeFunc
!= NULL
);
161 if (CpuFeature
->GetConfigDataFunc
!= NULL
) {
162 CpuFeature
->ConfigData
= CpuFeature
->GetConfigDataFunc (NumberOfCpus
);
164 Entry
= Entry
->ForwardLink
;
167 for (ProcessorNumber
= 0; ProcessorNumber
< NumberOfCpus
; ProcessorNumber
++) {
168 InitOrder
= &CpuFeaturesData
->InitOrder
[ProcessorNumber
];
169 InitOrder
->FeaturesSupportedMask
= AllocateZeroPool (CpuFeaturesData
->BitMaskSize
);
170 ASSERT (InitOrder
->FeaturesSupportedMask
!= NULL
);
171 InitializeListHead (&InitOrder
->OrderList
);
172 Status
= GetProcessorInformation (ProcessorNumber
, &ProcessorInfoBuffer
);
173 ASSERT_EFI_ERROR (Status
);
175 &InitOrder
->CpuInfo
.ProcessorInfo
,
176 &ProcessorInfoBuffer
,
177 sizeof (EFI_PROCESSOR_INFORMATION
)
181 // Get support and configuration PCDs
183 CpuFeaturesData
->SupportPcds
= GetSupportPcds ();
184 CpuFeaturesData
->ConfigurationPcds
= GetConfigurationPcds ();
188 Worker function to do OR operation on CPU feature supported bits mask buffer.
190 @param[in] SupportedFeatureMask The pointer to CPU feature bits mask buffer
191 @param[in] OrFeatureBitMask The feature bit mask to do OR operation
195 IN UINT8
*SupportedFeatureMask
,
196 IN UINT8
*OrFeatureBitMask
204 BitMaskSize
= PcdGetSize (PcdCpuFeaturesSupport
);
205 Data1
= SupportedFeatureMask
;
206 Data2
= OrFeatureBitMask
;
207 for (Index
= 0; Index
< BitMaskSize
; Index
++) {
208 *(Data1
++) |= *(Data2
++);
213 Worker function to do AND operation on CPU feature supported bits mask buffer.
215 @param[in] SupportedFeatureMask The pointer to CPU feature bits mask buffer
216 @param[in] AndFeatureBitMask The feature bit mask to do AND operation
220 IN UINT8
*SupportedFeatureMask
,
221 IN UINT8
*AndFeatureBitMask
229 BitMaskSize
= PcdGetSize (PcdCpuFeaturesSupport
);
230 Data1
= SupportedFeatureMask
;
231 Data2
= AndFeatureBitMask
;
232 for (Index
= 0; Index
< BitMaskSize
; Index
++) {
233 *(Data1
++) &= *(Data2
++);
238 Worker function to clean bit operation on CPU feature supported bits mask buffer.
240 @param[in] SupportedFeatureMask The pointer to CPU feature bits mask buffer
241 @param[in] AndFeatureBitMask The feature bit mask to do XOR operation
244 SupportedMaskCleanBit (
245 IN UINT8
*SupportedFeatureMask
,
246 IN UINT8
*AndFeatureBitMask
254 BitMaskSize
= PcdGetSize (PcdCpuFeaturesSupport
);
255 Data1
= SupportedFeatureMask
;
256 Data2
= AndFeatureBitMask
;
257 for (Index
= 0; Index
< BitMaskSize
; Index
++) {
258 *(Data1
++) &= ~(*(Data2
++));
263 Worker function to check if the compared CPU feature set in the CPU feature
264 supported bits mask buffer.
266 @param[in] SupportedFeatureMask The pointer to CPU feature bits mask buffer
267 @param[in] ComparedFeatureBitMask The feature bit mask to be compared
269 @retval TRUE The ComparedFeatureBitMask is set in CPU feature supported bits
271 @retval FALSE The ComparedFeatureBitMask is not set in CPU feature supported bits
276 IN UINT8
*SupportedFeatureMask
,
277 IN UINT8
*ComparedFeatureBitMask
285 BitMaskSize
= PcdGetSize (PcdCpuFeaturesSupport
);
287 Data1
= SupportedFeatureMask
;
288 Data2
= ComparedFeatureBitMask
;
289 for (Index
= 0; Index
< BitMaskSize
; Index
++) {
290 if (((*(Data1
++)) & (*(Data2
++))) != 0) {
298 Collects processor data for calling processor.
300 @param[in,out] Buffer The pointer to private data buffer.
304 CollectProcessorData (
308 UINTN ProcessorNumber
;
309 CPU_FEATURES_ENTRY
*CpuFeature
;
310 REGISTER_CPU_FEATURE_INFORMATION
*CpuInfo
;
312 CPU_FEATURES_DATA
*CpuFeaturesData
;
314 CpuFeaturesData
= GetCpuFeaturesData ();
315 ProcessorNumber
= GetProcessorIndex ();
316 CpuInfo
= &CpuFeaturesData
->InitOrder
[ProcessorNumber
].CpuInfo
;
318 // collect processor information
320 FillProcessorInfo (CpuInfo
);
321 Entry
= GetFirstNode (&CpuFeaturesData
->FeatureList
);
322 while (!IsNull (&CpuFeaturesData
->FeatureList
, Entry
)) {
323 CpuFeature
= CPU_FEATURE_ENTRY_FROM_LINK (Entry
);
324 if (IsBitMaskMatch (CpuFeaturesData
->SupportPcds
, CpuFeature
->FeatureMask
)) {
325 if (CpuFeature
->SupportFunc
== NULL
) {
327 // If SupportFunc is NULL, then the feature is supported.
330 CpuFeaturesData
->InitOrder
[ProcessorNumber
].FeaturesSupportedMask
,
331 CpuFeature
->FeatureMask
333 } else if (CpuFeature
->SupportFunc (ProcessorNumber
, CpuInfo
, CpuFeature
->ConfigData
)) {
335 CpuFeaturesData
->InitOrder
[ProcessorNumber
].FeaturesSupportedMask
,
336 CpuFeature
->FeatureMask
340 Entry
= Entry
->ForwardLink
;
345 Dump the contents of a CPU register table.
347 @param[in] ProcessorNumber The index of the CPU to show the register table contents
349 @note This service could be called by BSP only.
352 DumpRegisterTableOnProcessor (
353 IN UINTN ProcessorNumber
356 CPU_FEATURES_DATA
*CpuFeaturesData
;
358 CPU_REGISTER_TABLE
*RegisterTable
;
359 CPU_REGISTER_TABLE_ENTRY
*RegisterTableEntry
;
360 CPU_REGISTER_TABLE_ENTRY
*RegisterTableEntryHead
;
361 UINT32 DebugPrintErrorLevel
;
363 DebugPrintErrorLevel
= (ProcessorNumber
== 0) ? DEBUG_INFO
: DEBUG_VERBOSE
;
364 CpuFeaturesData
= GetCpuFeaturesData ();
368 RegisterTable
= &CpuFeaturesData
->RegisterTable
[ProcessorNumber
];
369 DEBUG ((DebugPrintErrorLevel
, "RegisterTable->TableLength = %d\n", RegisterTable
->TableLength
));
371 RegisterTableEntryHead
= (CPU_REGISTER_TABLE_ENTRY
*) (UINTN
) RegisterTable
->RegisterTableEntry
;
373 for (FeatureIndex
= 0; FeatureIndex
< RegisterTable
->TableLength
; FeatureIndex
++) {
374 RegisterTableEntry
= &RegisterTableEntryHead
[FeatureIndex
];
375 switch (RegisterTableEntry
->RegisterType
) {
378 DebugPrintErrorLevel
,
379 "Processor: %d: MSR: %x, Bit Start: %d, Bit Length: %d, Value: %lx\r\n",
381 RegisterTableEntry
->Index
,
382 RegisterTableEntry
->ValidBitStart
,
383 RegisterTableEntry
->ValidBitLength
,
384 RegisterTableEntry
->Value
387 case ControlRegister
:
389 DebugPrintErrorLevel
,
390 "Processor: %d: CR: %x, Bit Start: %d, Bit Length: %d, Value: %lx\r\n",
392 RegisterTableEntry
->Index
,
393 RegisterTableEntry
->ValidBitStart
,
394 RegisterTableEntry
->ValidBitLength
,
395 RegisterTableEntry
->Value
400 DebugPrintErrorLevel
,
401 "Processor: %d: MMIO: %lx, Bit Start: %d, Bit Length: %d, Value: %lx\r\n",
403 RegisterTableEntry
->Index
| LShiftU64 (RegisterTableEntry
->HighIndex
, 32),
404 RegisterTableEntry
->ValidBitStart
,
405 RegisterTableEntry
->ValidBitLength
,
406 RegisterTableEntry
->Value
411 DebugPrintErrorLevel
,
412 "Processor: %d: CACHE: %x, Bit Start: %d, Bit Length: %d, Value: %lx\r\n",
414 RegisterTableEntry
->Index
,
415 RegisterTableEntry
->ValidBitStart
,
416 RegisterTableEntry
->ValidBitLength
,
417 RegisterTableEntry
->Value
427 Analysis register CPU features on each processor and save CPU setting in CPU register table.
429 @param[in] NumberOfCpus Number of processor in system
433 AnalysisProcessorFeatures (
434 IN UINTN NumberOfCpus
438 UINTN ProcessorNumber
;
439 CPU_FEATURES_ENTRY
*CpuFeature
;
440 CPU_FEATURES_ENTRY
*CpuFeatureInOrder
;
441 CPU_FEATURES_INIT_ORDER
*CpuInitOrder
;
442 REGISTER_CPU_FEATURE_INFORMATION
*CpuInfo
;
444 CPU_FEATURES_DATA
*CpuFeaturesData
;
446 CpuFeaturesData
= GetCpuFeaturesData ();
447 CpuFeaturesData
->CapabilityPcds
= AllocatePool (CpuFeaturesData
->BitMaskSize
);
448 ASSERT (CpuFeaturesData
->CapabilityPcds
!= NULL
);
449 SetMem (CpuFeaturesData
->CapabilityPcds
, CpuFeaturesData
->BitMaskSize
, 0xFF);
450 for (ProcessorNumber
= 0; ProcessorNumber
< NumberOfCpus
; ProcessorNumber
++) {
451 CpuInitOrder
= &CpuFeaturesData
->InitOrder
[ProcessorNumber
];
453 // Calculate the last capability on all processors
455 SupportedMaskAnd (CpuFeaturesData
->CapabilityPcds
, CpuInitOrder
->FeaturesSupportedMask
);
458 // Calculate the last setting
461 CpuFeaturesData
->SettingPcds
= AllocateCopyPool (CpuFeaturesData
->BitMaskSize
, CpuFeaturesData
->CapabilityPcds
);
462 ASSERT (CpuFeaturesData
->SettingPcds
!= NULL
);
463 SupportedMaskAnd (CpuFeaturesData
->SettingPcds
, CpuFeaturesData
->ConfigurationPcds
);
466 // Save PCDs and display CPU PCDs
468 SetCapabilityPcd (CpuFeaturesData
->CapabilityPcds
);
469 SetSettingPcd (CpuFeaturesData
->SettingPcds
);
472 // Dump the last CPU feature list
475 DEBUG ((DEBUG_INFO
, "Last CPU features list...\n"));
476 Entry
= GetFirstNode (&CpuFeaturesData
->FeatureList
);
477 while (!IsNull (&CpuFeaturesData
->FeatureList
, Entry
)) {
478 CpuFeature
= CPU_FEATURE_ENTRY_FROM_LINK (Entry
);
479 if (IsBitMaskMatch (CpuFeature
->FeatureMask
, CpuFeaturesData
->CapabilityPcds
)) {
480 if (IsBitMaskMatch (CpuFeature
->FeatureMask
, CpuFeaturesData
->SettingPcds
)) {
481 DEBUG ((DEBUG_INFO
, "[Enable ] "));
483 DEBUG ((DEBUG_INFO
, "[Disable ] "));
486 DEBUG ((DEBUG_INFO
, "[Unsupport] "));
488 DumpCpuFeature (CpuFeature
);
489 Entry
= Entry
->ForwardLink
;
491 DEBUG ((DEBUG_INFO
, "PcdCpuFeaturesSupport:\n"));
492 DumpCpuFeatureMask (CpuFeaturesData
->SupportPcds
);
493 DEBUG ((DEBUG_INFO
, "PcdCpuFeaturesUserConfiguration:\n"));
494 DumpCpuFeatureMask (CpuFeaturesData
->ConfigurationPcds
);
495 DEBUG ((DEBUG_INFO
, "PcdCpuFeaturesCapability:\n"));
496 DumpCpuFeatureMask (CpuFeaturesData
->CapabilityPcds
);
497 DEBUG ((DEBUG_INFO
, "PcdCpuFeaturesSetting:\n"));
498 DumpCpuFeatureMask (CpuFeaturesData
->SettingPcds
);
501 for (ProcessorNumber
= 0; ProcessorNumber
< NumberOfCpus
; ProcessorNumber
++) {
502 CpuInitOrder
= &CpuFeaturesData
->InitOrder
[ProcessorNumber
];
503 Entry
= GetFirstNode (&CpuFeaturesData
->FeatureList
);
504 while (!IsNull (&CpuFeaturesData
->FeatureList
, Entry
)) {
506 // Insert each feature into processor's order list
508 CpuFeature
= CPU_FEATURE_ENTRY_FROM_LINK (Entry
);
509 if (IsBitMaskMatch (CpuFeature
->FeatureMask
, CpuFeaturesData
->CapabilityPcds
)) {
510 CpuFeatureInOrder
= AllocateCopyPool (sizeof (CPU_FEATURES_ENTRY
), CpuFeature
);
511 ASSERT (CpuFeatureInOrder
!= NULL
);
512 InsertTailList (&CpuInitOrder
->OrderList
, &CpuFeatureInOrder
->Link
);
514 Entry
= Entry
->ForwardLink
;
517 // Go through ordered feature list to initialize CPU features
519 CpuInfo
= &CpuFeaturesData
->InitOrder
[ProcessorNumber
].CpuInfo
;
520 Entry
= GetFirstNode (&CpuInitOrder
->OrderList
);
521 while (!IsNull (&CpuInitOrder
->OrderList
, Entry
)) {
522 CpuFeatureInOrder
= CPU_FEATURE_ENTRY_FROM_LINK (Entry
);
523 if (IsBitMaskMatch (CpuFeatureInOrder
->FeatureMask
, CpuFeaturesData
->SettingPcds
)) {
524 Status
= CpuFeatureInOrder
->InitializeFunc (ProcessorNumber
, CpuInfo
, CpuFeatureInOrder
->ConfigData
, TRUE
);
525 if (EFI_ERROR (Status
)) {
527 // Clean the CpuFeatureInOrder->FeatureMask in setting PCD.
529 SupportedMaskCleanBit (CpuFeaturesData
->SettingPcds
, CpuFeatureInOrder
->FeatureMask
);
530 if (CpuFeatureInOrder
->FeatureName
!= NULL
) {
531 DEBUG ((DEBUG_WARN
, "Warning :: Failed to enable Feature Name = %a.\n", CpuFeatureInOrder
->FeatureName
));
533 DEBUG ((DEBUG_WARN
, "Warning :: Failed to enable Feature Mask = "));
534 DumpCpuFeatureMask (CpuFeatureInOrder
->FeatureMask
);
538 Status
= CpuFeatureInOrder
->InitializeFunc (ProcessorNumber
, CpuInfo
, CpuFeatureInOrder
->ConfigData
, FALSE
);
539 ASSERT_EFI_ERROR (Status
);
541 Entry
= Entry
->ForwardLink
;
545 // Dump PcdCpuFeaturesSetting again because this value maybe updated
546 // again during initialize the features.
548 DEBUG ((DEBUG_INFO
, "Dump final value for PcdCpuFeaturesSetting:\n"));
549 DumpCpuFeatureMask (CpuFeaturesData
->SettingPcds
);
552 // Dump the RegisterTable
554 DumpRegisterTableOnProcessor (ProcessorNumber
);
559 Initialize the CPU registers from a register table.
561 @param[in] ProcessorNumber The index of the CPU executing this function.
563 @note This service could be called by BSP/APs.
566 ProgramProcessorRegister (
567 IN UINTN ProcessorNumber
570 CPU_FEATURES_DATA
*CpuFeaturesData
;
571 CPU_REGISTER_TABLE
*RegisterTable
;
572 CPU_REGISTER_TABLE_ENTRY
*RegisterTableEntry
;
575 CPU_REGISTER_TABLE_ENTRY
*RegisterTableEntryHead
;
577 CpuFeaturesData
= GetCpuFeaturesData ();
578 RegisterTable
= &CpuFeaturesData
->RegisterTable
[ProcessorNumber
];
581 // Traverse Register Table of this logical processor
583 RegisterTableEntryHead
= (CPU_REGISTER_TABLE_ENTRY
*) (UINTN
) RegisterTable
->RegisterTableEntry
;
585 for (Index
= 0; Index
< RegisterTable
->TableLength
; Index
++) {
587 RegisterTableEntry
= &RegisterTableEntryHead
[Index
];
590 // Check the type of specified register
592 switch (RegisterTableEntry
->RegisterType
) {
594 // The specified register is Control Register
596 case ControlRegister
:
597 switch (RegisterTableEntry
->Index
) {
599 Value
= AsmReadCr0 ();
600 Value
= (UINTN
) BitFieldWrite64 (
602 RegisterTableEntry
->ValidBitStart
,
603 RegisterTableEntry
->ValidBitStart
+ RegisterTableEntry
->ValidBitLength
- 1,
604 RegisterTableEntry
->Value
609 Value
= AsmReadCr2 ();
610 Value
= (UINTN
) BitFieldWrite64 (
612 RegisterTableEntry
->ValidBitStart
,
613 RegisterTableEntry
->ValidBitStart
+ RegisterTableEntry
->ValidBitLength
- 1,
614 RegisterTableEntry
->Value
619 Value
= AsmReadCr3 ();
620 Value
= (UINTN
) BitFieldWrite64 (
622 RegisterTableEntry
->ValidBitStart
,
623 RegisterTableEntry
->ValidBitStart
+ RegisterTableEntry
->ValidBitLength
- 1,
624 RegisterTableEntry
->Value
629 Value
= AsmReadCr4 ();
630 Value
= (UINTN
) BitFieldWrite64 (
632 RegisterTableEntry
->ValidBitStart
,
633 RegisterTableEntry
->ValidBitStart
+ RegisterTableEntry
->ValidBitLength
- 1,
634 RegisterTableEntry
->Value
640 // Do we need to support CR8?
648 // The specified register is Model Specific Register
652 // Get lock to avoid Package/Core scope MSRs programming issue in parallel execution mode
654 AcquireSpinLock (&CpuFeaturesData
->MsrLock
);
655 if (RegisterTableEntry
->ValidBitLength
>= 64) {
657 // If length is not less than 64 bits, then directly write without reading
660 RegisterTableEntry
->Index
,
661 RegisterTableEntry
->Value
665 // Set the bit section according to bit start and length
667 AsmMsrBitFieldWrite64 (
668 RegisterTableEntry
->Index
,
669 RegisterTableEntry
->ValidBitStart
,
670 RegisterTableEntry
->ValidBitStart
+ RegisterTableEntry
->ValidBitLength
- 1,
671 RegisterTableEntry
->Value
674 ReleaseSpinLock (&CpuFeaturesData
->MsrLock
);
677 // MemoryMapped operations
680 AcquireSpinLock (&CpuFeaturesData
->MemoryMappedLock
);
681 MmioBitFieldWrite32 (
682 (UINTN
)(RegisterTableEntry
->Index
| LShiftU64 (RegisterTableEntry
->HighIndex
, 32)),
683 RegisterTableEntry
->ValidBitStart
,
684 RegisterTableEntry
->ValidBitStart
+ RegisterTableEntry
->ValidBitLength
- 1,
685 (UINT32
)RegisterTableEntry
->Value
687 ReleaseSpinLock (&CpuFeaturesData
->MemoryMappedLock
);
690 // Enable or disable cache
694 // If value of the entry is 0, then disable cache. Otherwise, enable cache.
696 if (RegisterTableEntry
->Value
== 0) {
710 Programs registers for the calling processor.
712 @param[in,out] Buffer The pointer to private data buffer.
717 SetProcessorRegister (
721 UINTN ProcessorNumber
;
723 ProcessorNumber
= GetProcessorIndex ();
724 ProgramProcessorRegister (ProcessorNumber
);
728 Performs CPU features detection.
730 This service will invoke MP service to check CPU features'
731 capabilities on BSP/APs.
733 @note This service could be called by BSP only.
742 UINTN NumberOfEnabledProcessors
;
744 GetNumberOfProcessor (&NumberOfCpus
, &NumberOfEnabledProcessors
);
746 CpuInitDataInitialize (NumberOfCpus
);
749 // Wakeup all APs for data collection.
751 StartupAPsWorker (CollectProcessorData
);
754 // Collect data on BSP
756 CollectProcessorData (NULL
);
758 AnalysisProcessorFeatures (NumberOfCpus
);
762 Performs CPU features Initialization.
764 This service will invoke MP service to perform CPU features
765 initialization on BSP/APs per user configuration.
767 @note This service could be called by BSP only.
771 CpuFeaturesInitialize (
775 CPU_FEATURES_DATA
*CpuFeaturesData
;
778 CpuFeaturesData
= GetCpuFeaturesData ();
780 OldBspNumber
= GetProcessorIndex();
781 CpuFeaturesData
->BspNumber
= OldBspNumber
;
783 // Wakeup all APs for programming.
785 StartupAPsWorker (SetProcessorRegister
);
789 SetProcessorRegister (NULL
);
791 // Switch to new BSP if required
793 if (CpuFeaturesData
->BspNumber
!= OldBspNumber
) {
794 SwitchNewBsp (CpuFeaturesData
->BspNumber
);