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