@@ -17,6 +17,125 @@ void __iomem *mips_cm_base;
17
17
void __iomem * mips_cm_l2sync_base ;
18
18
int mips_cm_is64 ;
19
19
20
+ static char * cm2_tr [8 ] = {
21
+ "mem" , "gcr" , "gic" , "mmio" ,
22
+ "0x04" , "cpc" , "0x06" , "0x07"
23
+ };
24
+
25
+ /* CM3 Tag ECC transation type */
26
+ static char * cm3_tr [16 ] = {
27
+ [0x0 ] = "ReqNoData" ,
28
+ [0x1 ] = "0x1" ,
29
+ [0x2 ] = "ReqWData" ,
30
+ [0x3 ] = "0x3" ,
31
+ [0x4 ] = "IReqNoResp" ,
32
+ [0x5 ] = "IReqWResp" ,
33
+ [0x6 ] = "IReqNoRespDat" ,
34
+ [0x7 ] = "IReqWRespDat" ,
35
+ [0x8 ] = "RespNoData" ,
36
+ [0x9 ] = "RespDataFol" ,
37
+ [0xa ] = "RespWData" ,
38
+ [0xb ] = "RespDataOnly" ,
39
+ [0xc ] = "IRespNoData" ,
40
+ [0xd ] = "IRespDataFol" ,
41
+ [0xe ] = "IRespWData" ,
42
+ [0xf ] = "IRespDataOnly"
43
+ };
44
+
45
+ static char * cm2_cmd [32 ] = {
46
+ [0x00 ] = "0x00" ,
47
+ [0x01 ] = "Legacy Write" ,
48
+ [0x02 ] = "Legacy Read" ,
49
+ [0x03 ] = "0x03" ,
50
+ [0x04 ] = "0x04" ,
51
+ [0x05 ] = "0x05" ,
52
+ [0x06 ] = "0x06" ,
53
+ [0x07 ] = "0x07" ,
54
+ [0x08 ] = "Coherent Read Own" ,
55
+ [0x09 ] = "Coherent Read Share" ,
56
+ [0x0a ] = "Coherent Read Discard" ,
57
+ [0x0b ] = "Coherent Ready Share Always" ,
58
+ [0x0c ] = "Coherent Upgrade" ,
59
+ [0x0d ] = "Coherent Writeback" ,
60
+ [0x0e ] = "0x0e" ,
61
+ [0x0f ] = "0x0f" ,
62
+ [0x10 ] = "Coherent Copyback" ,
63
+ [0x11 ] = "Coherent Copyback Invalidate" ,
64
+ [0x12 ] = "Coherent Invalidate" ,
65
+ [0x13 ] = "Coherent Write Invalidate" ,
66
+ [0x14 ] = "Coherent Completion Sync" ,
67
+ [0x15 ] = "0x15" ,
68
+ [0x16 ] = "0x16" ,
69
+ [0x17 ] = "0x17" ,
70
+ [0x18 ] = "0x18" ,
71
+ [0x19 ] = "0x19" ,
72
+ [0x1a ] = "0x1a" ,
73
+ [0x1b ] = "0x1b" ,
74
+ [0x1c ] = "0x1c" ,
75
+ [0x1d ] = "0x1d" ,
76
+ [0x1e ] = "0x1e" ,
77
+ [0x1f ] = "0x1f"
78
+ };
79
+
80
+ /* CM3 Tag ECC command type */
81
+ static char * cm3_cmd [16 ] = {
82
+ [0x0 ] = "Legacy Read" ,
83
+ [0x1 ] = "Legacy Write" ,
84
+ [0x2 ] = "Coherent Read Own" ,
85
+ [0x3 ] = "Coherent Read Share" ,
86
+ [0x4 ] = "Coherent Read Discard" ,
87
+ [0x5 ] = "Coherent Evicted" ,
88
+ [0x6 ] = "Coherent Upgrade" ,
89
+ [0x7 ] = "Coherent Upgrade for Store Conditional" ,
90
+ [0x8 ] = "Coherent Writeback" ,
91
+ [0x9 ] = "Coherent Write Invalidate" ,
92
+ [0xa ] = "0xa" ,
93
+ [0xb ] = "0xb" ,
94
+ [0xc ] = "0xc" ,
95
+ [0xd ] = "0xd" ,
96
+ [0xe ] = "0xe" ,
97
+ [0xf ] = "0xf"
98
+ };
99
+
100
+ /* CM3 Tag ECC command group */
101
+ static char * cm3_cmd_group [8 ] = {
102
+ [0x0 ] = "Normal" ,
103
+ [0x1 ] = "Registers" ,
104
+ [0x2 ] = "TLB" ,
105
+ [0x3 ] = "0x3" ,
106
+ [0x4 ] = "L1I" ,
107
+ [0x5 ] = "L1D" ,
108
+ [0x6 ] = "L3" ,
109
+ [0x7 ] = "L2"
110
+ };
111
+
112
+ static char * cm2_core [8 ] = {
113
+ "Invalid/OK" , "Invalid/Data" ,
114
+ "Shared/OK" , "Shared/Data" ,
115
+ "Modified/OK" , "Modified/Data" ,
116
+ "Exclusive/OK" , "Exclusive/Data"
117
+ };
118
+
119
+ static char * cm2_causes [32 ] = {
120
+ "None" , "GC_WR_ERR" , "GC_RD_ERR" , "COH_WR_ERR" ,
121
+ "COH_RD_ERR" , "MMIO_WR_ERR" , "MMIO_RD_ERR" , "0x07" ,
122
+ "0x08" , "0x09" , "0x0a" , "0x0b" ,
123
+ "0x0c" , "0x0d" , "0x0e" , "0x0f" ,
124
+ "0x10" , "0x11" , "0x12" , "0x13" ,
125
+ "0x14" , "0x15" , "0x16" , "INTVN_WR_ERR" ,
126
+ "INTVN_RD_ERR" , "0x19" , "0x1a" , "0x1b" ,
127
+ "0x1c" , "0x1d" , "0x1e" , "0x1f"
128
+ };
129
+
130
+ static char * cm3_causes [32 ] = {
131
+ "0x0" , "MP_CORRECTABLE_ECC_ERR" , "MP_REQUEST_DECODE_ERR" ,
132
+ "MP_UNCORRECTABLE_ECC_ERR" , "MP_PARITY_ERR" , "MP_COHERENCE_ERR" ,
133
+ "CMBIU_REQUEST_DECODE_ERR" , "CMBIU_PARITY_ERR" , "CMBIU_AXI_RESP_ERR" ,
134
+ "0x9" , "RBI_BUS_ERR" , "0xb" , "0xc" , "0xd" , "0xe" , "0xf" , "0x10" ,
135
+ "0x11" , "0x12" , "0x13" , "0x14" , "0x15" , "0x16" , "0x17" , "0x18" ,
136
+ "0x19" , "0x1a" , "0x1b" , "0x1c" , "0x1d" , "0x1e" , "0x1f"
137
+ };
138
+
20
139
phys_addr_t __mips_cm_phys_base (void )
21
140
{
22
141
u32 config3 = read_c0_config3 ();
@@ -130,3 +249,128 @@ int mips_cm_probe(void)
130
249
131
250
return 0 ;
132
251
}
252
+
253
+ void mips_cm_error_report (void )
254
+ {
255
+ unsigned long revision = mips_cm_revision ();
256
+ /*
257
+ * CM3 has a 64-bit Error cause register with 0:57 containing the error
258
+ * info and 63:58 the error type. For old CMs, everything is contained
259
+ * in a single 32-bit register (0:26 and 31:27 respectively). Even
260
+ * though the cm_error is u64, we will simply ignore the upper word
261
+ * for CM2.
262
+ */
263
+ u64 cm_error = read_gcr_error_cause ();
264
+ int cm_error_cause_sft = CM_GCR_ERROR_CAUSE_ERRTYPE_SHF +
265
+ ((revision >= CM_REV_CM3 ) ? 31 : 0 );
266
+ unsigned long cm_addr = read_gcr_error_addr ();
267
+ unsigned long cm_other = read_gcr_error_mult ();
268
+ int ocause , cause ;
269
+ char buf [256 ];
270
+
271
+ if (!mips_cm_present ())
272
+ return ;
273
+
274
+ cause = cm_error >> cm_error_cause_sft ;
275
+
276
+ if (!cause )
277
+ /* All good */
278
+ return ;
279
+
280
+ ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF ;
281
+ if (revision < CM_REV_CM3 ) { /* CM2 */
282
+ if (cause < 16 ) {
283
+ unsigned long cca_bits = (cm_error >> 15 ) & 7 ;
284
+ unsigned long tr_bits = (cm_error >> 12 ) & 7 ;
285
+ unsigned long cmd_bits = (cm_error >> 7 ) & 0x1f ;
286
+ unsigned long stag_bits = (cm_error >> 3 ) & 15 ;
287
+ unsigned long sport_bits = (cm_error >> 0 ) & 7 ;
288
+
289
+ snprintf (buf , sizeof (buf ),
290
+ "CCA=%lu TR=%s MCmd=%s STag=%lu "
291
+ "SPort=%lu\n" , cca_bits , cm2_tr [tr_bits ],
292
+ cm2_cmd [cmd_bits ], stag_bits , sport_bits );
293
+ } else {
294
+ /* glob state & sresp together */
295
+ unsigned long c3_bits = (cm_error >> 18 ) & 7 ;
296
+ unsigned long c2_bits = (cm_error >> 15 ) & 7 ;
297
+ unsigned long c1_bits = (cm_error >> 12 ) & 7 ;
298
+ unsigned long c0_bits = (cm_error >> 9 ) & 7 ;
299
+ unsigned long sc_bit = (cm_error >> 8 ) & 1 ;
300
+ unsigned long cmd_bits = (cm_error >> 3 ) & 0x1f ;
301
+ unsigned long sport_bits = (cm_error >> 0 ) & 7 ;
302
+
303
+ snprintf (buf , sizeof (buf ),
304
+ "C3=%s C2=%s C1=%s C0=%s SC=%s "
305
+ "MCmd=%s SPort=%lu\n" ,
306
+ cm2_core [c3_bits ], cm2_core [c2_bits ],
307
+ cm2_core [c1_bits ], cm2_core [c0_bits ],
308
+ sc_bit ? "True" : "False" ,
309
+ cm2_cmd [cmd_bits ], sport_bits );
310
+ }
311
+ pr_err ("CM_ERROR=%08llx %s <%s>\n" , cm_error ,
312
+ cm2_causes [cause ], buf );
313
+ pr_err ("CM_ADDR =%08lx\n" , cm_addr );
314
+ pr_err ("CM_OTHER=%08lx %s\n" , cm_other , cm2_causes [ocause ]);
315
+ } else { /* CM3 */
316
+ /* Used by cause == {1,2,3} */
317
+ unsigned long core_id_bits = (cm_error >> 22 ) & 0xf ;
318
+ unsigned long vp_id_bits = (cm_error >> 18 ) & 0xf ;
319
+ unsigned long cmd_bits = (cm_error >> 14 ) & 0xf ;
320
+ unsigned long cmd_group_bits = (cm_error >> 11 ) & 0xf ;
321
+ unsigned long cm3_cca_bits = (cm_error >> 8 ) & 7 ;
322
+ unsigned long mcp_bits = (cm_error >> 5 ) & 0xf ;
323
+ unsigned long cm3_tr_bits = (cm_error >> 1 ) & 0xf ;
324
+ unsigned long sched_bit = cm_error & 0x1 ;
325
+
326
+ if (cause == 1 || cause == 3 ) { /* Tag ECC */
327
+ unsigned long tag_ecc = (cm_error >> 57 ) & 0x1 ;
328
+ unsigned long tag_way_bits = (cm_error >> 29 ) & 0xffff ;
329
+ unsigned long dword_bits = (cm_error >> 49 ) & 0xff ;
330
+ unsigned long data_way_bits = (cm_error >> 45 ) & 0xf ;
331
+ unsigned long data_sets_bits = (cm_error >> 29 ) & 0xfff ;
332
+ unsigned long bank_bit = (cm_error >> 28 ) & 0x1 ;
333
+ snprintf (buf , sizeof (buf ),
334
+ "%s ECC Error: Way=%lu (DWORD=%lu, Sets=%lu)"
335
+ "Bank=%lu CoreID=%lu VPID=%lu Command=%s"
336
+ "Command Group=%s CCA=%lu MCP=%d"
337
+ "Transaction type=%s Scheduler=%lu\n" ,
338
+ tag_ecc ? "TAG" : "DATA" ,
339
+ tag_ecc ? (unsigned long )ffs (tag_way_bits ) - 1 :
340
+ data_way_bits , bank_bit , dword_bits ,
341
+ data_sets_bits ,
342
+ core_id_bits , vp_id_bits ,
343
+ cm3_cmd [cmd_bits ],
344
+ cm3_cmd_group [cmd_group_bits ],
345
+ cm3_cca_bits , 1 << mcp_bits ,
346
+ cm3_tr [cm3_tr_bits ], sched_bit );
347
+ } else if (cause == 2 ) {
348
+ unsigned long data_error_type = (cm_error >> 41 ) & 0xfff ;
349
+ unsigned long data_decode_cmd = (cm_error >> 37 ) & 0xf ;
350
+ unsigned long data_decode_group = (cm_error >> 34 ) & 0x7 ;
351
+ unsigned long data_decode_destination_id = (cm_error >> 28 ) & 0x3f ;
352
+
353
+ snprintf (buf , sizeof (buf ),
354
+ "Decode Request Error: Type=%lu, Command=%lu"
355
+ "Command Group=%lu Destination ID=%lu"
356
+ "CoreID=%lu VPID=%lu Command=%s"
357
+ "Command Group=%s CCA=%lu MCP=%d"
358
+ "Transaction type=%s Scheduler=%lu\n" ,
359
+ data_error_type , data_decode_cmd ,
360
+ data_decode_group , data_decode_destination_id ,
361
+ core_id_bits , vp_id_bits ,
362
+ cm3_cmd [cmd_bits ],
363
+ cm3_cmd_group [cmd_group_bits ],
364
+ cm3_cca_bits , 1 << mcp_bits ,
365
+ cm3_tr [cm3_tr_bits ], sched_bit );
366
+ }
367
+
368
+ pr_err ("CM_ERROR=%llx %s <%s>\n" , cm_error ,
369
+ cm3_causes [cause ], buf );
370
+ pr_err ("CM_ADDR =%lx\n" , cm_addr );
371
+ pr_err ("CM_OTHER=%lx %s\n" , cm_other , cm3_causes [ocause ]);
372
+ }
373
+
374
+ /* reprime cause register */
375
+ write_gcr_error_cause (0 );
376
+ }
0 commit comments