xref: /linux/arch/alpha/kernel/err_tsunami.c (revision 73b8c00851e27ac3497d50d4ecc59892b0cc5577)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Machine check handling for Tsunami/Typhoon systems.
4  * Author: Magnus Lindholm <linmag7@gmail.com>
5  * Based on Titan error handling by Jeff Wiedemeier (Compaq).
6  * Register definitions: 21272 Hardware Reference Manual, revision 4.0.
7  */
8 #include <linux/init.h>
9 #include <linux/pci.h>
10 #include <linux/sched.h>
11 #include <asm/io.h>
12 #include <asm/core_tsunami.h>
13 #include <asm/smp.h>
14 #include <asm/err_common.h>
15 #include <asm/irq_regs.h>
16 #include "err_impl.h"
17 #include "proto.h"
18 #include "pci_impl.h"
19 
20 #define TSUNAMI_PERROR_ERRMASK	0xdffUL
21 #define TSUNAMI_PERROR_ECCMASK	(perror_m_uecc | perror_m_cre)
22 #define TSUNAMI_PERROR_INV	(1UL << 51)
23 #define TSUNAMI_MISC_NXM		(1UL << 28)
24 
25 static int
26 tsunami_frame_valid(struct el_common *header, size_t size)
27 {
28 	return !((header->sys_offset | header->size) & 7) &&
29 	       header->sys_offset >= sizeof(*header) &&
30 	       header->sys_offset <= header->size &&
31 	       size <= header->size - header->sys_offset;
32 }
33 
34 static int
35 tsunami_parse_p_perror(int which, u64 perror, int print)
36 {
37 	static const char * const errors[] = {
38 		"Lost error", "SERR asserted", "PERR asserted",
39 		"Delayed-completion retry timeout", "Invalid scatter-gather PTE",
40 		"Address parity error", "Target abort", "Read data parity error",
41 		"No DEVSEL (master abort)", NULL,
42 		"Uncorrectable ECC error", "Correctable ECC error"
43 	};
44 	static const char * const pci_cmd[] = {
45 		"Interrupt acknowledge", "Special cycle", "I/O read", "I/O write",
46 		"Reserved", "Reserved", "Memory read", "Memory write",
47 		"Reserved", "Reserved", "Configuration read", "Configuration write",
48 		"Memory read multiple", "Dual address cycle",
49 		"Memory read line", "Memory write and invalidate"
50 	};
51 	unsigned long addr;
52 	unsigned int cmd;
53 	int i;
54 
55 	if (!(perror & TSUNAMI_PERROR_ERRMASK))
56 		return MCHK_DISPOSITION_UNKNOWN_ERROR;
57 	/* Do not import Titan's BIOS master-abort dismissal policy. */
58 	if (!print)
59 		return MCHK_DISPOSITION_REPORT;
60 
61 	printk("%s  Pchip %d PERROR: %016llx\n", err_print_prefix, which, perror);
62 	for (i = 0; i < ARRAY_SIZE(errors); i++)
63 		if ((perror & TSUNAMI_PERROR_ERRMASK & (1UL << i)) && errors[i])
64 			printk("%s    %s\n", err_print_prefix, errors[i]);
65 
66 	/*
67 	 * INV invalidates SYN, CMD and ADDR. HRM 8.8.2.6 leaves command/address
68 	 * undefined whenever SERR is set, including with other error bits.
69 	 */
70 	if (perror & (TSUNAMI_PERROR_INV | perror_m_serr)) {
71 		printk("%s    Transaction information unavailable\n", err_print_prefix);
72 		return MCHK_DISPOSITION_REPORT;
73 	}
74 	cmd = (perror & perror_m_cmd) >> 52;
75 	/*
76 	 * Table 10-42 selects the ECC fields whenever CRE or UECC is set.
77 	 * The first error freezes PERROR (10.2.5.6); mixed error bits were
78 	 * detected together. Only LOST can be set afterwards.
79 	 */
80 	if (perror & TSUNAMI_PERROR_ECCMASK) {
81 		const char *command = "Reserved";
82 
83 		if (cmd == 0)
84 			command = "DMA read";
85 		else if (cmd == 1)
86 			command = "DMA RMW";
87 		else if (cmd == 3)
88 			command = "SGTE read";
89 		addr = ((perror >> 19) & 0xffffffffUL) << 3;
90 		printk("%s    Command: %s (%x), syndrome: %02llx\n",
91 		       err_print_prefix, command, cmd, (perror & perror_m_syn) >> 56);
92 		printk("%s    System address: %lx\n", err_print_prefix, addr);
93 	} else {
94 		addr = ((perror >> 18) & 0x3fffffffUL) << 2;
95 		/* SGE captures only PCI address bits <31:13> (8KB page). */
96 		if (perror & perror_m_sge)
97 			addr &= ~0x1fffUL;
98 		printk("%s    Command: %s (%x), PCI address: %lx%s\n",
99 		       err_print_prefix, pci_cmd[cmd], cmd, addr,
100 		       (perror & perror_m_sge) ? " (8KB page)" : "");
101 		if (perror & (1UL << 17))
102 			printk("%s    Monster window\n", err_print_prefix);
103 		else if (perror & (1UL << 16))
104 			printk("%s    DAC scatter-gather window 3\n", err_print_prefix);
105 	}
106 	return MCHK_DISPOSITION_REPORT;
107 }
108 
109 /* SESF bits 0/1 identify PCI errors, bit 2 covers ECC on either Pchip/CPU. */
110 static u64
111 tsunami_pchip_error(struct el_TSUNAMI_sysdata_mcheck *frame, int which)
112 {
113 	u64 perror = which ? frame->p1_perror : frame->p0_perror;
114 
115 	if (frame->sesf & (1UL << which))
116 		return perror;
117 	if ((frame->sesf & 4) && (perror & TSUNAMI_PERROR_ECCMASK))
118 		return perror;
119 	return 0;
120 }
121 
122 static struct el_TSUNAMI_sysdata_mcheck *
123 tsunami_system_frame(struct el_common *header)
124 {
125 	if (!tsunami_frame_valid(header, sizeof(struct el_TSUNAMI_sysdata_mcheck)))
126 		return NULL;
127 	return (void *)header + header->sys_offset;
128 }
129 
130 static int
131 tsunami_process_logout_frame(struct el_common *header, int print)
132 {
133 	struct el_TSUNAMI_sysdata_mcheck *frame = tsunami_system_frame(header);
134 	int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
135 	int i;
136 
137 	if (!frame) {
138 		if (print) {
139 			printk("%s  Invalid Tsunami system frame; raw frame follows\n",
140 			       err_print_prefix);
141 			mchk_dump_logout_frame_raw(header);
142 		}
143 		return MCHK_DISPOSITION_UNKNOWN_ERROR;
144 	}
145 	if (print)
146 		printk("%s  SESF: %016llx DIR: %016llx MISC: %016llx\n",
147 		       err_print_prefix, frame->sesf, frame->dir, frame->misc);
148 	if (frame->misc & TSUNAMI_MISC_NXM) {
149 		status = MCHK_DISPOSITION_REPORT;
150 		if (print)
151 			printk("%s  Non-existent memory, NXS: %llu\n",
152 			       err_print_prefix, (frame->misc >> 29) & 7);
153 	}
154 	for (i = 0; i < 2; i++)
155 		status |= tsunami_parse_p_perror(i, tsunami_pchip_error(frame, i), print);
156 	return status;
157 }
158 
159 struct tsunami_error_state {
160 	u64 perror[2];
161 	u64 misc;
162 };
163 
164 static void
165 tsunami_ack_pchip(tsunami_pchip *pchip, u64 perror)
166 {
167 	if (!(perror & TSUNAMI_PERROR_ERRMASK))
168 		return;
169 	pchip->perror.csr = perror & TSUNAMI_PERROR_ERRMASK;
170 	/* Complete the W1C write before releasing the logout frame. */
171 	mb();
172 	pchip->perror.csr;
173 }
174 
175 static void
176 tsunami_clear_errors(struct tsunami_error_state *state)
177 {
178 	bool pchip1 = TSUNAMI_cchip->csc.csr & (1UL << 14);
179 
180 	/* Preserve each chip's transaction and the NXM source before clearing. */
181 	state->perror[0] = TSUNAMI_pchip0->perror.csr;
182 	state->perror[1] = pchip1 ? TSUNAMI_pchip1->perror.csr : 0;
183 	state->misc = TSUNAMI_cchip->misc.csr;
184 
185 	/*
186 	 * Acknowledge both present Pchips: the saved frame may predate
187 	 * live errors. This can consume another chip's pending error
188 	 * with INV set before it reaches DRIR, losing its transaction
189 	 * details and subsequent system-error notification.
190 	 */
191 	tsunami_ack_pchip(TSUNAMI_pchip0, state->perror[0]);
192 	/* Do not access the second Pchip on single-Pchip systems. */
193 	if (pchip1)
194 		tsunami_ack_pchip(TSUNAMI_pchip1, state->perror[1]);
195 	if (state->misc & TSUNAMI_MISC_NXM) {
196 		/* Zero writes leave the other MISC fields unchanged. */
197 		TSUNAMI_cchip->misc.csr = TSUNAMI_MISC_NXM;
198 		/* Complete the NXM acknowledgment before releasing the frame. */
199 		mb();
200 		TSUNAMI_cchip->misc.csr;
201 	}
202 }
203 
204 static void
205 tsunami_report_live_errors(struct tsunami_error_state *state,
206 			  struct el_TSUNAMI_sysdata_mcheck *frame)
207 {
208 	int i;
209 
210 	/* PALcode's frame may predate these errors, or describe another chip. */
211 	for (i = 0; i < 2; i++) {
212 		if (!(state->perror[i] & TSUNAMI_PERROR_ERRMASK) ||
213 		    (frame && state->perror[i] == tsunami_pchip_error(frame, i)))
214 			continue;
215 		printk("%s  Live Pchip status before acknowledgment:\n", err_print_prefix);
216 		tsunami_parse_p_perror(i, state->perror[i], 1);
217 	}
218 	if ((state->misc & TSUNAMI_MISC_NXM) &&
219 	    (!frame || ((state->misc ^ frame->misc) & (0xfUL << 28))))
220 		printk("%s  Live MISC: %016llx, non-existent memory, NXS: %llu\n",
221 		       err_print_prefix, state->misc, (state->misc >> 29) & 7);
222 }
223 
224 void
225 tsunami_machine_check(unsigned long vector, unsigned long la_ptr)
226 {
227 	struct el_common *header = (void *)la_ptr;
228 	struct el_TSUNAMI_sysdata_mcheck *frame = NULL;
229 	struct tsunami_error_state live = {};
230 	char *saved_err_prefix = err_print_prefix;
231 	bool show_regs = vector == SCB_Q_SYSMCHK;
232 
233 	/* Synchronize pending accesses before inspecting the chipset. */
234 	mb();
235 	mb();
236 	draina();
237 	/* CPU/event vectors must not consume a pending Pchip system error. */
238 	if (vector == SCB_Q_SYSMCHK || vector == SCB_Q_SYSERR) {
239 		tsunami_clear_errors(&live);
240 		frame = tsunami_system_frame(header);
241 	}
242 
243 #ifdef CONFIG_VERBOSE_MCHECK
244 	show_regs |= alpha_verbose_mcheck != 0;
245 #endif
246 	err_print_prefix = KERN_CRIT;
247 	if (vector == SCB_Q_SYSMCHK || vector == SCB_Q_SYSERR) {
248 		printk("%sSystem %s error (vector %lx, code %x) on CPU %d:\n",
249 		       err_print_prefix, vector == SCB_Q_SYSERR ? "correctable" :
250 		       "uncorrectable", vector, header->code, smp_processor_id());
251 		tsunami_process_logout_frame(header, 1);
252 		if (show_regs)
253 			dik_show_regs(get_irq_regs(), NULL);
254 		tsunami_report_live_errors(&live, frame);
255 	} else if (vector == SCB_Q_SYSEVENT) {
256 		printk("%sTsunami environmental event (code %x): layout unknown\n",
257 		       err_print_prefix, header->code);
258 		mchk_dump_logout_frame_raw(header);
259 	}
260 	err_print_prefix = saved_err_prefix;
261 
262 	if (vector != SCB_Q_SYSMCHK && vector != SCB_Q_SYSERR &&
263 	    vector != SCB_Q_SYSEVENT) {
264 		/* EV6 decoding also releases the logout frame. */
265 		ev6_machine_check(vector, la_ptr);
266 	} else {
267 		wrmces(0x7);
268 		/* Complete acknowledgment before resuming. */
269 		mb();
270 	}
271 }
272 
273 static const char * const CLIPPER_EnvQW1SMIR[] = {
274 	"", /* SMIR<0>: retain as raw context until its semantics are known. */
275 	"OCP or RMC halt detected",
276 	"Sys_DC_Notok failure detected",
277 	"",
278 	"System temperature over 50 degrees C failure",
279 	"PCI Bus #0 is in reset",
280 	"PCI Bus #1 is in reset",
281 	"System is being reset"
282 };
283 
284 static const char * const CLIPPER_EnvQW2CPUIR[] = {
285 	"CPU0 regulator is enabled",
286 	"CPU1 regulator is enabled",
287 	"CPU2 regulator is enabled",
288 	"CPU3 regulator is enabled",
289 	"CPU0 regulator or configuration sequence fail",
290 	"CPU1 regulator or configuration sequence fail",
291 	"CPU2 regulator or configuration sequence fail",
292 	"CPU3 regulator or configuration sequence fail"
293 };
294 
295 static const char * const CLIPPER_EnvQW3PSIR[] = {
296 	"Power Supply 0 is enabled",
297 	"Power Supply 1 is enabled",
298 	"Power Supply 2 is enabled",
299 	"",
300 	"Power Supply 0 was enabled but failed",
301 	"Power Supply 1 was enabled but failed",
302 	"Power Supply 2 was enabled but failed"
303 };
304 
305 static const char * const CLIPPER_EnvQW4LM78ISR[] = {
306 	"PS +3.3V out of tolerance",
307 	"PS +5V out of tolerance",
308 	"PS +12V out of tolerance",
309 	"VTERM out of tolerance",
310 	"Temperature zone 0 (PCI Backplane slots 1-3 area) over limit failure",
311 	"LM75 CPU0-3 Temperature over limit failure",
312 	"System Fan 1 failure",
313 	"System Fan 2 failure",
314 	"CTERM out of tolerance",
315 	"",
316 	"-12V out of tolerance",
317 	"",
318 	"",
319 	"",
320 	"",
321 	"",
322 	"CPU0_VCORE +2V out of tolerance",
323 	"CPU0_VIO +1.5V out of tolerance",
324 	"CPU1_VCORE +2V out of tolerance",
325 	"CPU1_VIO +1.5V out of tolerance",
326 	"Temperature zone 1 (PCI Backplane slots 7-10 area) over limit failure",
327 	"",
328 	"System Fan 4 failure",
329 	"System Fan 5 failure",
330 	"",
331 	"",
332 	"",
333 	"",
334 	"",
335 	"",
336 	"",
337 	"",
338 	"CPU2_VCORE +2V out of tolerance",
339 	"CPU2_VIO +1.5V out of tolerance",
340 	"CPU3_VCORE +2V out of tolerance",
341 	"CPU3_VIO +1.5V out of tolerance",
342 	"Temperature zone 2 (PCI Backplane slots 4-6 area) over limit failure",
343 	"",
344 	"System Fan 3 failure",
345 	"System Fan 6 failure",
346 	"",
347 	"",
348 	"Power supply 3.3V rail above high amperage warning",
349 	"Power supply 5.0V rail above high amperage warning",
350 	"Power supply 12V rail above high amperage warning",
351 	"Power supply high temperature warning",
352 	"Power supply AC input low limit warning",
353 	"Power supply AC input high limit warning"
354 };
355 
356 static const char * const CLIPPER_EnvQW5DOOR[] = {
357 	"",
358 	"System CPU door is open",
359 	"System Fan door is open",
360 	"System PCI door is open",
361 	"",
362 	"System CPU door is closed",
363 	"System Fan door is closed",
364 	"System PCI door is closed"
365 };
366 
367 static const char * const CLIPPER_EnvQW6TEMP[] = {
368 	"CPU0 temperature warning fault has occurred",
369 	"CPU1 temperature warning fault has occurred",
370 	"CPU2 temperature warning fault has occurred",
371 	"CPU3 temperature warning fault has occurred",
372 	"System temperature zone 0 warning fault has occurred",
373 	"System temperature zone 1 warning fault has occurred",
374 	"System temperature zone 2 warning fault has occurred"
375 };
376 
377 static const char * const CLIPPER_EnvQW7FAN[] = {
378 	"System Fan 1 is not responding to RMC Commands",
379 	"System Fan 2 is not responding to RMC Commands",
380 	"System Fan 3 is not responding to RMC Commands",
381 	"System Fan 4 is not responding to RMC Commands",
382 	"System Fan 5 is not responding to RMC Commands",
383 	"System Fan 6 is not responding to RMC Commands",
384 	"",
385 	"",
386 	"CPU fans 5/6 at maximum speed",
387 	"CPU fans 5/6 reduced speed from maximum",
388 	"PCI fans 1-4 at maximum speed",
389 	"PCI fans 1-4 reduced speed from maximum"
390 };
391 
392 #define CLIPPER_ENV_LM78ISR_MASK	0xfcdf00df05ffUL
393 
394 /* ES40 Service Guide EK-ES240-SV A01, live frame: Tables D-20 and D-21. */
395 struct el_clipper_envdata {
396 	u64 summary;
397 	u64 dir;
398 	u64 smir;
399 	u64 cpuir;
400 	u64 psir;
401 	u64 fault;
402 	u64 doors;
403 	u64 temp_warn;
404 	u64 fan_ctrl;
405 	u64 fatal_power_down;
406 	u64 reserved;
407 };
408 
409 static bool
410 clipper_print_bits(const char * const *messages, size_t count,
411 		   u64 value, u64 mask)
412 {
413 	size_t i;
414 
415 	if (!(value & mask))
416 		return false;
417 	for (i = 0; i < count; i++)
418 		if (value & mask & (1UL << i))
419 			printk("%s    %s\n", err_print_prefix, messages[i]);
420 	return true;
421 }
422 
423 #define CLIPPER_BITS(table, value, mask) \
424 	clipper_print_bits(table, ARRAY_SIZE(table), value, mask)
425 
426 static void
427 clipper_process_environment(struct el_common *header)
428 {
429 	struct el_clipper_envdata *frame;
430 	bool fault = false;
431 
432 	if (!tsunami_frame_valid(header, sizeof(*frame))) {
433 		printk("%s  Truncated Clipper environmental frame\n", err_print_prefix);
434 		mchk_dump_logout_frame_raw(header);
435 		return;
436 	}
437 	frame = (void *)header + header->sys_offset;
438 	/* Only QW1 through QW7 carry error state in the live 680 frame. */
439 	/* PSU summary and inverted halt/reset signals remain raw context. */
440 	fault |= CLIPPER_BITS(CLIPPER_EnvQW1SMIR, frame->smir, 0x14);
441 	fault |= CLIPPER_BITS(CLIPPER_EnvQW2CPUIR, frame->cpuir, 0xf0);
442 	fault |= CLIPPER_BITS(CLIPPER_EnvQW3PSIR, frame->psir, 0x70);
443 	fault |= CLIPPER_BITS(CLIPPER_EnvQW4LM78ISR,
444 			       frame->fault, CLIPPER_ENV_LM78ISR_MASK);
445 	fault |= CLIPPER_BITS(CLIPPER_EnvQW5DOOR, frame->doors, 0x0e);
446 	fault |= CLIPPER_BITS(CLIPPER_EnvQW6TEMP, frame->temp_warn, 0x7f);
447 	fault |= CLIPPER_BITS(CLIPPER_EnvQW7FAN, frame->fan_ctrl, 0x3f);
448 	/* A notification with no recognized fault can describe recovery. */
449 	if (!fault)
450 		printk("%s    No recognized environmental fault bits set\n",
451 		       err_print_prefix);
452 	printk("%s  Environmental summary: %016llx DIR: %016llx\n",
453 	       err_print_prefix, frame->summary, frame->dir);
454 	printk("%s  SMIR: %016llx (PSU summary/halt/reset bits undecoded)\n",
455 	       err_print_prefix, frame->smir);
456 	CLIPPER_BITS(CLIPPER_EnvQW2CPUIR, frame->cpuir, 0x0f);
457 	CLIPPER_BITS(CLIPPER_EnvQW3PSIR, frame->psir, 0x07);
458 	CLIPPER_BITS(CLIPPER_EnvQW5DOOR, frame->doors, 0xe0);
459 	CLIPPER_BITS(CLIPPER_EnvQW7FAN, frame->fan_ctrl, 0xf00);
460 	if (frame->fault & (0x3fUL << 42))
461 		printk("%s  Power supply warning source: %llu (3 = reserved)\n",
462 		       err_print_prefix, (frame->fault >> 40) & 3);
463 }
464 
465 void
466 clipper_machine_check(unsigned long vector, unsigned long la_ptr)
467 {
468 	struct el_common *header = (void *)la_ptr;
469 	char *saved_err_prefix = err_print_prefix;
470 
471 	if (vector != SCB_Q_SYSEVENT) {
472 		tsunami_machine_check(vector, la_ptr);
473 		return;
474 	}
475 	/* Drain pending accesses before inspecting the environmental frame. */
476 	mb();
477 	draina();
478 	err_print_prefix = KERN_CRIT;
479 	printk("%sSystem correctable environmental event (code %x) on CPU %d:\n",
480 	       err_print_prefix, header->code, smp_processor_id());
481 	if (header->code == 0x206)
482 		clipper_process_environment(header);
483 	else {
484 		printk("%s  Unrecognized environmental event; raw frame follows\n",
485 		       err_print_prefix);
486 		mchk_dump_logout_frame_raw(header);
487 	}
488 	err_print_prefix = saved_err_prefix;
489 	wrmces(0x7);
490 	/* Complete acknowledgment before returning from the event. */
491 	mb();
492 }
493