/** @file\r
Clock Modulation feature.\r
\r
- Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include "CpuCommonFeatures.h"\r
\r
+typedef struct {\r
+ CPUID_THERMAL_POWER_MANAGEMENT_EAX ThermalPowerManagementEax;\r
+ MSR_IA32_CLOCK_MODULATION_REGISTER ClockModulation;\r
+} CLOCK_MODULATION_CONFIG_DATA;\r
+\r
+/**\r
+ Prepares for the data used by CPU feature detection and initialization.\r
+\r
+ @param[in] NumberOfProcessors The number of CPUs in the platform.\r
+\r
+ @return Pointer to a buffer of CPU related configuration data.\r
+\r
+ @note This service could be called by BSP only.\r
+**/\r
+VOID *\r
+EFIAPI\r
+ClockModulationGetConfigData (\r
+ IN UINTN NumberOfProcessors\r
+ )\r
+{\r
+ UINT32 *ConfigData;\r
+\r
+ ConfigData = AllocateZeroPool (sizeof (CLOCK_MODULATION_CONFIG_DATA) * NumberOfProcessors);\r
+ ASSERT (ConfigData != NULL);\r
+ return ConfigData;\r
+}\r
+\r
/**\r
Detects if Clock Modulation feature supported on current processor.\r
\r
IN VOID *ConfigData OPTIONAL\r
)\r
{\r
- return (CpuInfo->CpuIdVersionInfoEdx.Bits.ACPI == 1);\r
+ CLOCK_MODULATION_CONFIG_DATA *CmConfigData;\r
+\r
+ if (CpuInfo->CpuIdVersionInfoEdx.Bits.ACPI == 1) {\r
+ CmConfigData = (CLOCK_MODULATION_CONFIG_DATA *) ConfigData;\r
+ ASSERT (CmConfigData != NULL);\r
+ AsmCpuid (\r
+ CPUID_THERMAL_POWER_MANAGEMENT,\r
+ &CmConfigData[ProcessorNumber].ThermalPowerManagementEax.Uint32,\r
+ NULL,\r
+ NULL,\r
+ NULL\r
+ );\r
+ CmConfigData[ProcessorNumber].ClockModulation.Uint64 = AsmReadMsr64 (MSR_IA32_CLOCK_MODULATION);\r
+ return TRUE;\r
+ }\r
+ return FALSE;\r
}\r
\r
/**\r
IN BOOLEAN State\r
)\r
{\r
- CPUID_THERMAL_POWER_MANAGEMENT_EAX ThermalPowerManagementEax;\r
- AsmCpuid (CPUID_THERMAL_POWER_MANAGEMENT, &ThermalPowerManagementEax.Uint32, NULL, NULL, NULL);\r
+ CLOCK_MODULATION_CONFIG_DATA *CmConfigData;\r
+ MSR_IA32_CLOCK_MODULATION_REGISTER *ClockModulation;\r
\r
- CPU_REGISTER_TABLE_WRITE_FIELD (\r
- ProcessorNumber,\r
- Msr,\r
- MSR_IA32_CLOCK_MODULATION,\r
- MSR_IA32_CLOCK_MODULATION_REGISTER,\r
- Bits.OnDemandClockModulationDutyCycle,\r
- PcdGet8 (PcdCpuClockModulationDutyCycle) >> 1\r
- );\r
- if (ThermalPowerManagementEax.Bits.ECMD == 1) {\r
- CPU_REGISTER_TABLE_WRITE_FIELD (\r
- ProcessorNumber,\r
- Msr,\r
- MSR_IA32_CLOCK_MODULATION,\r
- MSR_IA32_CLOCK_MODULATION_REGISTER,\r
- Bits.ExtendedOnDemandClockModulationDutyCycle,\r
- PcdGet8 (PcdCpuClockModulationDutyCycle) & BIT0\r
- );\r
+ CmConfigData = (CLOCK_MODULATION_CONFIG_DATA *) ConfigData;\r
+ ASSERT (CmConfigData != NULL);\r
+ ClockModulation = &CmConfigData[ProcessorNumber].ClockModulation;\r
+\r
+ if (State) {\r
+ ClockModulation->Bits.OnDemandClockModulationEnable = 1;\r
+ ClockModulation->Bits.OnDemandClockModulationDutyCycle = PcdGet8 (PcdCpuClockModulationDutyCycle) >> 1;\r
+ if (CmConfigData[ProcessorNumber].ThermalPowerManagementEax.Bits.ECMD == 1) {\r
+ ClockModulation->Bits.ExtendedOnDemandClockModulationDutyCycle = PcdGet8 (PcdCpuClockModulationDutyCycle) & BIT0;\r
+ }\r
+ } else {\r
+ ClockModulation->Bits.OnDemandClockModulationEnable = 0;\r
}\r
- CPU_REGISTER_TABLE_WRITE_FIELD (\r
+\r
+ CPU_REGISTER_TABLE_WRITE64 (\r
ProcessorNumber,\r
Msr,\r
MSR_IA32_CLOCK_MODULATION,\r
- MSR_IA32_CLOCK_MODULATION_REGISTER,\r
- Bits.OnDemandClockModulationEnable,\r
- (State) ? 1 : 0\r
+ ClockModulation->Uint64\r
);\r
+\r
return RETURN_SUCCESS;\r
}\r