ia64/linux-2.6.18-xen.hg

view arch/alpha/kernel/err_marvel.c @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

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