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.
63 UINT8
*SupportBitMask
;
65 SupportBitMask
= AllocateCopyPool (
66 PcdGetSize (PcdCpuFeaturesSupport
),
67 PcdGetPtr (PcdCpuFeaturesSupport
)
69 ASSERT (SupportBitMask
!= NULL
);
71 return SupportBitMask
;
75 Worker function to get PcdCpuFeaturesUserConfiguration.
77 @return The pointer to CPU feature bits mask buffer.
84 UINT8
*SupportBitMask
;
86 SupportBitMask
= AllocateCopyPool (
87 PcdGetSize (PcdCpuFeaturesUserConfiguration
),
88 PcdGetPtr (PcdCpuFeaturesUserConfiguration
)
90 ASSERT (SupportBitMask
!= NULL
);
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
= (UINT32
) 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
->SupportPcd
= GetSupportPcd ();
184 CpuFeaturesData
->ConfigurationPcd
= GetConfigurationPcd ();
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
->SupportPcd
, 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
->CapabilityPcd
= AllocatePool (CpuFeaturesData
->BitMaskSize
);
448 ASSERT (CpuFeaturesData
->CapabilityPcd
!= NULL
);
449 SetMem (CpuFeaturesData
->CapabilityPcd
, 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
->CapabilityPcd
, CpuInitOrder
->FeaturesSupportedMask
);
458 // Calculate the last setting
461 CpuFeaturesData
->SettingPcd
= AllocateCopyPool (CpuFeaturesData
->BitMaskSize
, CpuFeaturesData
->CapabilityPcd
);
462 ASSERT (CpuFeaturesData
->SettingPcd
!= NULL
);
463 SupportedMaskAnd (CpuFeaturesData
->SettingPcd
, CpuFeaturesData
->ConfigurationPcd
);
466 // Save PCDs and display CPU PCDs
468 SetCapabilityPcd (CpuFeaturesData
->CapabilityPcd
);
469 SetSettingPcd (CpuFeaturesData
->SettingPcd
);
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
->CapabilityPcd
)) {
480 if (IsBitMaskMatch (CpuFeature
->FeatureMask
, CpuFeaturesData
->SettingPcd
)) {
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
->SupportPcd
);
493 DEBUG ((DEBUG_INFO
, "PcdCpuFeaturesUserConfiguration:\n"));
494 DumpCpuFeatureMask (CpuFeaturesData
->ConfigurationPcd
);
495 DEBUG ((DEBUG_INFO
, "PcdCpuFeaturesCapability:\n"));
496 DumpCpuFeatureMask (CpuFeaturesData
->CapabilityPcd
);
497 DEBUG ((DEBUG_INFO
, "PcdCpuFeaturesSetting:\n"));
498 DumpCpuFeatureMask (CpuFeaturesData
->SettingPcd
);
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
->CapabilityPcd
)) {
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
->SettingPcd
)) {
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
->SettingPcd
, 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 if (EFI_ERROR (Status
)) {
540 if (CpuFeatureInOrder
->FeatureName
!= NULL
) {
541 DEBUG ((DEBUG_WARN
, "Warning :: Failed to disable Feature: Name = %a.\n", CpuFeatureInOrder
->FeatureName
));
543 DEBUG ((DEBUG_WARN
, "Warning :: Failed to disable Feature: Mask = "));
544 DumpCpuFeatureMask (CpuFeatureInOrder
->FeatureMask
);
548 Entry
= Entry
->ForwardLink
;
552 // Dump PcdCpuFeaturesSetting again because this value maybe updated
553 // again during initialize the features.
555 DEBUG ((DEBUG_INFO
, "Dump final value for PcdCpuFeaturesSetting:\n"));
556 DumpCpuFeatureMask (CpuFeaturesData
->SettingPcd
);
559 // Dump the RegisterTable
561 DumpRegisterTableOnProcessor (ProcessorNumber
);
566 Initialize the CPU registers from a register table.
568 @param[in] ProcessorNumber The index of the CPU executing this function.
570 @note This service could be called by BSP/APs.
573 ProgramProcessorRegister (
574 IN UINTN ProcessorNumber
577 CPU_FEATURES_DATA
*CpuFeaturesData
;
578 CPU_REGISTER_TABLE
*RegisterTable
;
579 CPU_REGISTER_TABLE_ENTRY
*RegisterTableEntry
;
582 CPU_REGISTER_TABLE_ENTRY
*RegisterTableEntryHead
;
584 CpuFeaturesData
= GetCpuFeaturesData ();
585 RegisterTable
= &CpuFeaturesData
->RegisterTable
[ProcessorNumber
];
588 // Traverse Register Table of this logical processor
590 RegisterTableEntryHead
= (CPU_REGISTER_TABLE_ENTRY
*) (UINTN
) RegisterTable
->RegisterTableEntry
;
592 for (Index
= 0; Index
< RegisterTable
->TableLength
; Index
++) {
594 RegisterTableEntry
= &RegisterTableEntryHead
[Index
];
597 // Check the type of specified register
599 switch (RegisterTableEntry
->RegisterType
) {
601 // The specified register is Control Register
603 case ControlRegister
:
604 switch (RegisterTableEntry
->Index
) {
606 Value
= AsmReadCr0 ();
607 Value
= (UINTN
) BitFieldWrite64 (
609 RegisterTableEntry
->ValidBitStart
,
610 RegisterTableEntry
->ValidBitStart
+ RegisterTableEntry
->ValidBitLength
- 1,
611 RegisterTableEntry
->Value
616 Value
= AsmReadCr2 ();
617 Value
= (UINTN
) BitFieldWrite64 (
619 RegisterTableEntry
->ValidBitStart
,
620 RegisterTableEntry
->ValidBitStart
+ RegisterTableEntry
->ValidBitLength
- 1,
621 RegisterTableEntry
->Value
626 Value
= AsmReadCr3 ();
627 Value
= (UINTN
) BitFieldWrite64 (
629 RegisterTableEntry
->ValidBitStart
,
630 RegisterTableEntry
->ValidBitStart
+ RegisterTableEntry
->ValidBitLength
- 1,
631 RegisterTableEntry
->Value
636 Value
= AsmReadCr4 ();
637 Value
= (UINTN
) BitFieldWrite64 (
639 RegisterTableEntry
->ValidBitStart
,
640 RegisterTableEntry
->ValidBitStart
+ RegisterTableEntry
->ValidBitLength
- 1,
641 RegisterTableEntry
->Value
647 // Do we need to support CR8?
655 // The specified register is Model Specific Register
659 // Get lock to avoid Package/Core scope MSRs programming issue in parallel execution mode
661 AcquireSpinLock (&CpuFeaturesData
->MsrLock
);
662 if (RegisterTableEntry
->ValidBitLength
>= 64) {
664 // If length is not less than 64 bits, then directly write without reading
667 RegisterTableEntry
->Index
,
668 RegisterTableEntry
->Value
672 // Set the bit section according to bit start and length
674 AsmMsrBitFieldWrite64 (
675 RegisterTableEntry
->Index
,
676 RegisterTableEntry
->ValidBitStart
,
677 RegisterTableEntry
->ValidBitStart
+ RegisterTableEntry
->ValidBitLength
- 1,
678 RegisterTableEntry
->Value
681 ReleaseSpinLock (&CpuFeaturesData
->MsrLock
);
684 // MemoryMapped operations
687 AcquireSpinLock (&CpuFeaturesData
->MemoryMappedLock
);
688 MmioBitFieldWrite32 (
689 (UINTN
)(RegisterTableEntry
->Index
| LShiftU64 (RegisterTableEntry
->HighIndex
, 32)),
690 RegisterTableEntry
->ValidBitStart
,
691 RegisterTableEntry
->ValidBitStart
+ RegisterTableEntry
->ValidBitLength
- 1,
692 (UINT32
)RegisterTableEntry
->Value
694 ReleaseSpinLock (&CpuFeaturesData
->MemoryMappedLock
);
697 // Enable or disable cache
701 // If value of the entry is 0, then disable cache. Otherwise, enable cache.
703 if (RegisterTableEntry
->Value
== 0) {
717 Programs registers for the calling processor.
719 @param[in,out] Buffer The pointer to private data buffer.
724 SetProcessorRegister (
728 UINTN ProcessorNumber
;
730 ProcessorNumber
= GetProcessorIndex ();
731 ProgramProcessorRegister (ProcessorNumber
);
735 Performs CPU features detection.
737 This service will invoke MP service to check CPU features'
738 capabilities on BSP/APs.
740 @note This service could be called by BSP only.
749 UINTN NumberOfEnabledProcessors
;
751 GetNumberOfProcessor (&NumberOfCpus
, &NumberOfEnabledProcessors
);
753 CpuInitDataInitialize (NumberOfCpus
);
756 // Wakeup all APs for data collection.
758 StartupAPsWorker (CollectProcessorData
);
761 // Collect data on BSP
763 CollectProcessorData (NULL
);
765 AnalysisProcessorFeatures (NumberOfCpus
);
769 Performs CPU features Initialization.
771 This service will invoke MP service to perform CPU features
772 initialization on BSP/APs per user configuration.
774 @note This service could be called by BSP only.
778 CpuFeaturesInitialize (
782 CPU_FEATURES_DATA
*CpuFeaturesData
;
785 CpuFeaturesData
= GetCpuFeaturesData ();
787 OldBspNumber
= GetProcessorIndex();
788 CpuFeaturesData
->BspNumber
= OldBspNumber
;
790 // Wakeup all APs for programming.
792 StartupAPsWorker (SetProcessorRegister
);
796 SetProcessorRegister (NULL
);
798 // Switch to new BSP if required
800 if (CpuFeaturesData
->BspNumber
!= OldBspNumber
) {
801 SwitchNewBsp (CpuFeaturesData
->BspNumber
);