UefiCpuPkg/FeaturesLib: don't init MCi_CTL/STATUS when MCA's disabled
[mirror_edk2.git] / UefiCpuPkg / Library / CpuCommonFeaturesLib / MachineCheck.c
CommitLineData
80c4b236
JF
1/** @file\r
2 Machine Check features.\r
3\r
dc7363f8 4 Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>\r
80c4b236
JF
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 Detects if Machine Check Exception feature supported on current processor.\r
19\r
20 @param[in] ProcessorNumber The index of the CPU executing this function.\r
21 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION\r
22 structure for the CPU executing this function.\r
23 @param[in] ConfigData A pointer to the configuration buffer returned\r
24 by CPU_FEATURE_GET_CONFIG_DATA. NULL if\r
25 CPU_FEATURE_GET_CONFIG_DATA was not provided in\r
26 RegisterCpuFeature().\r
27\r
28 @retval TRUE Machine Check Exception feature is supported.\r
29 @retval FALSE Machine Check Exception feature is not supported.\r
30\r
31 @note This service could be called by BSP/APs.\r
32**/\r
33BOOLEAN\r
34EFIAPI\r
35MceSupport (\r
36 IN UINTN ProcessorNumber,\r
37 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,\r
38 IN VOID *ConfigData OPTIONAL\r
39 )\r
40{\r
41 return (CpuInfo->CpuIdVersionInfoEdx.Bits.MCE == 1);\r
42}\r
43\r
44/**\r
45 Initializes Machine Check Exception feature to specific state.\r
46\r
47 @param[in] ProcessorNumber The index of the CPU executing this function.\r
48 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION\r
49 structure for the CPU executing this function.\r
50 @param[in] ConfigData A pointer to the configuration buffer returned\r
51 by CPU_FEATURE_GET_CONFIG_DATA. NULL if\r
52 CPU_FEATURE_GET_CONFIG_DATA was not provided in\r
53 RegisterCpuFeature().\r
54 @param[in] State If TRUE, then the Machine Check Exception feature must be enabled.\r
55 If FALSE, then the Machine Check Exception feature must be disabled.\r
56\r
57 @retval RETURN_SUCCESS Machine Check Exception feature is initialized.\r
58\r
59 @note This service could be called by BSP only.\r
60**/\r
61RETURN_STATUS\r
62EFIAPI\r
63MceInitialize (\r
64 IN UINTN ProcessorNumber,\r
65 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,\r
66 IN VOID *ConfigData, OPTIONAL\r
67 IN BOOLEAN State\r
68 )\r
69{\r
70 //\r
71 // Set MCE bit in CR4\r
72 //\r
73 CPU_REGISTER_TABLE_WRITE_FIELD (\r
74 ProcessorNumber,\r
75 ControlRegister,\r
76 4,\r
77 IA32_CR4,\r
78 Bits.MCE,\r
79 (State) ? 1 : 0\r
80 );\r
81 return RETURN_SUCCESS;\r
82}\r
83\r
84/**\r
85 Detects if Machine Check Architecture feature supported on current processor.\r
86\r
87 @param[in] ProcessorNumber The index of the CPU executing this function.\r
88 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION\r
89 structure for the CPU executing this function.\r
90 @param[in] ConfigData A pointer to the configuration buffer returned\r
91 by CPU_FEATURE_GET_CONFIG_DATA. NULL if\r
92 CPU_FEATURE_GET_CONFIG_DATA was not provided in\r
93 RegisterCpuFeature().\r
94\r
95 @retval TRUE Machine Check Architecture feature is supported.\r
96 @retval FALSE Machine Check Architecture feature is not supported.\r
97\r
98 @note This service could be called by BSP/APs.\r
99**/\r
100BOOLEAN\r
101EFIAPI\r
102McaSupport (\r
103 IN UINTN ProcessorNumber,\r
104 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,\r
105 IN VOID *ConfigData OPTIONAL\r
106 )\r
107{\r
57d1afc8
SB
108 if (!MceSupport (ProcessorNumber, CpuInfo, ConfigData)) {\r
109 return FALSE;\r
110 }\r
80c4b236
JF
111 return (CpuInfo->CpuIdVersionInfoEdx.Bits.MCA == 1);\r
112}\r
113\r
114/**\r
115 Initializes Machine Check Architecture feature to specific state.\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 @param[in] State If TRUE, then the Machine Check Architecture feature must be enabled.\r
125 If FALSE, then the Machine Check Architecture feature must be disabled.\r
126\r
127 @retval RETURN_SUCCESS Machine Check Architecture feature is initialized.\r
128\r
129 @note This service could be called by BSP only.\r
130**/\r
131RETURN_STATUS\r
132EFIAPI\r
133McaInitialize (\r
134 IN UINTN ProcessorNumber,\r
135 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,\r
136 IN VOID *ConfigData, OPTIONAL\r
137 IN BOOLEAN State\r
138 )\r
139{\r
140 MSR_IA32_MCG_CAP_REGISTER McgCap;\r
141 UINT32 BankIndex;\r
142\r
dc7363f8
RN
143 if (State == TRUE) {\r
144 McgCap.Uint64 = AsmReadMsr64 (MSR_IA32_MCG_CAP);\r
145 for (BankIndex = 0; BankIndex < (UINT32) McgCap.Bits.Count; BankIndex++) {\r
80c4b236
JF
146 CPU_REGISTER_TABLE_WRITE64 (\r
147 ProcessorNumber,\r
148 Msr,\r
dc7363f8
RN
149 MSR_IA32_MC0_CTL + BankIndex * 4,\r
150 MAX_UINT64\r
80c4b236
JF
151 );\r
152 }\r
dc7363f8
RN
153\r
154 if (PcdGetBool (PcdIsPowerOnReset)) {\r
155 for (BankIndex = 0; BankIndex < (UINTN) McgCap.Bits.Count; BankIndex++) {\r
156 CPU_REGISTER_TABLE_WRITE64 (\r
157 ProcessorNumber,\r
158 Msr,\r
159 MSR_IA32_MC0_STATUS + BankIndex * 4,\r
160 0\r
161 );\r
162 }\r
163 }\r
80c4b236
JF
164 }\r
165\r
166 return RETURN_SUCCESS;\r
167}\r
168\r
169/**\r
170 Detects if IA32_MCG_CTL feature supported on current processor.\r
171\r
172 @param[in] ProcessorNumber The index of the CPU executing this function.\r
173 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION\r
174 structure for the CPU executing this function.\r
175 @param[in] ConfigData A pointer to the configuration buffer returned\r
176 by CPU_FEATURE_GET_CONFIG_DATA. NULL if\r
177 CPU_FEATURE_GET_CONFIG_DATA was not provided in\r
178 RegisterCpuFeature().\r
179\r
180 @retval TRUE IA32_MCG_CTL feature is supported.\r
181 @retval FALSE IA32_MCG_CTL feature is not supported.\r
182\r
183 @note This service could be called by BSP/APs.\r
184**/\r
185BOOLEAN\r
186EFIAPI\r
187McgCtlSupport (\r
188 IN UINTN ProcessorNumber,\r
189 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,\r
190 IN VOID *ConfigData OPTIONAL\r
191 )\r
192{\r
193 MSR_IA32_MCG_CAP_REGISTER McgCap;\r
194\r
195 if (!McaSupport (ProcessorNumber, CpuInfo, ConfigData)) {\r
196 return FALSE;\r
197 }\r
198 McgCap.Uint64 = AsmReadMsr64 (MSR_IA32_MCG_CAP);\r
199 return (McgCap.Bits.MCG_CTL_P == 1);\r
200}\r
201\r
202/**\r
203 Initializes IA32_MCG_CTL feature to specific state.\r
204\r
205 @param[in] ProcessorNumber The index of the CPU executing this function.\r
206 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION\r
207 structure for the CPU executing this function.\r
208 @param[in] ConfigData A pointer to the configuration buffer returned\r
209 by CPU_FEATURE_GET_CONFIG_DATA. NULL if\r
210 CPU_FEATURE_GET_CONFIG_DATA was not provided in\r
211 RegisterCpuFeature().\r
212 @param[in] State If TRUE, then the IA32_MCG_CTL feature must be enabled.\r
213 If FALSE, then the IA32_MCG_CTL feature must be disabled.\r
214\r
215 @retval RETURN_SUCCESS IA32_MCG_CTL feature is initialized.\r
216\r
217 @note This service could be called by BSP only.\r
218**/\r
219RETURN_STATUS\r
220EFIAPI\r
221McgCtlInitialize (\r
222 IN UINTN ProcessorNumber,\r
223 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,\r
224 IN VOID *ConfigData, OPTIONAL\r
225 IN BOOLEAN State\r
226 )\r
227{\r
228 CPU_REGISTER_TABLE_WRITE64 (\r
229 ProcessorNumber,\r
230 Msr,\r
231 MSR_IA32_MCG_CTL,\r
232 (State)? MAX_UINT64 : 0\r
233 );\r
234 return RETURN_SUCCESS;\r
235}\r
236\r
306a5bcc
ED
237/**\r
238 Detects if Local machine check exception feature supported on current \r
239 processor.\r
240\r
241 @param[in] ProcessorNumber The index of the CPU executing this function.\r
242 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION\r
243 structure for the CPU executing this function.\r
244 @param[in] ConfigData A pointer to the configuration buffer returned\r
245 by CPU_FEATURE_GET_CONFIG_DATA. NULL if\r
246 CPU_FEATURE_GET_CONFIG_DATA was not provided in\r
247 RegisterCpuFeature().\r
248\r
249 @retval TRUE Local machine check exception feature is supported.\r
250 @retval FALSE Local machine check exception feature is not supported.\r
251\r
252 @note This service could be called by BSP/APs.\r
253**/\r
254BOOLEAN\r
255EFIAPI\r
256LmceSupport (\r
257 IN UINTN ProcessorNumber,\r
258 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,\r
259 IN VOID *ConfigData OPTIONAL\r
260 )\r
261{\r
262 MSR_IA32_MCG_CAP_REGISTER McgCap;\r
263\r
264 if (!McaSupport (ProcessorNumber, CpuInfo, ConfigData)) {\r
265 return FALSE;\r
266 }\r
267\r
268 McgCap.Uint64 = AsmReadMsr64 (MSR_IA32_MCG_CAP);\r
269 if (ProcessorNumber == 0) {\r
270 DEBUG ((EFI_D_INFO, "LMCE eanble = %x\n", (BOOLEAN) (McgCap.Bits.MCG_LMCE_P != 0)));\r
271 }\r
272 return (BOOLEAN) (McgCap.Bits.MCG_LMCE_P != 0);\r
273}\r
274\r
275/**\r
276 Initializes Local machine check exception feature to specific state.\r
277\r
278 @param[in] ProcessorNumber The index of the CPU executing this function.\r
279 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION\r
280 structure for the CPU executing this function.\r
281 @param[in] ConfigData A pointer to the configuration buffer returned\r
282 by CPU_FEATURE_GET_CONFIG_DATA. NULL if\r
283 CPU_FEATURE_GET_CONFIG_DATA was not provided in\r
284 RegisterCpuFeature().\r
285 @param[in] State If TRUE, then the Local machine check exception\r
286 feature must be enabled.\r
287 If FALSE, then the Local machine check exception\r
288 feature must be disabled.\r
289\r
290 @retval RETURN_SUCCESS Local machine check exception feature is initialized.\r
291\r
292**/\r
293RETURN_STATUS\r
294EFIAPI\r
295LmceInitialize (\r
296 IN UINTN ProcessorNumber,\r
297 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,\r
298 IN VOID *ConfigData, OPTIONAL\r
299 IN BOOLEAN State\r
300 )\r
301{\r
302 MSR_IA32_FEATURE_CONTROL_REGISTER *MsrRegister;\r
303\r
304 ASSERT (ConfigData != NULL);\r
305 MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;\r
306 if (MsrRegister[ProcessorNumber].Bits.Lock == 0) {\r
307 CPU_REGISTER_TABLE_WRITE_FIELD (\r
308 ProcessorNumber,\r
309 Msr,\r
310 MSR_IA32_FEATURE_CONTROL,\r
311 MSR_IA32_FEATURE_CONTROL_REGISTER,\r
312 Bits.LmceOn,\r
313 (State) ? 1 : 0\r
314 );\r
315 }\r
316 return RETURN_SUCCESS;\r
317}\r