1// SPDX-License-Identifier: GPL-2.0
2/*
3 * linux/arch/alpha/kernel/err_marvel.c
4 *
5 * Copyright (C) 2001 Jeff Wiedemeier (Compaq Computer Corporation)
6 *
7 */
8
9#include <linux/init.h>
10#include <linux/pci.h>
11#include <linux/sched.h>
12
13#include <asm/io.h>
14#include <asm/console.h>
15#include <asm/core_marvel.h>
16#include <asm/hwrpb.h>
17#include <asm/smp.h>
18#include <asm/err_common.h>
19#include <asm/err_ev7.h>
20
21#include "err_impl.h"
22#include "proto.h"
23
24static void
25marvel_print_680_frame(struct ev7_lf_subpackets *lf_subpackets)
26{
27#ifdef CONFIG_VERBOSE_MCHECK
28 struct ev7_pal_environmental_subpacket *env;
29 struct { int type; char *name; } ev_packets[] = {
30 { EL_TYPE__PAL__ENV__AMBIENT_TEMPERATURE,
31 "Ambient Temperature" },
32 { EL_TYPE__PAL__ENV__AIRMOVER_FAN,
33 "AirMover / Fan" },
34 { EL_TYPE__PAL__ENV__VOLTAGE,
35 "Voltage" },
36 { EL_TYPE__PAL__ENV__INTRUSION,
37 "Intrusion" },
38 { EL_TYPE__PAL__ENV__POWER_SUPPLY,
39 "Power Supply" },
40 { EL_TYPE__PAL__ENV__LAN,
41 "LAN" },
42 { EL_TYPE__PAL__ENV__HOT_PLUG,
43 "Hot Plug" },
44 { 0, NULL }
45 };
46 int i;
47
48 for (i = 0; ev_packets[i].type != 0; i++) {
49 env = lf_subpackets->env[ev7_lf_env_index(ev_packets[i].type)];
50 if (!env)
51 continue;
52
53 printk("%s**%s event (cabinet %d, drawer %d)\n",
54 err_print_prefix,
55 ev_packets[i].name,
56 env->cabinet,
57 env->drawer);
58 printk("%s Module Type: 0x%x - Unit ID 0x%x - "
59 "Condition 0x%x\n",
60 err_print_prefix,
61 env->module_type,
62 env->unit_id,
63 env->condition);
64 }
65#endif /* CONFIG_VERBOSE_MCHECK */
66}
67
68static int
69marvel_process_680_frame(struct ev7_lf_subpackets *lf_subpackets, int print)
70{
71 int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
72 int i;
73
74 for (i = ev7_lf_env_index(EL_TYPE__PAL__ENV__AMBIENT_TEMPERATURE);
75 i <= ev7_lf_env_index(EL_TYPE__PAL__ENV__HOT_PLUG);
76 i++) {
77 if (lf_subpackets->env[i])
78 status = MCHK_DISPOSITION_REPORT;
79 }
80
81 if (print)
82 marvel_print_680_frame(lf_subpackets);
83
84 return status;
85}
86
87#ifdef CONFIG_VERBOSE_MCHECK
88
89static void
90marvel_print_err_cyc(u64 err_cyc)
91{
92 static char *packet_desc[] = {
93 "No Error",
94 "UNKNOWN",
95 "1 cycle (1 or 2 flit packet)",
96 "2 cycles (3 flit packet)",
97 "9 cycles (18 flit packet)",
98 "10 cycles (19 flit packet)",
99 "UNKNOWN",
100 "UNKNOWN",
101 "UNKNOWN"
102 };
103
104#define IO7__ERR_CYC__ODD_FLT (1UL << 0)
105#define IO7__ERR_CYC__EVN_FLT (1UL << 1)
106#define IO7__ERR_CYC__PACKET__S (6)
107#define IO7__ERR_CYC__PACKET__M (0x7)
108#define IO7__ERR_CYC__LOC (1UL << 5)
109#define IO7__ERR_CYC__CYCLE__S (2)
110#define IO7__ERR_CYC__CYCLE__M (0x7)
111
112 printk("%s Packet In Error: %s\n"
113 "%s Error in %s, cycle %lld%s%s\n",
114 err_print_prefix,
115 packet_desc[EXTRACT(err_cyc, IO7__ERR_CYC__PACKET)],
116 err_print_prefix,
117 (err_cyc & IO7__ERR_CYC__LOC) ? "DATA" : "HEADER",
118 EXTRACT(err_cyc, IO7__ERR_CYC__CYCLE),
119 (err_cyc & IO7__ERR_CYC__ODD_FLT) ? " [ODD Flit]": "",
120 (err_cyc & IO7__ERR_CYC__EVN_FLT) ? " [Even Flit]": "");
121}
122
123static void
124marvel_print_po7_crrct_sym(u64 crrct_sym)
125{
126#define IO7__PO7_CRRCT_SYM__SYN__S (0)
127#define IO7__PO7_CRRCT_SYM__SYN__M (0x7f)
128#define IO7__PO7_CRRCT_SYM__ERR_CYC__S (7) /* ERR_CYC + ODD_FLT + EVN_FLT */
129#define IO7__PO7_CRRCT_SYM__ERR_CYC__M (0x1ff)
130
131
132 printk("%s Correctable Error Symptoms:\n"
133 "%s Syndrome: 0x%llx\n",
134 err_print_prefix,
135 err_print_prefix, EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__SYN));
136 marvel_print_err_cyc(EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__ERR_CYC));
137}
138
139static void
140marvel_print_po7_uncrr_sym(u64 uncrr_sym, u64 valid_mask)
141{
142 static char *clk_names[] = { "_h[0]", "_h[1]", "_n[0]", "_n[1]" };
143 static char *clk_decode[] = {
144 "No Error",
145 "One extra rising edge",
146 "Two extra rising edges",
147 "Lost one clock"
148 };
149 static char *port_names[] = { "Port 0", "Port 1",
150 "Port 2", "Port 3",
151 "Unknown Port", "Unknown Port",
152 "Unknown Port", "Port 7" };
153 int scratch, i;
154
155#define IO7__PO7_UNCRR_SYM__SYN__S (0)
156#define IO7__PO7_UNCRR_SYM__SYN__M (0x7f)
157#define IO7__PO7_UNCRR_SYM__ERR_CYC__S (7) /* ERR_CYC + ODD_FLT... */
158#define IO7__PO7_UNCRR_SYM__ERR_CYC__M (0x1ff) /* ... + EVN_FLT */
159#define IO7__PO7_UNCRR_SYM__CLK__S (16)
160#define IO7__PO7_UNCRR_SYM__CLK__M (0xff)
161#define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__REQ (1UL << 24)
162#define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__RIO (1UL << 25)
163#define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__WIO (1UL << 26)
164#define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__BLK (1UL << 27)
165#define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__NBK (1UL << 28)
166#define IO7__PO7_UNCRR_SYM__OVF__READIO (1UL << 29)
167#define IO7__PO7_UNCRR_SYM__OVF__WRITEIO (1UL << 30)
168#define IO7__PO7_UNCRR_SYM__OVF__FWD (1UL << 31)
169#define IO7__PO7_UNCRR_SYM__VICTIM_SP__S (32)
170#define IO7__PO7_UNCRR_SYM__VICTIM_SP__M (0xff)
171#define IO7__PO7_UNCRR_SYM__DETECT_SP__S (40)
172#define IO7__PO7_UNCRR_SYM__DETECT_SP__M (0xff)
173#define IO7__PO7_UNCRR_SYM__STRV_VTR__S (48)
174#define IO7__PO7_UNCRR_SYM__STRV_VTR__M (0x3ff)
175
176#define IO7__STRV_VTR__LSI__INTX__S (0)
177#define IO7__STRV_VTR__LSI__INTX__M (0x3)
178#define IO7__STRV_VTR__LSI__SLOT__S (2)
179#define IO7__STRV_VTR__LSI__SLOT__M (0x7)
180#define IO7__STRV_VTR__LSI__BUS__S (5)
181#define IO7__STRV_VTR__LSI__BUS__M (0x3)
182#define IO7__STRV_VTR__MSI__INTNUM__S (0)
183#define IO7__STRV_VTR__MSI__INTNUM__M (0x1ff)
184#define IO7__STRV_VTR__IS_MSI (1UL << 9)
185
186 printk("%s Uncorrectable Error Symptoms:\n", err_print_prefix);
187 uncrr_sym &= valid_mask;
188
189 if (EXTRACT(valid_mask, IO7__PO7_UNCRR_SYM__SYN))
190 printk("%s Syndrome: 0x%llx\n",
191 err_print_prefix,
192 EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__SYN));
193
194 if (EXTRACT(valid_mask, IO7__PO7_UNCRR_SYM__ERR_CYC))
195 marvel_print_err_cyc(EXTRACT(uncrr_sym,
196 IO7__PO7_UNCRR_SYM__ERR_CYC));
197
198 scratch = EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__CLK);
199 for (i = 0; i < 4; i++, scratch >>= 2) {
200 if (scratch & 0x3)
201 printk("%s Clock %s: %s\n",
202 err_print_prefix,
203 clk_names[i], clk_decode[scratch & 0x3]);
204 }
205
206 if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__REQ)
207 printk("%s REQ Credit Timeout or Overflow\n",
208 err_print_prefix);
209 if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__RIO)
210 printk("%s RIO Credit Timeout or Overflow\n",
211 err_print_prefix);
212 if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__WIO)
213 printk("%s WIO Credit Timeout or Overflow\n",
214 err_print_prefix);
215 if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__BLK)
216 printk("%s BLK Credit Timeout or Overflow\n",
217 err_print_prefix);
218 if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__NBK)
219 printk("%s NBK Credit Timeout or Overflow\n",
220 err_print_prefix);
221
222 if (uncrr_sym & IO7__PO7_UNCRR_SYM__OVF__READIO)
223 printk("%s Read I/O Buffer Overflow\n",
224 err_print_prefix);
225 if (uncrr_sym & IO7__PO7_UNCRR_SYM__OVF__WRITEIO)
226 printk("%s Write I/O Buffer Overflow\n",
227 err_print_prefix);
228 if (uncrr_sym & IO7__PO7_UNCRR_SYM__OVF__FWD)
229 printk("%s FWD Buffer Overflow\n",
230 err_print_prefix);
231
232 if ((scratch = EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__VICTIM_SP))) {
233 int lost = scratch & (1UL << 4);
234 scratch &= ~lost;
235 for (i = 0; i < 8; i++, scratch >>= 1) {
236 if (!(scratch & 1))
237 continue;
238 printk("%s Error Response sent to %s",
239 err_print_prefix, port_names[i]);
240 }
241 if (lost)
242 printk("%s Lost Error sent somewhere else\n",
243 err_print_prefix);
244 }
245
246 if ((scratch = EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__DETECT_SP))) {
247 for (i = 0; i < 8; i++, scratch >>= 1) {
248 if (!(scratch & 1))
249 continue;
250 printk("%s Error Reported by %s",
251 err_print_prefix, port_names[i]);
252 }
253 }
254
255 if (EXTRACT(valid_mask, IO7__PO7_UNCRR_SYM__STRV_VTR)) {
256 char starvation_message[80];
257
258 scratch = EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__STRV_VTR);
259 if (scratch & IO7__STRV_VTR__IS_MSI)
260 sprintf(starvation_message,
261 "MSI Interrupt 0x%x",
262 EXTRACT(scratch, IO7__STRV_VTR__MSI__INTNUM));
263 else
264 sprintf(starvation_message,
265 "LSI INT%c for Bus:Slot (%d:%d)\n",
266 'A' + EXTRACT(scratch,
267 IO7__STRV_VTR__LSI__INTX),
268 EXTRACT(scratch, IO7__STRV_VTR__LSI__BUS),
269 EXTRACT(scratch, IO7__STRV_VTR__LSI__SLOT));
270
271 printk("%s Starvation Int Trigger By: %s\n",
272 err_print_prefix, starvation_message);
273 }
274}
275
276static void
277marvel_print_po7_ugbge_sym(u64 ugbge_sym)
278{
279 char opcode_str[10];
280
281#define IO7__PO7_UGBGE_SYM__UPH_PKT_OFF__S (6)
282#define IO7__PO7_UGBGE_SYM__UPH_PKT_OFF__M (0xfffffffful)
283#define IO7__PO7_UGBGE_SYM__UPH_OPCODE__S (40)
284#define IO7__PO7_UGBGE_SYM__UPH_OPCODE__M (0xff)
285#define IO7__PO7_UGBGE_SYM__UPH_SRC_PORT__S (48)
286#define IO7__PO7_UGBGE_SYM__UPH_SRC_PORT__M (0xf)
287#define IO7__PO7_UGBGE_SYM__UPH_DEST_PID__S (52)
288#define IO7__PO7_UGBGE_SYM__UPH_DEST_PID__M (0x7ff)
289#define IO7__PO7_UGBGE_SYM__VALID (1UL << 63)
290
291 if (!(ugbge_sym & IO7__PO7_UGBGE_SYM__VALID))
292 return;
293
294 switch(EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE)) {
295 case 0x51:
296 sprintf(opcode_str, "Wr32");
297 break;
298 case 0x50:
299 sprintf(opcode_str, "WrQW");
300 break;
301 case 0x54:
302 sprintf(opcode_str, "WrIPR");
303 break;
304 case 0xD8:
305 sprintf(opcode_str, "Victim");
306 break;
307 case 0xC5:
308 sprintf(opcode_str, "BlkIO");
309 break;
310 default:
311 sprintf(opcode_str, "0x%llx\n",
312 EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE));
313 break;
314 }
315
316 printk("%s Up Hose Garbage Symptom:\n"
317 "%s Source Port: %lld - Dest PID: %lld - OpCode: %s\n",
318 err_print_prefix,
319 err_print_prefix,
320 EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_SRC_PORT),
321 EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_DEST_PID),
322 opcode_str);
323
324 if (0xC5 != EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE))
325 printk("%s Packet Offset 0x%08llx\n",
326 err_print_prefix,
327 EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_PKT_OFF));
328}
329
330static void
331marvel_print_po7_err_sum(struct ev7_pal_io_subpacket *io)
332{
333 u64 uncrr_sym_valid = 0;
334
335#define IO7__PO7_ERRSUM__CR_SBE (1UL << 32)
336#define IO7__PO7_ERRSUM__CR_SBE2 (1UL << 33)
337#define IO7__PO7_ERRSUM__CR_PIO_WBYTE (1UL << 34)
338#define IO7__PO7_ERRSUM__CR_CSR_NXM (1UL << 35)
339#define IO7__PO7_ERRSUM__CR_RPID_ACV (1UL << 36)
340#define IO7__PO7_ERRSUM__CR_RSP_NXM (1UL << 37)
341#define IO7__PO7_ERRSUM__CR_ERR_RESP (1UL << 38)
342#define IO7__PO7_ERRSUM__CR_CLK_DERR (1UL << 39)
343#define IO7__PO7_ERRSUM__CR_DAT_DBE (1UL << 40)
344#define IO7__PO7_ERRSUM__CR_DAT_GRBG (1UL << 41)
345#define IO7__PO7_ERRSUM__MAF_TO (1UL << 42)
346#define IO7__PO7_ERRSUM__UGBGE (1UL << 43)
347#define IO7__PO7_ERRSUM__UN_MAF_LOST (1UL << 44)
348#define IO7__PO7_ERRSUM__UN_PKT_OVF (1UL << 45)
349#define IO7__PO7_ERRSUM__UN_CDT_OVF (1UL << 46)
350#define IO7__PO7_ERRSUM__UN_DEALLOC (1UL << 47)
351#define IO7__PO7_ERRSUM__BH_CDT_TO (1UL << 51)
352#define IO7__PO7_ERRSUM__BH_CLK_HDR (1UL << 52)
353#define IO7__PO7_ERRSUM__BH_DBE_HDR (1UL << 53)
354#define IO7__PO7_ERRSUM__BH_GBG_HDR (1UL << 54)
355#define IO7__PO7_ERRSUM__BH_BAD_CMD (1UL << 55)
356#define IO7__PO7_ERRSUM__HLT_INT (1UL << 56)
357#define IO7__PO7_ERRSUM__HP_INT (1UL << 57)
358#define IO7__PO7_ERRSUM__CRD_INT (1UL << 58)
359#define IO7__PO7_ERRSUM__STV_INT (1UL << 59)
360#define IO7__PO7_ERRSUM__HRD_INT (1UL << 60)
361#define IO7__PO7_ERRSUM__BH_SUM (1UL << 61)
362#define IO7__PO7_ERRSUM__ERR_LST (1UL << 62)
363#define IO7__PO7_ERRSUM__ERR_VALID (1UL << 63)
364
365#define IO7__PO7_ERRSUM__ERR_MASK (IO7__PO7_ERRSUM__ERR_VALID | \
366 IO7__PO7_ERRSUM__CR_SBE)
367
368 /*
369 * Single bit errors aren't covered by ERR_VALID.
370 */
371 if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_SBE) {
372 printk("%s %sSingle Bit Error(s) detected/corrected\n",
373 err_print_prefix,
374 (io->po7_error_sum & IO7__PO7_ERRSUM__CR_SBE2)
375 ? "Multiple " : "");
376 marvel_print_po7_crrct_sym(io->po7_crrct_sym);
377 }
378
379 /*
380 * Neither are the interrupt status bits
381 */
382 if (io->po7_error_sum & IO7__PO7_ERRSUM__HLT_INT)
383 printk("%s Halt Interrupt posted", err_print_prefix);
384 if (io->po7_error_sum & IO7__PO7_ERRSUM__HP_INT) {
385 printk("%s Hot Plug Event Interrupt posted",
386 err_print_prefix);
387 uncrr_sym_valid |= GEN_MASK(IO7__PO7_UNCRR_SYM__DETECT_SP);
388 }
389 if (io->po7_error_sum & IO7__PO7_ERRSUM__CRD_INT)
390 printk("%s Correctable Error Interrupt posted",
391 err_print_prefix);
392 if (io->po7_error_sum & IO7__PO7_ERRSUM__STV_INT) {
393 printk("%s Starvation Interrupt posted", err_print_prefix);
394 uncrr_sym_valid |= GEN_MASK(IO7__PO7_UNCRR_SYM__STRV_VTR);
395 }
396 if (io->po7_error_sum & IO7__PO7_ERRSUM__HRD_INT) {
397 printk("%s Hard Error Interrupt posted", err_print_prefix);
398 uncrr_sym_valid |= GEN_MASK(IO7__PO7_UNCRR_SYM__DETECT_SP);
399 }
400
401 /*
402 * Everything else is valid only with ERR_VALID, so skip to the end
403 * (uncrr_sym check) unless ERR_VALID is set.
404 */
405 if (!(io->po7_error_sum & IO7__PO7_ERRSUM__ERR_VALID))
406 goto check_uncrr_sym;
407
408 /*
409 * Since ERR_VALID is set, VICTIM_SP in uncrr_sym is valid.
410 * For bits [29:0] to also be valid, the following bits must
411 * not be set:
412 * CR_PIO_WBYTE CR_CSR_NXM CR_RSP_NXM
413 * CR_ERR_RESP MAF_TO
414 */
415 uncrr_sym_valid |= GEN_MASK(IO7__PO7_UNCRR_SYM__VICTIM_SP);
416 if (!(io->po7_error_sum & (IO7__PO7_ERRSUM__CR_PIO_WBYTE |
417 IO7__PO7_ERRSUM__CR_CSR_NXM |
418 IO7__PO7_ERRSUM__CR_RSP_NXM |
419 IO7__PO7_ERRSUM__CR_ERR_RESP |
420 IO7__PO7_ERRSUM__MAF_TO)))
421 uncrr_sym_valid |= 0x3ffffffful;
422
423 if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_PIO_WBYTE)
424 printk("%s Write byte into IO7 CSR\n", err_print_prefix);
425 if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_CSR_NXM)
426 printk("%s PIO to non-existent CSR\n", err_print_prefix);
427 if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_RPID_ACV)
428 printk("%s Bus Requester PID (Access Violation)\n",
429 err_print_prefix);
430 if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_RSP_NXM)
431 printk("%s Received NXM response from EV7\n",
432 err_print_prefix);
433 if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_ERR_RESP)
434 printk("%s Received ERROR RESPONSE\n", err_print_prefix);
435 if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_CLK_DERR)
436 printk("%s Clock error on data flit\n", err_print_prefix);
437 if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_DAT_DBE)
438 printk("%s Double Bit Error Data Error Detected\n",
439 err_print_prefix);
440 if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_DAT_GRBG)
441 printk("%s Garbage Encoding Detected on the data\n",
442 err_print_prefix);
443 if (io->po7_error_sum & IO7__PO7_ERRSUM__UGBGE) {
444 printk("%s Garbage Encoding sent up hose\n",
445 err_print_prefix);
446 marvel_print_po7_ugbge_sym(io->po7_ugbge_sym);
447 }
448 if (io->po7_error_sum & IO7__PO7_ERRSUM__UN_MAF_LOST)
449 printk("%s Orphan response (unexpected response)\n",
450 err_print_prefix);
451 if (io->po7_error_sum & IO7__PO7_ERRSUM__UN_PKT_OVF)
452 printk("%s Down hose packet overflow\n", err_print_prefix);
453 if (io->po7_error_sum & IO7__PO7_ERRSUM__UN_CDT_OVF)
454 printk("%s Down hose credit overflow\n", err_print_prefix);
455 if (io->po7_error_sum & IO7__PO7_ERRSUM__UN_DEALLOC)
456 printk("%s Unexpected or bad dealloc field\n",
457 err_print_prefix);
458
459 /*
460 * The black hole events.
461 */
462 if (io->po7_error_sum & IO7__PO7_ERRSUM__MAF_TO)
463 printk("%s BLACK HOLE: Timeout for all responses\n",
464 err_print_prefix);
465 if (io->po7_error_sum & IO7__PO7_ERRSUM__BH_CDT_TO)
466 printk("%s BLACK HOLE: Credit Timeout\n", err_print_prefix);
467 if (io->po7_error_sum & IO7__PO7_ERRSUM__BH_CLK_HDR)
468 printk("%s BLACK HOLE: Clock check on header\n",
469 err_print_prefix);
470 if (io->po7_error_sum & IO7__PO7_ERRSUM__BH_DBE_HDR)
471 printk("%s BLACK HOLE: Uncorrectable Error on header\n",
472 err_print_prefix);
473 if (io->po7_error_sum & IO7__PO7_ERRSUM__BH_GBG_HDR)
474 printk("%s BLACK HOLE: Garbage on header\n",
475 err_print_prefix);
476 if (io->po7_error_sum & IO7__PO7_ERRSUM__BH_BAD_CMD)
477 printk("%s BLACK HOLE: Bad EV7 command\n",
478 err_print_prefix);
479
480 if (io->po7_error_sum & IO7__PO7_ERRSUM__ERR_LST)
481 printk("%s Lost Error\n", err_print_prefix);
482
483 printk("%s Failing Packet:\n"
484 "%s Cycle 1: %016llx\n"
485 "%s Cycle 2: %016llx\n",
486 err_print_prefix,
487 err_print_prefix, io->po7_err_pkt0,
488 err_print_prefix, io->po7_err_pkt1);
489 /*
490 * If there are any valid bits in UNCRR sym for this err,
491 * print UNCRR_SYM as well.
492 */
493check_uncrr_sym:
494 if (uncrr_sym_valid)
495 marvel_print_po7_uncrr_sym(io->po7_uncrr_sym, uncrr_sym_valid);
496}
497
498static void
499marvel_print_pox_tlb_err(u64 tlb_err)
500{
501 static char *tlb_errors[] = {
502 "No Error",
503 "North Port Signaled Error fetching TLB entry",
504 "PTE invalid or UCC or GBG error on this entry",
505 "Address did not hit any DMA window"
506 };
507
508#define IO7__POX_TLBERR__ERR_VALID (1UL << 63)
509#define IO7__POX_TLBERR__ERRCODE__S (0)
510#define IO7__POX_TLBERR__ERRCODE__M (0x3)
511#define IO7__POX_TLBERR__ERR_TLB_PTR__S (3)
512#define IO7__POX_TLBERR__ERR_TLB_PTR__M (0x7)
513#define IO7__POX_TLBERR__FADDR__S (6)
514#define IO7__POX_TLBERR__FADDR__M (0x3fffffffffful)
515
516 if (!(tlb_err & IO7__POX_TLBERR__ERR_VALID))
517 return;
518
519 printk("%s TLB Error on index 0x%llx:\n"
520 "%s - %s\n"
521 "%s - Addr: 0x%016llx\n",
522 err_print_prefix,
523 EXTRACT(tlb_err, IO7__POX_TLBERR__ERR_TLB_PTR),
524 err_print_prefix,
525 tlb_errors[EXTRACT(tlb_err, IO7__POX_TLBERR__ERRCODE)],
526 err_print_prefix,
527 EXTRACT(tlb_err, IO7__POX_TLBERR__FADDR) << 6);
528}
529
530static void
531marvel_print_pox_spl_cmplt(u64 spl_cmplt)
532{
533 char message[80];
534
535#define IO7__POX_SPLCMPLT__MESSAGE__S (0)
536#define IO7__POX_SPLCMPLT__MESSAGE__M (0x0fffffffful)
537#define IO7__POX_SPLCMPLT__SOURCE_BUS__S (40)
538#define IO7__POX_SPLCMPLT__SOURCE_BUS__M (0xfful)
539#define IO7__POX_SPLCMPLT__SOURCE_DEV__S (35)
540#define IO7__POX_SPLCMPLT__SOURCE_DEV__M (0x1ful)
541#define IO7__POX_SPLCMPLT__SOURCE_FUNC__S (32)
542#define IO7__POX_SPLCMPLT__SOURCE_FUNC__M (0x07ul)
543
544#define IO7__POX_SPLCMPLT__MSG_CLASS__S (28)
545#define IO7__POX_SPLCMPLT__MSG_CLASS__M (0xf)
546#define IO7__POX_SPLCMPLT__MSG_INDEX__S (20)
547#define IO7__POX_SPLCMPLT__MSG_INDEX__M (0xff)
548#define IO7__POX_SPLCMPLT__MSG_CLASSINDEX__S (20)
549#define IO7__POX_SPLCMPLT__MSG_CLASSINDEX__M (0xfff)
550#define IO7__POX_SPLCMPLT__REM_LOWER_ADDR__S (12)
551#define IO7__POX_SPLCMPLT__REM_LOWER_ADDR__M (0x7f)
552#define IO7__POX_SPLCMPLT__REM_BYTE_COUNT__S (0)
553#define IO7__POX_SPLCMPLT__REM_BYTE_COUNT__M (0xfff)
554
555 printk("%s Split Completion Error:\n"
556 "%s Source (Bus:Dev:Func): %lld:%lld:%lld\n",
557 err_print_prefix,
558 err_print_prefix,
559 EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__SOURCE_BUS),
560 EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__SOURCE_DEV),
561 EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__SOURCE_FUNC));
562
563 switch(EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__MSG_CLASSINDEX)) {
564 case 0x000:
565 sprintf(message, "Normal completion");
566 break;
567 case 0x100:
568 sprintf(message, "Bridge - Master Abort");
569 break;
570 case 0x101:
571 sprintf(message, "Bridge - Target Abort");
572 break;
573 case 0x102:
574 sprintf(message, "Bridge - Uncorrectable Write Data Error");
575 break;
576 case 0x200:
577 sprintf(message, "Byte Count Out of Range");
578 break;
579 case 0x201:
580 sprintf(message, "Uncorrectable Split Write Data Error");
581 break;
582 default:
583 sprintf(message, "%08llx\n",
584 EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__MESSAGE));
585 break;
586 }
587 printk("%s Message: %s\n", err_print_prefix, message);
588}
589
590static void
591marvel_print_pox_trans_sum(u64 trans_sum)
592{
593 static const char * const pcix_cmd[] = {
594 "Interrupt Acknowledge",
595 "Special Cycle",
596 "I/O Read",
597 "I/O Write",
598 "Reserved",
599 "Reserved / Device ID Message",
600 "Memory Read",
601 "Memory Write",
602 "Reserved / Alias to Memory Read Block",
603 "Reserved / Alias to Memory Write Block",
604 "Configuration Read",
605 "Configuration Write",
606 "Memory Read Multiple / Split Completion",
607 "Dual Address Cycle",
608 "Memory Read Line / Memory Read Block",
609 "Memory Write and Invalidate / Memory Write Block"
610 };
611
612#define IO7__POX_TRANSUM__PCI_ADDR__S (0)
613#define IO7__POX_TRANSUM__PCI_ADDR__M (0x3fffffffffffful)
614#define IO7__POX_TRANSUM__DAC (1UL << 50)
615#define IO7__POX_TRANSUM__PCIX_MASTER_SLOT__S (52)
616#define IO7__POX_TRANSUM__PCIX_MASTER_SLOT__M (0xf)
617#define IO7__POX_TRANSUM__PCIX_CMD__S (56)
618#define IO7__POX_TRANSUM__PCIX_CMD__M (0xf)
619#define IO7__POX_TRANSUM__ERR_VALID (1UL << 63)
620
621 if (!(trans_sum & IO7__POX_TRANSUM__ERR_VALID))
622 return;
623
624 printk("%s Transaction Summary:\n"
625 "%s Command: 0x%llx - %s\n"
626 "%s Address: 0x%016llx%s\n"
627 "%s PCI-X Master Slot: 0x%llx\n",
628 err_print_prefix,
629 err_print_prefix,
630 EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_CMD),
631 pcix_cmd[EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_CMD)],
632 err_print_prefix,
633 EXTRACT(trans_sum, IO7__POX_TRANSUM__PCI_ADDR),
634 (trans_sum & IO7__POX_TRANSUM__DAC) ? " (DAC)" : "",
635 err_print_prefix,
636 EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_MASTER_SLOT));
637}
638
639static void
640marvel_print_pox_err(u64 err_sum, struct ev7_pal_io_one_port *port)
641{
642#define IO7__POX_ERRSUM__AGP_REQQ_OVFL (1UL << 4)
643#define IO7__POX_ERRSUM__AGP_SYNC_ERR (1UL << 5)
644#define IO7__POX_ERRSUM__MRETRY_TO (1UL << 6)
645#define IO7__POX_ERRSUM__PCIX_UX_SPL (1UL << 7)
646#define IO7__POX_ERRSUM__PCIX_SPLIT_TO (1UL << 8)
647#define IO7__POX_ERRSUM__PCIX_DISCARD_SPL (1UL << 9)
648#define IO7__POX_ERRSUM__DMA_RD_TO (1UL << 10)
649#define IO7__POX_ERRSUM__CSR_NXM_RD (1UL << 11)
650#define IO7__POX_ERRSUM__CSR_NXM_WR (1UL << 12)
651#define IO7__POX_ERRSUM__DMA_TO (1UL << 13)
652#define IO7__POX_ERRSUM__ALL_MABORTS (1UL << 14)
653#define IO7__POX_ERRSUM__MABORT (1UL << 15)
654#define IO7__POX_ERRSUM__MABORT_MASK (IO7__POX_ERRSUM__ALL_MABORTS|\
655 IO7__POX_ERRSUM__MABORT)
656#define IO7__POX_ERRSUM__PT_TABORT (1UL << 16)
657#define IO7__POX_ERRSUM__PM_TABORT (1UL << 17)
658#define IO7__POX_ERRSUM__TABORT_MASK (IO7__POX_ERRSUM__PT_TABORT | \
659 IO7__POX_ERRSUM__PM_TABORT)
660#define IO7__POX_ERRSUM__SERR (1UL << 18)
661#define IO7__POX_ERRSUM__ADDRERR_STB (1UL << 19)
662#define IO7__POX_ERRSUM__DETECTED_SERR (1UL << 20)
663#define IO7__POX_ERRSUM__PERR (1UL << 21)
664#define IO7__POX_ERRSUM__DATAERR_STB_NIOW (1UL << 22)
665#define IO7__POX_ERRSUM__DETECTED_PERR (1UL << 23)
666#define IO7__POX_ERRSUM__PM_PERR (1UL << 24)
667#define IO7__POX_ERRSUM__PT_SCERROR (1UL << 26)
668#define IO7__POX_ERRSUM__HUNG_BUS (1UL << 28)
669#define IO7__POX_ERRSUM__UPE_ERROR__S (51)
670#define IO7__POX_ERRSUM__UPE_ERROR__M (0xffUL)
671#define IO7__POX_ERRSUM__UPE_ERROR GEN_MASK(IO7__POX_ERRSUM__UPE_ERROR)
672#define IO7__POX_ERRSUM__TLB_ERR (1UL << 59)
673#define IO7__POX_ERRSUM__ERR_VALID (1UL << 63)
674
675#define IO7__POX_ERRSUM__TRANS_SUM__MASK (IO7__POX_ERRSUM__MRETRY_TO | \
676 IO7__POX_ERRSUM__PCIX_UX_SPL | \
677 IO7__POX_ERRSUM__PCIX_SPLIT_TO | \
678 IO7__POX_ERRSUM__DMA_TO | \
679 IO7__POX_ERRSUM__MABORT_MASK | \
680 IO7__POX_ERRSUM__TABORT_MASK | \
681 IO7__POX_ERRSUM__SERR | \
682 IO7__POX_ERRSUM__ADDRERR_STB | \
683 IO7__POX_ERRSUM__PERR | \
684 IO7__POX_ERRSUM__DATAERR_STB_NIOW |\
685 IO7__POX_ERRSUM__DETECTED_PERR | \
686 IO7__POX_ERRSUM__PM_PERR | \
687 IO7__POX_ERRSUM__PT_SCERROR | \
688 IO7__POX_ERRSUM__UPE_ERROR)
689
690 if (!(err_sum & IO7__POX_ERRSUM__ERR_VALID))
691 return;
692
693 /*
694 * First the transaction summary errors
695 */
696 if (err_sum & IO7__POX_ERRSUM__MRETRY_TO)
697 printk("%s IO7 Master Retry Timeout expired\n",
698 err_print_prefix);
699 if (err_sum & IO7__POX_ERRSUM__PCIX_UX_SPL)
700 printk("%s Unexpected Split Completion\n",
701 err_print_prefix);
702 if (err_sum & IO7__POX_ERRSUM__PCIX_SPLIT_TO)
703 printk("%s IO7 Split Completion Timeout expired\n",
704 err_print_prefix);
705 if (err_sum & IO7__POX_ERRSUM__DMA_TO)
706 printk("%s Hung bus during DMA transaction\n",
707 err_print_prefix);
708 if (err_sum & IO7__POX_ERRSUM__MABORT_MASK)
709 printk("%s Master Abort\n", err_print_prefix);
710 if (err_sum & IO7__POX_ERRSUM__PT_TABORT)
711 printk("%s IO7 Asserted Target Abort\n", err_print_prefix);
712 if (err_sum & IO7__POX_ERRSUM__PM_TABORT)
713 printk("%s IO7 Received Target Abort\n", err_print_prefix);
714 if (err_sum & IO7__POX_ERRSUM__ADDRERR_STB) {
715 printk("%s Address or PCI-X Attribute Parity Error\n",
716 err_print_prefix);
717 if (err_sum & IO7__POX_ERRSUM__SERR)
718 printk("%s IO7 Asserted SERR\n", err_print_prefix);
719 }
720 if (err_sum & IO7__POX_ERRSUM__PERR) {
721 if (err_sum & IO7__POX_ERRSUM__DATAERR_STB_NIOW)
722 printk("%s IO7 Detected Data Parity Error\n",
723 err_print_prefix);
724 else
725 printk("%s Split Completion Response with "
726 "Parity Error\n", err_print_prefix);
727 }
728 if (err_sum & IO7__POX_ERRSUM__DETECTED_PERR)
729 printk("%s PERR detected\n", err_print_prefix);
730 if (err_sum & IO7__POX_ERRSUM__PM_PERR)
731 printk("%s PERR while IO7 is master\n", err_print_prefix);
732 if (err_sum & IO7__POX_ERRSUM__PT_SCERROR) {
733 printk("%s IO7 Received Split Completion Error message\n",
734 err_print_prefix);
735 marvel_print_pox_spl_cmplt(port->pox_spl_cmplt);
736 }
737 if (err_sum & IO7__POX_ERRSUM__UPE_ERROR) {
738 unsigned int upe_error = EXTRACT(err_sum,
739 IO7__POX_ERRSUM__UPE_ERROR);
740 int i;
741 static char *upe_errors[] = {
742 "Parity Error on MSI write data",
743 "MSI read (MSI window is write only",
744 "TLB - Invalid WR transaction",
745 "TLB - Invalid RD transaction",
746 "DMA - WR error (see north port)",
747 "DMA - RD error (see north port)",
748 "PPR - WR error (see north port)",
749 "PPR - RD error (see north port)"
750 };
751
752 printk("%s UPE Error:\n", err_print_prefix);
753 for (i = 0; i < 8; i++) {
754 if (upe_error & (1 << i))
755 printk("%s %s\n", err_print_prefix,
756 upe_errors[i]);
757 }
758 }
759
760 /*
761 * POx_TRANS_SUM, if appropriate.
762 */
763 if (err_sum & IO7__POX_ERRSUM__TRANS_SUM__MASK)
764 marvel_print_pox_trans_sum(port->pox_trans_sum);
765
766 /*
767 * Then TLB_ERR.
768 */
769 if (err_sum & IO7__POX_ERRSUM__TLB_ERR) {
770 printk("%s TLB ERROR\n", err_print_prefix);
771 marvel_print_pox_tlb_err(port->pox_tlb_err);
772 }
773
774 /*
775 * And the single bit status errors.
776 */
777 if (err_sum & IO7__POX_ERRSUM__AGP_REQQ_OVFL)
778 printk("%s AGP Request Queue Overflow\n", err_print_prefix);
779 if (err_sum & IO7__POX_ERRSUM__AGP_SYNC_ERR)
780 printk("%s AGP Sync Error\n", err_print_prefix);
781 if (err_sum & IO7__POX_ERRSUM__PCIX_DISCARD_SPL)
782 printk("%s Discarded split completion\n", err_print_prefix);
783 if (err_sum & IO7__POX_ERRSUM__DMA_RD_TO)
784 printk("%s DMA Read Timeout\n", err_print_prefix);
785 if (err_sum & IO7__POX_ERRSUM__CSR_NXM_RD)
786 printk("%s CSR NXM READ\n", err_print_prefix);
787 if (err_sum & IO7__POX_ERRSUM__CSR_NXM_WR)
788 printk("%s CSR NXM WRITE\n", err_print_prefix);
789 if (err_sum & IO7__POX_ERRSUM__DETECTED_SERR)
790 printk("%s SERR detected\n", err_print_prefix);
791 if (err_sum & IO7__POX_ERRSUM__HUNG_BUS)
792 printk("%s HUNG BUS detected\n", err_print_prefix);
793}
794
795#endif /* CONFIG_VERBOSE_MCHECK */
796
797static struct ev7_pal_io_subpacket *
798marvel_find_io7_with_error(struct ev7_lf_subpackets *lf_subpackets)
799{
800 struct ev7_pal_io_subpacket *io = lf_subpackets->io;
801 struct io7 *io7;
802 int i;
803
804 /*
805 * Caller must provide the packet to fill
806 */
807 if (!io)
808 return NULL;
809
810 /*
811 * Fill the subpacket with the console's standard fill pattern
812 */
813 memset(io, 0x55, sizeof(*io));
814
815 for (io7 = NULL; NULL != (io7 = marvel_next_io7(prev: io7)); ) {
816 unsigned long err_sum = 0;
817
818 err_sum |= io7->csrs->PO7_ERROR_SUM.csr;
819 for (i = 0; i < IO7_NUM_PORTS; i++) {
820 if (!io7->ports[i].enabled)
821 continue;
822 err_sum |= io7->ports[i].csrs->POx_ERR_SUM.csr;
823 }
824
825 /*
826 * Is there at least one error?
827 */
828 if (err_sum & (1UL << 63))
829 break;
830 }
831
832 /*
833 * Did we find an IO7 with an error?
834 */
835 if (!io7)
836 return NULL;
837
838 /*
839 * We have an IO7 with an error.
840 *
841 * Fill in the IO subpacket.
842 */
843 io->io_asic_rev = io7->csrs->IO_ASIC_REV.csr;
844 io->io_sys_rev = io7->csrs->IO_SYS_REV.csr;
845 io->io7_uph = io7->csrs->IO7_UPH.csr;
846 io->hpi_ctl = io7->csrs->HPI_CTL.csr;
847 io->crd_ctl = io7->csrs->CRD_CTL.csr;
848 io->hei_ctl = io7->csrs->HEI_CTL.csr;
849 io->po7_error_sum = io7->csrs->PO7_ERROR_SUM.csr;
850 io->po7_uncrr_sym = io7->csrs->PO7_UNCRR_SYM.csr;
851 io->po7_crrct_sym = io7->csrs->PO7_CRRCT_SYM.csr;
852 io->po7_ugbge_sym = io7->csrs->PO7_UGBGE_SYM.csr;
853 io->po7_err_pkt0 = io7->csrs->PO7_ERR_PKT[0].csr;
854 io->po7_err_pkt1 = io7->csrs->PO7_ERR_PKT[1].csr;
855
856 for (i = 0; i < IO7_NUM_PORTS; i++) {
857 io7_ioport_csrs *csrs = io7->ports[i].csrs;
858
859 if (!io7->ports[i].enabled)
860 continue;
861
862 io->ports[i].pox_err_sum = csrs->POx_ERR_SUM.csr;
863 io->ports[i].pox_tlb_err = csrs->POx_TLB_ERR.csr;
864 io->ports[i].pox_spl_cmplt = csrs->POx_SPL_COMPLT.csr;
865 io->ports[i].pox_trans_sum = csrs->POx_TRANS_SUM.csr;
866 io->ports[i].pox_first_err = csrs->POx_FIRST_ERR.csr;
867 io->ports[i].pox_mult_err = csrs->POx_MULT_ERR.csr;
868 io->ports[i].pox_dm_source = csrs->POx_DM_SOURCE.csr;
869 io->ports[i].pox_dm_dest = csrs->POx_DM_DEST.csr;
870 io->ports[i].pox_dm_size = csrs->POx_DM_SIZE.csr;
871 io->ports[i].pox_dm_ctrl = csrs->POx_DM_CTRL.csr;
872
873 /*
874 * Ack this port's errors, if any. POx_ERR_SUM must be last.
875 *
876 * Most of the error registers get cleared and unlocked when
877 * the associated bits in POx_ERR_SUM are cleared (by writing
878 * 1). POx_TLB_ERR is an exception and must be explicitly
879 * cleared.
880 */
881 csrs->POx_TLB_ERR.csr = io->ports[i].pox_tlb_err;
882 csrs->POx_ERR_SUM.csr = io->ports[i].pox_err_sum;
883 mb();
884 csrs->POx_ERR_SUM.csr;
885 }
886
887 /*
888 * Ack any port 7 error(s).
889 */
890 io7->csrs->PO7_ERROR_SUM.csr = io->po7_error_sum;
891 mb();
892 io7->csrs->PO7_ERROR_SUM.csr;
893
894 /*
895 * Correct the io7_pid.
896 */
897 lf_subpackets->io_pid = io7->pe;
898
899 return io;
900}
901
902static int
903marvel_process_io_error(struct ev7_lf_subpackets *lf_subpackets, int print)
904{
905 int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
906
907#ifdef CONFIG_VERBOSE_MCHECK
908 struct ev7_pal_io_subpacket *io = lf_subpackets->io;
909 int i;
910#endif /* CONFIG_VERBOSE_MCHECK */
911
912#define MARVEL_IO_ERR_VALID(x) ((x) & (1UL << 63))
913
914 if (!lf_subpackets->logout || !lf_subpackets->io)
915 return status;
916
917 /*
918 * The PALcode only builds an IO subpacket if there is a
919 * locally connected IO7. In the cases of
920 * 1) a uniprocessor kernel
921 * 2) an mp kernel before the local secondary has called in
922 * error interrupts are all directed to the primary processor.
923 * In that case, we may not have an IO subpacket at all and, event
924 * if we do, it may not be the right now.
925 *
926 * If the RBOX indicates an I/O error interrupt, make sure we have
927 * the correct IO7 information. If we don't have an IO subpacket
928 * or it's the wrong one, try to find the right one.
929 *
930 * RBOX I/O error interrupts are indicated by RBOX_INT<29> and
931 * RBOX_INT<10>.
932 */
933 if ((lf_subpackets->io->po7_error_sum & (1UL << 32)) ||
934 ((lf_subpackets->io->po7_error_sum |
935 lf_subpackets->io->ports[0].pox_err_sum |
936 lf_subpackets->io->ports[1].pox_err_sum |
937 lf_subpackets->io->ports[2].pox_err_sum |
938 lf_subpackets->io->ports[3].pox_err_sum) & (1UL << 63))) {
939 /*
940 * Either we have no IO subpacket or no error is
941 * indicated in the one we do have. Try find the
942 * one with the error.
943 */
944 if (!marvel_find_io7_with_error(lf_subpackets))
945 return status;
946 }
947
948 /*
949 * We have an IO7 indicating an error - we're going to report it
950 */
951 status = MCHK_DISPOSITION_REPORT;
952
953#ifdef CONFIG_VERBOSE_MCHECK
954
955 if (!print)
956 return status;
957
958 printk("%s*Error occurred on IO7 at PID %u\n",
959 err_print_prefix, lf_subpackets->io_pid);
960
961 /*
962 * Check port 7 first
963 */
964 if (lf_subpackets->io->po7_error_sum & IO7__PO7_ERRSUM__ERR_MASK) {
965 marvel_print_po7_err_sum(io);
966
967#if 0
968 printk("%s PORT 7 ERROR:\n"
969 "%s PO7_ERROR_SUM: %016llx\n"
970 "%s PO7_UNCRR_SYM: %016llx\n"
971 "%s PO7_CRRCT_SYM: %016llx\n"
972 "%s PO7_UGBGE_SYM: %016llx\n"
973 "%s PO7_ERR_PKT0: %016llx\n"
974 "%s PO7_ERR_PKT1: %016llx\n",
975 err_print_prefix,
976 err_print_prefix, io->po7_error_sum,
977 err_print_prefix, io->po7_uncrr_sym,
978 err_print_prefix, io->po7_crrct_sym,
979 err_print_prefix, io->po7_ugbge_sym,
980 err_print_prefix, io->po7_err_pkt0,
981 err_print_prefix, io->po7_err_pkt1);
982#endif
983 }
984
985 /*
986 * Then loop through the ports
987 */
988 for (i = 0; i < IO7_NUM_PORTS; i++) {
989 if (!MARVEL_IO_ERR_VALID(io->ports[i].pox_err_sum))
990 continue;
991
992 printk("%s PID %u PORT %d POx_ERR_SUM: %016llx\n",
993 err_print_prefix,
994 lf_subpackets->io_pid, i, io->ports[i].pox_err_sum);
995 marvel_print_pox_err(io->ports[i].pox_err_sum, &io->ports[i]);
996
997 printk("%s [ POx_FIRST_ERR: %016llx ]\n",
998 err_print_prefix, io->ports[i].pox_first_err);
999 marvel_print_pox_err(io->ports[i].pox_first_err,
1000 &io->ports[i]);
1001
1002 }
1003
1004
1005#endif /* CONFIG_VERBOSE_MCHECK */
1006
1007 return status;
1008}
1009
1010static int
1011marvel_process_logout_frame(struct ev7_lf_subpackets *lf_subpackets, int print)
1012{
1013 int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
1014
1015 /*
1016 * I/O error?
1017 */
1018#define EV7__RBOX_INT__IO_ERROR__MASK 0x20000400ul
1019 if (lf_subpackets->logout &&
1020 (lf_subpackets->logout->rbox_int & 0x20000400ul))
1021 status = marvel_process_io_error(lf_subpackets, print);
1022
1023 /*
1024 * Probing behind PCI-X bridges can cause machine checks on
1025 * Marvel when the probe is handled by the bridge as a split
1026 * completion transaction. The symptom is an ERROR_RESPONSE
1027 * to a CONFIG address. Since these errors will happen in
1028 * normal operation, dismiss them.
1029 *
1030 * Dismiss if:
1031 * C_STAT = 0x14 (Error Response)
1032 * C_STS<3> = 0 (C_ADDR valid)
1033 * C_ADDR<42> = 1 (I/O)
1034 * C_ADDR<31:22> = 111110xxb (PCI Config space)
1035 */
1036 if (lf_subpackets->ev7 &&
1037 (lf_subpackets->ev7->c_stat == 0x14) &&
1038 !(lf_subpackets->ev7->c_sts & 0x8) &&
1039 ((lf_subpackets->ev7->c_addr & 0x400ff000000ul)
1040 == 0x400fe000000ul))
1041 status = MCHK_DISPOSITION_DISMISS;
1042
1043 return status;
1044}
1045
1046void
1047marvel_machine_check(unsigned long vector, unsigned long la_ptr)
1048{
1049 struct el_subpacket *el_ptr = (struct el_subpacket *)la_ptr;
1050 int (*process_frame)(struct ev7_lf_subpackets *, int) = NULL;
1051 struct ev7_lf_subpackets subpacket_collection = { NULL, };
1052 struct ev7_pal_io_subpacket scratch_io_packet = { 0, };
1053 struct ev7_lf_subpackets *lf_subpackets = NULL;
1054 int disposition = MCHK_DISPOSITION_UNKNOWN_ERROR;
1055 char *saved_err_prefix = err_print_prefix;
1056 char *error_type = NULL;
1057
1058 /*
1059 * Sync the processor
1060 */
1061 mb();
1062 draina();
1063
1064 switch(vector) {
1065 case SCB_Q_SYSEVENT:
1066 process_frame = marvel_process_680_frame;
1067 error_type = "System Event";
1068 break;
1069
1070 case SCB_Q_SYSMCHK:
1071 process_frame = marvel_process_logout_frame;
1072 error_type = "System Uncorrectable Error";
1073 break;
1074
1075 case SCB_Q_SYSERR:
1076 process_frame = marvel_process_logout_frame;
1077 error_type = "System Correctable Error";
1078 break;
1079
1080 default:
1081 /* Don't know it - pass it up. */
1082 ev7_machine_check(vector, la_ptr);
1083 return;
1084 }
1085
1086 /*
1087 * A system event or error has occurred, handle it here.
1088 *
1089 * Any errors in the logout frame have already been cleared by the
1090 * PALcode, so just parse it.
1091 */
1092 err_print_prefix = KERN_CRIT;
1093
1094 /*
1095 * Parse the logout frame without printing first. If the only error(s)
1096 * found are classified as "dismissable", then just dismiss them and
1097 * don't print any message
1098 */
1099 lf_subpackets =
1100 ev7_collect_logout_frame_subpackets(el_ptr,
1101 &subpacket_collection);
1102 if (process_frame && lf_subpackets && lf_subpackets->logout) {
1103 /*
1104 * We might not have the correct (or any) I/O subpacket.
1105 * [ See marvel_process_io_error() for explanation. ]
1106 * If we don't have one, point the io subpacket in
1107 * lf_subpackets at scratch_io_packet so that
1108 * marvel_find_io7_with_error() will have someplace to
1109 * store the info.
1110 */
1111 if (!lf_subpackets->io)
1112 lf_subpackets->io = &scratch_io_packet;
1113
1114 /*
1115 * Default io_pid to the processor reporting the error
1116 * [this will get changed in marvel_find_io7_with_error()
1117 * if a different one is needed]
1118 */
1119 lf_subpackets->io_pid = lf_subpackets->logout->whami;
1120
1121 /*
1122 * Evaluate the frames.
1123 */
1124 disposition = process_frame(lf_subpackets, 0);
1125 }
1126 switch(disposition) {
1127 case MCHK_DISPOSITION_DISMISS:
1128 /* Nothing to do. */
1129 break;
1130
1131 case MCHK_DISPOSITION_REPORT:
1132 /* Recognized error, report it. */
1133 printk("%s*%s (Vector 0x%x) reported on CPU %d\n",
1134 err_print_prefix, error_type,
1135 (unsigned int)vector, (int)smp_processor_id());
1136 el_print_timestamp(&lf_subpackets->logout->timestamp);
1137 process_frame(lf_subpackets, 1);
1138 break;
1139
1140 default:
1141 /* Unknown - dump the annotated subpackets. */
1142 printk("%s*%s (Vector 0x%x) reported on CPU %d\n",
1143 err_print_prefix, error_type,
1144 (unsigned int)vector, (int)smp_processor_id());
1145 el_process_subpacket(el_ptr);
1146 break;
1147
1148 }
1149
1150 err_print_prefix = saved_err_prefix;
1151
1152 /* Release the logout frame. */
1153 wrmces(mces: 0x7);
1154 mb();
1155}
1156
1157void __init
1158marvel_register_error_handlers(void)
1159{
1160 ev7_register_error_handlers();
1161}
1162

source code of linux/arch/alpha/kernel/err_marvel.c