1 /* 2 * linux/arch/alpha/kernel/err_titan.c 3 * 4 * Copyright (C) 2000 Jeff Wiedemeier (Compaq Computer Corporation) 5 * 6 * Error handling code supporting TITAN systems 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/core_titan.h> 15 #include <asm/hwrpb.h> 16 #include <asm/smp.h> 17 #include <asm/err_common.h> 18 #include <asm/err_ev6.h> 19 #include <asm/irq_regs.h> 20 21 #include "err_impl.h" 22 #include "proto.h" 23 24 25 static int 26 titan_parse_c_misc(u64 c_misc, int print) 27 { 28 #ifdef CONFIG_VERBOSE_MCHECK 29 char *src; 30 int nxs = 0; 31 #endif 32 int status = MCHK_DISPOSITION_REPORT; 33 34 #define TITAN__CCHIP_MISC__NXM (1UL << 28) 35 #define TITAN__CCHIP_MISC__NXS__S (29) 36 #define TITAN__CCHIP_MISC__NXS__M (0x7) 37 38 if (!(c_misc & TITAN__CCHIP_MISC__NXM)) 39 return MCHK_DISPOSITION_UNKNOWN_ERROR; 40 41 #ifdef CONFIG_VERBOSE_MCHECK 42 if (!print) 43 return status; 44 45 nxs = EXTRACT(c_misc, TITAN__CCHIP_MISC__NXS); 46 switch(nxs) { 47 case 0: /* CPU 0 */ 48 case 1: /* CPU 1 */ 49 case 2: /* CPU 2 */ 50 case 3: /* CPU 3 */ 51 src = "CPU"; 52 /* num is already the CPU number */ 53 break; 54 case 4: /* Pchip 0 */ 55 case 5: /* Pchip 1 */ 56 src = "Pchip"; 57 nxs -= 4; 58 break; 59 default:/* reserved */ 60 src = "Unknown, NXS ="; 61 /* leave num untouched */ 62 break; 63 } 64 65 printk("%s Non-existent memory access from: %s %d\n", 66 err_print_prefix, src, nxs); 67 #endif /* CONFIG_VERBOSE_MCHECK */ 68 69 return status; 70 } 71 72 static int 73 titan_parse_p_serror(int which, u64 serror, int print) 74 { 75 int status = MCHK_DISPOSITION_REPORT; 76 77 #ifdef CONFIG_VERBOSE_MCHECK 78 char *serror_src[] = {"GPCI", "APCI", "AGP HP", "AGP LP"}; 79 char *serror_cmd[] = {"DMA Read", "DMA RMW", "SGTE Read", "Reserved"}; 80 #endif /* CONFIG_VERBOSE_MCHECK */ 81 82 #define TITAN__PCHIP_SERROR__LOST_UECC (1UL << 0) 83 #define TITAN__PCHIP_SERROR__UECC (1UL << 1) 84 #define TITAN__PCHIP_SERROR__CRE (1UL << 2) 85 #define TITAN__PCHIP_SERROR__NXIO (1UL << 3) 86 #define TITAN__PCHIP_SERROR__LOST_CRE (1UL << 4) 87 #define TITAN__PCHIP_SERROR__ECCMASK (TITAN__PCHIP_SERROR__UECC | \ 88 TITAN__PCHIP_SERROR__CRE) 89 #define TITAN__PCHIP_SERROR__ERRMASK (TITAN__PCHIP_SERROR__LOST_UECC | \ 90 TITAN__PCHIP_SERROR__UECC | \ 91 TITAN__PCHIP_SERROR__CRE | \ 92 TITAN__PCHIP_SERROR__NXIO | \ 93 TITAN__PCHIP_SERROR__LOST_CRE) 94 #define TITAN__PCHIP_SERROR__SRC__S (52) 95 #define TITAN__PCHIP_SERROR__SRC__M (0x3) 96 #define TITAN__PCHIP_SERROR__CMD__S (54) 97 #define TITAN__PCHIP_SERROR__CMD__M (0x3) 98 #define TITAN__PCHIP_SERROR__SYN__S (56) 99 #define TITAN__PCHIP_SERROR__SYN__M (0xff) 100 #define TITAN__PCHIP_SERROR__ADDR__S (15) 101 #define TITAN__PCHIP_SERROR__ADDR__M (0xffffffffUL) 102 103 if (!(serror & TITAN__PCHIP_SERROR__ERRMASK)) 104 return MCHK_DISPOSITION_UNKNOWN_ERROR; 105 106 #ifdef CONFIG_VERBOSE_MCHECK 107 if (!print) 108 return status; 109 110 printk("%s PChip %d SERROR: %016llx\n", 111 err_print_prefix, which, serror); 112 if (serror & TITAN__PCHIP_SERROR__ECCMASK) { 113 printk("%s %sorrectable ECC Error:\n" 114 " Source: %-6s Command: %-8s Syndrome: 0x%08x\n" 115 " Address: 0x%llx\n", 116 err_print_prefix, 117 (serror & TITAN__PCHIP_SERROR__UECC) ? "Unc" : "C", 118 serror_src[EXTRACT(serror, TITAN__PCHIP_SERROR__SRC)], 119 serror_cmd[EXTRACT(serror, TITAN__PCHIP_SERROR__CMD)], 120 (unsigned)EXTRACT(serror, TITAN__PCHIP_SERROR__SYN), 121 EXTRACT(serror, TITAN__PCHIP_SERROR__ADDR)); 122 } 123 if (serror & TITAN__PCHIP_SERROR__NXIO) 124 printk("%s Non Existent I/O Error\n", err_print_prefix); 125 if (serror & TITAN__PCHIP_SERROR__LOST_UECC) 126 printk("%s Lost Uncorrectable ECC Error\n", 127 err_print_prefix); 128 if (serror & TITAN__PCHIP_SERROR__LOST_CRE) 129 printk("%s Lost Correctable ECC Error\n", err_print_prefix); 130 #endif /* CONFIG_VERBOSE_MCHECK */ 131 132 return status; 133 } 134 135 static int 136 titan_parse_p_perror(int which, int port, u64 perror, int print) 137 { 138 int cmd; 139 unsigned long addr; 140 int status = MCHK_DISPOSITION_REPORT; 141 142 #ifdef CONFIG_VERBOSE_MCHECK 143 char *perror_cmd[] = { "Interrupt Acknowledge", "Special Cycle", 144 "I/O Read", "I/O Write", 145 "Reserved", "Reserved", 146 "Memory Read", "Memory Write", 147 "Reserved", "Reserved", 148 "Configuration Read", "Configuration Write", 149 "Memory Read Multiple", "Dual Address Cycle", 150 "Memory Read Line","Memory Write and Invalidate" 151 }; 152 #endif /* CONFIG_VERBOSE_MCHECK */ 153 154 #define TITAN__PCHIP_PERROR__LOST (1UL << 0) 155 #define TITAN__PCHIP_PERROR__SERR (1UL << 1) 156 #define TITAN__PCHIP_PERROR__PERR (1UL << 2) 157 #define TITAN__PCHIP_PERROR__DCRTO (1UL << 3) 158 #define TITAN__PCHIP_PERROR__SGE (1UL << 4) 159 #define TITAN__PCHIP_PERROR__APE (1UL << 5) 160 #define TITAN__PCHIP_PERROR__TA (1UL << 6) 161 #define TITAN__PCHIP_PERROR__DPE (1UL << 7) 162 #define TITAN__PCHIP_PERROR__NDS (1UL << 8) 163 #define TITAN__PCHIP_PERROR__IPTPR (1UL << 9) 164 #define TITAN__PCHIP_PERROR__IPTPW (1UL << 10) 165 #define TITAN__PCHIP_PERROR__ERRMASK (TITAN__PCHIP_PERROR__LOST | \ 166 TITAN__PCHIP_PERROR__SERR | \ 167 TITAN__PCHIP_PERROR__PERR | \ 168 TITAN__PCHIP_PERROR__DCRTO | \ 169 TITAN__PCHIP_PERROR__SGE | \ 170 TITAN__PCHIP_PERROR__APE | \ 171 TITAN__PCHIP_PERROR__TA | \ 172 TITAN__PCHIP_PERROR__DPE | \ 173 TITAN__PCHIP_PERROR__NDS | \ 174 TITAN__PCHIP_PERROR__IPTPR | \ 175 TITAN__PCHIP_PERROR__IPTPW) 176 #define TITAN__PCHIP_PERROR__DAC (1UL << 47) 177 #define TITAN__PCHIP_PERROR__MWIN (1UL << 48) 178 #define TITAN__PCHIP_PERROR__CMD__S (52) 179 #define TITAN__PCHIP_PERROR__CMD__M (0x0f) 180 #define TITAN__PCHIP_PERROR__ADDR__S (14) 181 #define TITAN__PCHIP_PERROR__ADDR__M (0x1fffffffful) 182 183 if (!(perror & TITAN__PCHIP_PERROR__ERRMASK)) 184 return MCHK_DISPOSITION_UNKNOWN_ERROR; 185 186 cmd = EXTRACT(perror, TITAN__PCHIP_PERROR__CMD); 187 addr = EXTRACT(perror, TITAN__PCHIP_PERROR__ADDR) << 2; 188 189 /* 190 * Initializing the BIOS on a video card on a bus without 191 * a south bridge (subtractive decode agent) can result in 192 * master aborts as the BIOS probes the capabilities of the 193 * card. XFree86 does such initialization. If the error 194 * is a master abort (No DevSel as PCI Master) and the command 195 * is an I/O read or write below the address where we start 196 * assigning PCI I/O spaces (SRM uses 0x1000), then mark the 197 * error as dismissable so starting XFree86 doesn't result 198 * in a series of uncorrectable errors being reported. Also 199 * dismiss master aborts to VGA frame buffer space 200 * (0xA0000 - 0xC0000) and legacy BIOS space (0xC0000 - 0x100000) 201 * for the same reason. 202 * 203 * Also mark the error dismissible if it looks like the right 204 * error but only the Lost bit is set. Since the BIOS initialization 205 * can cause multiple master aborts and the error interrupt can 206 * be handled on a different CPU than the BIOS code is run on, 207 * it is possible for a second master abort to occur between the 208 * time the PALcode reads PERROR and the time it writes PERROR 209 * to acknowledge the error. If this timing happens, a second 210 * error will be signalled after the first, and if no additional 211 * errors occur, will look like a Lost error with no additional 212 * errors on the same transaction as the previous error. 213 */ 214 if (((perror & TITAN__PCHIP_PERROR__NDS) || 215 ((perror & TITAN__PCHIP_PERROR__ERRMASK) == 216 TITAN__PCHIP_PERROR__LOST)) && 217 ((((cmd & 0xE) == 2) && (addr < 0x1000)) || 218 (((cmd & 0xE) == 6) && (addr >= 0xA0000) && (addr < 0x100000)))) { 219 status = MCHK_DISPOSITION_DISMISS; 220 } 221 222 #ifdef CONFIG_VERBOSE_MCHECK 223 if (!print) 224 return status; 225 226 printk("%s PChip %d %cPERROR: %016llx\n", 227 err_print_prefix, which, 228 port ? 'A' : 'G', perror); 229 if (perror & TITAN__PCHIP_PERROR__IPTPW) 230 printk("%s Invalid Peer-to-Peer Write\n", err_print_prefix); 231 if (perror & TITAN__PCHIP_PERROR__IPTPR) 232 printk("%s Invalid Peer-to-Peer Read\n", err_print_prefix); 233 if (perror & TITAN__PCHIP_PERROR__NDS) 234 printk("%s No DEVSEL as PCI Master [Master Abort]\n", 235 err_print_prefix); 236 if (perror & TITAN__PCHIP_PERROR__DPE) 237 printk("%s Data Parity Error\n", err_print_prefix); 238 if (perror & TITAN__PCHIP_PERROR__TA) 239 printk("%s Target Abort\n", err_print_prefix); 240 if (perror & TITAN__PCHIP_PERROR__APE) 241 printk("%s Address Parity Error\n", err_print_prefix); 242 if (perror & TITAN__PCHIP_PERROR__SGE) 243 printk("%s Scatter-Gather Error, Invalid PTE\n", 244 err_print_prefix); 245 if (perror & TITAN__PCHIP_PERROR__DCRTO) 246 printk("%s Delayed-Completion Retry Timeout\n", 247 err_print_prefix); 248 if (perror & TITAN__PCHIP_PERROR__PERR) 249 printk("%s PERR Asserted\n", err_print_prefix); 250 if (perror & TITAN__PCHIP_PERROR__SERR) 251 printk("%s SERR Asserted\n", err_print_prefix); 252 if (perror & TITAN__PCHIP_PERROR__LOST) 253 printk("%s Lost Error\n", err_print_prefix); 254 printk("%s Command: 0x%x - %s\n" 255 " Address: 0x%lx\n", 256 err_print_prefix, 257 cmd, perror_cmd[cmd], 258 addr); 259 if (perror & TITAN__PCHIP_PERROR__DAC) 260 printk("%s Dual Address Cycle\n", err_print_prefix); 261 if (perror & TITAN__PCHIP_PERROR__MWIN) 262 printk("%s Hit in Monster Window\n", err_print_prefix); 263 #endif /* CONFIG_VERBOSE_MCHECK */ 264 265 return status; 266 } 267 268 static int 269 titan_parse_p_agperror(int which, u64 agperror, int print) 270 { 271 int status = MCHK_DISPOSITION_REPORT; 272 #ifdef CONFIG_VERBOSE_MCHECK 273 int cmd, len; 274 unsigned long addr; 275 276 char *agperror_cmd[] = { "Read (low-priority)", "Read (high-priority)", 277 "Write (low-priority)", 278 "Write (high-priority)", 279 "Reserved", "Reserved", 280 "Flush", "Fence" 281 }; 282 #endif /* CONFIG_VERBOSE_MCHECK */ 283 284 #define TITAN__PCHIP_AGPERROR__LOST (1UL << 0) 285 #define TITAN__PCHIP_AGPERROR__LPQFULL (1UL << 1) 286 #define TITAN__PCHIP_AGPERROR__HPQFULL (1UL << 2) 287 #define TITAN__PCHIP_AGPERROR__RESCMD (1UL << 3) 288 #define TITAN__PCHIP_AGPERROR__IPTE (1UL << 4) 289 #define TITAN__PCHIP_AGPERROR__PTP (1UL << 5) 290 #define TITAN__PCHIP_AGPERROR__NOWINDOW (1UL << 6) 291 #define TITAN__PCHIP_AGPERROR__ERRMASK (TITAN__PCHIP_AGPERROR__LOST | \ 292 TITAN__PCHIP_AGPERROR__LPQFULL | \ 293 TITAN__PCHIP_AGPERROR__HPQFULL | \ 294 TITAN__PCHIP_AGPERROR__RESCMD | \ 295 TITAN__PCHIP_AGPERROR__IPTE | \ 296 TITAN__PCHIP_AGPERROR__PTP | \ 297 TITAN__PCHIP_AGPERROR__NOWINDOW) 298 #define TITAN__PCHIP_AGPERROR__DAC (1UL << 48) 299 #define TITAN__PCHIP_AGPERROR__MWIN (1UL << 49) 300 #define TITAN__PCHIP_AGPERROR__FENCE (1UL << 59) 301 #define TITAN__PCHIP_AGPERROR__CMD__S (50) 302 #define TITAN__PCHIP_AGPERROR__CMD__M (0x07) 303 #define TITAN__PCHIP_AGPERROR__ADDR__S (15) 304 #define TITAN__PCHIP_AGPERROR__ADDR__M (0xffffffffUL) 305 #define TITAN__PCHIP_AGPERROR__LEN__S (53) 306 #define TITAN__PCHIP_AGPERROR__LEN__M (0x3f) 307 308 if (!(agperror & TITAN__PCHIP_AGPERROR__ERRMASK)) 309 return MCHK_DISPOSITION_UNKNOWN_ERROR; 310 311 #ifdef CONFIG_VERBOSE_MCHECK 312 if (!print) 313 return status; 314 315 cmd = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__CMD); 316 addr = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__ADDR) << 3; 317 len = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__LEN); 318 319 printk("%s PChip %d AGPERROR: %016llx\n", err_print_prefix, 320 which, agperror); 321 if (agperror & TITAN__PCHIP_AGPERROR__NOWINDOW) 322 printk("%s No Window\n", err_print_prefix); 323 if (agperror & TITAN__PCHIP_AGPERROR__PTP) 324 printk("%s Peer-to-Peer set\n", err_print_prefix); 325 if (agperror & TITAN__PCHIP_AGPERROR__IPTE) 326 printk("%s Invalid PTE\n", err_print_prefix); 327 if (agperror & TITAN__PCHIP_AGPERROR__RESCMD) 328 printk("%s Reserved Command\n", err_print_prefix); 329 if (agperror & TITAN__PCHIP_AGPERROR__HPQFULL) 330 printk("%s HP Transaction Received while Queue Full\n", 331 err_print_prefix); 332 if (agperror & TITAN__PCHIP_AGPERROR__LPQFULL) 333 printk("%s LP Transaction Received while Queue Full\n", 334 err_print_prefix); 335 if (agperror & TITAN__PCHIP_AGPERROR__LOST) 336 printk("%s Lost Error\n", err_print_prefix); 337 printk("%s Command: 0x%x - %s, %d Quadwords%s\n" 338 " Address: 0x%lx\n", 339 err_print_prefix, cmd, agperror_cmd[cmd], len, 340 (agperror & TITAN__PCHIP_AGPERROR__FENCE) ? ", FENCE" : "", 341 addr); 342 if (agperror & TITAN__PCHIP_AGPERROR__DAC) 343 printk("%s Dual Address Cycle\n", err_print_prefix); 344 if (agperror & TITAN__PCHIP_AGPERROR__MWIN) 345 printk("%s Hit in Monster Window\n", err_print_prefix); 346 #endif /* CONFIG_VERBOSE_MCHECK */ 347 348 return status; 349 } 350 351 static int 352 titan_parse_p_chip(int which, u64 serror, u64 gperror, 353 u64 aperror, u64 agperror, int print) 354 { 355 int status = MCHK_DISPOSITION_UNKNOWN_ERROR; 356 status |= titan_parse_p_serror(which, serror, print); 357 status |= titan_parse_p_perror(which, 0, gperror, print); 358 status |= titan_parse_p_perror(which, 1, aperror, print); 359 status |= titan_parse_p_agperror(which, agperror, print); 360 return status; 361 } 362 363 int 364 titan_process_logout_frame(struct el_common *mchk_header, int print) 365 { 366 struct el_TITAN_sysdata_mcheck *tmchk = 367 (struct el_TITAN_sysdata_mcheck *) 368 ((unsigned long)mchk_header + mchk_header->sys_offset); 369 int status = MCHK_DISPOSITION_UNKNOWN_ERROR; 370 371 status |= titan_parse_c_misc(tmchk->c_misc, print); 372 status |= titan_parse_p_chip(0, tmchk->p0_serror, tmchk->p0_gperror, 373 tmchk->p0_aperror, tmchk->p0_agperror, 374 print); 375 status |= titan_parse_p_chip(1, tmchk->p1_serror, tmchk->p1_gperror, 376 tmchk->p1_aperror, tmchk->p1_agperror, 377 print); 378 379 return status; 380 } 381 382 void 383 titan_machine_check(unsigned long vector, unsigned long la_ptr) 384 { 385 struct el_common *mchk_header = (struct el_common *)la_ptr; 386 struct el_TITAN_sysdata_mcheck *tmchk = 387 (struct el_TITAN_sysdata_mcheck *) 388 ((unsigned long)mchk_header + mchk_header->sys_offset); 389 u64 irqmask; 390 391 /* 392 * Mask of Titan interrupt sources which are reported as machine checks 393 * 394 * 63 - CChip Error 395 * 62 - PChip 0 H_Error 396 * 61 - PChip 1 H_Error 397 * 60 - PChip 0 C_Error 398 * 59 - PChip 1 C_Error 399 */ 400 #define TITAN_MCHECK_INTERRUPT_MASK 0xF800000000000000UL 401 402 /* 403 * Sync the processor 404 */ 405 mb(); 406 draina(); 407 408 /* 409 * Only handle system errors here 410 */ 411 if ((vector != SCB_Q_SYSMCHK) && (vector != SCB_Q_SYSERR)) { 412 ev6_machine_check(vector, la_ptr); 413 return; 414 } 415 416 /* 417 * It's a system error, handle it here 418 * 419 * The PALcode has already cleared the error, so just parse it 420 */ 421 422 /* 423 * Parse the logout frame without printing first. If the only error(s) 424 * found are classified as "dismissable", then just dismiss them and 425 * don't print any message 426 */ 427 if (titan_process_logout_frame(mchk_header, 0) != 428 MCHK_DISPOSITION_DISMISS) { 429 char *saved_err_prefix = err_print_prefix; 430 err_print_prefix = KERN_CRIT; 431 432 /* 433 * Either a nondismissable error was detected or no 434 * recognized error was detected in the logout frame 435 * -- report the error in either case 436 */ 437 printk("%s" 438 "*System %s Error (Vector 0x%x) reported on CPU %d:\n", 439 err_print_prefix, 440 (vector == SCB_Q_SYSERR)?"Correctable":"Uncorrectable", 441 (unsigned int)vector, (int)smp_processor_id()); 442 443 #ifdef CONFIG_VERBOSE_MCHECK 444 titan_process_logout_frame(mchk_header, alpha_verbose_mcheck); 445 if (alpha_verbose_mcheck) 446 dik_show_regs(get_irq_regs(), NULL); 447 #endif /* CONFIG_VERBOSE_MCHECK */ 448 449 err_print_prefix = saved_err_prefix; 450 451 /* 452 * Convert any pending interrupts which report as system 453 * machine checks to interrupts 454 */ 455 irqmask = tmchk->c_dirx & TITAN_MCHECK_INTERRUPT_MASK; 456 titan_dispatch_irqs(irqmask); 457 } 458 459 460 /* 461 * Release the logout frame 462 */ 463 wrmces(0x7); 464 mb(); 465 } 466 467 /* 468 * Subpacket Annotations 469 */ 470 static char *el_titan_pchip0_extended_annotation[] = { 471 "Subpacket Header", "P0_SCTL", "P0_SERREN", 472 "P0_APCTL", "P0_APERREN", "P0_AGPERREN", 473 "P0_ASPRST", "P0_AWSBA0", "P0_AWSBA1", 474 "P0_AWSBA2", "P0_AWSBA3", "P0_AWSM0", 475 "P0_AWSM1", "P0_AWSM2", "P0_AWSM3", 476 "P0_ATBA0", "P0_ATBA1", "P0_ATBA2", 477 "P0_ATBA3", "P0_GPCTL", "P0_GPERREN", 478 "P0_GSPRST", "P0_GWSBA0", "P0_GWSBA1", 479 "P0_GWSBA2", "P0_GWSBA3", "P0_GWSM0", 480 "P0_GWSM1", "P0_GWSM2", "P0_GWSM3", 481 "P0_GTBA0", "P0_GTBA1", "P0_GTBA2", 482 "P0_GTBA3", NULL 483 }; 484 static char *el_titan_pchip1_extended_annotation[] = { 485 "Subpacket Header", "P1_SCTL", "P1_SERREN", 486 "P1_APCTL", "P1_APERREN", "P1_AGPERREN", 487 "P1_ASPRST", "P1_AWSBA0", "P1_AWSBA1", 488 "P1_AWSBA2", "P1_AWSBA3", "P1_AWSM0", 489 "P1_AWSM1", "P1_AWSM2", "P1_AWSM3", 490 "P1_ATBA0", "P1_ATBA1", "P1_ATBA2", 491 "P1_ATBA3", "P1_GPCTL", "P1_GPERREN", 492 "P1_GSPRST", "P1_GWSBA0", "P1_GWSBA1", 493 "P1_GWSBA2", "P1_GWSBA3", "P1_GWSM0", 494 "P1_GWSM1", "P1_GWSM2", "P1_GWSM3", 495 "P1_GTBA0", "P1_GTBA1", "P1_GTBA2", 496 "P1_GTBA3", NULL 497 }; 498 static char *el_titan_memory_extended_annotation[] = { 499 "Subpacket Header", "AAR0", "AAR1", 500 "AAR2", "AAR3", "P0_SCTL", 501 "P0_GPCTL", "P0_APCTL", "P1_SCTL", 502 "P1_GPCTL", "P1_SCTL", NULL 503 }; 504 505 static struct el_subpacket_annotation el_titan_annotations[] = { 506 SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY, 507 EL_TYPE__REGATTA__TITAN_PCHIP0_EXTENDED, 508 1, 509 "Titan PChip 0 Extended Frame", 510 el_titan_pchip0_extended_annotation), 511 SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY, 512 EL_TYPE__REGATTA__TITAN_PCHIP1_EXTENDED, 513 1, 514 "Titan PChip 1 Extended Frame", 515 el_titan_pchip1_extended_annotation), 516 SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY, 517 EL_TYPE__REGATTA__TITAN_MEMORY_EXTENDED, 518 1, 519 "Titan Memory Extended Frame", 520 el_titan_memory_extended_annotation), 521 SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY, 522 EL_TYPE__TERMINATION__TERMINATION, 523 1, 524 "Termination Subpacket", 525 NULL) 526 }; 527 528 static struct el_subpacket * 529 el_process_regatta_subpacket(struct el_subpacket *header) 530 { 531 int status; 532 533 if (header->class != EL_CLASS__REGATTA_FAMILY) { 534 printk("%s ** Unexpected header CLASS %d TYPE %d, aborting\n", 535 err_print_prefix, 536 header->class, header->type); 537 return NULL; 538 } 539 540 switch(header->type) { 541 case EL_TYPE__REGATTA__PROCESSOR_ERROR_FRAME: 542 case EL_TYPE__REGATTA__SYSTEM_ERROR_FRAME: 543 case EL_TYPE__REGATTA__ENVIRONMENTAL_FRAME: 544 case EL_TYPE__REGATTA__PROCESSOR_DBL_ERROR_HALT: 545 case EL_TYPE__REGATTA__SYSTEM_DBL_ERROR_HALT: 546 printk("%s ** Occurred on CPU %d:\n", 547 err_print_prefix, 548 (int)header->by_type.regatta_frame.cpuid); 549 status = privateer_process_logout_frame((struct el_common *) 550 header->by_type.regatta_frame.data_start, 1); 551 break; 552 default: 553 printk("%s ** REGATTA TYPE %d SUBPACKET\n", 554 err_print_prefix, header->type); 555 el_annotate_subpacket(header); 556 break; 557 } 558 559 560 return (struct el_subpacket *)((unsigned long)header + header->length); 561 } 562 563 static struct el_subpacket_handler titan_subpacket_handler = 564 SUBPACKET_HANDLER_INIT(EL_CLASS__REGATTA_FAMILY, 565 el_process_regatta_subpacket); 566 567 void __init 568 titan_register_error_handlers(void) 569 { 570 size_t i; 571 572 for (i = 0; i < ARRAY_SIZE (el_titan_annotations); i++) 573 cdl_register_subpacket_annotation(&el_titan_annotations[i]); 574 575 cdl_register_subpacket_handler(&titan_subpacket_handler); 576 577 ev6_register_error_handlers(); 578 } 579 580 581 /* 582 * Privateer 583 */ 584 585 static int 586 privateer_process_680_frame(struct el_common *mchk_header, int print) 587 { 588 int status = MCHK_DISPOSITION_UNKNOWN_ERROR; 589 #ifdef CONFIG_VERBOSE_MCHECK 590 struct el_PRIVATEER_envdata_mcheck *emchk = 591 (struct el_PRIVATEER_envdata_mcheck *) 592 ((unsigned long)mchk_header + mchk_header->sys_offset); 593 594 /* TODO - categorize errors, for now, no error */ 595 596 if (!print) 597 return status; 598 599 /* TODO - decode instead of just dumping... */ 600 printk("%s Summary Flags: %016llx\n" 601 " CChip DIRx: %016llx\n" 602 " System Management IR: %016llx\n" 603 " CPU IR: %016llx\n" 604 " Power Supply IR: %016llx\n" 605 " LM78 Fault Status: %016llx\n" 606 " System Doors: %016llx\n" 607 " Temperature Warning: %016llx\n" 608 " Fan Control: %016llx\n" 609 " Fatal Power Down Code: %016llx\n", 610 err_print_prefix, 611 emchk->summary, 612 emchk->c_dirx, 613 emchk->smir, 614 emchk->cpuir, 615 emchk->psir, 616 emchk->fault, 617 emchk->sys_doors, 618 emchk->temp_warn, 619 emchk->fan_ctrl, 620 emchk->code); 621 #endif /* CONFIG_VERBOSE_MCHECK */ 622 623 return status; 624 } 625 626 int 627 privateer_process_logout_frame(struct el_common *mchk_header, int print) 628 { 629 struct el_common_EV6_mcheck *ev6mchk = 630 (struct el_common_EV6_mcheck *)mchk_header; 631 int status = MCHK_DISPOSITION_UNKNOWN_ERROR; 632 633 /* 634 * Machine check codes 635 */ 636 #define PRIVATEER_MCHK__CORR_ECC 0x86 /* 630 */ 637 #define PRIVATEER_MCHK__DC_TAG_PERR 0x9E /* 630 */ 638 #define PRIVATEER_MCHK__PAL_BUGCHECK 0x8E /* 670 */ 639 #define PRIVATEER_MCHK__OS_BUGCHECK 0x90 /* 670 */ 640 #define PRIVATEER_MCHK__PROC_HRD_ERR 0x98 /* 670 */ 641 #define PRIVATEER_MCHK__ISTREAM_CMOV_PRX 0xA0 /* 670 */ 642 #define PRIVATEER_MCHK__ISTREAM_CMOV_FLT 0xA2 /* 670 */ 643 #define PRIVATEER_MCHK__SYS_HRD_ERR 0x202 /* 660 */ 644 #define PRIVATEER_MCHK__SYS_CORR_ERR 0x204 /* 620 */ 645 #define PRIVATEER_MCHK__SYS_ENVIRON 0x206 /* 680 */ 646 647 switch(ev6mchk->MCHK_Code) { 648 /* 649 * Vector 630 - Processor, Correctable 650 */ 651 case PRIVATEER_MCHK__CORR_ECC: 652 case PRIVATEER_MCHK__DC_TAG_PERR: 653 /* 654 * Fall through to vector 670 for processing... 655 */ 656 /* 657 * Vector 670 - Processor, Uncorrectable 658 */ 659 case PRIVATEER_MCHK__PAL_BUGCHECK: 660 case PRIVATEER_MCHK__OS_BUGCHECK: 661 case PRIVATEER_MCHK__PROC_HRD_ERR: 662 case PRIVATEER_MCHK__ISTREAM_CMOV_PRX: 663 case PRIVATEER_MCHK__ISTREAM_CMOV_FLT: 664 status |= ev6_process_logout_frame(mchk_header, print); 665 break; 666 667 /* 668 * Vector 620 - System, Correctable 669 */ 670 case PRIVATEER_MCHK__SYS_CORR_ERR: 671 /* 672 * Fall through to vector 660 for processing... 673 */ 674 /* 675 * Vector 660 - System, Uncorrectable 676 */ 677 case PRIVATEER_MCHK__SYS_HRD_ERR: 678 status |= titan_process_logout_frame(mchk_header, print); 679 break; 680 681 /* 682 * Vector 680 - System, Environmental 683 */ 684 case PRIVATEER_MCHK__SYS_ENVIRON: /* System, Environmental */ 685 status |= privateer_process_680_frame(mchk_header, print); 686 break; 687 688 /* 689 * Unknown 690 */ 691 default: 692 status |= MCHK_DISPOSITION_REPORT; 693 if (print) { 694 printk("%s** Unknown Error, frame follows\n", 695 err_print_prefix); 696 mchk_dump_logout_frame(mchk_header); 697 } 698 699 } 700 701 return status; 702 } 703 704 void 705 privateer_machine_check(unsigned long vector, unsigned long la_ptr) 706 { 707 struct el_common *mchk_header = (struct el_common *)la_ptr; 708 struct el_TITAN_sysdata_mcheck *tmchk = 709 (struct el_TITAN_sysdata_mcheck *) 710 (la_ptr + mchk_header->sys_offset); 711 u64 irqmask; 712 char *saved_err_prefix = err_print_prefix; 713 714 #define PRIVATEER_680_INTERRUPT_MASK (0xE00UL) 715 #define PRIVATEER_HOTPLUG_INTERRUPT_MASK (0xE00UL) 716 717 /* 718 * Sync the processor. 719 */ 720 mb(); 721 draina(); 722 723 /* 724 * Only handle system events here. 725 */ 726 if (vector != SCB_Q_SYSEVENT) 727 return titan_machine_check(vector, la_ptr); 728 729 /* 730 * Report the event - System Events should be reported even if no 731 * error is indicated since the event could indicate the return 732 * to normal status. 733 */ 734 err_print_prefix = KERN_CRIT; 735 printk("%s*System Event (Vector 0x%x) reported on CPU %d:\n", 736 err_print_prefix, 737 (unsigned int)vector, (int)smp_processor_id()); 738 privateer_process_680_frame(mchk_header, 1); 739 err_print_prefix = saved_err_prefix; 740 741 /* 742 * Convert any pending interrupts which report as 680 machine 743 * checks to interrupts. 744 */ 745 irqmask = tmchk->c_dirx & PRIVATEER_680_INTERRUPT_MASK; 746 747 /* 748 * Dispatch the interrupt(s). 749 */ 750 titan_dispatch_irqs(irqmask); 751 752 /* 753 * Release the logout frame. 754 */ 755 wrmces(0x7); 756 mb(); 757 } 758