Ppin.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /** @file
  2. Protected Processor Inventory Number(PPIN) feature.
  3. Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include "CpuCommonFeatures.h"
  7. /**
  8. Prepares for the data used by CPU feature detection and initialization.
  9. @param[in] NumberOfProcessors The number of CPUs in the platform.
  10. @return Pointer to a buffer of CPU related configuration data.
  11. @note This service could be called by BSP only.
  12. **/
  13. VOID *
  14. EFIAPI
  15. PpinGetConfigData (
  16. IN UINTN NumberOfProcessors
  17. )
  18. {
  19. VOID *ConfigData;
  20. ConfigData = AllocateZeroPool (sizeof (MSR_IVY_BRIDGE_PPIN_CTL_REGISTER) * NumberOfProcessors);
  21. ASSERT (ConfigData != NULL);
  22. return ConfigData;
  23. }
  24. /**
  25. Detects if Protected Processor Inventory Number feature supported on current
  26. processor.
  27. @param[in] ProcessorNumber The index of the CPU executing this function.
  28. @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION
  29. structure for the CPU executing this function.
  30. @param[in] ConfigData A pointer to the configuration buffer returned
  31. by CPU_FEATURE_GET_CONFIG_DATA. NULL if
  32. CPU_FEATURE_GET_CONFIG_DATA was not provided in
  33. RegisterCpuFeature().
  34. @retval TRUE Protected Processor Inventory Number feature is supported.
  35. @retval FALSE Protected Processor Inventory Number feature is not supported.
  36. @note This service could be called by BSP/APs.
  37. **/
  38. BOOLEAN
  39. EFIAPI
  40. PpinSupport (
  41. IN UINTN ProcessorNumber,
  42. IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,
  43. IN VOID *ConfigData OPTIONAL
  44. )
  45. {
  46. MSR_IVY_BRIDGE_PLATFORM_INFO_1_REGISTER PlatformInfo;
  47. MSR_IVY_BRIDGE_PPIN_CTL_REGISTER *MsrPpinCtrl;
  48. if ((CpuInfo->DisplayFamily == 0x06) &&
  49. ((CpuInfo->DisplayModel == 0x3E) || // Xeon E5 V2
  50. (CpuInfo->DisplayModel == 0x56) || // Xeon Processor D Product
  51. (CpuInfo->DisplayModel == 0x4F) || // Xeon E5 v4, E7 v4
  52. (CpuInfo->DisplayModel == 0x55) || // Xeon Processor Scalable
  53. (CpuInfo->DisplayModel == 0x57) || // Xeon Phi processor 3200, 5200, 7200 series.
  54. (CpuInfo->DisplayModel == 0x85) // Future Xeon phi processor
  55. ))
  56. {
  57. //
  58. // Check whether platform support this feature.
  59. //
  60. PlatformInfo.Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_PLATFORM_INFO_1);
  61. if (PlatformInfo.Bits.PPIN_CAP != 0) {
  62. MsrPpinCtrl = (MSR_IVY_BRIDGE_PPIN_CTL_REGISTER *)ConfigData;
  63. ASSERT (MsrPpinCtrl != NULL);
  64. MsrPpinCtrl[ProcessorNumber].Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_PPIN_CTL);
  65. return TRUE;
  66. }
  67. }
  68. return FALSE;
  69. }
  70. /**
  71. Initializes Protected Processor Inventory Number feature to specific state.
  72. @param[in] ProcessorNumber The index of the CPU executing this function.
  73. @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION
  74. structure for the CPU executing this function.
  75. @param[in] ConfigData A pointer to the configuration buffer returned
  76. by CPU_FEATURE_GET_CONFIG_DATA. NULL if
  77. CPU_FEATURE_GET_CONFIG_DATA was not provided in
  78. RegisterCpuFeature().
  79. @param[in] State If TRUE, then the Protected Processor Inventory
  80. Number feature must be enabled.
  81. If FALSE, then the Protected Processor Inventory
  82. Number feature must be disabled.
  83. @retval RETURN_SUCCESS Protected Processor Inventory Number feature is
  84. initialized.
  85. @retval RETURN_DEVICE_ERROR Device can't change state because it has been
  86. locked.
  87. @note This service could be called by BSP only.
  88. **/
  89. RETURN_STATUS
  90. EFIAPI
  91. PpinInitialize (
  92. IN UINTN ProcessorNumber,
  93. IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,
  94. IN VOID *ConfigData OPTIONAL,
  95. IN BOOLEAN State
  96. )
  97. {
  98. MSR_IVY_BRIDGE_PPIN_CTL_REGISTER *MsrPpinCtrl;
  99. MsrPpinCtrl = (MSR_IVY_BRIDGE_PPIN_CTL_REGISTER *)ConfigData;
  100. ASSERT (MsrPpinCtrl != NULL);
  101. //
  102. // Check whether processor already lock this register.
  103. // If already locked, just based on the request state and
  104. // the current state to return the status.
  105. //
  106. if (MsrPpinCtrl[ProcessorNumber].Bits.LockOut != 0) {
  107. return MsrPpinCtrl[ProcessorNumber].Bits.Enable_PPIN == State ? RETURN_SUCCESS : RETURN_DEVICE_ERROR;
  108. }
  109. //
  110. // Support function already check the processor which support PPIN feature, so this function not need
  111. // to check the processor again.
  112. //
  113. // The scope of the MSR_IVY_BRIDGE_PPIN_CTL is package level, only program MSR_IVY_BRIDGE_PPIN_CTL
  114. // once for each package.
  115. //
  116. if ((CpuInfo->First.Thread == 0) || (CpuInfo->First.Core == 0)) {
  117. return RETURN_SUCCESS;
  118. }
  119. if (State) {
  120. //
  121. // Enable and Unlock.
  122. // According to SDM, once Enable_PPIN is set, attempt to write 1 to LockOut will cause #GP.
  123. //
  124. MsrPpinCtrl[ProcessorNumber].Bits.Enable_PPIN = 1;
  125. MsrPpinCtrl[ProcessorNumber].Bits.LockOut = 0;
  126. } else {
  127. //
  128. // Disable and Lock.
  129. // According to SDM, writing 1 to LockOut is permitted only if Enable_PPIN is clear.
  130. //
  131. MsrPpinCtrl[ProcessorNumber].Bits.Enable_PPIN = 0;
  132. MsrPpinCtrl[ProcessorNumber].Bits.LockOut = 1;
  133. }
  134. CPU_REGISTER_TABLE_WRITE64 (
  135. ProcessorNumber,
  136. Msr,
  137. MSR_IVY_BRIDGE_PPIN_CTL,
  138. MsrPpinCtrl[ProcessorNumber].Uint64
  139. );
  140. return RETURN_SUCCESS;
  141. }