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