]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/Library/CpuCommonFeaturesLib/ClockModulation.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / UefiCpuPkg / Library / CpuCommonFeaturesLib / ClockModulation.c
1 /** @file
2 Clock Modulation feature.
3
4 Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "CpuCommonFeatures.h"
10
11 typedef struct {
12 CPUID_THERMAL_POWER_MANAGEMENT_EAX ThermalPowerManagementEax;
13 MSR_IA32_CLOCK_MODULATION_REGISTER ClockModulation;
14 } CLOCK_MODULATION_CONFIG_DATA;
15
16 /**
17 Prepares for the data used by CPU feature detection and initialization.
18
19 @param[in] NumberOfProcessors The number of CPUs in the platform.
20
21 @return Pointer to a buffer of CPU related configuration data.
22
23 @note This service could be called by BSP only.
24 **/
25 VOID *
26 EFIAPI
27 ClockModulationGetConfigData (
28 IN UINTN NumberOfProcessors
29 )
30 {
31 UINT32 *ConfigData;
32
33 ConfigData = AllocateZeroPool (sizeof (CLOCK_MODULATION_CONFIG_DATA) * NumberOfProcessors);
34 ASSERT (ConfigData != NULL);
35 return ConfigData;
36 }
37
38 /**
39 Detects if Clock Modulation feature supported on current processor.
40
41 @param[in] ProcessorNumber The index of the CPU executing this function.
42 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION
43 structure for the CPU executing this function.
44 @param[in] ConfigData A pointer to the configuration buffer returned
45 by CPU_FEATURE_GET_CONFIG_DATA. NULL if
46 CPU_FEATURE_GET_CONFIG_DATA was not provided in
47 RegisterCpuFeature().
48
49 @retval TRUE Clock Modulation feature is supported.
50 @retval FALSE Clock Modulation feature is not supported.
51
52 @note This service could be called by BSP/APs.
53 **/
54 BOOLEAN
55 EFIAPI
56 ClockModulationSupport (
57 IN UINTN ProcessorNumber,
58 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,
59 IN VOID *ConfigData OPTIONAL
60 )
61 {
62 CLOCK_MODULATION_CONFIG_DATA *CmConfigData;
63
64 if (CpuInfo->CpuIdVersionInfoEdx.Bits.ACPI == 1) {
65 CmConfigData = (CLOCK_MODULATION_CONFIG_DATA *)ConfigData;
66 ASSERT (CmConfigData != NULL);
67 AsmCpuid (
68 CPUID_THERMAL_POWER_MANAGEMENT,
69 &CmConfigData[ProcessorNumber].ThermalPowerManagementEax.Uint32,
70 NULL,
71 NULL,
72 NULL
73 );
74 CmConfigData[ProcessorNumber].ClockModulation.Uint64 = AsmReadMsr64 (MSR_IA32_CLOCK_MODULATION);
75 return TRUE;
76 }
77
78 return FALSE;
79 }
80
81 /**
82 Initializes Clock Modulation feature to specific state.
83
84 @param[in] ProcessorNumber The index of the CPU executing this function.
85 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION
86 structure for the CPU executing this function.
87 @param[in] ConfigData A pointer to the configuration buffer returned
88 by CPU_FEATURE_GET_CONFIG_DATA. NULL if
89 CPU_FEATURE_GET_CONFIG_DATA was not provided in
90 RegisterCpuFeature().
91 @param[in] State If TRUE, then the Clock Modulation feature must be enabled.
92 If FALSE, then the Clock Modulation feature must be disabled.
93
94 @retval RETURN_SUCCESS Clock Modulation feature is initialized.
95
96 @note This service could be called by BSP only.
97 **/
98 RETURN_STATUS
99 EFIAPI
100 ClockModulationInitialize (
101 IN UINTN ProcessorNumber,
102 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,
103 IN VOID *ConfigData OPTIONAL,
104 IN BOOLEAN State
105 )
106 {
107 CLOCK_MODULATION_CONFIG_DATA *CmConfigData;
108 MSR_IA32_CLOCK_MODULATION_REGISTER *ClockModulation;
109
110 CmConfigData = (CLOCK_MODULATION_CONFIG_DATA *)ConfigData;
111 ASSERT (CmConfigData != NULL);
112 ClockModulation = &CmConfigData[ProcessorNumber].ClockModulation;
113
114 if (State) {
115 ClockModulation->Bits.OnDemandClockModulationEnable = 1;
116 ClockModulation->Bits.OnDemandClockModulationDutyCycle = PcdGet8 (PcdCpuClockModulationDutyCycle) >> 1;
117 if (CmConfigData[ProcessorNumber].ThermalPowerManagementEax.Bits.ECMD == 1) {
118 ClockModulation->Bits.ExtendedOnDemandClockModulationDutyCycle = PcdGet8 (PcdCpuClockModulationDutyCycle) & BIT0;
119 }
120 } else {
121 ClockModulation->Bits.OnDemandClockModulationEnable = 0;
122 }
123
124 CPU_REGISTER_TABLE_WRITE64 (
125 ProcessorNumber,
126 Msr,
127 MSR_IA32_CLOCK_MODULATION,
128 ClockModulation->Uint64
129 );
130
131 return RETURN_SUCCESS;
132 }