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