]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/Library/CpuCommonFeaturesLib/MachineCheck.c
UefiCpuPkg CpuCommFeaturesLib: Fix ASSERT if LMCE is supported
[mirror_edk2.git] / UefiCpuPkg / Library / CpuCommonFeaturesLib / MachineCheck.c
1 /** @file
2 Machine Check features.
3
4 Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "CpuCommonFeatures.h"
10
11 /**
12 Detects if Machine Check Exception feature supported on current processor.
13
14 @param[in] ProcessorNumber The index of the CPU executing this function.
15 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION
16 structure for the CPU executing this function.
17 @param[in] ConfigData A pointer to the configuration buffer returned
18 by CPU_FEATURE_GET_CONFIG_DATA. NULL if
19 CPU_FEATURE_GET_CONFIG_DATA was not provided in
20 RegisterCpuFeature().
21
22 @retval TRUE Machine Check Exception feature is supported.
23 @retval FALSE Machine Check Exception feature is not supported.
24
25 @note This service could be called by BSP/APs.
26 **/
27 BOOLEAN
28 EFIAPI
29 MceSupport (
30 IN UINTN ProcessorNumber,
31 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,
32 IN VOID *ConfigData OPTIONAL
33 )
34 {
35 return (CpuInfo->CpuIdVersionInfoEdx.Bits.MCE == 1);
36 }
37
38 /**
39 Initializes Machine Check Exception feature to specific state.
40
41 @param[in] ProcessorNumber The index of the CPU executing this function.
42 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION
43 structure for the CPU executing this function.
44 @param[in] ConfigData A pointer to the configuration buffer returned
45 by CPU_FEATURE_GET_CONFIG_DATA. NULL if
46 CPU_FEATURE_GET_CONFIG_DATA was not provided in
47 RegisterCpuFeature().
48 @param[in] State If TRUE, then the Machine Check Exception feature must be enabled.
49 If FALSE, then the Machine Check Exception feature must be disabled.
50
51 @retval RETURN_SUCCESS Machine Check Exception feature is initialized.
52
53 @note This service could be called by BSP only.
54 **/
55 RETURN_STATUS
56 EFIAPI
57 MceInitialize (
58 IN UINTN ProcessorNumber,
59 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,
60 IN VOID *ConfigData, OPTIONAL
61 IN BOOLEAN State
62 )
63 {
64 //
65 // Set MCE bit in CR4
66 //
67 CPU_REGISTER_TABLE_WRITE_FIELD (
68 ProcessorNumber,
69 ControlRegister,
70 4,
71 IA32_CR4,
72 Bits.MCE,
73 (State) ? 1 : 0
74 );
75 return RETURN_SUCCESS;
76 }
77
78 /**
79 Detects if Machine Check Architecture feature supported on current processor.
80
81 @param[in] ProcessorNumber The index of the CPU executing this function.
82 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION
83 structure for the CPU executing this function.
84 @param[in] ConfigData A pointer to the configuration buffer returned
85 by CPU_FEATURE_GET_CONFIG_DATA. NULL if
86 CPU_FEATURE_GET_CONFIG_DATA was not provided in
87 RegisterCpuFeature().
88
89 @retval TRUE Machine Check Architecture feature is supported.
90 @retval FALSE Machine Check Architecture feature is not supported.
91
92 @note This service could be called by BSP/APs.
93 **/
94 BOOLEAN
95 EFIAPI
96 McaSupport (
97 IN UINTN ProcessorNumber,
98 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,
99 IN VOID *ConfigData OPTIONAL
100 )
101 {
102 if (!MceSupport (ProcessorNumber, CpuInfo, ConfigData)) {
103 return FALSE;
104 }
105 return (CpuInfo->CpuIdVersionInfoEdx.Bits.MCA == 1);
106 }
107
108 /**
109 Initializes Machine Check Architecture feature to specific state.
110
111 @param[in] ProcessorNumber The index of the CPU executing this function.
112 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION
113 structure for the CPU executing this function.
114 @param[in] ConfigData A pointer to the configuration buffer returned
115 by CPU_FEATURE_GET_CONFIG_DATA. NULL if
116 CPU_FEATURE_GET_CONFIG_DATA was not provided in
117 RegisterCpuFeature().
118 @param[in] State If TRUE, then the Machine Check Architecture feature must be enabled.
119 If FALSE, then the Machine Check Architecture feature must be disabled.
120
121 @retval RETURN_SUCCESS Machine Check Architecture feature is initialized.
122
123 @note This service could be called by BSP only.
124 **/
125 RETURN_STATUS
126 EFIAPI
127 McaInitialize (
128 IN UINTN ProcessorNumber,
129 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,
130 IN VOID *ConfigData, OPTIONAL
131 IN BOOLEAN State
132 )
133 {
134 MSR_IA32_MCG_CAP_REGISTER McgCap;
135 UINT32 BankIndex;
136
137 //
138 // The scope of MSR_IA32_MC*_CTL/MSR_IA32_MC*_STATUS is core for below processor type, only program
139 // MSR_IA32_MC*_CTL/MSR_IA32_MC*_STATUS for thread 0 in each core.
140 //
141 if (IS_ATOM_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) ||
142 IS_SILVERMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) ||
143 IS_SANDY_BRIDGE_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) ||
144 IS_SKYLAKE_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) ||
145 IS_XEON_PHI_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) ||
146 IS_PENTIUM_4_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) ||
147 IS_CORE_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) {
148 if (CpuInfo->ProcessorInfo.Location.Thread != 0) {
149 return RETURN_SUCCESS;
150 }
151 }
152
153 //
154 // The scope of MSR_IA32_MC*_CTL/MSR_IA32_MC*_STATUS is package for below processor type, only program
155 // MSR_IA32_MC*_CTL/MSR_IA32_MC*_STATUS for thread 0 core 0 in each package.
156 //
157 if (IS_NEHALEM_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) {
158 if ((CpuInfo->ProcessorInfo.Location.Thread != 0) || (CpuInfo->ProcessorInfo.Location.Core != 0)) {
159 return RETURN_SUCCESS;
160 }
161 }
162
163 if (State) {
164 McgCap.Uint64 = AsmReadMsr64 (MSR_IA32_MCG_CAP);
165 for (BankIndex = 0; BankIndex < (UINT32) McgCap.Bits.Count; BankIndex++) {
166 CPU_REGISTER_TABLE_WRITE64 (
167 ProcessorNumber,
168 Msr,
169 MSR_IA32_MC0_CTL + BankIndex * 4,
170 MAX_UINT64
171 );
172 }
173
174 if (PcdGetBool (PcdIsPowerOnReset)) {
175 for (BankIndex = 0; BankIndex < (UINTN) McgCap.Bits.Count; BankIndex++) {
176 CPU_REGISTER_TABLE_WRITE64 (
177 ProcessorNumber,
178 Msr,
179 MSR_IA32_MC0_STATUS + BankIndex * 4,
180 0
181 );
182 }
183 }
184 }
185
186 return RETURN_SUCCESS;
187 }
188
189 /**
190 Detects if IA32_MCG_CTL feature supported on current processor.
191
192 @param[in] ProcessorNumber The index of the CPU executing this function.
193 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION
194 structure for the CPU executing this function.
195 @param[in] ConfigData A pointer to the configuration buffer returned
196 by CPU_FEATURE_GET_CONFIG_DATA. NULL if
197 CPU_FEATURE_GET_CONFIG_DATA was not provided in
198 RegisterCpuFeature().
199
200 @retval TRUE IA32_MCG_CTL feature is supported.
201 @retval FALSE IA32_MCG_CTL feature is not supported.
202
203 @note This service could be called by BSP/APs.
204 **/
205 BOOLEAN
206 EFIAPI
207 McgCtlSupport (
208 IN UINTN ProcessorNumber,
209 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,
210 IN VOID *ConfigData OPTIONAL
211 )
212 {
213 MSR_IA32_MCG_CAP_REGISTER McgCap;
214
215 if (!McaSupport (ProcessorNumber, CpuInfo, ConfigData)) {
216 return FALSE;
217 }
218 McgCap.Uint64 = AsmReadMsr64 (MSR_IA32_MCG_CAP);
219 return (McgCap.Bits.MCG_CTL_P == 1);
220 }
221
222 /**
223 Initializes IA32_MCG_CTL feature to specific state.
224
225 @param[in] ProcessorNumber The index of the CPU executing this function.
226 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION
227 structure for the CPU executing this function.
228 @param[in] ConfigData A pointer to the configuration buffer returned
229 by CPU_FEATURE_GET_CONFIG_DATA. NULL if
230 CPU_FEATURE_GET_CONFIG_DATA was not provided in
231 RegisterCpuFeature().
232 @param[in] State If TRUE, then the IA32_MCG_CTL feature must be enabled.
233 If FALSE, then the IA32_MCG_CTL feature must be disabled.
234
235 @retval RETURN_SUCCESS IA32_MCG_CTL feature is initialized.
236
237 @note This service could be called by BSP only.
238 **/
239 RETURN_STATUS
240 EFIAPI
241 McgCtlInitialize (
242 IN UINTN ProcessorNumber,
243 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,
244 IN VOID *ConfigData, OPTIONAL
245 IN BOOLEAN State
246 )
247 {
248 CPU_REGISTER_TABLE_WRITE64 (
249 ProcessorNumber,
250 Msr,
251 MSR_IA32_MCG_CTL,
252 (State)? MAX_UINT64 : 0
253 );
254 return RETURN_SUCCESS;
255 }
256
257 /**
258 Detects if Local machine check exception feature supported on current
259 processor.
260
261 @param[in] ProcessorNumber The index of the CPU executing this function.
262 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION
263 structure for the CPU executing this function.
264 @param[in] ConfigData A pointer to the configuration buffer returned
265 by CPU_FEATURE_GET_CONFIG_DATA. NULL if
266 CPU_FEATURE_GET_CONFIG_DATA was not provided in
267 RegisterCpuFeature().
268
269 @retval TRUE Local machine check exception feature is supported.
270 @retval FALSE Local machine check exception feature is not supported.
271
272 @note This service could be called by BSP/APs.
273 **/
274 BOOLEAN
275 EFIAPI
276 LmceSupport (
277 IN UINTN ProcessorNumber,
278 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,
279 IN VOID *ConfigData OPTIONAL
280 )
281 {
282 MSR_IA32_MCG_CAP_REGISTER McgCap;
283
284 if (!McaSupport (ProcessorNumber, CpuInfo, ConfigData)) {
285 return FALSE;
286 }
287
288 McgCap.Uint64 = AsmReadMsr64 (MSR_IA32_MCG_CAP);
289 if (ProcessorNumber == 0) {
290 DEBUG ((EFI_D_INFO, "LMCE eanble = %x\n", (BOOLEAN) (McgCap.Bits.MCG_LMCE_P != 0)));
291 }
292 return (BOOLEAN) (McgCap.Bits.MCG_LMCE_P != 0);
293 }
294
295 /**
296 Initializes Local machine check exception feature to specific state.
297
298 @param[in] ProcessorNumber The index of the CPU executing this function.
299 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION
300 structure for the CPU executing this function.
301 @param[in] ConfigData A pointer to the configuration buffer returned
302 by CPU_FEATURE_GET_CONFIG_DATA. NULL if
303 CPU_FEATURE_GET_CONFIG_DATA was not provided in
304 RegisterCpuFeature().
305 @param[in] State If TRUE, then the Local machine check exception
306 feature must be enabled.
307 If FALSE, then the Local machine check exception
308 feature must be disabled.
309
310 @retval RETURN_SUCCESS Local machine check exception feature is initialized.
311
312 **/
313 RETURN_STATUS
314 EFIAPI
315 LmceInitialize (
316 IN UINTN ProcessorNumber,
317 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,
318 IN VOID *ConfigData, OPTIONAL
319 IN BOOLEAN State
320 )
321 {
322 MSR_IA32_FEATURE_CONTROL_REGISTER *MsrRegister;
323
324 //
325 // The scope of LcmeOn bit in the MSR_IA32_MISC_ENABLE is core for below processor type, only program
326 // MSR_IA32_MISC_ENABLE for thread 0 in each core.
327 //
328 if (IS_SILVERMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) ||
329 IS_GOLDMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) ||
330 IS_PENTIUM_4_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) {
331 if (CpuInfo->ProcessorInfo.Location.Thread != 0) {
332 return RETURN_SUCCESS;
333 }
334 }
335
336 ASSERT (ConfigData != NULL);
337 MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;
338 if (MsrRegister[ProcessorNumber].Bits.Lock == 0) {
339 CPU_REGISTER_TABLE_WRITE_FIELD (
340 ProcessorNumber,
341 Msr,
342 MSR_IA32_FEATURE_CONTROL,
343 MSR_IA32_FEATURE_CONTROL_REGISTER,
344 Bits.LmceOn,
345 (State) ? 1 : 0
346 );
347 }
348 return RETURN_SUCCESS;
349 }