]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/Library/CpuCommonFeaturesLib/FeatureControl.c
UefiCpuPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / UefiCpuPkg / Library / CpuCommonFeaturesLib / FeatureControl.c
1 /** @file
2 Features in MSR_IA32_FEATURE_CONTROL register.
3
4 Copyright (c) 2017, 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 FeatureControlGetConfigData (
23 IN UINTN NumberOfProcessors
24 )
25 {
26 VOID *ConfigData;
27
28 ConfigData = AllocateZeroPool (sizeof (MSR_IA32_FEATURE_CONTROL_REGISTER) * NumberOfProcessors);
29 ASSERT (ConfigData != NULL);
30 return ConfigData;
31 }
32
33 /**
34 Detects if VMX feature supported on current processor.
35
36 @param[in] ProcessorNumber The index of the CPU executing this function.
37 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION
38 structure for the CPU executing this function.
39 @param[in] ConfigData A pointer to the configuration buffer returned
40 by CPU_FEATURE_GET_CONFIG_DATA. NULL if
41 CPU_FEATURE_GET_CONFIG_DATA was not provided in
42 RegisterCpuFeature().
43
44 @retval TRUE VMX feature is supported.
45 @retval FALSE VMX feature is not supported.
46
47 @note This service could be called by BSP/APs.
48 **/
49 BOOLEAN
50 EFIAPI
51 VmxSupport (
52 IN UINTN ProcessorNumber,
53 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,
54 IN VOID *ConfigData OPTIONAL
55 )
56 {
57 MSR_IA32_FEATURE_CONTROL_REGISTER *MsrRegister;
58
59 ASSERT (ConfigData != NULL);
60 MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;
61 MsrRegister[ProcessorNumber].Uint64 = AsmReadMsr64 (MSR_IA32_FEATURE_CONTROL);
62 return (CpuInfo->CpuIdVersionInfoEcx.Bits.VMX == 1);
63 }
64
65 /**
66 Initializes VMX feature to specific state.
67
68 @param[in] ProcessorNumber The index of the CPU executing this function.
69 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION
70 structure for the CPU executing this function.
71 @param[in] ConfigData A pointer to the configuration buffer returned
72 by CPU_FEATURE_GET_CONFIG_DATA. NULL if
73 CPU_FEATURE_GET_CONFIG_DATA was not provided in
74 RegisterCpuFeature().
75 @param[in] State If TRUE, then the VMX feature must be enabled.
76 If FALSE, then the VMX feature must be disabled.
77
78 @retval RETURN_SUCCESS VMX feature is initialized.
79
80 @note This service could be called by BSP only.
81 **/
82 RETURN_STATUS
83 EFIAPI
84 VmxInitialize (
85 IN UINTN ProcessorNumber,
86 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,
87 IN VOID *ConfigData, OPTIONAL
88 IN BOOLEAN State
89 )
90 {
91 MSR_IA32_FEATURE_CONTROL_REGISTER *MsrRegister;
92
93 //
94 // The scope of EnableVmxOutsideSmx bit in the MSR_IA32_FEATURE_CONTROL is core for
95 // below processor type, only program MSR_IA32_FEATURE_CONTROL for thread 0 in each
96 // core.
97 //
98 if (IS_SILVERMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) ||
99 IS_GOLDMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) ||
100 IS_GOLDMONT_PLUS_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) {
101 if (CpuInfo->ProcessorInfo.Location.Thread != 0) {
102 return RETURN_SUCCESS;
103 }
104 }
105
106 ASSERT (ConfigData != NULL);
107 MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;
108 if (MsrRegister[ProcessorNumber].Bits.Lock == 0) {
109 CPU_REGISTER_TABLE_WRITE_FIELD (
110 ProcessorNumber,
111 Msr,
112 MSR_IA32_FEATURE_CONTROL,
113 MSR_IA32_FEATURE_CONTROL_REGISTER,
114 Bits.EnableVmxOutsideSmx,
115 (State) ? 1 : 0
116 );
117 }
118 return RETURN_SUCCESS;
119 }
120
121 /**
122 Detects if Lock Feature Control Register feature supported on current processor.
123
124 @param[in] ProcessorNumber The index of the CPU executing this function.
125 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION
126 structure for the CPU executing this function.
127 @param[in] ConfigData A pointer to the configuration buffer returned
128 by CPU_FEATURE_GET_CONFIG_DATA. NULL if
129 CPU_FEATURE_GET_CONFIG_DATA was not provided in
130 RegisterCpuFeature().
131
132 @retval TRUE Lock Feature Control Register feature is supported.
133 @retval FALSE Lock Feature Control Register feature is not supported.
134
135 @note This service could be called by BSP/APs.
136 **/
137 BOOLEAN
138 EFIAPI
139 LockFeatureControlRegisterSupport (
140 IN UINTN ProcessorNumber,
141 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,
142 IN VOID *ConfigData OPTIONAL
143 )
144 {
145 MSR_IA32_FEATURE_CONTROL_REGISTER *MsrRegister;
146
147 ASSERT (ConfigData != NULL);
148 MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;
149 MsrRegister[ProcessorNumber].Uint64 = AsmReadMsr64 (MSR_IA32_FEATURE_CONTROL);
150 return TRUE;
151 }
152
153 /**
154 Initializes Lock Feature Control Register feature to specific state.
155
156 @param[in] ProcessorNumber The index of the CPU executing this function.
157 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION
158 structure for the CPU executing this function.
159 @param[in] ConfigData A pointer to the configuration buffer returned
160 by CPU_FEATURE_GET_CONFIG_DATA. NULL if
161 CPU_FEATURE_GET_CONFIG_DATA was not provided in
162 RegisterCpuFeature().
163 @param[in] State If TRUE, then the Lock Feature Control Register feature must be enabled.
164 If FALSE, then the Lock Feature Control Register feature must be disabled.
165
166 @retval RETURN_SUCCESS Lock Feature Control Register feature is initialized.
167
168 @note This service could be called by BSP only.
169 **/
170 RETURN_STATUS
171 EFIAPI
172 LockFeatureControlRegisterInitialize (
173 IN UINTN ProcessorNumber,
174 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,
175 IN VOID *ConfigData, OPTIONAL
176 IN BOOLEAN State
177 )
178 {
179 MSR_IA32_FEATURE_CONTROL_REGISTER *MsrRegister;
180
181 //
182 // The scope of Lock bit in the MSR_IA32_FEATURE_CONTROL is core for
183 // below processor type, only program MSR_IA32_FEATURE_CONTROL for thread 0 in each
184 // core.
185 //
186 if (IS_SILVERMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) ||
187 IS_GOLDMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) ||
188 IS_GOLDMONT_PLUS_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) {
189 if (CpuInfo->ProcessorInfo.Location.Thread != 0) {
190 return RETURN_SUCCESS;
191 }
192 }
193
194 ASSERT (ConfigData != NULL);
195 MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;
196 if (MsrRegister[ProcessorNumber].Bits.Lock == 0) {
197 CPU_REGISTER_TABLE_WRITE_FIELD (
198 ProcessorNumber,
199 Msr,
200 MSR_IA32_FEATURE_CONTROL,
201 MSR_IA32_FEATURE_CONTROL_REGISTER,
202 Bits.Lock,
203 1
204 );
205 }
206 return RETURN_SUCCESS;
207 }
208
209 /**
210 Detects if SMX feature supported on current processor.
211
212 @param[in] ProcessorNumber The index of the CPU executing this function.
213 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION
214 structure for the CPU executing this function.
215 @param[in] ConfigData A pointer to the configuration buffer returned
216 by CPU_FEATURE_GET_CONFIG_DATA. NULL if
217 CPU_FEATURE_GET_CONFIG_DATA was not provided in
218 RegisterCpuFeature().
219
220 @retval TRUE SMX feature is supported.
221 @retval FALSE SMX feature is not supported.
222
223 @note This service could be called by BSP/APs.
224 **/
225 BOOLEAN
226 EFIAPI
227 SmxSupport (
228 IN UINTN ProcessorNumber,
229 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,
230 IN VOID *ConfigData OPTIONAL
231 )
232 {
233 MSR_IA32_FEATURE_CONTROL_REGISTER *MsrRegister;
234
235 ASSERT (ConfigData != NULL);
236 MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;
237 MsrRegister[ProcessorNumber].Uint64 = AsmReadMsr64 (MSR_IA32_FEATURE_CONTROL);
238 return (CpuInfo->CpuIdVersionInfoEcx.Bits.SMX == 1);
239 }
240
241 /**
242 Initializes SMX feature to specific state.
243
244 @param[in] ProcessorNumber The index of the CPU executing this function.
245 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION
246 structure for the CPU executing this function.
247 @param[in] ConfigData A pointer to the configuration buffer returned
248 by CPU_FEATURE_GET_CONFIG_DATA. NULL if
249 CPU_FEATURE_GET_CONFIG_DATA was not provided in
250 RegisterCpuFeature().
251 @param[in] State If TRUE, then SMX feature must be enabled.
252 If FALSE, then SMX feature must be disabled.
253
254 @retval RETURN_SUCCESS SMX feature is initialized.
255 @retval RETURN_UNSUPPORTED VMX not initialized.
256
257 @note This service could be called by BSP only.
258 **/
259 RETURN_STATUS
260 EFIAPI
261 SmxInitialize (
262 IN UINTN ProcessorNumber,
263 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,
264 IN VOID *ConfigData, OPTIONAL
265 IN BOOLEAN State
266 )
267 {
268 MSR_IA32_FEATURE_CONTROL_REGISTER *MsrRegister;
269 RETURN_STATUS Status;
270
271 //
272 // The scope of Lock bit in the MSR_IA32_FEATURE_CONTROL is core for
273 // below processor type, only program MSR_IA32_FEATURE_CONTROL for thread 0 in each
274 // core.
275 //
276 if (IS_GOLDMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) ||
277 IS_GOLDMONT_PLUS_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) {
278 if (CpuInfo->ProcessorInfo.Location.Thread != 0) {
279 return RETURN_SUCCESS;
280 }
281 }
282
283 Status = RETURN_SUCCESS;
284
285 if (State && (!IsCpuFeatureInSetting (CPU_FEATURE_VMX))) {
286 DEBUG ((DEBUG_WARN, "Warning :: Can't enable SMX feature when VMX feature not enabled, disable it.\n"));
287 State = FALSE;
288 Status = RETURN_UNSUPPORTED;
289 }
290
291 ASSERT (ConfigData != NULL);
292 MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;
293 if (MsrRegister[ProcessorNumber].Bits.Lock == 0) {
294 CPU_REGISTER_TABLE_WRITE_FIELD (
295 ProcessorNumber,
296 Msr,
297 MSR_IA32_FEATURE_CONTROL,
298 MSR_IA32_FEATURE_CONTROL_REGISTER,
299 Bits.SenterLocalFunctionEnables,
300 (State) ? 0x7F : 0
301 );
302
303 CPU_REGISTER_TABLE_WRITE_FIELD (
304 ProcessorNumber,
305 Msr,
306 MSR_IA32_FEATURE_CONTROL,
307 MSR_IA32_FEATURE_CONTROL_REGISTER,
308 Bits.SenterGlobalEnable,
309 (State) ? 1 : 0
310 );
311
312 CPU_REGISTER_TABLE_WRITE_FIELD (
313 ProcessorNumber,
314 Msr,
315 MSR_IA32_FEATURE_CONTROL,
316 MSR_IA32_FEATURE_CONTROL_REGISTER,
317 Bits.EnableVmxInsideSmx,
318 (State) ? 1 : 0
319 );
320 }
321 return Status;
322 }