@@ -110,12 +110,15 @@ void cper_print_bits(const char *pfx, unsigned int bits,
110
110
static const char * const proc_type_strs [] = {
111
111
"IA32/X64" ,
112
112
"IA64" ,
113
+ "ARM" ,
113
114
};
114
115
115
116
static const char * const proc_isa_strs [] = {
116
117
"IA32" ,
117
118
"IA64" ,
118
119
"X64" ,
120
+ "ARM A32/T32" ,
121
+ "ARM A64" ,
119
122
};
120
123
121
124
static const char * const proc_error_type_strs [] = {
@@ -184,6 +187,122 @@ static void cper_print_proc_generic(const char *pfx,
184
187
printk ("%s" "IP: 0x%016llx\n" , pfx , proc -> ip );
185
188
}
186
189
190
+ #if defined(CONFIG_ARM64 ) || defined(CONFIG_ARM )
191
+ static const char * const arm_reg_ctx_strs [] = {
192
+ "AArch32 general purpose registers" ,
193
+ "AArch32 EL1 context registers" ,
194
+ "AArch32 EL2 context registers" ,
195
+ "AArch32 secure context registers" ,
196
+ "AArch64 general purpose registers" ,
197
+ "AArch64 EL1 context registers" ,
198
+ "AArch64 EL2 context registers" ,
199
+ "AArch64 EL3 context registers" ,
200
+ "Misc. system register structure" ,
201
+ };
202
+
203
+ static void cper_print_proc_arm (const char * pfx ,
204
+ const struct cper_sec_proc_arm * proc )
205
+ {
206
+ int i , len , max_ctx_type ;
207
+ struct cper_arm_err_info * err_info ;
208
+ struct cper_arm_ctx_info * ctx_info ;
209
+ char newpfx [64 ];
210
+
211
+ printk ("%sMIDR: 0x%016llx\n" , pfx , proc -> midr );
212
+
213
+ len = proc -> section_length - (sizeof (* proc ) +
214
+ proc -> err_info_num * (sizeof (* err_info )));
215
+ if (len < 0 ) {
216
+ printk ("%ssection length: %d\n" , pfx , proc -> section_length );
217
+ printk ("%ssection length is too small\n" , pfx );
218
+ printk ("%sfirmware-generated error record is incorrect\n" , pfx );
219
+ printk ("%sERR_INFO_NUM is %d\n" , pfx , proc -> err_info_num );
220
+ return ;
221
+ }
222
+
223
+ if (proc -> validation_bits & CPER_ARM_VALID_MPIDR )
224
+ printk ("%sMultiprocessor Affinity Register (MPIDR): 0x%016llx\n" ,
225
+ pfx , proc -> mpidr );
226
+
227
+ if (proc -> validation_bits & CPER_ARM_VALID_AFFINITY_LEVEL )
228
+ printk ("%serror affinity level: %d\n" , pfx ,
229
+ proc -> affinity_level );
230
+
231
+ if (proc -> validation_bits & CPER_ARM_VALID_RUNNING_STATE ) {
232
+ printk ("%srunning state: 0x%x\n" , pfx , proc -> running_state );
233
+ printk ("%sPower State Coordination Interface state: %d\n" ,
234
+ pfx , proc -> psci_state );
235
+ }
236
+
237
+ snprintf (newpfx , sizeof (newpfx ), "%s%s" , pfx , INDENT_SP );
238
+
239
+ err_info = (struct cper_arm_err_info * )(proc + 1 );
240
+ for (i = 0 ; i < proc -> err_info_num ; i ++ ) {
241
+ printk ("%sError info structure %d:\n" , pfx , i );
242
+
243
+ printk ("%snum errors: %d\n" , pfx , err_info -> multiple_error + 1 );
244
+
245
+ if (err_info -> validation_bits & CPER_ARM_INFO_VALID_FLAGS ) {
246
+ if (err_info -> flags & CPER_ARM_INFO_FLAGS_FIRST )
247
+ printk ("%sfirst error captured\n" , newpfx );
248
+ if (err_info -> flags & CPER_ARM_INFO_FLAGS_LAST )
249
+ printk ("%slast error captured\n" , newpfx );
250
+ if (err_info -> flags & CPER_ARM_INFO_FLAGS_PROPAGATED )
251
+ printk ("%spropagated error captured\n" ,
252
+ newpfx );
253
+ if (err_info -> flags & CPER_ARM_INFO_FLAGS_OVERFLOW )
254
+ printk ("%soverflow occurred, error info is incomplete\n" ,
255
+ newpfx );
256
+ }
257
+
258
+ printk ("%serror_type: %d, %s\n" , newpfx , err_info -> type ,
259
+ err_info -> type < ARRAY_SIZE (proc_error_type_strs ) ?
260
+ proc_error_type_strs [err_info -> type ] : "unknown" );
261
+ if (err_info -> validation_bits & CPER_ARM_INFO_VALID_ERR_INFO )
262
+ printk ("%serror_info: 0x%016llx\n" , newpfx ,
263
+ err_info -> error_info );
264
+ if (err_info -> validation_bits & CPER_ARM_INFO_VALID_VIRT_ADDR )
265
+ printk ("%svirtual fault address: 0x%016llx\n" ,
266
+ newpfx , err_info -> virt_fault_addr );
267
+ if (err_info -> validation_bits & CPER_ARM_INFO_VALID_PHYSICAL_ADDR )
268
+ printk ("%sphysical fault address: 0x%016llx\n" ,
269
+ newpfx , err_info -> physical_fault_addr );
270
+ err_info += 1 ;
271
+ }
272
+
273
+ ctx_info = (struct cper_arm_ctx_info * )err_info ;
274
+ max_ctx_type = ARRAY_SIZE (arm_reg_ctx_strs ) - 1 ;
275
+ for (i = 0 ; i < proc -> context_info_num ; i ++ ) {
276
+ int size = sizeof (* ctx_info ) + ctx_info -> size ;
277
+
278
+ printk ("%sContext info structure %d:\n" , pfx , i );
279
+ if (len < size ) {
280
+ printk ("%ssection length is too small\n" , newpfx );
281
+ printk ("%sfirmware-generated error record is incorrect\n" , pfx );
282
+ return ;
283
+ }
284
+ if (ctx_info -> type > max_ctx_type ) {
285
+ printk ("%sInvalid context type: %d (max: %d)\n" ,
286
+ newpfx , ctx_info -> type , max_ctx_type );
287
+ return ;
288
+ }
289
+ printk ("%sregister context type: %s\n" , newpfx ,
290
+ arm_reg_ctx_strs [ctx_info -> type ]);
291
+ print_hex_dump (newpfx , "" , DUMP_PREFIX_OFFSET , 16 , 4 ,
292
+ (ctx_info + 1 ), ctx_info -> size , 0 );
293
+ len -= size ;
294
+ ctx_info = (struct cper_arm_ctx_info * )((long )ctx_info + size );
295
+ }
296
+
297
+ if (len > 0 ) {
298
+ printk ("%sVendor specific error info has %u bytes:\n" , pfx ,
299
+ len );
300
+ print_hex_dump (newpfx , "" , DUMP_PREFIX_OFFSET , 16 , 4 , ctx_info ,
301
+ len , true);
302
+ }
303
+ }
304
+ #endif
305
+
187
306
static const char * const mem_err_type_strs [] = {
188
307
"unknown" ,
189
308
"no error" ,
@@ -456,6 +575,16 @@ cper_estatus_print_section(const char *pfx, struct acpi_hest_generic_data *gdata
456
575
cper_print_pcie (newpfx , pcie , gdata );
457
576
else
458
577
goto err_section_too_small ;
578
+ #if defined(CONFIG_ARM64 ) || defined(CONFIG_ARM )
579
+ } else if (!uuid_le_cmp (* sec_type , CPER_SEC_PROC_ARM )) {
580
+ struct cper_sec_proc_arm * arm_err = acpi_hest_get_payload (gdata );
581
+
582
+ printk ("%ssection_type: ARM processor error\n" , newpfx );
583
+ if (gdata -> error_data_length >= sizeof (* arm_err ))
584
+ cper_print_proc_arm (newpfx , arm_err );
585
+ else
586
+ goto err_section_too_small ;
587
+ #endif
459
588
} else
460
589
printk ("%s" "section type: unknown, %pUl\n" , newpfx , sec_type );
461
590
0 commit comments