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
);
154 // Collect CPU Features information
156 Entry
= GetFirstNode (&CpuFeaturesData
->FeatureList
);
157 while (!IsNull (&CpuFeaturesData
->FeatureList
, Entry
)) {
158 CpuFeature
= CPU_FEATURE_ENTRY_FROM_LINK (Entry
);
159 ASSERT (CpuFeature
->InitializeFunc
!= NULL
);
160 if (CpuFeature
->GetConfigDataFunc
!= NULL
) {
161 CpuFeature
->ConfigData
= CpuFeature
->GetConfigDataFunc (NumberOfCpus
);
163 Entry
= Entry
->ForwardLink
;
166 for (ProcessorNumber
= 0; ProcessorNumber
< NumberOfCpus
; ProcessorNumber
++) {
167 InitOrder
= &CpuFeaturesData
->InitOrder
[ProcessorNumber
];
168 InitOrder
->FeaturesSupportedMask
= AllocateZeroPool (CpuFeaturesData
->BitMaskSize
);
169 ASSERT (InitOrder
->FeaturesSupportedMask
!= NULL
);
170 InitializeListHead (&InitOrder
->OrderList
);
171 Status
= GetProcessorInformation (ProcessorNumber
, &ProcessorInfoBuffer
);
172 ASSERT_EFI_ERROR (Status
);
174 &InitOrder
->CpuInfo
.ProcessorInfo
,
175 &ProcessorInfoBuffer
,
176 sizeof (EFI_PROCESSOR_INFORMATION
)
180 // Get support and configuration PCDs
182 CpuFeaturesData
->SupportPcd
= GetSupportPcd ();
183 CpuFeaturesData
->ConfigurationPcd
= GetConfigurationPcd ();
187 Worker function to do OR operation on CPU feature supported bits mask buffer.
189 @param[in] SupportedFeatureMask The pointer to CPU feature bits mask buffer
190 @param[in] OrFeatureBitMask The feature bit mask to do OR operation
194 IN UINT8
*SupportedFeatureMask
,
195 IN UINT8
*OrFeatureBitMask
203 BitMaskSize
= PcdGetSize (PcdCpuFeaturesSupport
);
204 Data1
= SupportedFeatureMask
;
205 Data2
= OrFeatureBitMask
;
206 for (Index
= 0; Index
< BitMaskSize
; Index
++) {
207 *(Data1
++) |= *(Data2
++);
212 Worker function to do AND operation on CPU feature supported bits mask buffer.
214 @param[in] SupportedFeatureMask The pointer to CPU feature bits mask buffer
215 @param[in] AndFeatureBitMask The feature bit mask to do AND operation
219 IN UINT8
*SupportedFeatureMask
,
220 IN UINT8
*AndFeatureBitMask
228 BitMaskSize
= PcdGetSize (PcdCpuFeaturesSupport
);
229 Data1
= SupportedFeatureMask
;
230 Data2
= AndFeatureBitMask
;
231 for (Index
= 0; Index
< BitMaskSize
; Index
++) {
232 *(Data1
++) &= *(Data2
++);
237 Worker function to clean bit operation on CPU feature supported bits mask buffer.
239 @param[in] SupportedFeatureMask The pointer to CPU feature bits mask buffer
240 @param[in] AndFeatureBitMask The feature bit mask to do XOR operation
243 SupportedMaskCleanBit (
244 IN UINT8
*SupportedFeatureMask
,
245 IN UINT8
*AndFeatureBitMask
253 BitMaskSize
= PcdGetSize (PcdCpuFeaturesSupport
);
254 Data1
= SupportedFeatureMask
;
255 Data2
= AndFeatureBitMask
;
256 for (Index
= 0; Index
< BitMaskSize
; Index
++) {
257 *(Data1
++) &= ~(*(Data2
++));
262 Worker function to check if the compared CPU feature set in the CPU feature
263 supported bits mask buffer.
265 @param[in] SupportedFeatureMask The pointer to CPU feature bits mask buffer
266 @param[in] ComparedFeatureBitMask The feature bit mask to be compared
268 @retval TRUE The ComparedFeatureBitMask is set in CPU feature supported bits
270 @retval FALSE The ComparedFeatureBitMask is not set in CPU feature supported bits
275 IN UINT8
*SupportedFeatureMask
,
276 IN UINT8
*ComparedFeatureBitMask
284 BitMaskSize
= PcdGetSize (PcdCpuFeaturesSupport
);
286 Data1
= SupportedFeatureMask
;
287 Data2
= ComparedFeatureBitMask
;
288 for (Index
= 0; Index
< BitMaskSize
; Index
++) {
289 if (((*(Data1
++)) & (*(Data2
++))) != 0) {
297 Collects processor data for calling processor.
299 @param[in,out] Buffer The pointer to private data buffer.
303 CollectProcessorData (
307 UINTN ProcessorNumber
;
308 CPU_FEATURES_ENTRY
*CpuFeature
;
309 REGISTER_CPU_FEATURE_INFORMATION
*CpuInfo
;
311 CPU_FEATURES_DATA
*CpuFeaturesData
;
313 CpuFeaturesData
= GetCpuFeaturesData ();
314 ProcessorNumber
= GetProcessorIndex ();
315 CpuInfo
= &CpuFeaturesData
->InitOrder
[ProcessorNumber
].CpuInfo
;
317 // collect processor information
319 FillProcessorInfo (CpuInfo
);
320 Entry
= GetFirstNode (&CpuFeaturesData
->FeatureList
);
321 while (!IsNull (&CpuFeaturesData
->FeatureList
, Entry
)) {
322 CpuFeature
= CPU_FEATURE_ENTRY_FROM_LINK (Entry
);
323 if (IsBitMaskMatch (CpuFeaturesData
->SupportPcd
, CpuFeature
->FeatureMask
)) {
324 if (CpuFeature
->SupportFunc
== NULL
) {
326 // If SupportFunc is NULL, then the feature is supported.
329 CpuFeaturesData
->InitOrder
[ProcessorNumber
].FeaturesSupportedMask
,
330 CpuFeature
->FeatureMask
332 } else if (CpuFeature
->SupportFunc (ProcessorNumber
, CpuInfo
, CpuFeature
->ConfigData
)) {
334 CpuFeaturesData
->InitOrder
[ProcessorNumber
].FeaturesSupportedMask
,
335 CpuFeature
->FeatureMask
339 Entry
= Entry
->ForwardLink
;
344 Dump the contents of a CPU register table.
346 @param[in] ProcessorNumber The index of the CPU to show the register table contents
348 @note This service could be called by BSP only.
351 DumpRegisterTableOnProcessor (
352 IN UINTN ProcessorNumber
355 CPU_FEATURES_DATA
*CpuFeaturesData
;
357 CPU_REGISTER_TABLE
*RegisterTable
;
358 CPU_REGISTER_TABLE_ENTRY
*RegisterTableEntry
;
359 CPU_REGISTER_TABLE_ENTRY
*RegisterTableEntryHead
;
360 UINT32 DebugPrintErrorLevel
;
362 DebugPrintErrorLevel
= (ProcessorNumber
== 0) ? DEBUG_INFO
: DEBUG_VERBOSE
;
363 CpuFeaturesData
= GetCpuFeaturesData ();
367 RegisterTable
= &CpuFeaturesData
->RegisterTable
[ProcessorNumber
];
368 DEBUG ((DebugPrintErrorLevel
, "RegisterTable->TableLength = %d\n", RegisterTable
->TableLength
));
370 RegisterTableEntryHead
= (CPU_REGISTER_TABLE_ENTRY
*) (UINTN
) RegisterTable
->RegisterTableEntry
;
372 for (FeatureIndex
= 0; FeatureIndex
< RegisterTable
->TableLength
; FeatureIndex
++) {
373 RegisterTableEntry
= &RegisterTableEntryHead
[FeatureIndex
];
374 switch (RegisterTableEntry
->RegisterType
) {
377 DebugPrintErrorLevel
,
378 "Processor: %d: MSR: %x, Bit Start: %d, Bit Length: %d, Value: %lx\r\n",
380 RegisterTableEntry
->Index
,
381 RegisterTableEntry
->ValidBitStart
,
382 RegisterTableEntry
->ValidBitLength
,
383 RegisterTableEntry
->Value
386 case ControlRegister
:
388 DebugPrintErrorLevel
,
389 "Processor: %d: CR: %x, Bit Start: %d, Bit Length: %d, Value: %lx\r\n",
391 RegisterTableEntry
->Index
,
392 RegisterTableEntry
->ValidBitStart
,
393 RegisterTableEntry
->ValidBitLength
,
394 RegisterTableEntry
->Value
399 DebugPrintErrorLevel
,
400 "Processor: %d: MMIO: %lx, Bit Start: %d, Bit Length: %d, Value: %lx\r\n",
402 RegisterTableEntry
->Index
| LShiftU64 (RegisterTableEntry
->HighIndex
, 32),
403 RegisterTableEntry
->ValidBitStart
,
404 RegisterTableEntry
->ValidBitLength
,
405 RegisterTableEntry
->Value
410 DebugPrintErrorLevel
,
411 "Processor: %d: CACHE: %x, Bit Start: %d, Bit Length: %d, Value: %lx\r\n",
413 RegisterTableEntry
->Index
,
414 RegisterTableEntry
->ValidBitStart
,
415 RegisterTableEntry
->ValidBitLength
,
416 RegisterTableEntry
->Value
426 Analysis register CPU features on each processor and save CPU setting in CPU register table.
428 @param[in] NumberOfCpus Number of processor in system
432 AnalysisProcessorFeatures (
433 IN UINTN NumberOfCpus
437 UINTN ProcessorNumber
;
438 CPU_FEATURES_ENTRY
*CpuFeature
;
439 CPU_FEATURES_ENTRY
*CpuFeatureInOrder
;
440 CPU_FEATURES_INIT_ORDER
*CpuInitOrder
;
441 REGISTER_CPU_FEATURE_INFORMATION
*CpuInfo
;
443 CPU_FEATURES_DATA
*CpuFeaturesData
;
445 CpuFeaturesData
= GetCpuFeaturesData ();
446 CpuFeaturesData
->CapabilityPcd
= AllocatePool (CpuFeaturesData
->BitMaskSize
);
447 ASSERT (CpuFeaturesData
->CapabilityPcd
!= NULL
);
448 SetMem (CpuFeaturesData
->CapabilityPcd
, CpuFeaturesData
->BitMaskSize
, 0xFF);
449 for (ProcessorNumber
= 0; ProcessorNumber
< NumberOfCpus
; ProcessorNumber
++) {
450 CpuInitOrder
= &CpuFeaturesData
->InitOrder
[ProcessorNumber
];
452 // Calculate the last capability on all processors
454 SupportedMaskAnd (CpuFeaturesData
->CapabilityPcd
, CpuInitOrder
->FeaturesSupportedMask
);
457 // Calculate the last setting
460 CpuFeaturesData
->SettingPcd
= AllocateCopyPool (CpuFeaturesData
->BitMaskSize
, CpuFeaturesData
->CapabilityPcd
);
461 ASSERT (CpuFeaturesData
->SettingPcd
!= NULL
);
462 SupportedMaskAnd (CpuFeaturesData
->SettingPcd
, CpuFeaturesData
->ConfigurationPcd
);
465 // Save PCDs and display CPU PCDs
467 SetCapabilityPcd (CpuFeaturesData
->CapabilityPcd
);
468 SetSettingPcd (CpuFeaturesData
->SettingPcd
);
471 // Dump the last CPU feature list
474 DEBUG ((DEBUG_INFO
, "Last CPU features list...\n"));
475 Entry
= GetFirstNode (&CpuFeaturesData
->FeatureList
);
476 while (!IsNull (&CpuFeaturesData
->FeatureList
, Entry
)) {
477 CpuFeature
= CPU_FEATURE_ENTRY_FROM_LINK (Entry
);
478 if (IsBitMaskMatch (CpuFeature
->FeatureMask
, CpuFeaturesData
->CapabilityPcd
)) {
479 if (IsBitMaskMatch (CpuFeature
->FeatureMask
, CpuFeaturesData
->SettingPcd
)) {
480 DEBUG ((DEBUG_INFO
, "[Enable ] "));
482 DEBUG ((DEBUG_INFO
, "[Disable ] "));
485 DEBUG ((DEBUG_INFO
, "[Unsupport] "));
487 DumpCpuFeature (CpuFeature
);
488 Entry
= Entry
->ForwardLink
;
490 DEBUG ((DEBUG_INFO
, "PcdCpuFeaturesSupport:\n"));
491 DumpCpuFeatureMask (CpuFeaturesData
->SupportPcd
);
492 DEBUG ((DEBUG_INFO
, "PcdCpuFeaturesUserConfiguration:\n"));
493 DumpCpuFeatureMask (CpuFeaturesData
->ConfigurationPcd
);
494 DEBUG ((DEBUG_INFO
, "PcdCpuFeaturesCapability:\n"));
495 DumpCpuFeatureMask (CpuFeaturesData
->CapabilityPcd
);
496 DEBUG ((DEBUG_INFO
, "PcdCpuFeaturesSetting:\n"));
497 DumpCpuFeatureMask (CpuFeaturesData
->SettingPcd
);
500 for (ProcessorNumber
= 0; ProcessorNumber
< NumberOfCpus
; ProcessorNumber
++) {
501 CpuInitOrder
= &CpuFeaturesData
->InitOrder
[ProcessorNumber
];
502 Entry
= GetFirstNode (&CpuFeaturesData
->FeatureList
);
503 while (!IsNull (&CpuFeaturesData
->FeatureList
, Entry
)) {
505 // Insert each feature into processor's order list
507 CpuFeature
= CPU_FEATURE_ENTRY_FROM_LINK (Entry
);
508 if (IsBitMaskMatch (CpuFeature
->FeatureMask
, CpuFeaturesData
->CapabilityPcd
)) {
509 CpuFeatureInOrder
= AllocateCopyPool (sizeof (CPU_FEATURES_ENTRY
), CpuFeature
);
510 ASSERT (CpuFeatureInOrder
!= NULL
);
511 InsertTailList (&CpuInitOrder
->OrderList
, &CpuFeatureInOrder
->Link
);
513 Entry
= Entry
->ForwardLink
;
516 // Go through ordered feature list to initialize CPU features
518 CpuInfo
= &CpuFeaturesData
->InitOrder
[ProcessorNumber
].CpuInfo
;
519 Entry
= GetFirstNode (&CpuInitOrder
->OrderList
);
520 while (!IsNull (&CpuInitOrder
->OrderList
, Entry
)) {
521 CpuFeatureInOrder
= CPU_FEATURE_ENTRY_FROM_LINK (Entry
);
522 if (IsBitMaskMatch (CpuFeatureInOrder
->FeatureMask
, CpuFeaturesData
->SettingPcd
)) {
523 Status
= CpuFeatureInOrder
->InitializeFunc (ProcessorNumber
, CpuInfo
, CpuFeatureInOrder
->ConfigData
, TRUE
);
524 if (EFI_ERROR (Status
)) {
526 // Clean the CpuFeatureInOrder->FeatureMask in setting PCD.
528 SupportedMaskCleanBit (CpuFeaturesData
->SettingPcd
, CpuFeatureInOrder
->FeatureMask
);
529 if (CpuFeatureInOrder
->FeatureName
!= NULL
) {
530 DEBUG ((DEBUG_WARN
, "Warning :: Failed to enable Feature: Name = %a.\n", CpuFeatureInOrder
->FeatureName
));
532 DEBUG ((DEBUG_WARN
, "Warning :: Failed to enable Feature: Mask = "));
533 DumpCpuFeatureMask (CpuFeatureInOrder
->FeatureMask
);
537 Status
= CpuFeatureInOrder
->InitializeFunc (ProcessorNumber
, CpuInfo
, CpuFeatureInOrder
->ConfigData
, FALSE
);
538 if (EFI_ERROR (Status
)) {
539 if (CpuFeatureInOrder
->FeatureName
!= NULL
) {
540 DEBUG ((DEBUG_WARN
, "Warning :: Failed to disable Feature: Name = %a.\n", CpuFeatureInOrder
->FeatureName
));
542 DEBUG ((DEBUG_WARN
, "Warning :: Failed to disable Feature: Mask = "));
543 DumpCpuFeatureMask (CpuFeatureInOrder
->FeatureMask
);
547 Entry
= Entry
->ForwardLink
;
551 // Dump PcdCpuFeaturesSetting again because this value maybe updated
552 // again during initialize the features.
554 DEBUG ((DEBUG_INFO
, "Dump final value for PcdCpuFeaturesSetting:\n"));
555 DumpCpuFeatureMask (CpuFeaturesData
->SettingPcd
);
558 // Dump the RegisterTable
560 DumpRegisterTableOnProcessor (ProcessorNumber
);
565 Initialize the CPU registers from a register table.
567 @param[in] ProcessorNumber The index of the CPU executing this function.
569 @note This service could be called by BSP/APs.
572 ProgramProcessorRegister (
573 IN UINTN ProcessorNumber
576 CPU_FEATURES_DATA
*CpuFeaturesData
;
577 CPU_REGISTER_TABLE
*RegisterTable
;
578 CPU_REGISTER_TABLE_ENTRY
*RegisterTableEntry
;
581 CPU_REGISTER_TABLE_ENTRY
*RegisterTableEntryHead
;
583 CpuFeaturesData
= GetCpuFeaturesData ();
584 RegisterTable
= &CpuFeaturesData
->RegisterTable
[ProcessorNumber
];
587 // Traverse Register Table of this logical processor
589 RegisterTableEntryHead
= (CPU_REGISTER_TABLE_ENTRY
*) (UINTN
) RegisterTable
->RegisterTableEntry
;
591 for (Index
= 0; Index
< RegisterTable
->TableLength
; Index
++) {
593 RegisterTableEntry
= &RegisterTableEntryHead
[Index
];
596 // Check the type of specified register
598 switch (RegisterTableEntry
->RegisterType
) {
600 // The specified register is Control Register
602 case ControlRegister
:
603 switch (RegisterTableEntry
->Index
) {
605 Value
= AsmReadCr0 ();
606 Value
= (UINTN
) BitFieldWrite64 (
608 RegisterTableEntry
->ValidBitStart
,
609 RegisterTableEntry
->ValidBitStart
+ RegisterTableEntry
->ValidBitLength
- 1,
610 RegisterTableEntry
->Value
615 Value
= AsmReadCr2 ();
616 Value
= (UINTN
) BitFieldWrite64 (
618 RegisterTableEntry
->ValidBitStart
,
619 RegisterTableEntry
->ValidBitStart
+ RegisterTableEntry
->ValidBitLength
- 1,
620 RegisterTableEntry
->Value
625 Value
= AsmReadCr3 ();
626 Value
= (UINTN
) BitFieldWrite64 (
628 RegisterTableEntry
->ValidBitStart
,
629 RegisterTableEntry
->ValidBitStart
+ RegisterTableEntry
->ValidBitLength
- 1,
630 RegisterTableEntry
->Value
635 Value
= AsmReadCr4 ();
636 Value
= (UINTN
) BitFieldWrite64 (
638 RegisterTableEntry
->ValidBitStart
,
639 RegisterTableEntry
->ValidBitStart
+ RegisterTableEntry
->ValidBitLength
- 1,
640 RegisterTableEntry
->Value
646 // Do we need to support CR8?
654 // The specified register is Model Specific Register
658 // Get lock to avoid Package/Core scope MSRs programming issue in parallel execution mode
660 AcquireSpinLock (&CpuFeaturesData
->MsrLock
);
661 if (RegisterTableEntry
->ValidBitLength
>= 64) {
663 // If length is not less than 64 bits, then directly write without reading
666 RegisterTableEntry
->Index
,
667 RegisterTableEntry
->Value
671 // Set the bit section according to bit start and length
673 AsmMsrBitFieldWrite64 (
674 RegisterTableEntry
->Index
,
675 RegisterTableEntry
->ValidBitStart
,
676 RegisterTableEntry
->ValidBitStart
+ RegisterTableEntry
->ValidBitLength
- 1,
677 RegisterTableEntry
->Value
680 ReleaseSpinLock (&CpuFeaturesData
->MsrLock
);
683 // MemoryMapped operations
686 AcquireSpinLock (&CpuFeaturesData
->MemoryMappedLock
);
687 MmioBitFieldWrite32 (
688 (UINTN
)(RegisterTableEntry
->Index
| LShiftU64 (RegisterTableEntry
->HighIndex
, 32)),
689 RegisterTableEntry
->ValidBitStart
,
690 RegisterTableEntry
->ValidBitStart
+ RegisterTableEntry
->ValidBitLength
- 1,
691 (UINT32
)RegisterTableEntry
->Value
693 ReleaseSpinLock (&CpuFeaturesData
->MemoryMappedLock
);
696 // Enable or disable cache
700 // If value of the entry is 0, then disable cache. Otherwise, enable cache.
702 if (RegisterTableEntry
->Value
== 0) {
716 Programs registers for the calling processor.
718 @param[in,out] Buffer The pointer to private data buffer.
723 SetProcessorRegister (
727 UINTN ProcessorNumber
;
729 ProcessorNumber
= GetProcessorIndex ();
730 ProgramProcessorRegister (ProcessorNumber
);
734 Performs CPU features detection.
736 This service will invoke MP service to check CPU features'
737 capabilities on BSP/APs.
739 @note This service could be called by BSP only.
748 UINTN NumberOfEnabledProcessors
;
750 GetNumberOfProcessor (&NumberOfCpus
, &NumberOfEnabledProcessors
);
752 CpuInitDataInitialize (NumberOfCpus
);
755 // Wakeup all APs for data collection.
757 StartupAPsWorker (CollectProcessorData
);
760 // Collect data on BSP
762 CollectProcessorData (NULL
);
764 AnalysisProcessorFeatures (NumberOfCpus
);
768 Performs CPU features Initialization.
770 This service will invoke MP service to perform CPU features
771 initialization on BSP/APs per user configuration.
773 @note This service could be called by BSP only.
777 CpuFeaturesInitialize (
781 CPU_FEATURES_DATA
*CpuFeaturesData
;
784 CpuFeaturesData
= GetCpuFeaturesData ();
786 OldBspNumber
= GetProcessorIndex();
787 CpuFeaturesData
->BspNumber
= OldBspNumber
;
789 // Wakeup all APs for programming.
791 StartupAPsWorker (SetProcessorRegister
);
795 SetProcessorRegister (NULL
);
797 // Switch to new BSP if required
799 if (CpuFeaturesData
->BspNumber
!= OldBspNumber
) {
800 SwitchNewBsp (CpuFeaturesData
->BspNumber
);