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