]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/Library/CpuCommonFeaturesLib/FeatureControl.c
UefiCpuPkg: Enhance feature dependency check
[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
99 ASSERT (ConfigData != NULL);\r
100 MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;\r
101 if (MsrRegister[ProcessorNumber].Bits.Lock == 0) {\r
102 CPU_REGISTER_TABLE_WRITE_FIELD (\r
103 ProcessorNumber,\r
104 Msr,\r
105 MSR_IA32_FEATURE_CONTROL,\r
106 MSR_IA32_FEATURE_CONTROL_REGISTER,\r
b1fe2029 107 Bits.EnableVmxOutsideSmx,\r
80c4b236
JF
108 (State) ? 1 : 0\r
109 );\r
110 }\r
111 return RETURN_SUCCESS;\r
112}\r
113\r
114/**\r
115 Detects if Lock Feature Control Register feature supported on current processor.\r
116\r
117 @param[in] ProcessorNumber The index of the CPU executing this function.\r
118 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION\r
119 structure for the CPU executing this function.\r
120 @param[in] ConfigData A pointer to the configuration buffer returned\r
121 by CPU_FEATURE_GET_CONFIG_DATA. NULL if\r
122 CPU_FEATURE_GET_CONFIG_DATA was not provided in\r
123 RegisterCpuFeature().\r
124\r
125 @retval TRUE Lock Feature Control Register feature is supported.\r
126 @retval FALSE Lock Feature Control Register feature is not supported.\r
127\r
128 @note This service could be called by BSP/APs.\r
129**/\r
130BOOLEAN\r
131EFIAPI\r
132LockFeatureControlRegisterSupport (\r
133 IN UINTN ProcessorNumber,\r
134 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,\r
135 IN VOID *ConfigData OPTIONAL\r
136 )\r
137{\r
138 MSR_IA32_FEATURE_CONTROL_REGISTER *MsrRegister;\r
139\r
140 ASSERT (ConfigData != NULL);\r
141 MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;\r
142 MsrRegister[ProcessorNumber].Uint64 = AsmReadMsr64 (MSR_IA32_FEATURE_CONTROL);\r
143 return TRUE;\r
144}\r
145\r
146/**\r
147 Initializes Lock Feature Control Register feature to specific state.\r
148\r
149 @param[in] ProcessorNumber The index of the CPU executing this function.\r
150 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION\r
151 structure for the CPU executing this function.\r
152 @param[in] ConfigData A pointer to the configuration buffer returned\r
153 by CPU_FEATURE_GET_CONFIG_DATA. NULL if\r
154 CPU_FEATURE_GET_CONFIG_DATA was not provided in\r
155 RegisterCpuFeature().\r
156 @param[in] State If TRUE, then the Lock Feature Control Register feature must be enabled.\r
157 If FALSE, then the Lock Feature Control Register feature must be disabled.\r
158\r
159 @retval RETURN_SUCCESS Lock Feature Control Register feature is initialized.\r
160\r
161 @note This service could be called by BSP only.\r
162**/\r
163RETURN_STATUS\r
164EFIAPI\r
165LockFeatureControlRegisterInitialize (\r
166 IN UINTN ProcessorNumber,\r
167 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,\r
168 IN VOID *ConfigData, OPTIONAL\r
169 IN BOOLEAN State\r
170 )\r
171{\r
172 MSR_IA32_FEATURE_CONTROL_REGISTER *MsrRegister;\r
173\r
174 ASSERT (ConfigData != NULL);\r
175 MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;\r
176 if (MsrRegister[ProcessorNumber].Bits.Lock == 0) {\r
177 CPU_REGISTER_TABLE_WRITE_FIELD (\r
178 ProcessorNumber,\r
179 Msr,\r
180 MSR_IA32_FEATURE_CONTROL,\r
181 MSR_IA32_FEATURE_CONTROL_REGISTER,\r
182 Bits.Lock,\r
183 1\r
184 );\r
185 }\r
186 return RETURN_SUCCESS;\r
187}\r
188\r
189/**\r
190 Detects if SMX feature supported on current processor.\r
191\r
192 @param[in] ProcessorNumber The index of the CPU executing this function.\r
193 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION\r
194 structure for the CPU executing this function.\r
195 @param[in] ConfigData A pointer to the configuration buffer returned\r
196 by CPU_FEATURE_GET_CONFIG_DATA. NULL if\r
197 CPU_FEATURE_GET_CONFIG_DATA was not provided in\r
198 RegisterCpuFeature().\r
199\r
200 @retval TRUE SMX feature is supported.\r
201 @retval FALSE SMX feature is not supported.\r
202\r
203 @note This service could be called by BSP/APs.\r
204**/\r
205BOOLEAN\r
206EFIAPI\r
207SmxSupport (\r
208 IN UINTN ProcessorNumber,\r
209 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,\r
210 IN VOID *ConfigData OPTIONAL\r
211 )\r
212{\r
213 MSR_IA32_FEATURE_CONTROL_REGISTER *MsrRegister;\r
214\r
215 ASSERT (ConfigData != NULL);\r
216 MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;\r
217 MsrRegister[ProcessorNumber].Uint64 = AsmReadMsr64 (MSR_IA32_FEATURE_CONTROL);\r
218 return (CpuInfo->CpuIdVersionInfoEcx.Bits.SMX == 1);\r
219}\r
220\r
221/**\r
b1fe2029 222 Initializes SMX feature to specific state.\r
80c4b236
JF
223\r
224 @param[in] ProcessorNumber The index of the CPU executing this function.\r
225 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION\r
226 structure for the CPU executing this function.\r
227 @param[in] ConfigData A pointer to the configuration buffer returned\r
228 by CPU_FEATURE_GET_CONFIG_DATA. NULL if\r
229 CPU_FEATURE_GET_CONFIG_DATA was not provided in\r
230 RegisterCpuFeature().\r
b1fe2029
ED
231 @param[in] State If TRUE, then SMX feature must be enabled.\r
232 If FALSE, then SMX feature must be disabled.\r
80c4b236 233\r
b1fe2029
ED
234 @retval RETURN_SUCCESS SMX feature is initialized.\r
235 @retval RETURN_UNSUPPORTED VMX not initialized.\r
80c4b236
JF
236\r
237 @note This service could be called by BSP only.\r
238**/\r
239RETURN_STATUS\r
240EFIAPI\r
b1fe2029 241SmxInitialize (\r
80c4b236
JF
242 IN UINTN ProcessorNumber,\r
243 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,\r
244 IN VOID *ConfigData, OPTIONAL\r
245 IN BOOLEAN State\r
246 )\r
247{\r
248 MSR_IA32_FEATURE_CONTROL_REGISTER *MsrRegister;\r
b1fe2029
ED
249 RETURN_STATUS Status;\r
250\r
251 Status = RETURN_SUCCESS;\r
252\r
253 if (State && (!IsCpuFeatureInSetting (CPU_FEATURE_VMX))) {\r
254 DEBUG ((DEBUG_WARN, "Warning :: Can't enable SMX feature when VMX feature not enabled, disable it.\n"));\r
255 State = FALSE;\r
256 Status = RETURN_UNSUPPORTED;\r
257 }\r
80c4b236
JF
258\r
259 ASSERT (ConfigData != NULL);\r
260 MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;\r
261 if (MsrRegister[ProcessorNumber].Bits.Lock == 0) {\r
262 CPU_REGISTER_TABLE_WRITE_FIELD (\r
263 ProcessorNumber,\r
264 Msr,\r
265 MSR_IA32_FEATURE_CONTROL,\r
266 MSR_IA32_FEATURE_CONTROL_REGISTER,\r
b1fe2029
ED
267 Bits.SenterLocalFunctionEnables,\r
268 (State) ? 0x7F : 0\r
269 );\r
270\r
271 CPU_REGISTER_TABLE_WRITE_FIELD (\r
272 ProcessorNumber,\r
273 Msr,\r
274 MSR_IA32_FEATURE_CONTROL,\r
275 MSR_IA32_FEATURE_CONTROL_REGISTER,\r
276 Bits.SenterGlobalEnable,\r
277 (State) ? 1 : 0\r
278 );\r
279\r
280 CPU_REGISTER_TABLE_WRITE_FIELD (\r
281 ProcessorNumber,\r
282 Msr,\r
283 MSR_IA32_FEATURE_CONTROL,\r
284 MSR_IA32_FEATURE_CONTROL_REGISTER,\r
285 Bits.EnableVmxInsideSmx,\r
80c4b236
JF
286 (State) ? 1 : 0\r
287 );\r
288 }\r
b1fe2029 289 return Status;\r
80c4b236 290}\r