2 * UEFI Common Platform Error Record (CPER) support
4 * Copyright (C) 2017, The Linux Foundation. All rights reserved.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include <linux/kernel.h>
21 #include <linux/module.h>
22 #include <linux/time.h>
23 #include <linux/cper.h>
24 #include <linux/dmi.h>
25 #include <linux/acpi.h>
26 #include <linux/pci.h>
27 #include <linux/aer.h>
28 #include <linux/printk.h>
29 #include <linux/bcd.h>
30 #include <acpi/ghes.h>
31 #include <ras/ras_event.h>
33 static const char * const arm_reg_ctx_strs
[] = {
34 "AArch32 general purpose registers",
35 "AArch32 EL1 context registers",
36 "AArch32 EL2 context registers",
37 "AArch32 secure context registers",
38 "AArch64 general purpose registers",
39 "AArch64 EL1 context registers",
40 "AArch64 EL2 context registers",
41 "AArch64 EL3 context registers",
42 "Misc. system register structure",
45 static const char * const arm_err_trans_type_strs
[] = {
51 static const char * const arm_bus_err_op_strs
[] = {
52 "Generic error (type cannot be determined)",
53 "Generic read (type of instruction or data request cannot be determined)",
54 "Generic write (type of instruction of data request cannot be determined)",
61 static const char * const arm_cache_err_op_strs
[] = {
62 "Generic error (type cannot be determined)",
63 "Generic read (type of instruction or data request cannot be determined)",
64 "Generic write (type of instruction of data request cannot be determined)",
70 "Snooping (processor initiated a cache snoop that resulted in an error)",
71 "Snooped (processor raised a cache error caused by another processor or device snooping its cache)",
75 static const char * const arm_tlb_err_op_strs
[] = {
76 "Generic error (type cannot be determined)",
77 "Generic read (type of instruction or data request cannot be determined)",
78 "Generic write (type of instruction of data request cannot be determined)",
83 "Local management operation (processor initiated a TLB management operation that resulted in an error)",
84 "External management operation (processor raised a TLB error caused by another processor or device broadcasting TLB operations)",
87 static const char * const arm_bus_err_part_type_strs
[] = {
88 "Local processor originated request",
89 "Local processor responded to request",
90 "Local processor observed",
94 static const char * const arm_bus_err_addr_space_strs
[] = {
95 "External Memory Access",
96 "Internal Memory Access",
98 "Device Memory Access",
101 static void cper_print_arm_err_info(const char *pfx
, u32 type
,
104 u8 trans_type
, op_type
, level
, participation_type
, address_space
;
106 bool proc_context_corrupt
, corrected
, precise_pc
, restartable_pc
;
107 bool time_out
, access_mode
;
109 /* If the type is unknown, bail. */
110 if (type
> CPER_ARM_MAX_TYPE
)
114 * Vendor type errors have error information values that are vendor
117 if (type
== CPER_ARM_VENDOR_ERROR
)
120 if (error_info
& CPER_ARM_ERR_VALID_TRANSACTION_TYPE
) {
121 trans_type
= ((error_info
>> CPER_ARM_ERR_TRANSACTION_SHIFT
)
122 & CPER_ARM_ERR_TRANSACTION_MASK
);
123 if (trans_type
< ARRAY_SIZE(arm_err_trans_type_strs
)) {
124 printk("%stransaction type: %s\n", pfx
,
125 arm_err_trans_type_strs
[trans_type
]);
129 if (error_info
& CPER_ARM_ERR_VALID_OPERATION_TYPE
) {
130 op_type
= ((error_info
>> CPER_ARM_ERR_OPERATION_SHIFT
)
131 & CPER_ARM_ERR_OPERATION_MASK
);
133 case CPER_ARM_CACHE_ERROR
:
134 if (op_type
< ARRAY_SIZE(arm_cache_err_op_strs
)) {
135 printk("%soperation type: %s\n", pfx
,
136 arm_cache_err_op_strs
[op_type
]);
139 case CPER_ARM_TLB_ERROR
:
140 if (op_type
< ARRAY_SIZE(arm_tlb_err_op_strs
)) {
141 printk("%soperation type: %s\n", pfx
,
142 arm_tlb_err_op_strs
[op_type
]);
145 case CPER_ARM_BUS_ERROR
:
146 if (op_type
< ARRAY_SIZE(arm_bus_err_op_strs
)) {
147 printk("%soperation type: %s\n", pfx
,
148 arm_bus_err_op_strs
[op_type
]);
154 if (error_info
& CPER_ARM_ERR_VALID_LEVEL
) {
155 level
= ((error_info
>> CPER_ARM_ERR_LEVEL_SHIFT
)
156 & CPER_ARM_ERR_LEVEL_MASK
);
158 case CPER_ARM_CACHE_ERROR
:
159 printk("%scache level: %d\n", pfx
, level
);
161 case CPER_ARM_TLB_ERROR
:
162 printk("%sTLB level: %d\n", pfx
, level
);
164 case CPER_ARM_BUS_ERROR
:
165 printk("%saffinity level at which the bus error occurred: %d\n",
171 if (error_info
& CPER_ARM_ERR_VALID_PROC_CONTEXT_CORRUPT
) {
172 proc_context_corrupt
= ((error_info
>> CPER_ARM_ERR_PC_CORRUPT_SHIFT
)
173 & CPER_ARM_ERR_PC_CORRUPT_MASK
);
174 if (proc_context_corrupt
)
175 printk("%sprocessor context corrupted\n", pfx
);
177 printk("%sprocessor context not corrupted\n", pfx
);
180 if (error_info
& CPER_ARM_ERR_VALID_CORRECTED
) {
181 corrected
= ((error_info
>> CPER_ARM_ERR_CORRECTED_SHIFT
)
182 & CPER_ARM_ERR_CORRECTED_MASK
);
184 printk("%sthe error has been corrected\n", pfx
);
186 printk("%sthe error has not been corrected\n", pfx
);
189 if (error_info
& CPER_ARM_ERR_VALID_PRECISE_PC
) {
190 precise_pc
= ((error_info
>> CPER_ARM_ERR_PRECISE_PC_SHIFT
)
191 & CPER_ARM_ERR_PRECISE_PC_MASK
);
193 printk("%sPC is precise\n", pfx
);
195 printk("%sPC is imprecise\n", pfx
);
198 if (error_info
& CPER_ARM_ERR_VALID_RESTARTABLE_PC
) {
199 restartable_pc
= ((error_info
>> CPER_ARM_ERR_RESTARTABLE_PC_SHIFT
)
200 & CPER_ARM_ERR_RESTARTABLE_PC_MASK
);
202 printk("%sProgram execution can be restarted reliably at the PC associated with the error.\n", pfx
);
205 /* The rest of the fields are specific to bus errors */
206 if (type
!= CPER_ARM_BUS_ERROR
)
209 if (error_info
& CPER_ARM_ERR_VALID_PARTICIPATION_TYPE
) {
210 participation_type
= ((error_info
>> CPER_ARM_ERR_PARTICIPATION_TYPE_SHIFT
)
211 & CPER_ARM_ERR_PARTICIPATION_TYPE_MASK
);
212 if (participation_type
< ARRAY_SIZE(arm_bus_err_part_type_strs
)) {
213 printk("%sparticipation type: %s\n", pfx
,
214 arm_bus_err_part_type_strs
[participation_type
]);
218 if (error_info
& CPER_ARM_ERR_VALID_TIME_OUT
) {
219 time_out
= ((error_info
>> CPER_ARM_ERR_TIME_OUT_SHIFT
)
220 & CPER_ARM_ERR_TIME_OUT_MASK
);
222 printk("%srequest timed out\n", pfx
);
225 if (error_info
& CPER_ARM_ERR_VALID_ADDRESS_SPACE
) {
226 address_space
= ((error_info
>> CPER_ARM_ERR_ADDRESS_SPACE_SHIFT
)
227 & CPER_ARM_ERR_ADDRESS_SPACE_MASK
);
228 if (address_space
< ARRAY_SIZE(arm_bus_err_addr_space_strs
)) {
229 printk("%saddress space: %s\n", pfx
,
230 arm_bus_err_addr_space_strs
[address_space
]);
234 if (error_info
& CPER_ARM_ERR_VALID_MEM_ATTRIBUTES
) {
235 mem_attributes
= ((error_info
>> CPER_ARM_ERR_MEM_ATTRIBUTES_SHIFT
)
236 & CPER_ARM_ERR_MEM_ATTRIBUTES_MASK
);
237 printk("%smemory access attributes:0x%x\n", pfx
, mem_attributes
);
240 if (error_info
& CPER_ARM_ERR_VALID_ACCESS_MODE
) {
241 access_mode
= ((error_info
>> CPER_ARM_ERR_ACCESS_MODE_SHIFT
)
242 & CPER_ARM_ERR_ACCESS_MODE_MASK
);
244 printk("%saccess mode: normal\n", pfx
);
246 printk("%saccess mode: secure\n", pfx
);
250 void cper_print_proc_arm(const char *pfx
,
251 const struct cper_sec_proc_arm
*proc
)
253 int i
, len
, max_ctx_type
;
254 struct cper_arm_err_info
*err_info
;
255 struct cper_arm_ctx_info
*ctx_info
;
256 char newpfx
[64], infopfx
[64];
258 printk("%sMIDR: 0x%016llx\n", pfx
, proc
->midr
);
260 len
= proc
->section_length
- (sizeof(*proc
) +
261 proc
->err_info_num
* (sizeof(*err_info
)));
263 printk("%ssection length: %d\n", pfx
, proc
->section_length
);
264 printk("%ssection length is too small\n", pfx
);
265 printk("%sfirmware-generated error record is incorrect\n", pfx
);
266 printk("%sERR_INFO_NUM is %d\n", pfx
, proc
->err_info_num
);
270 if (proc
->validation_bits
& CPER_ARM_VALID_MPIDR
)
271 printk("%sMultiprocessor Affinity Register (MPIDR): 0x%016llx\n",
274 if (proc
->validation_bits
& CPER_ARM_VALID_AFFINITY_LEVEL
)
275 printk("%serror affinity level: %d\n", pfx
,
276 proc
->affinity_level
);
278 if (proc
->validation_bits
& CPER_ARM_VALID_RUNNING_STATE
) {
279 printk("%srunning state: 0x%x\n", pfx
, proc
->running_state
);
280 printk("%sPower State Coordination Interface state: %d\n",
281 pfx
, proc
->psci_state
);
284 snprintf(newpfx
, sizeof(newpfx
), "%s ", pfx
);
286 err_info
= (struct cper_arm_err_info
*)(proc
+ 1);
287 for (i
= 0; i
< proc
->err_info_num
; i
++) {
288 printk("%sError info structure %d:\n", pfx
, i
);
290 printk("%snum errors: %d\n", pfx
, err_info
->multiple_error
+ 1);
292 if (err_info
->validation_bits
& CPER_ARM_INFO_VALID_FLAGS
) {
293 if (err_info
->flags
& CPER_ARM_INFO_FLAGS_FIRST
)
294 printk("%sfirst error captured\n", newpfx
);
295 if (err_info
->flags
& CPER_ARM_INFO_FLAGS_LAST
)
296 printk("%slast error captured\n", newpfx
);
297 if (err_info
->flags
& CPER_ARM_INFO_FLAGS_PROPAGATED
)
298 printk("%spropagated error captured\n",
300 if (err_info
->flags
& CPER_ARM_INFO_FLAGS_OVERFLOW
)
301 printk("%soverflow occurred, error info is incomplete\n",
305 printk("%serror_type: %d, %s\n", newpfx
, err_info
->type
,
306 err_info
->type
< ARRAY_SIZE(cper_proc_error_type_strs
) ?
307 cper_proc_error_type_strs
[err_info
->type
] : "unknown");
308 if (err_info
->validation_bits
& CPER_ARM_INFO_VALID_ERR_INFO
) {
309 printk("%serror_info: 0x%016llx\n", newpfx
,
310 err_info
->error_info
);
311 snprintf(infopfx
, sizeof(infopfx
), "%s ", newpfx
);
312 cper_print_arm_err_info(infopfx
, err_info
->type
,
313 err_info
->error_info
);
315 if (err_info
->validation_bits
& CPER_ARM_INFO_VALID_VIRT_ADDR
)
316 printk("%svirtual fault address: 0x%016llx\n",
317 newpfx
, err_info
->virt_fault_addr
);
318 if (err_info
->validation_bits
& CPER_ARM_INFO_VALID_PHYSICAL_ADDR
)
319 printk("%sphysical fault address: 0x%016llx\n",
320 newpfx
, err_info
->physical_fault_addr
);
324 ctx_info
= (struct cper_arm_ctx_info
*)err_info
;
325 max_ctx_type
= ARRAY_SIZE(arm_reg_ctx_strs
) - 1;
326 for (i
= 0; i
< proc
->context_info_num
; i
++) {
327 int size
= sizeof(*ctx_info
) + ctx_info
->size
;
329 printk("%sContext info structure %d:\n", pfx
, i
);
331 printk("%ssection length is too small\n", newpfx
);
332 printk("%sfirmware-generated error record is incorrect\n", pfx
);
335 if (ctx_info
->type
> max_ctx_type
) {
336 printk("%sInvalid context type: %d (max: %d)\n",
337 newpfx
, ctx_info
->type
, max_ctx_type
);
340 printk("%sregister context type: %s\n", newpfx
,
341 arm_reg_ctx_strs
[ctx_info
->type
]);
342 print_hex_dump(newpfx
, "", DUMP_PREFIX_OFFSET
, 16, 4,
343 (ctx_info
+ 1), ctx_info
->size
, 0);
345 ctx_info
= (struct cper_arm_ctx_info
*)((long)ctx_info
+ size
);
349 printk("%sVendor specific error info has %u bytes:\n", pfx
,
351 print_hex_dump(newpfx
, "", DUMP_PREFIX_OFFSET
, 16, 4, ctx_info
,