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