ClockModulation.c 4.5 KB

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