1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <sys/types.h> 28 #include <sys/cmn_err.h> 29 #include <sys/errno.h> 30 #include <sys/log.h> 31 #include <sys/systm.h> 32 #include <sys/modctl.h> 33 #include <sys/errorq.h> 34 #include <sys/controlregs.h> 35 #include <sys/fm/util.h> 36 #include <sys/fm/protocol.h> 37 #include <sys/sysevent.h> 38 #include <sys/pghw.h> 39 #include <sys/cyclic.h> 40 #include <sys/pci_cfgspace.h> 41 #include <sys/mc_intel.h> 42 #include <sys/smbios.h> 43 #include "nb5000.h" 44 #include "nb_log.h" 45 #include "dimm_phys.h" 46 47 int nb_check_validlog = 1; 48 49 static uint32_t uerrcnt[2]; 50 static uint32_t cerrcnta[2][2]; 51 static uint32_t cerrcntb[2][2]; 52 static uint32_t cerrcntc[2][2]; 53 static uint32_t cerrcntd[2][2]; 54 static nb_logout_t nb_log; 55 56 struct mch_error_code { 57 int intel_error_list; /* error number in Chipset Error List */ 58 uint32_t emask; /* mask for machine check */ 59 uint32_t error_bit; /* error bit in fault register */ 60 }; 61 62 static struct mch_error_code fat_fbd_error_code[] = { 63 { 23, EMASK_FBD_M23, ERR_FAT_FBD_M23 }, 64 { 3, EMASK_FBD_M3, ERR_FAT_FBD_M3 }, 65 { 2, EMASK_FBD_M2, ERR_FAT_FBD_M2 }, 66 { 1, EMASK_FBD_M1, ERR_FAT_FBD_M1 } 67 }; 68 69 static int 70 intel_fat_fbd_err(uint32_t fat_fbd) 71 { 72 int rt = -1; 73 int nerr = 0; 74 uint32_t emask_fbd = 0; 75 int i; 76 int sz; 77 78 sz = sizeof (fat_fbd_error_code) / sizeof (struct mch_error_code); 79 80 for (i = 0; i < sz; i++) { 81 if (fat_fbd & fat_fbd_error_code[i].error_bit) { 82 rt = fat_fbd_error_code[i].intel_error_list; 83 emask_fbd |= fat_fbd_error_code[i].emask; 84 nerr++; 85 } 86 } 87 88 if (emask_fbd) 89 nb_fbd_mask_mc(emask_fbd); 90 if (nerr > 1) 91 rt = -1; 92 return (rt); 93 } 94 95 static char * 96 fat_memory_error(const nb_regs_t *rp, void *data) 97 { 98 int channel; 99 uint32_t ferr_fat_fbd, nrecmemb; 100 uint32_t nrecmema; 101 char *intr = "nb.unknown"; 102 nb_mem_scatchpad_t *sp = &((nb_scatchpad_t *)data)->ms; 103 104 ferr_fat_fbd = rp->nb.fat_fbd_regs.ferr_fat_fbd; 105 if ((ferr_fat_fbd & ERR_FAT_FBD_MASK) == 0) { 106 sp->intel_error_list = 107 intel_fat_fbd_err(rp->nb.fat_fbd_regs.nerr_fat_fbd); 108 sp->branch = -1; 109 sp->channel = -1; 110 sp->rank = -1; 111 sp->dimm = -1; 112 sp->bank = -1; 113 sp->cas = -1; 114 sp->ras = -1; 115 sp->pa = -1LL; 116 sp->offset = -1; 117 return (intr); 118 } 119 sp->intel_error_list = intel_fat_fbd_err(ferr_fat_fbd); 120 channel = (ferr_fat_fbd >> 28) & 3; 121 sp->branch = channel >> 1; 122 sp->channel = channel; 123 if ((ferr_fat_fbd & (ERR_FAT_FBD_M2|ERR_FAT_FBD_M1)) != 0) { 124 if ((ferr_fat_fbd & ERR_FAT_FBD_M1) != 0) 125 intr = "nb.fbd.alert"; /* Alert on FB-DIMM M1 */ 126 else 127 intr = "nb.fbd.crc"; /* CRC error FB_DIMM M2 */ 128 nrecmema = rp->nb.fat_fbd_regs.nrecmema; 129 nrecmemb = rp->nb.fat_fbd_regs.nrecmemb; 130 sp->rank = (nrecmema >> 8) & RANK_MASK; 131 sp->dimm = sp->rank >> 1; 132 sp->bank = (nrecmema >> 12) & BANK_MASK; 133 sp->cas = (nrecmemb >> 16) & CAS_MASK; 134 sp->ras = nrecmemb & RAS_MASK; 135 /* 136 * If driver was built with closed tree present then we will 137 * have Intel proprietary code for finding physaddr 138 */ 139 if (&dimm_getphys) { 140 sp->pa = dimm_getphys((uint16_t)sp->branch, 141 (uint16_t)sp->rank, (uint64_t)sp->bank, 142 (uint64_t)sp->ras, (uint64_t)sp->cas); 143 if (sp->pa >= MAXPHYS_ADDR) 144 sp->pa = -1ULL; 145 } else { 146 sp->pa = -1ULL; 147 } 148 /* 149 * If there is an offset decoder use it otherwise encode 150 * rank/bank/ras/cas 151 */ 152 if (&dimm_getoffset) { 153 sp->offset = dimm_getoffset(sp->branch, sp->rank, 154 sp->bank, sp->ras, sp->cas); 155 } else { 156 sp->offset = TCODE_OFFSET(sp->rank, sp->bank, sp->ras, 157 sp->cas); 158 } 159 } else { 160 if ((ferr_fat_fbd & ERR_FAT_FBD_M3) != 0) 161 intr = "nb.fbd.otf"; /* thermal temp > Tmid M3 */ 162 else if ((ferr_fat_fbd & ERR_FAT_FBD_M23) != 0) { 163 intr = "nb.fbd.reset_timeout"; 164 sp->channel = -1; 165 } 166 sp->rank = -1; 167 sp->dimm = -1; 168 sp->bank = -1; 169 sp->cas = -1; 170 sp->ras = -1; 171 sp->pa = -1LL; 172 sp->offset = -1; 173 } 174 return (intr); 175 } 176 177 178 static struct mch_error_code nf_fbd_error_code[] = { 179 { 29, EMASK_FBD_M29, ERR_NF_FBD_M29 }, 180 { 28, EMASK_FBD_M28, ERR_NF_FBD_M28 }, 181 { 27, EMASK_FBD_M27, ERR_NF_FBD_M27 }, 182 { 26, EMASK_FBD_M26, ERR_NF_FBD_M26 }, 183 { 25, EMASK_FBD_M25, ERR_NF_FBD_M25 }, 184 { 24, EMASK_FBD_M24, ERR_NF_FBD_M24 }, 185 { 22, EMASK_FBD_M22, ERR_NF_FBD_M22 }, 186 { 21, EMASK_FBD_M21, ERR_NF_FBD_M21 }, 187 { 20, EMASK_FBD_M20, ERR_NF_FBD_M20 }, 188 { 19, EMASK_FBD_M19, ERR_NF_FBD_M19 }, 189 { 18, EMASK_FBD_M18, ERR_NF_FBD_M18 }, 190 { 17, EMASK_FBD_M17, ERR_NF_FBD_M17 }, 191 { 16, EMASK_FBD_M16, ERR_NF_FBD_M16 }, 192 { 15, EMASK_FBD_M15, ERR_NF_FBD_M15 }, 193 { 14, EMASK_FBD_M14, ERR_NF_FBD_M14 }, 194 { 13, EMASK_FBD_M13, ERR_NF_FBD_M13 }, 195 { 12, EMASK_FBD_M12, ERR_NF_FBD_M12 }, 196 { 11, EMASK_FBD_M11, ERR_NF_FBD_M11 }, 197 { 10, EMASK_FBD_M10, ERR_NF_FBD_M10 }, 198 { 9, EMASK_FBD_M9, ERR_NF_FBD_M9 }, 199 { 8, EMASK_FBD_M8, ERR_NF_FBD_M8 }, 200 { 7, EMASK_FBD_M7, ERR_NF_FBD_M7 }, 201 { 6, EMASK_FBD_M6, ERR_NF_FBD_M6 }, 202 { 5, EMASK_FBD_M5, ERR_NF_FBD_M5 }, 203 { 4, EMASK_FBD_M4, ERR_NF_FBD_M4 } 204 }; 205 206 static int 207 intel_nf_fbd_err(uint32_t nf_fbd) 208 { 209 int rt = -1; 210 int nerr = 0; 211 uint32_t emask_fbd = 0; 212 int i; 213 int sz; 214 215 sz = sizeof (nf_fbd_error_code) / sizeof (struct mch_error_code); 216 217 for (i = 0; i < sz; i++) { 218 if (nf_fbd & nf_fbd_error_code[i].error_bit) { 219 rt = nf_fbd_error_code[i].intel_error_list; 220 emask_fbd |= nf_fbd_error_code[i].emask; 221 nerr++; 222 } 223 } 224 if (emask_fbd) 225 nb_fbd_mask_mc(emask_fbd); 226 if (nerr > 1) 227 rt = -1; 228 return (rt); 229 } 230 231 static char * 232 nf_memory_error(const nb_regs_t *rp, void *data) 233 { 234 uint32_t ferr_nf_fbd, recmemb, redmemb; 235 uint32_t recmema; 236 int branch, channel, ecc_locator; 237 char *intr = "nb.unknown"; 238 nb_mem_scatchpad_t *sp = &((nb_scatchpad_t *)data)->ms; 239 240 sp->rank = -1; 241 sp->dimm = -1; 242 sp->bank = -1; 243 sp->cas = -1; 244 sp->ras = -1LL; 245 sp->pa = -1LL; 246 sp->offset = -1; 247 ferr_nf_fbd = rp->nb.nf_fbd_regs.ferr_nf_fbd; 248 if ((ferr_nf_fbd & ERR_NF_FBD_MASK) == 0) { 249 /* unknown ereport if a recognizable error was not found */ 250 sp->branch = -1; 251 sp->channel = -1; 252 sp->intel_error_list = -1; 253 return (intr); 254 } 255 sp->intel_error_list = intel_nf_fbd_err(ferr_nf_fbd); 256 channel = (ferr_nf_fbd >> ERR_FBD_CH_SHIFT) & 3; 257 branch = channel >> 1; 258 sp->branch = branch; 259 sp->channel = channel; 260 if (ferr_nf_fbd & ERR_NF_FBD_MASK) { 261 if (ferr_nf_fbd & ERR_NF_FBD_ECC_UE) { 262 /* 263 * uncorrectable ECC M4 - M12 264 * we can only isolate to pair of dimms 265 * for single dimm configuration let eversholt 266 * sort it out with out needing a special rule 267 */ 268 sp->channel = -1; 269 recmema = rp->nb.nf_fbd_regs.recmema; 270 recmemb = rp->nb.nf_fbd_regs.recmemb; 271 sp->rank = (recmema >> 8) & RANK_MASK; 272 sp->bank = (recmema >> 12) & BANK_MASK; 273 sp->cas = (recmemb >> 16) & CAS_MASK; 274 sp->ras = recmemb & RAS_MASK; 275 intr = "nb.mem_ue"; 276 } else if (ferr_nf_fbd & ERR_NF_FBD_M13) { 277 /* 278 * write error M13 279 * we can only isolate to pair of dimms 280 */ 281 sp->channel = -1; 282 if (nb_mode != NB_MEMORY_MIRROR) { 283 recmema = rp->nb.nf_fbd_regs.recmema; 284 sp->rank = (recmema >> 8) & RANK_MASK; 285 sp->bank = (recmema >> 12) & BANK_MASK; 286 sp->cas = (recmemb >> 16) & CAS_MASK; 287 sp->ras = recmemb & RAS_MASK; 288 } 289 intr = "nb.fbd.ma"; /* memory alert */ 290 } else if (ferr_nf_fbd & ERR_NF_FBD_MA) { /* M14, M15 and M21 */ 291 intr = "nb.fbd.ch"; /* FBD on channel */ 292 } else if ((ferr_nf_fbd & ERR_NF_FBD_ECC_CE) != 0) { 293 /* correctable ECC M17-M20 */ 294 recmema = rp->nb.nf_fbd_regs.recmema; 295 recmemb = rp->nb.nf_fbd_regs.recmemb; 296 sp->rank = (recmema >> 8) & RANK_MASK; 297 redmemb = rp->nb.nf_fbd_regs.redmemb; 298 ecc_locator = redmemb & 0x3ffff; 299 if (ecc_locator & 0x1ff) 300 sp->channel = branch << 1; 301 else if (ecc_locator & 0x3fe00) 302 sp->channel = (branch << 1) + 1; 303 sp->dimm = sp->rank >> 1; 304 sp->bank = (recmema >> 12) & BANK_MASK; 305 sp->cas = (recmemb >> 16) & CAS_MASK; 306 sp->ras = recmemb & RAS_MASK; 307 intr = "nb.mem_ce"; 308 } else if ((ferr_nf_fbd & ERR_NF_FBD_SPARE) != 0) { 309 /* spare dimm M27, M28 */ 310 intr = "nb.mem_ds"; 311 sp->channel = -1; 312 if (rp->nb.nf_fbd_regs.spcps & SPCPS_SPARE_DEPLOYED) { 313 sp->rank = 314 SPCPS_FAILED_RANK(rp->nb.nf_fbd_regs.spcps); 315 nb_used_spare_rank(sp->branch, sp->rank); 316 nb_config_gen++; 317 } 318 } else if ((ferr_nf_fbd & ERR_NF_FBD_M22) != 0) { 319 intr = "nb.spd"; /* SPD protocol */ 320 } 321 } 322 if (sp->ras != -1) { 323 /* 324 * If driver was built with closed tree present then we will 325 * have Intel proprietary code for finding physaddr 326 */ 327 if (&dimm_getphys) { 328 sp->pa = dimm_getphys((uint16_t)sp->branch, 329 (uint16_t)sp->rank, (uint64_t)sp->bank, 330 (uint64_t)sp->ras, (uint64_t)sp->cas); 331 if (sp->pa >= MAXPHYS_ADDR) 332 sp->pa = -1ULL; 333 } else { 334 sp->pa = -1ULL; 335 } 336 if (&dimm_getoffset) { 337 sp->offset = dimm_getoffset(sp->branch, sp->rank, 338 sp->bank, sp->ras, sp->cas); 339 } else { 340 sp->offset = TCODE_OFFSET(sp->rank, sp->bank, sp->ras, 341 sp->cas); 342 } 343 } 344 return (intr); 345 } 346 347 static struct mch_error_code nf_mem_error_code[] = { 348 { 21, EMASK_MEM_M21, ERR_NF_MEM_M21 }, 349 { 20, EMASK_MEM_M20, ERR_NF_MEM_M20 }, 350 { 18, EMASK_MEM_M18, ERR_NF_MEM_M18 }, 351 { 16, EMASK_MEM_M16, ERR_NF_MEM_M16 }, 352 { 15, EMASK_MEM_M15, ERR_NF_MEM_M15 }, 353 { 14, EMASK_MEM_M14, ERR_NF_MEM_M14 }, 354 { 12, EMASK_MEM_M12, ERR_NF_MEM_M12 }, 355 { 11, EMASK_MEM_M11, ERR_NF_MEM_M11 }, 356 { 10, EMASK_MEM_M10, ERR_NF_MEM_M10 }, 357 { 6, EMASK_MEM_M6, ERR_NF_MEM_M6 }, 358 { 5, EMASK_MEM_M5, ERR_NF_MEM_M5 }, 359 { 4, EMASK_MEM_M4, ERR_NF_MEM_M4 }, 360 { 1, EMASK_MEM_M1, ERR_NF_MEM_M1 } 361 }; 362 363 static int 364 intel_nf_mem_err(uint32_t nf_mem) 365 { 366 int rt = -1; 367 int nerr = 0; 368 uint32_t emask_mem = 0; 369 int i; 370 int sz; 371 372 sz = sizeof (nf_mem_error_code) / sizeof (struct mch_error_code); 373 374 for (i = 0; i < sz; i++) { 375 if (nf_mem & nf_mem_error_code[i].error_bit) { 376 rt = nf_mem_error_code[i].intel_error_list; 377 emask_mem |= nf_mem_error_code[i].emask; 378 nerr++; 379 } 380 } 381 if (emask_mem) 382 nb_mem_mask_mc(emask_mem); 383 if (nerr > 1) 384 rt = -1; 385 return (rt); 386 } 387 388 static char * 389 nf_mem_error(const nb_regs_t *rp, void *data) 390 { 391 uint32_t ferr_nf_mem, recmema, recmemb; 392 uint32_t nrecmema, nrecmemb, validlog; 393 int channel; 394 char *intr = "nb.unknown"; 395 nb_mem_scatchpad_t *sp = &((nb_scatchpad_t *)data)->ms; 396 397 sp->rank = -1; 398 sp->dimm = -1; 399 sp->bank = -1; 400 sp->cas = -1; 401 sp->ras = -1LL; 402 sp->pa = -1LL; 403 sp->offset = -1; 404 ferr_nf_mem = rp->nb.nf_mem_regs.ferr_nf_mem; 405 if ((ferr_nf_mem & ERR_NF_MEM_MASK) == 0) { 406 /* no first error found */ 407 sp->branch = -1; 408 sp->channel = -1; 409 sp->intel_error_list = 410 intel_nf_mem_err(rp->nb.nf_mem_regs.nerr_nf_mem); 411 return (intr); 412 } 413 sp->intel_error_list = intel_nf_mem_err(ferr_nf_mem); 414 415 channel = (ferr_nf_mem >> ERR_MEM_CH_SHIFT) & 0x1; 416 sp->branch = channel; 417 sp->channel = -1; 418 if (ferr_nf_mem & ERR_NF_MEM_MASK) { 419 if (ferr_nf_mem & ERR_NF_MEM_ECC_UE) { 420 /* 421 * uncorrectable ECC M1,M4-M6,M10-M12 422 * There is only channel per branch 423 * Invalidate the channel number so the mem ereport 424 * has the same detector with existing 5000 ereports. 425 * so we can leverage the existing Everhsolt rule. 426 */ 427 validlog = rp->nb.nf_mem_regs.validlog; 428 if (ferr_nf_mem & ERR_NF_MEM_M1) { 429 nrecmema = rp->nb.nf_mem_regs.nrecmema; 430 nrecmemb = rp->nb.nf_mem_regs.nrecmemb; 431 /* check if the nrecmem log is valid */ 432 if (validlog & 0x1 || nb_check_validlog == 0) { 433 sp->rank = (nrecmema >> 8) & RANK_MASK; 434 sp->bank = (nrecmema >> 12) & BANK_MASK; 435 sp->cas = (nrecmemb >> 16) & CAS_MASK; 436 sp->ras = nrecmemb & RAS_MASK; 437 } 438 } else { 439 recmema = rp->nb.nf_mem_regs.recmema; 440 recmemb = rp->nb.nf_mem_regs.recmemb; 441 /* check if the recmem log is valid */ 442 if (validlog & 0x2 || nb_check_validlog == 0) { 443 sp->rank = (recmema >> 8) & RANK_MASK; 444 sp->bank = (recmema >> 12) & BANK_MASK; 445 sp->cas = (recmemb >> 16) & CAS_MASK; 446 sp->ras = recmemb & RAS_MASK; 447 } 448 } 449 intr = "nb.ddr2_mem_ue"; 450 } else if ((ferr_nf_mem & ERR_NF_MEM_ECC_CE) != 0) { 451 /* correctable ECC M14-M16 */ 452 recmema = rp->nb.nf_mem_regs.recmema; 453 recmemb = rp->nb.nf_mem_regs.recmemb; 454 validlog = rp->nb.nf_mem_regs.validlog; 455 /* check if the recmem log is valid */ 456 if (validlog & 0x2 || nb_check_validlog == 0) { 457 sp->channel = channel; 458 sp->rank = (recmema >> 8) & RANK_MASK; 459 sp->dimm = nb_rank2dimm(sp->channel, sp->rank); 460 sp->bank = (recmema >> 12) & BANK_MASK; 461 sp->cas = (recmemb >> 16) & CAS_MASK; 462 sp->ras = recmemb & RAS_MASK; 463 } 464 intr = "nb.ddr2_mem_ce"; 465 } else if ((ferr_nf_mem & ERR_NF_MEM_SPARE) != 0) { 466 /* spare dimm M20, M21 */ 467 intr = "nb.ddr2_mem_ds"; 468 469 /* 470 * The channel can be valid here. 471 * However, there is only one channel per branch and 472 * to leverage the eversolt rules of other chipsets, 473 * the channel is ignored and let the rule find it out 474 * from the topology. 475 */ 476 if (rp->nb.nf_mem_regs.spcps & SPCPS_SPARE_DEPLOYED) { 477 sp->rank = 478 SPCPS_FAILED_RANK(rp->nb.nf_mem_regs.spcps); 479 nb_used_spare_rank(sp->branch, sp->rank); 480 nb_config_gen++; 481 } 482 } else if ((ferr_nf_mem & ERR_NF_MEM_M18) != 0) { 483 sp->channel = channel; 484 intr = "nb.ddr2_spd"; /* SPD protocol */ 485 486 } 487 } 488 if (sp->ras != -1) { 489 /* 490 * If driver was built with closed tree present then we will 491 * have Intel proprietary code for finding physaddr 492 */ 493 if (&dimm_getphys) { 494 sp->pa = dimm_getphys((uint16_t)sp->branch, 495 (uint16_t)sp->rank, (uint64_t)sp->bank, 496 (uint64_t)sp->ras, (uint64_t)sp->cas); 497 if (sp->pa >= MAXPHYS_ADDR) 498 sp->pa = -1ULL; 499 } else { 500 sp->pa = -1ULL; 501 } 502 if (&dimm_getoffset) { 503 sp->offset = dimm_getoffset(sp->branch, sp->rank, 504 sp->bank, sp->ras, sp->cas); 505 } else { 506 sp->offset = TCODE_OFFSET(sp->rank, sp->bank, sp->ras, 507 sp->cas); 508 } 509 } 510 return (intr); 511 } 512 513 static struct mch_error_code fat_int_error_code[] = { 514 { 14, EMASK_INT_B14, ERR_FAT_INT_B14 }, 515 { 12, EMASK_INT_B12, ERR_FAT_INT_B12 }, 516 { 25, EMASK_INT_B25, ERR_FAT_INT_B25 }, 517 { 23, EMASK_INT_B23, ERR_FAT_INT_B23 }, 518 { 21, EMASK_INT_B21, ERR_FAT_INT_B21 }, 519 { 7, EMASK_INT_B7, ERR_FAT_INT_B7 }, 520 { 4, EMASK_INT_B4, ERR_FAT_INT_B4 }, 521 { 3, EMASK_INT_B3, ERR_FAT_INT_B3 }, 522 { 2, EMASK_INT_B2, ERR_FAT_INT_B2 }, 523 { 1, EMASK_INT_B1, ERR_FAT_INT_B1 } 524 }; 525 526 static struct mch_error_code nf_int_error_code[] = { 527 { 27, 0, ERR_NF_INT_B27 }, 528 { 24, 0, ERR_NF_INT_B24 }, 529 { 22, EMASK_INT_B22, ERR_NF_INT_B22 }, 530 { 20, EMASK_INT_B20, ERR_NF_INT_B20 }, 531 { 19, EMASK_INT_B19, ERR_NF_INT_B19 }, 532 { 18, 0, ERR_NF_INT_B18 }, 533 { 17, 0, ERR_NF_INT_B17 }, 534 { 16, 0, ERR_NF_INT_B16 }, 535 { 11, EMASK_INT_B11, ERR_NF_INT_B11 }, 536 { 10, EMASK_INT_B10, ERR_NF_INT_B10 }, 537 { 9, EMASK_INT_B9, ERR_NF_INT_B9 }, 538 { 8, EMASK_INT_B8, ERR_NF_INT_B8 }, 539 { 6, EMASK_INT_B6, ERR_NF_INT_B6 }, 540 { 5, EMASK_INT_B5, ERR_NF_INT_B5 } 541 }; 542 543 static int 544 intel_int_err(uint16_t err_fat_int, uint16_t err_nf_int) 545 { 546 int rt = -1; 547 int nerr = 0; 548 uint32_t emask_int = 0; 549 int i; 550 int sz; 551 552 sz = sizeof (fat_int_error_code) / sizeof (struct mch_error_code); 553 554 for (i = 0; i < sz; i++) { 555 if (err_fat_int & fat_int_error_code[i].error_bit) { 556 rt = fat_int_error_code[i].intel_error_list; 557 emask_int |= fat_int_error_code[i].emask; 558 nerr++; 559 } 560 } 561 562 if (nb_chipset == INTEL_NB_5400 && 563 (err_nf_int & NERR_NF_5400_INT_B26) != 0) { 564 err_nf_int &= ~NERR_NF_5400_INT_B26; 565 rt = 26; 566 nerr++; 567 } 568 569 if (rt) 570 err_nf_int &= ~ERR_NF_INT_B18; 571 572 sz = sizeof (nf_int_error_code) / sizeof (struct mch_error_code); 573 574 for (i = 0; i < sz; i++) { 575 if (err_nf_int & nf_int_error_code[i].error_bit) { 576 rt = nf_int_error_code[i].intel_error_list; 577 emask_int |= nf_int_error_code[i].emask; 578 nerr++; 579 } 580 } 581 582 if (emask_int) 583 nb_int_mask_mc(emask_int); 584 if (nerr > 1) 585 rt = -1; 586 return (rt); 587 } 588 589 static int 590 log_int_err(nb_regs_t *rp, int willpanic, int *interpose) 591 { 592 int t = 0; 593 int rt = 0; 594 595 rp->flag = NB_REG_LOG_INT; 596 rp->nb.int_regs.ferr_fat_int = FERR_FAT_INT_RD(interpose); 597 rp->nb.int_regs.ferr_nf_int = FERR_NF_INT_RD(&t); 598 *interpose |= t; 599 rp->nb.int_regs.nerr_fat_int = NERR_FAT_INT_RD(&t); 600 *interpose |= t; 601 rp->nb.int_regs.nerr_nf_int = NERR_NF_INT_RD(&t); 602 *interpose |= t; 603 rp->nb.int_regs.nrecint = NRECINT_RD(); 604 rp->nb.int_regs.recint = RECINT_RD(); 605 rp->nb.int_regs.nrecsf = NRECSF_RD(); 606 rp->nb.int_regs.recsf = RECSF_RD(); 607 608 if (!willpanic) { 609 if (rp->nb.int_regs.ferr_fat_int || *interpose) 610 FERR_FAT_INT_WR(rp->nb.int_regs.ferr_fat_int); 611 if (rp->nb.int_regs.ferr_nf_int || *interpose) 612 FERR_NF_INT_WR(rp->nb.int_regs.ferr_nf_int); 613 if (rp->nb.int_regs.nerr_fat_int) 614 NERR_FAT_INT_WR(rp->nb.int_regs.nerr_fat_int); 615 if (rp->nb.int_regs.nerr_nf_int) 616 NERR_NF_INT_WR(rp->nb.int_regs.nerr_nf_int); 617 /* 618 * if interpose write read-only registers to clear from pcii 619 * cache 620 */ 621 if (*interpose) { 622 NRECINT_WR(); 623 RECINT_WR(); 624 NRECSF_WR(); 625 RECSF_WR(); 626 } 627 } 628 if (rp->nb.int_regs.ferr_fat_int == 0 && 629 rp->nb.int_regs.nerr_fat_int == 0 && 630 (rp->nb.int_regs.ferr_nf_int == ERR_NF_INT_B18 || 631 (rp->nb.int_regs.ferr_nf_int == 0 && 632 rp->nb.int_regs.nerr_nf_int == ERR_NF_INT_B18))) { 633 rt = 1; 634 } 635 return (rt); 636 } 637 638 static void 639 log_thermal_err(nb_regs_t *rp, int willpanic, int *interpose) 640 { 641 int t = 0; 642 643 rp->flag = NB_REG_LOG_THR; 644 rp->nb.thr_regs.ferr_fat_thr = FERR_FAT_THR_RD(interpose); 645 rp->nb.thr_regs.nerr_fat_thr = NERR_FAT_THR_RD(&t); 646 *interpose |= t; 647 rp->nb.thr_regs.ferr_nf_thr = FERR_NF_THR_RD(&t); 648 *interpose |= t; 649 rp->nb.thr_regs.nerr_nf_thr = NERR_NF_THR_RD(&t); 650 *interpose |= t; 651 rp->nb.thr_regs.ctsts = CTSTS_RD(); 652 rp->nb.thr_regs.thrtsts = THRTSTS_RD(); 653 654 if (!willpanic) { 655 if (rp->nb.thr_regs.ferr_fat_thr || *interpose) 656 FERR_FAT_THR_WR(rp->nb.thr_regs.ferr_fat_thr); 657 if (rp->nb.thr_regs.nerr_fat_thr || *interpose) 658 NERR_FAT_THR_WR(rp->nb.thr_regs.nerr_fat_thr); 659 if (rp->nb.thr_regs.ferr_nf_thr || *interpose) 660 FERR_NF_THR_WR(rp->nb.thr_regs.ferr_nf_thr); 661 if (rp->nb.thr_regs.nerr_nf_thr || *interpose) 662 NERR_NF_THR_WR(rp->nb.thr_regs.nerr_nf_thr); 663 664 if (*interpose) { 665 CTSTS_WR(rp->nb.thr_regs.ctsts); 666 THRTSTS_WR(rp->nb.thr_regs.thrtsts); 667 } 668 } 669 } 670 671 static void 672 log_dma_err(nb_regs_t *rp, int *interpose) 673 { 674 rp->flag = NB_REG_LOG_DMA; 675 676 rp->nb.dma_regs.pcists = PCISTS_RD(interpose); 677 rp->nb.dma_regs.pexdevsts = PCIDEVSTS_RD(); 678 } 679 680 static struct mch_error_code fat_fsb_error_code[] = { 681 { 9, EMASK_FSB_F9, ERR_FAT_FSB_F9 }, 682 { 2, EMASK_FSB_F2, ERR_FAT_FSB_F2 }, 683 { 1, EMASK_FSB_F1, ERR_FAT_FSB_F1 } 684 }; 685 686 static struct mch_error_code nf_fsb_error_code[] = { 687 { 8, EMASK_FSB_F8, ERR_NF_FSB_F8 }, 688 { 7, EMASK_FSB_F7, ERR_NF_FSB_F7 }, 689 { 6, EMASK_FSB_F6, ERR_NF_FSB_F6 } 690 }; 691 692 static int 693 intel_fsb_err(int fsb, uint8_t err_fat_fsb, uint8_t err_nf_fsb) 694 { 695 int rt = -1; 696 int nerr = 0; 697 uint16_t emask_fsb = 0; 698 int i; 699 int sz; 700 701 sz = sizeof (fat_fsb_error_code) / sizeof (struct mch_error_code); 702 703 for (i = 0; i < sz; i++) { 704 if (err_fat_fsb & fat_fsb_error_code[i].error_bit) { 705 rt = fat_fsb_error_code[i].intel_error_list; 706 emask_fsb |= fat_fsb_error_code[i].emask; 707 nerr++; 708 } 709 } 710 711 sz = sizeof (nf_fsb_error_code) / sizeof (struct mch_error_code); 712 713 for (i = 0; i < sz; i++) { 714 if (err_nf_fsb & nf_fsb_error_code[i].error_bit) { 715 rt = nf_fsb_error_code[i].intel_error_list; 716 emask_fsb |= nf_fsb_error_code[i].emask; 717 nerr++; 718 } 719 } 720 721 if (emask_fsb) 722 nb_fsb_mask_mc(fsb, emask_fsb); 723 if (nerr > 1) 724 rt = -1; 725 return (rt); 726 } 727 728 static void 729 log_fsb_err(uint64_t ferr, nb_regs_t *rp, int willpanic, int *interpose) 730 { 731 uint8_t fsb; 732 int t = 0; 733 734 fsb = GE_FERR_FSB(ferr); 735 rp->flag = NB_REG_LOG_FSB; 736 737 rp->nb.fsb_regs.fsb = fsb; 738 rp->nb.fsb_regs.ferr_fat_fsb = FERR_FAT_FSB_RD(fsb, interpose); 739 rp->nb.fsb_regs.ferr_nf_fsb = FERR_NF_FSB_RD(fsb, &t); 740 *interpose |= t; 741 rp->nb.fsb_regs.nerr_fat_fsb = NERR_FAT_FSB_RD(fsb, &t); 742 *interpose |= t; 743 rp->nb.fsb_regs.nerr_nf_fsb = NERR_NF_FSB_RD(fsb, &t); 744 *interpose |= t; 745 rp->nb.fsb_regs.nrecfsb = NRECFSB_RD(fsb); 746 rp->nb.fsb_regs.nrecfsb_addr = NRECADDR_RD(fsb); 747 rp->nb.fsb_regs.recfsb = RECFSB_RD(fsb); 748 if (!willpanic) { 749 /* Clear the fatal/non-fatal first/next FSB errors */ 750 if (rp->nb.fsb_regs.ferr_fat_fsb || *interpose) 751 FERR_FAT_FSB_WR(fsb, rp->nb.fsb_regs.ferr_fat_fsb); 752 if (rp->nb.fsb_regs.ferr_nf_fsb || *interpose) 753 FERR_NF_FSB_WR(fsb, rp->nb.fsb_regs.ferr_nf_fsb); 754 if (rp->nb.fsb_regs.nerr_fat_fsb || *interpose) 755 NERR_FAT_FSB_WR(fsb, rp->nb.fsb_regs.nerr_fat_fsb); 756 if (rp->nb.fsb_regs.nerr_nf_fsb || *interpose) 757 NERR_NF_FSB_WR(fsb, rp->nb.fsb_regs.nerr_nf_fsb); 758 759 /* 760 * if interpose write read-only registers to clear from pcii 761 * cache 762 */ 763 if (*interpose) { 764 NRECFSB_WR(fsb); 765 NRECADDR_WR(fsb); 766 RECFSB_WR(fsb); 767 } 768 } 769 } 770 771 static struct mch_error_code fat_pex_error_code[] = { 772 { 19, EMASK_UNCOR_PEX_IO19, PEX_FAT_IO19 }, 773 { 18, EMASK_UNCOR_PEX_IO18, PEX_FAT_IO18 }, 774 { 10, EMASK_UNCOR_PEX_IO10, PEX_FAT_IO10 }, 775 { 9, EMASK_UNCOR_PEX_IO9, PEX_FAT_IO9 }, 776 { 8, EMASK_UNCOR_PEX_IO8, PEX_FAT_IO8 }, 777 { 7, EMASK_UNCOR_PEX_IO7, PEX_FAT_IO7 }, 778 { 6, EMASK_UNCOR_PEX_IO6, PEX_FAT_IO6 }, 779 { 5, EMASK_UNCOR_PEX_IO5, PEX_FAT_IO5 }, 780 { 4, EMASK_UNCOR_PEX_IO4, PEX_FAT_IO4 }, 781 { 3, EMASK_UNCOR_PEX_IO3, PEX_FAT_IO3 }, 782 { 2, EMASK_UNCOR_PEX_IO2, PEX_FAT_IO2 }, 783 { 0, EMASK_UNCOR_PEX_IO0, PEX_FAT_IO0 } 784 }; 785 786 static struct mch_error_code fat_unit_pex_5400_error_code[] = { 787 { 32, EMASK_UNIT_PEX_IO32, PEX_5400_FAT_IO32 }, 788 { 31, EMASK_UNIT_PEX_IO31, PEX_5400_FAT_IO31 }, 789 { 30, EMASK_UNIT_PEX_IO30, PEX_5400_FAT_IO30 }, 790 { 29, EMASK_UNIT_PEX_IO29, PEX_5400_FAT_IO29 }, 791 { 27, EMASK_UNIT_PEX_IO27, PEX_5400_FAT_IO27 }, 792 { 26, EMASK_UNIT_PEX_IO26, PEX_5400_FAT_IO26 }, 793 { 25, EMASK_UNIT_PEX_IO25, PEX_5400_FAT_IO25 }, 794 { 24, EMASK_UNIT_PEX_IO24, PEX_5400_FAT_IO24 }, 795 { 23, EMASK_UNIT_PEX_IO23, PEX_5400_FAT_IO23 }, 796 { 22, EMASK_UNIT_PEX_IO22, PEX_5400_FAT_IO22 }, 797 }; 798 799 static struct mch_error_code fat_pex_5400_error_code[] = { 800 { 19, EMASK_UNCOR_PEX_IO19, PEX_5400_FAT_IO19 }, 801 { 18, EMASK_UNCOR_PEX_IO18, PEX_5400_FAT_IO18 }, 802 { 10, EMASK_UNCOR_PEX_IO10, PEX_5400_FAT_IO10 }, 803 { 9, EMASK_UNCOR_PEX_IO9, PEX_5400_FAT_IO9 }, 804 { 8, EMASK_UNCOR_PEX_IO8, PEX_5400_FAT_IO8 }, 805 { 7, EMASK_UNCOR_PEX_IO7, PEX_5400_FAT_IO7 }, 806 { 6, EMASK_UNCOR_PEX_IO6, PEX_5400_FAT_IO6 }, 807 { 5, EMASK_UNCOR_PEX_IO5, PEX_5400_FAT_IO5 }, 808 { 4, EMASK_UNCOR_PEX_IO4, PEX_5400_FAT_IO4 }, 809 { 2, EMASK_UNCOR_PEX_IO2, PEX_5400_FAT_IO2 }, 810 { 0, EMASK_UNCOR_PEX_IO0, PEX_5400_FAT_IO0 } 811 }; 812 813 static struct mch_error_code fat_rp_5400_error_code[] = { 814 { 1, EMASK_RP_PEX_IO1, PEX_5400_FAT_IO1 } 815 }; 816 817 static struct mch_error_code fat_rp_error_code[] = { 818 { 1, EMASK_RP_PEX_IO1, PEX_FAT_IO1 } 819 }; 820 821 static struct mch_error_code uncor_pex_error_code[] = { 822 { 19, EMASK_UNCOR_PEX_IO19, PEX_NF_IO19 }, 823 { 9, EMASK_UNCOR_PEX_IO9, PEX_NF_IO9 }, 824 { 8, EMASK_UNCOR_PEX_IO8, PEX_NF_IO8 }, 825 { 7, EMASK_UNCOR_PEX_IO7, PEX_NF_IO7 }, 826 { 6, EMASK_UNCOR_PEX_IO6, PEX_NF_IO6 }, 827 { 5, EMASK_UNCOR_PEX_IO5, PEX_NF_IO5 }, 828 { 4, EMASK_UNCOR_PEX_IO4, PEX_NF_IO4 }, 829 { 3, EMASK_UNCOR_PEX_IO3, PEX_NF_IO3 }, 830 { 0, EMASK_UNCOR_PEX_IO0, PEX_NF_IO0 } 831 }; 832 833 static struct mch_error_code uncor_pex_5400_error_code[] = { 834 { 33, EMASK_UNIT_PEX_IO33, PEX_5400_NF_IO33 }, 835 { 32, EMASK_UNIT_PEX_IO32, PEX_5400_NF_IO32 }, 836 { 31, EMASK_UNIT_PEX_IO31, PEX_5400_NF_IO31 }, 837 { 30, EMASK_UNIT_PEX_IO30, PEX_5400_NF_IO30 }, 838 { 29, EMASK_UNIT_PEX_IO29, PEX_5400_NF_IO29 }, 839 { 28, EMASK_UNIT_PEX_IO28, PEX_5400_NF_IO28 }, 840 { 27, EMASK_UNIT_PEX_IO27, PEX_5400_NF_IO27 }, 841 { 26, EMASK_UNIT_PEX_IO26, PEX_5400_NF_IO26 }, 842 { 25, EMASK_UNIT_PEX_IO25, PEX_5400_NF_IO25 }, 843 { 24, EMASK_UNIT_PEX_IO24, PEX_5400_NF_IO24 }, 844 { 23, EMASK_UNIT_PEX_IO23, PEX_5400_NF_IO23 }, 845 }; 846 847 static struct mch_error_code cor_pex_error_code[] = { 848 { 20, EMASK_COR_PEX_IO20, PEX_5400_NF_IO20 }, 849 { 16, EMASK_COR_PEX_IO16, PEX_NF_IO16 }, 850 { 15, EMASK_COR_PEX_IO15, PEX_NF_IO15 }, 851 { 14, EMASK_COR_PEX_IO14, PEX_NF_IO14 }, 852 { 13, EMASK_COR_PEX_IO13, PEX_NF_IO13 }, 853 { 12, EMASK_COR_PEX_IO12, PEX_NF_IO12 }, 854 { 10, 0, PEX_NF_IO10 }, 855 { 2, 0, PEX_NF_IO2 } 856 }; 857 858 static struct mch_error_code rp_pex_5400_error_code[] = { 859 { 17, EMASK_RP_PEX_IO17, PEX_5400_NF_IO17 }, 860 { 11, EMASK_RP_PEX_IO11, PEX_5400_NF_IO11 } 861 }; 862 863 static struct mch_error_code cor_pex_5400_error_code1[] = { 864 { 19, EMASK_UNCOR_PEX_IO19, PEX_5400_NF_IO19 }, 865 { 10, EMASK_UNCOR_PEX_IO10, PEX_5400_NF_IO10 }, 866 { 9, EMASK_UNCOR_PEX_IO9, PEX_5400_NF_IO9 }, 867 { 8, EMASK_UNCOR_PEX_IO8, PEX_5400_NF_IO8 }, 868 { 7, EMASK_UNCOR_PEX_IO7, PEX_5400_NF_IO7 }, 869 { 6, EMASK_UNCOR_PEX_IO6, PEX_5400_NF_IO6 }, 870 { 5, EMASK_UNCOR_PEX_IO5, PEX_5400_NF_IO5 }, 871 { 4, EMASK_UNCOR_PEX_IO4, PEX_5400_NF_IO4 }, 872 { 2, EMASK_UNCOR_PEX_IO2, PEX_5400_NF_IO2 }, 873 { 0, EMASK_UNCOR_PEX_IO0, PEX_5400_NF_IO0 } 874 }; 875 876 static struct mch_error_code cor_pex_5400_error_code2[] = { 877 { 20, EMASK_COR_PEX_IO20, PEX_5400_NF_IO20 }, 878 { 16, EMASK_COR_PEX_IO16, PEX_5400_NF_IO16 }, 879 { 15, EMASK_COR_PEX_IO15, PEX_5400_NF_IO15 }, 880 { 14, EMASK_COR_PEX_IO14, PEX_5400_NF_IO14 }, 881 { 13, EMASK_COR_PEX_IO13, PEX_5400_NF_IO13 }, 882 { 12, EMASK_COR_PEX_IO12, PEX_5400_NF_IO12 } 883 }; 884 885 static struct mch_error_code cor_pex_5400_error_code3[] = { 886 { 33, EMASK_UNIT_PEX_IO33, PEX_5400_NF_IO33 }, 887 { 32, EMASK_UNIT_PEX_IO32, PEX_5400_NF_IO32 }, 888 { 31, EMASK_UNIT_PEX_IO31, PEX_5400_NF_IO31 }, 889 { 30, EMASK_UNIT_PEX_IO30, PEX_5400_NF_IO30 }, 890 { 29, EMASK_UNIT_PEX_IO29, PEX_5400_NF_IO29 }, 891 { 28, EMASK_UNIT_PEX_IO28, PEX_5400_NF_IO28 }, 892 { 27, EMASK_UNIT_PEX_IO27, PEX_5400_NF_IO27 }, 893 { 26, EMASK_UNIT_PEX_IO26, PEX_5400_NF_IO26 }, 894 { 25, EMASK_UNIT_PEX_IO25, PEX_5400_NF_IO25 }, 895 { 24, EMASK_UNIT_PEX_IO24, PEX_5400_NF_IO24 }, 896 { 23, EMASK_UNIT_PEX_IO23, PEX_5400_NF_IO23 } 897 }; 898 899 static struct mch_error_code rp_pex_error_code[] = { 900 { 17, EMASK_RP_PEX_IO17, PEX_NF_IO17 }, 901 { 11, EMASK_RP_PEX_IO11, PEX_NF_IO11 }, 902 }; 903 904 static int 905 intel_pex_err(uint32_t pex_fat, uint32_t pex_nf_cor) 906 { 907 int rt = -1; 908 int nerr = 0; 909 int i; 910 int sz; 911 912 sz = sizeof (fat_pex_error_code) / sizeof (struct mch_error_code); 913 914 for (i = 0; i < sz; i++) { 915 if (pex_fat & fat_pex_error_code[i].error_bit) { 916 rt = fat_pex_error_code[i].intel_error_list; 917 nerr++; 918 } 919 } 920 sz = sizeof (fat_rp_error_code) / sizeof (struct mch_error_code); 921 922 for (i = 0; i < sz; i++) { 923 if (pex_fat & fat_rp_error_code[i].error_bit) { 924 rt = fat_rp_error_code[i].intel_error_list; 925 nerr++; 926 } 927 } 928 sz = sizeof (uncor_pex_error_code) / sizeof (struct mch_error_code); 929 930 for (i = 0; i < sz; i++) { 931 if (pex_nf_cor & uncor_pex_error_code[i].error_bit) { 932 rt = uncor_pex_error_code[i].intel_error_list; 933 nerr++; 934 } 935 } 936 937 sz = sizeof (cor_pex_error_code) / sizeof (struct mch_error_code); 938 939 for (i = 0; i < sz; i++) { 940 if (pex_nf_cor & cor_pex_error_code[i].error_bit) { 941 rt = cor_pex_error_code[i].intel_error_list; 942 nerr++; 943 } 944 } 945 sz = sizeof (rp_pex_error_code) / sizeof (struct mch_error_code); 946 947 for (i = 0; i < sz; i++) { 948 if (pex_nf_cor & rp_pex_error_code[i].error_bit) { 949 rt = rp_pex_error_code[i].intel_error_list; 950 nerr++; 951 } 952 } 953 954 if (nerr > 1) 955 rt = -1; 956 return (rt); 957 } 958 959 static struct mch_error_code fat_thr_error_code[] = { 960 { 2, EMASK_THR_F2, ERR_FAT_THR_F2 }, 961 { 1, EMASK_THR_F1, ERR_FAT_THR_F1 } 962 }; 963 964 static struct mch_error_code nf_thr_error_code[] = { 965 { 5, EMASK_THR_F5, ERR_NF_THR_F5 }, 966 { 4, EMASK_THR_F4, ERR_NF_THR_F4 }, 967 { 3, EMASK_THR_F3, ERR_NF_THR_F3 } 968 }; 969 970 static int 971 intel_thr_err(uint8_t err_fat_thr, uint8_t err_nf_thr) 972 { 973 int rt = -1; 974 int nerr = 0; 975 uint16_t emask_thr = 0; 976 int i; 977 int sz; 978 979 sz = sizeof (fat_thr_error_code) / sizeof (struct mch_error_code); 980 981 for (i = 0; i < sz; i++) { 982 if (err_fat_thr & fat_thr_error_code[i].error_bit) { 983 rt = fat_thr_error_code[i].intel_error_list; 984 emask_thr |= fat_thr_error_code[i].emask; 985 nerr++; 986 } 987 } 988 989 sz = sizeof (nf_thr_error_code) / sizeof (struct mch_error_code); 990 991 for (i = 0; i < sz; i++) { 992 if (err_nf_thr & nf_thr_error_code[i].error_bit) { 993 rt = nf_thr_error_code[i].intel_error_list; 994 emask_thr |= nf_thr_error_code[i].emask; 995 nerr++; 996 } 997 } 998 999 if (emask_thr) 1000 nb_thr_mask_mc(emask_thr); 1001 if (nerr > 1) 1002 rt = -1; 1003 return (rt); 1004 } 1005 1006 static int 1007 intel_pex_5400_err(uint32_t pex_fat, uint32_t pex_nf_cor) 1008 { 1009 int rt = -1; 1010 int nerr = 0; 1011 int i; 1012 int sz; 1013 1014 sz = sizeof (fat_pex_5400_error_code) / sizeof (struct mch_error_code); 1015 1016 for (i = 0; i < sz; i++) { 1017 if (pex_fat & fat_pex_5400_error_code[i].error_bit) { 1018 rt = fat_pex_5400_error_code[i].intel_error_list; 1019 nerr++; 1020 } 1021 } 1022 sz = sizeof (fat_rp_5400_error_code) / sizeof (struct mch_error_code); 1023 1024 for (i = 0; i < sz; i++) { 1025 if (pex_fat & fat_rp_5400_error_code[i].error_bit) { 1026 rt = fat_rp_5400_error_code[i].intel_error_list; 1027 nerr++; 1028 } 1029 } 1030 sz = sizeof (fat_unit_pex_5400_error_code) / 1031 sizeof (struct mch_error_code); 1032 1033 for (i = 0; i < sz; i++) { 1034 if (pex_fat & 1035 fat_unit_pex_5400_error_code[i].error_bit) { 1036 rt = fat_unit_pex_5400_error_code[i].intel_error_list; 1037 nerr++; 1038 } 1039 } 1040 sz = sizeof (uncor_pex_5400_error_code) / 1041 sizeof (struct mch_error_code); 1042 1043 for (i = 0; i < sz; i++) { 1044 if (pex_fat & uncor_pex_5400_error_code[i].error_bit) { 1045 rt = uncor_pex_5400_error_code[i].intel_error_list; 1046 nerr++; 1047 } 1048 } 1049 1050 sz = sizeof (rp_pex_5400_error_code) / sizeof (struct mch_error_code); 1051 1052 for (i = 0; i < sz; i++) { 1053 if (pex_nf_cor & rp_pex_5400_error_code[i].error_bit) { 1054 rt = rp_pex_5400_error_code[i].intel_error_list; 1055 nerr++; 1056 } 1057 } 1058 1059 sz = sizeof (cor_pex_5400_error_code1) / sizeof (struct mch_error_code); 1060 1061 for (i = 0; i < sz; i++) { 1062 if (pex_nf_cor & cor_pex_5400_error_code1[i].error_bit) { 1063 rt = cor_pex_5400_error_code1[i].intel_error_list; 1064 nerr++; 1065 } 1066 } 1067 1068 sz = sizeof (cor_pex_5400_error_code2) / sizeof (struct mch_error_code); 1069 1070 for (i = 0; i < sz; i++) { 1071 if (pex_nf_cor & cor_pex_5400_error_code2[i].error_bit) { 1072 rt = cor_pex_5400_error_code2[i].intel_error_list; 1073 nerr++; 1074 } 1075 } 1076 1077 sz = sizeof (cor_pex_5400_error_code3) / sizeof (struct mch_error_code); 1078 1079 for (i = 0; i < sz; i++) { 1080 if (pex_nf_cor & cor_pex_5400_error_code3[i].error_bit) { 1081 rt = cor_pex_5400_error_code3[i].intel_error_list; 1082 nerr++; 1083 } 1084 } 1085 1086 if (nerr > 1) 1087 rt = -1; 1088 return (rt); 1089 } 1090 1091 static void 1092 log_pex_err(uint64_t ferr, nb_regs_t *rp, int willpanic, int *interpose) 1093 { 1094 uint8_t pex = (uint8_t)-1; 1095 int t = 0; 1096 1097 rp->flag = NB_REG_LOG_PEX; 1098 pex = GE_ERR_PEX(ferr); 1099 1100 rp->nb.pex_regs.pex = pex; 1101 rp->nb.pex_regs.pex_fat_ferr = PEX_FAT_FERR_RD(pex, interpose); 1102 rp->nb.pex_regs.pex_fat_nerr = PEX_FAT_NERR_RD(pex, &t); 1103 *interpose |= t; 1104 rp->nb.pex_regs.pex_nf_corr_ferr = PEX_NF_FERR_RD(pex, &t); 1105 *interpose |= t; 1106 rp->nb.pex_regs.pex_nf_corr_nerr = PEX_NF_NERR_RD(pex, &t); 1107 *interpose |= t; 1108 rp->nb.pex_regs.uncerrsev = UNCERRSEV_RD(pex); 1109 rp->nb.pex_regs.rperrsts = RPERRSTS_RD(pex); 1110 rp->nb.pex_regs.rperrsid = RPERRSID_RD(pex); 1111 if (pex != (uint8_t)-1) 1112 rp->nb.pex_regs.uncerrsts = UNCERRSTS_RD(pex); 1113 else 1114 rp->nb.pex_regs.uncerrsts = 0; 1115 rp->nb.pex_regs.aerrcapctrl = AERRCAPCTRL_RD(pex); 1116 rp->nb.pex_regs.corerrsts = CORERRSTS_RD(pex); 1117 rp->nb.pex_regs.pexdevsts = PEXDEVSTS_RD(pex); 1118 1119 if (!willpanic) { 1120 if (rp->nb.pex_regs.pex_fat_ferr || *interpose) 1121 PEX_FAT_FERR_WR(pex, rp->nb.pex_regs.pex_fat_ferr); 1122 if (rp->nb.pex_regs.pex_fat_nerr) 1123 PEX_FAT_NERR_WR(pex, rp->nb.pex_regs.pex_fat_nerr); 1124 if (rp->nb.pex_regs.pex_nf_corr_ferr || *interpose) 1125 PEX_NF_FERR_WR(pex, rp->nb.pex_regs.pex_nf_corr_ferr); 1126 if (rp->nb.pex_regs.pex_nf_corr_nerr) 1127 PEX_NF_NERR_WR(pex, rp->nb.pex_regs.pex_nf_corr_nerr); 1128 if (*interpose) 1129 UNCERRSTS_WR(pex, rp->nb.pex_regs.uncerrsts); 1130 if (*interpose) 1131 RPERRSTS_WR(pex, rp->nb.pex_regs.rperrsts); 1132 if (*interpose) 1133 PEXDEVSTS_WR(pex, 0); 1134 } 1135 } 1136 1137 static void 1138 log_fat_fbd_err(nb_regs_t *rp, int willpanic, int *interpose) 1139 { 1140 int channel, branch; 1141 int t = 0; 1142 1143 rp->flag = NB_REG_LOG_FAT_FBD; 1144 rp->nb.fat_fbd_regs.ferr_fat_fbd = FERR_FAT_FBD_RD(interpose); 1145 channel = (rp->nb.fat_fbd_regs.ferr_fat_fbd >> 28) & 3; 1146 branch = channel >> 1; 1147 rp->nb.fat_fbd_regs.nerr_fat_fbd = NERR_FAT_FBD_RD(&t); 1148 *interpose |= t; 1149 rp->nb.fat_fbd_regs.nrecmema = NRECMEMA_RD(branch); 1150 rp->nb.fat_fbd_regs.nrecmemb = NRECMEMB_RD(branch); 1151 rp->nb.fat_fbd_regs.nrecfglog = NRECFGLOG_RD(branch); 1152 rp->nb.fat_fbd_regs.nrecfbda = NRECFBDA_RD(branch); 1153 rp->nb.fat_fbd_regs.nrecfbdb = NRECFBDB_RD(branch); 1154 rp->nb.fat_fbd_regs.nrecfbdc = NRECFBDC_RD(branch); 1155 rp->nb.fat_fbd_regs.nrecfbdd = NRECFBDD_RD(branch); 1156 rp->nb.fat_fbd_regs.nrecfbde = NRECFBDE_RD(branch); 1157 rp->nb.fat_fbd_regs.nrecfbdf = NRECFBDF_RD(branch); 1158 rp->nb.fat_fbd_regs.spcps = SPCPS_RD(branch); 1159 rp->nb.fat_fbd_regs.spcpc = SPCPC_RD(branch); 1160 rp->nb.fat_fbd_regs.uerrcnt = UERRCNT_RD(branch); 1161 rp->nb.fat_fbd_regs.uerrcnt_last = uerrcnt[branch]; 1162 uerrcnt[branch] = rp->nb.fat_fbd_regs.uerrcnt; 1163 rp->nb.fat_fbd_regs.badrama = BADRAMA_RD(branch); 1164 rp->nb.fat_fbd_regs.badramb = BADRAMB_RD(branch); 1165 rp->nb.fat_fbd_regs.badcnt = BADCNT_RD(branch); 1166 if (!willpanic) { 1167 if (rp->nb.fat_fbd_regs.ferr_fat_fbd || *interpose) 1168 FERR_FAT_FBD_WR(rp->nb.fat_fbd_regs.ferr_fat_fbd); 1169 if (rp->nb.fat_fbd_regs.nerr_fat_fbd) 1170 NERR_FAT_FBD_WR(rp->nb.fat_fbd_regs.nerr_fat_fbd); 1171 /* 1172 * if interpose write read-only registers to clear from pcii 1173 * cache 1174 */ 1175 if (*interpose) { 1176 NRECMEMA_WR(branch); 1177 NRECMEMB_WR(branch); 1178 NRECFGLOG_WR(branch); 1179 NRECFBDA_WR(branch); 1180 NRECFBDB_WR(branch); 1181 NRECFBDC_WR(branch); 1182 NRECFBDD_WR(branch); 1183 NRECFBDE_WR(branch); 1184 NRECFBDF_WR(branch); 1185 } 1186 } 1187 } 1188 1189 static void 1190 log_nf_fbd_err(nb_regs_t *rp, int willpanic, int *interpose) 1191 { 1192 int channel, branch; 1193 int t = 0; 1194 1195 rp->flag = NB_REG_LOG_NF_FBD; 1196 rp->nb.nf_fbd_regs.ferr_nf_fbd = FERR_NF_FBD_RD(interpose); 1197 channel = (rp->nb.nf_fbd_regs.ferr_nf_fbd >> 28) & 3; 1198 branch = channel >> 1; 1199 rp->nb.nf_fbd_regs.nerr_nf_fbd = NERR_NF_FBD_RD(&t); 1200 *interpose |= t; 1201 rp->nb.nf_fbd_regs.redmemb = REDMEMB_RD(); 1202 rp->nb.nf_fbd_regs.recmema = RECMEMA_RD(branch); 1203 rp->nb.nf_fbd_regs.recmemb = RECMEMB_RD(branch); 1204 rp->nb.nf_fbd_regs.recfglog = RECFGLOG_RD(branch); 1205 rp->nb.nf_fbd_regs.recfbda = RECFBDA_RD(branch); 1206 rp->nb.nf_fbd_regs.recfbdb = RECFBDB_RD(branch); 1207 rp->nb.nf_fbd_regs.recfbdc = RECFBDC_RD(branch); 1208 rp->nb.nf_fbd_regs.recfbdd = RECFBDD_RD(branch); 1209 rp->nb.nf_fbd_regs.recfbde = RECFBDE_RD(branch); 1210 rp->nb.nf_fbd_regs.recfbdf = RECFBDF_RD(branch); 1211 rp->nb.nf_fbd_regs.spcps = SPCPS_RD(branch); 1212 rp->nb.nf_fbd_regs.spcpc = SPCPC_RD(branch); 1213 if (nb_chipset == INTEL_NB_7300 || nb_chipset == INTEL_NB_5400) { 1214 rp->nb.nf_fbd_regs.cerrcnta = CERRCNTA_RD(branch, channel); 1215 rp->nb.nf_fbd_regs.cerrcntb = CERRCNTB_RD(branch, channel); 1216 rp->nb.nf_fbd_regs.cerrcntc = CERRCNTC_RD(branch, channel); 1217 rp->nb.nf_fbd_regs.cerrcntd = CERRCNTD_RD(branch, channel); 1218 } else { 1219 rp->nb.nf_fbd_regs.cerrcnta = CERRCNT_RD(branch); 1220 rp->nb.nf_fbd_regs.cerrcntb = 0; 1221 rp->nb.nf_fbd_regs.cerrcntc = 0; 1222 rp->nb.nf_fbd_regs.cerrcntd = 0; 1223 } 1224 rp->nb.nf_fbd_regs.cerrcnta_last = cerrcnta[branch][channel & 1]; 1225 rp->nb.nf_fbd_regs.cerrcntb_last = cerrcntb[branch][channel & 1]; 1226 rp->nb.nf_fbd_regs.cerrcntc_last = cerrcntc[branch][channel & 1]; 1227 rp->nb.nf_fbd_regs.cerrcntd_last = cerrcntd[branch][channel & 1]; 1228 cerrcnta[branch][channel & 1] = rp->nb.nf_fbd_regs.cerrcnta; 1229 cerrcntb[branch][channel & 1] = rp->nb.nf_fbd_regs.cerrcntb; 1230 cerrcntc[branch][channel & 1] = rp->nb.nf_fbd_regs.cerrcntc; 1231 cerrcntd[branch][channel & 1] = rp->nb.nf_fbd_regs.cerrcntd; 1232 rp->nb.nf_fbd_regs.badrama = BADRAMA_RD(branch); 1233 rp->nb.nf_fbd_regs.badramb = BADRAMB_RD(branch); 1234 rp->nb.nf_fbd_regs.badcnt = BADCNT_RD(branch); 1235 if (!willpanic) { 1236 if (rp->nb.nf_fbd_regs.ferr_nf_fbd || *interpose) 1237 FERR_NF_FBD_WR(rp->nb.nf_fbd_regs.ferr_nf_fbd); 1238 if (rp->nb.nf_fbd_regs.nerr_nf_fbd) 1239 NERR_NF_FBD_WR(rp->nb.nf_fbd_regs.nerr_nf_fbd); 1240 /* 1241 * if interpose write read-only registers to clear from pcii 1242 * cache 1243 */ 1244 if (*interpose) { 1245 RECMEMA_WR(branch); 1246 RECMEMB_WR(branch); 1247 RECFGLOG_WR(branch); 1248 RECFBDA_WR(branch); 1249 RECFBDB_WR(branch); 1250 RECFBDC_WR(branch); 1251 RECFBDD_WR(branch); 1252 RECFBDE_WR(branch); 1253 RECFBDF_WR(branch); 1254 SPCPS_WR(branch); 1255 } 1256 } 1257 } 1258 1259 static void 1260 log_nf_mem_err(nb_regs_t *rp, int willpanic, int *interpose) 1261 { 1262 int channel, branch; 1263 int t = 0; 1264 1265 rp->flag = NB_REG_LOG_NF_MEM; 1266 1267 /* Memmory err registers */ 1268 rp->nb.nf_mem_regs.ferr_nf_mem = FERR_NF_MEM_RD(interpose); 1269 channel = (rp->nb.nf_mem_regs.ferr_nf_mem >> 28) & 0x1; 1270 branch = channel; 1271 rp->nb.nf_mem_regs.nerr_nf_mem = NERR_NF_MEM_RD(&t); 1272 *interpose |= t; 1273 rp->nb.nf_mem_regs.redmema = MEM_REDMEMA_RD(branch); 1274 rp->nb.nf_mem_regs.redmemb = MEM_REDMEMB_RD(branch); 1275 rp->nb.nf_mem_regs.recmema = MEM_RECMEMA_RD(branch); 1276 rp->nb.nf_mem_regs.recmemb = MEM_RECMEMB_RD(branch); 1277 rp->nb.nf_mem_regs.nrecmema = MEM_NRECMEMA_RD(branch); 1278 rp->nb.nf_mem_regs.nrecmemb = MEM_NRECMEMB_RD(branch); 1279 1280 /* spare rank */ 1281 rp->nb.nf_mem_regs.spcps = SPCPS_RD(branch); 1282 rp->nb.nf_mem_regs.spcpc = SPCPC_RD(branch); 1283 1284 /* RAS registers */ 1285 rp->nb.nf_mem_regs.cerrcnt = MEM_CERRCNT_RD(branch); 1286 rp->nb.nf_mem_regs.cerrcnt_ext = (uint32_t)MEM_CERRCNT_EXT_RD(branch); 1287 rp->nb.nf_mem_regs.cerrcnt_last = cerrcnta[branch][channel & 1]; 1288 rp->nb.nf_mem_regs.cerrcnt_ext_last = cerrcntb[branch][channel & 1]; 1289 cerrcnta[branch][channel & 1] = rp->nb.nf_mem_regs.cerrcnt; 1290 cerrcntb[branch][channel & 1] = rp->nb.nf_mem_regs.cerrcnt_ext; 1291 rp->nb.nf_mem_regs.badram = BADRAMA_RD(branch); 1292 rp->nb.nf_mem_regs.badcnt = BADCNT_RD(branch); 1293 rp->nb.nf_mem_regs.validlog = VALIDLOG_RD(branch); 1294 1295 if (!willpanic) { 1296 if (rp->nb.nf_mem_regs.ferr_nf_mem || *interpose) 1297 FERR_NF_MEM_WR(rp->nb.nf_mem_regs.ferr_nf_mem); 1298 if (rp->nb.nf_mem_regs.nerr_nf_mem) 1299 NERR_NF_MEM_WR(rp->nb.nf_mem_regs.nerr_nf_mem); 1300 /* 1301 * if interpose, write read-only registers to clear from pci 1302 * cache 1303 */ 1304 if (*interpose) { 1305 MEM_NRECMEMA_WR(branch); 1306 MEM_NRECMEMB_WR(branch); 1307 MEM_REDMEMA_WR(branch); 1308 MEM_REDMEMB_WR(branch); 1309 MEM_RECMEMA_WR(branch); 1310 MEM_RECMEMB_WR(branch); 1311 SPCPS_WR(branch); 1312 } 1313 } 1314 } 1315 1316 static void 1317 log_ferr(uint64_t ferr, uint32_t *nerrp, nb_logout_t *log, int willpanic) 1318 { 1319 nb_regs_t *rp = &log->nb_regs; 1320 uint32_t nerr = *nerrp; 1321 int interpose = 0; 1322 int spurious = 0; 1323 1324 log->acl_timestamp = gethrtime_waitfree(); 1325 if ((ferr & (GE_PCIEX_FATAL | GE_PCIEX_NF)) != 0) { 1326 log_pex_err(ferr, rp, willpanic, &interpose); 1327 *nerrp = nerr & ~(GE_PCIEX_FATAL | GE_PCIEX_NF); 1328 } else if ((ferr & GE_FBD_FATAL) != 0) { 1329 log_fat_fbd_err(rp, willpanic, &interpose); 1330 *nerrp = nerr & ~GE_NERR_FBD_FATAL; 1331 } else if ((ferr & GE_FBD_NF) != 0) { 1332 log_nf_fbd_err(rp, willpanic, &interpose); 1333 *nerrp = nerr & ~GE_NERR_FBD_NF; 1334 } else if ((ferr & GE_MEM_NF) != 0) { 1335 log_nf_mem_err(rp, willpanic, &interpose); 1336 *nerrp = nerr & ~GE_NERR_MEM_NF; 1337 } else if ((ferr & (GE_FERR_FSB_FATAL | GE_FERR_FSB_NF)) != 0) { 1338 log_fsb_err(ferr, rp, willpanic, &interpose); 1339 *nerrp = nerr & ~(GE_NERR_FSB_FATAL | GE_NERR_FSB_NF); 1340 } else if ((ferr & (GE_DMA_FATAL | GE_DMA_NF)) != 0) { 1341 log_dma_err(rp, &interpose); 1342 *nerrp = nerr & ~(GE_DMA_FATAL | GE_DMA_NF); 1343 } else if ((ferr & (GE_INT_FATAL | GE_INT_NF)) != 0) { 1344 spurious = log_int_err(rp, willpanic, &interpose); 1345 *nerrp = nerr & ~(GE_INT_FATAL | GE_INT_NF); 1346 } else if (nb_chipset == INTEL_NB_5400 && 1347 (ferr & (GE_FERR_THERMAL_FATAL | GE_FERR_THERMAL_NF)) != 0) { 1348 log_thermal_err(rp, willpanic, &interpose); 1349 *nerrp = nerr & ~(GE_FERR_THERMAL_FATAL | GE_FERR_THERMAL_NF); 1350 } 1351 if (interpose) 1352 log->type = "inject"; 1353 else 1354 log->type = "error"; 1355 if (!spurious) { 1356 errorq_dispatch(nb_queue, log, sizeof (nb_logout_t), 1357 willpanic ? ERRORQ_SYNC : ERRORQ_ASYNC); 1358 } 1359 } 1360 1361 static void 1362 log_nerr(uint32_t *errp, nb_logout_t *log, int willpanic) 1363 { 1364 uint32_t err; 1365 nb_regs_t *rp = &log->nb_regs; 1366 int interpose = 0; 1367 int spurious = 0; 1368 1369 err = *errp; 1370 log->acl_timestamp = gethrtime_waitfree(); 1371 if ((err & (GE_PCIEX_FATAL | GE_PCIEX_NF)) != 0) { 1372 log_pex_err(err, rp, willpanic, &interpose); 1373 *errp = err & ~(GE_PCIEX_FATAL | GE_PCIEX_NF); 1374 } else if ((err & GE_NERR_FBD_FATAL) != 0) { 1375 log_fat_fbd_err(rp, willpanic, &interpose); 1376 *errp = err & ~GE_NERR_FBD_FATAL; 1377 } else if ((err & GE_NERR_FBD_NF) != 0) { 1378 log_nf_fbd_err(rp, willpanic, &interpose); 1379 *errp = err & ~GE_NERR_FBD_NF; 1380 } else if ((err & GE_NERR_MEM_NF) != 0) { 1381 log_nf_mem_err(rp, willpanic, &interpose); 1382 *errp = err & ~GE_NERR_MEM_NF; 1383 } else if ((err & (GE_NERR_FSB_FATAL | GE_NERR_FSB_NF)) != 0) { 1384 log_fsb_err(GE_NERR_TO_FERR_FSB(err), rp, willpanic, 1385 &interpose); 1386 *errp = err & ~(GE_NERR_FSB_FATAL | GE_NERR_FSB_NF); 1387 } else if ((err & (GE_DMA_FATAL | GE_DMA_NF)) != 0) { 1388 log_dma_err(rp, &interpose); 1389 *errp = err & ~(GE_DMA_FATAL | GE_DMA_NF); 1390 } else if ((err & (GE_INT_FATAL | GE_INT_NF)) != 0) { 1391 spurious = log_int_err(rp, willpanic, &interpose); 1392 *errp = err & ~(GE_INT_FATAL | GE_INT_NF); 1393 } 1394 if (interpose) 1395 log->type = "inject"; 1396 else 1397 log->type = "error"; 1398 if (!spurious) { 1399 errorq_dispatch(nb_queue, log, sizeof (nb_logout_t), 1400 willpanic ? ERRORQ_SYNC : ERRORQ_ASYNC); 1401 } 1402 } 1403 1404 /*ARGSUSED*/ 1405 void 1406 nb_error_trap(cmi_hdl_t hdl, boolean_t ismc, boolean_t willpanic) 1407 { 1408 uint64_t ferr; 1409 uint32_t nerr, err; 1410 int nmc = 0; 1411 int i; 1412 1413 if (mutex_tryenter(&nb_mutex) == 0) 1414 return; 1415 1416 nerr = NERR_GLOBAL_RD(); 1417 err = nerr; 1418 for (i = 0; i < NB_MAX_ERRORS; i++) { 1419 ferr = FERR_GLOBAL_RD(); 1420 nb_log.nb_regs.chipset = nb_chipset; 1421 nb_log.nb_regs.ferr = ferr; 1422 nb_log.nb_regs.nerr = nerr; 1423 if (ferr) { 1424 log_ferr(ferr, &err, &nb_log, willpanic); 1425 FERR_GLOBAL_WR(ferr); 1426 nmc++; 1427 } else if (err) { 1428 log_nerr(&err, &nb_log, willpanic); 1429 nmc++; 1430 } 1431 } 1432 if (nerr) { 1433 NERR_GLOBAL_WR(nerr); 1434 } 1435 if (nmc == 0 && nb_mask_mc_set) 1436 nb_mask_mc_reset(); 1437 mutex_exit(&nb_mutex); 1438 } 1439 1440 static void 1441 nb_fsb_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload, 1442 nb_scatchpad_t *data) 1443 { 1444 int intel_error_list; 1445 char buf[32]; 1446 1447 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FSB, 1448 DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.fsb, NULL); 1449 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_FAT_FSB, 1450 DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.ferr_fat_fsb, NULL); 1451 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_FAT_FSB, 1452 DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.nerr_fat_fsb, NULL); 1453 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_FSB, 1454 DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.ferr_nf_fsb, NULL); 1455 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_FSB, 1456 DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.nerr_nf_fsb, NULL); 1457 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFSB, 1458 DATA_TYPE_UINT32, nb_regs->nb.fsb_regs.nrecfsb, NULL); 1459 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFSB_ADDR, 1460 DATA_TYPE_UINT64, nb_regs->nb.fsb_regs.nrecfsb_addr, NULL); 1461 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFSB, 1462 DATA_TYPE_UINT32, nb_regs->nb.fsb_regs.recfsb, NULL); 1463 intel_error_list = data->intel_error_list; 1464 if (intel_error_list >= 0) 1465 (void) snprintf(buf, sizeof (buf), "F%d", intel_error_list); 1466 else 1467 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error"); 1468 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO, 1469 DATA_TYPE_STRING, buf, NULL); 1470 } 1471 1472 static void 1473 nb_pex_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload, 1474 nb_scatchpad_t *data) 1475 { 1476 int intel_error_list; 1477 char buf[32]; 1478 1479 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX, 1480 DATA_TYPE_UINT8, nb_regs->nb.pex_regs.pex, NULL); 1481 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX_FAT_FERR, 1482 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.pex_fat_ferr, NULL); 1483 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX_FAT_NERR, 1484 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.pex_fat_nerr, NULL); 1485 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX_NF_CORR_FERR, 1486 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.pex_nf_corr_ferr, NULL); 1487 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX_NF_CORR_NERR, 1488 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.pex_nf_corr_nerr, NULL); 1489 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_UNCERRSEV, 1490 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.uncerrsev, NULL); 1491 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RPERRSTS, 1492 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.rperrsts, NULL); 1493 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RPERRSID, 1494 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.rperrsid, NULL); 1495 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_UNCERRSTS, 1496 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.uncerrsts, NULL); 1497 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_AERRCAPCTRL, 1498 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.aerrcapctrl, NULL); 1499 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CORERRSTS, 1500 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.corerrsts, NULL); 1501 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEXDEVSTS, 1502 DATA_TYPE_UINT16, nb_regs->nb.pex_regs.pexdevsts, NULL); 1503 intel_error_list = data->intel_error_list; 1504 if (intel_error_list >= 0) 1505 (void) snprintf(buf, sizeof (buf), "IO%d", intel_error_list); 1506 else 1507 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error"); 1508 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO, 1509 DATA_TYPE_STRING, buf, NULL); 1510 } 1511 1512 static void 1513 nb_int_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload, 1514 nb_scatchpad_t *data) 1515 { 1516 int intel_error_list; 1517 char buf[32]; 1518 1519 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_FAT_INT, 1520 DATA_TYPE_UINT16, nb_regs->nb.int_regs.ferr_fat_int, NULL); 1521 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_INT, 1522 DATA_TYPE_UINT16, nb_regs->nb.int_regs.ferr_nf_int, NULL); 1523 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_FAT_INT, 1524 DATA_TYPE_UINT16, nb_regs->nb.int_regs.nerr_fat_int, NULL); 1525 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_INT, 1526 DATA_TYPE_UINT16, nb_regs->nb.int_regs.nerr_nf_int, NULL); 1527 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECINT, 1528 DATA_TYPE_UINT32, nb_regs->nb.int_regs.nrecint, NULL); 1529 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECINT, 1530 DATA_TYPE_UINT32, nb_regs->nb.int_regs.recint, NULL); 1531 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECSF, 1532 DATA_TYPE_UINT64, nb_regs->nb.int_regs.nrecsf, NULL); 1533 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECSF, 1534 DATA_TYPE_UINT64, nb_regs->nb.int_regs.recsf, NULL); 1535 intel_error_list = data->intel_error_list; 1536 if (intel_error_list >= 0) 1537 (void) snprintf(buf, sizeof (buf), "B%d", intel_error_list); 1538 else 1539 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error"); 1540 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO, 1541 DATA_TYPE_STRING, buf, NULL); 1542 } 1543 1544 static void 1545 nb_fat_fbd_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload, 1546 nb_scatchpad_t *data) 1547 { 1548 nb_mem_scatchpad_t *sp; 1549 char buf[32]; 1550 1551 sp = &((nb_scatchpad_t *)data)->ms; 1552 1553 if (sp->ras != -1) { 1554 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BANK, 1555 DATA_TYPE_INT32, sp->bank, NULL); 1556 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CAS, 1557 DATA_TYPE_INT32, sp->cas, NULL); 1558 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RAS, 1559 DATA_TYPE_INT32, sp->ras, NULL); 1560 if (sp->offset != -1LL) { 1561 fm_payload_set(payload, FM_FMRI_MEM_OFFSET, 1562 DATA_TYPE_UINT64, sp->offset, NULL); 1563 } 1564 if (sp->pa != -1LL) { 1565 fm_payload_set(payload, FM_FMRI_MEM_PHYSADDR, 1566 DATA_TYPE_UINT64, sp->pa, NULL); 1567 } 1568 } 1569 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_FAT_FBD, 1570 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.ferr_fat_fbd, NULL); 1571 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_FAT_FBD, 1572 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nerr_fat_fbd, NULL); 1573 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECMEMA, 1574 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecmema, NULL); 1575 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECMEMB, 1576 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecmemb, NULL); 1577 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFGLOG, 1578 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfglog, NULL); 1579 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDA, 1580 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbda, NULL); 1581 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDB, 1582 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbdb, NULL); 1583 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDC, 1584 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbdc, NULL); 1585 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDD, 1586 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbdd, NULL); 1587 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDE, 1588 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbde, NULL); 1589 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDF, 1590 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbdf, NULL); 1591 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPS, 1592 DATA_TYPE_UINT8, nb_regs->nb.fat_fbd_regs.spcps, NULL); 1593 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPC, 1594 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.spcpc, NULL); 1595 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_UERRCNT, 1596 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.uerrcnt, NULL); 1597 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_UERRCNT_LAST, 1598 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.uerrcnt_last, NULL); 1599 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAMA, 1600 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.badrama, NULL); 1601 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAMB, 1602 DATA_TYPE_UINT16, nb_regs->nb.fat_fbd_regs.badramb, NULL); 1603 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADCNT, 1604 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.badcnt, NULL); 1605 1606 if (sp->intel_error_list >= 0) 1607 (void) snprintf(buf, sizeof (buf), "M%d", sp->intel_error_list); 1608 else 1609 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error"); 1610 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO, 1611 DATA_TYPE_STRING, buf, NULL); 1612 } 1613 1614 static void 1615 nb_nf_fbd_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload, 1616 nb_scatchpad_t *data) 1617 { 1618 nb_mem_scatchpad_t *sp; 1619 char buf[32]; 1620 1621 sp = &((nb_scatchpad_t *)data)->ms; 1622 1623 if (sp->dimm == -1 && sp->rank != -1) { 1624 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RANK, 1625 DATA_TYPE_INT32, sp->rank, NULL); 1626 } 1627 if (sp->ras != -1) { 1628 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BANK, 1629 DATA_TYPE_INT32, sp->bank, NULL); 1630 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CAS, 1631 DATA_TYPE_INT32, sp->cas, NULL); 1632 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RAS, 1633 DATA_TYPE_INT32, sp->ras, NULL); 1634 if (sp->offset != -1LL) { 1635 fm_payload_set(payload, FM_FMRI_MEM_OFFSET, 1636 DATA_TYPE_UINT64, sp->offset, NULL); 1637 } 1638 if (sp->pa != -1LL) { 1639 fm_payload_set(payload, FM_FMRI_MEM_PHYSADDR, 1640 DATA_TYPE_UINT64, sp->pa, NULL); 1641 } 1642 } 1643 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_FBD, 1644 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.ferr_nf_fbd, NULL); 1645 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_FBD, 1646 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.nerr_nf_fbd, NULL); 1647 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECMEMA, 1648 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recmema, NULL); 1649 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECMEMB, 1650 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recmemb, NULL); 1651 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFGLOG, 1652 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfglog, NULL); 1653 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDA, 1654 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbda, NULL); 1655 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDB, 1656 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbdb, NULL); 1657 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDC, 1658 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbdc, NULL); 1659 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDD, 1660 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbdd, NULL); 1661 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDE, 1662 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbde, NULL); 1663 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDF, 1664 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbdf, NULL); 1665 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPS, 1666 DATA_TYPE_UINT8, nb_regs->nb.nf_fbd_regs.spcps, NULL); 1667 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPC, 1668 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.spcpc, NULL); 1669 if (nb_chipset == INTEL_NB_7300 || nb_chipset == INTEL_NB_5400) { 1670 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNTA, 1671 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcnta, NULL); 1672 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNTB, 1673 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcntb, NULL); 1674 if (nb_chipset == INTEL_NB_7300) { 1675 fm_payload_set(payload, 1676 FM_EREPORT_PAYLOAD_NAME_CERRCNTC, 1677 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcntc, 1678 NULL); 1679 fm_payload_set(payload, 1680 FM_EREPORT_PAYLOAD_NAME_CERRCNTD, 1681 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcntd, 1682 NULL); 1683 } 1684 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNTA_LAST, 1685 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcnta_last, 1686 NULL); 1687 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNTB_LAST, 1688 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcntb_last, 1689 NULL); 1690 if (nb_chipset == INTEL_NB_7300) { 1691 fm_payload_set(payload, 1692 FM_EREPORT_PAYLOAD_NAME_CERRCNTC_LAST, 1693 DATA_TYPE_UINT32, 1694 nb_regs->nb.nf_fbd_regs.cerrcntc_last, NULL); 1695 fm_payload_set(payload, 1696 FM_EREPORT_PAYLOAD_NAME_CERRCNTD_LAST, 1697 DATA_TYPE_UINT32, 1698 nb_regs->nb.nf_fbd_regs.cerrcntd_last, NULL); 1699 } 1700 } else { 1701 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT, 1702 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcnta, NULL); 1703 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT_LAST, 1704 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcnta_last, 1705 NULL); 1706 } 1707 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAMA, 1708 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.badrama, NULL); 1709 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAMB, 1710 DATA_TYPE_UINT16, nb_regs->nb.nf_fbd_regs.badramb, NULL); 1711 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADCNT, 1712 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.badcnt, NULL); 1713 1714 if (sp->intel_error_list >= 0) 1715 (void) snprintf(buf, sizeof (buf), "M%d", sp->intel_error_list); 1716 else 1717 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error"); 1718 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO, 1719 DATA_TYPE_STRING, buf, NULL); 1720 } 1721 1722 static void 1723 nb_nf_mem_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload, 1724 nb_scatchpad_t *data) 1725 { 1726 nb_mem_scatchpad_t *sp; 1727 char buf[32]; 1728 1729 sp = &((nb_scatchpad_t *)data)->ms; 1730 1731 if (sp->dimm == -1 && sp->rank != -1) { 1732 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RANK, 1733 DATA_TYPE_INT32, sp->rank, NULL); 1734 } 1735 if (sp->ras != -1) { 1736 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BANK, 1737 DATA_TYPE_INT32, sp->bank, NULL); 1738 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CAS, 1739 DATA_TYPE_INT32, sp->cas, NULL); 1740 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RAS, 1741 DATA_TYPE_INT32, sp->ras, NULL); 1742 if (sp->offset != -1LL) { 1743 fm_payload_set(payload, FM_FMRI_MEM_OFFSET, 1744 DATA_TYPE_UINT64, sp->offset, NULL); 1745 } 1746 if (sp->pa != -1LL) { 1747 fm_payload_set(payload, FM_FMRI_MEM_PHYSADDR, 1748 DATA_TYPE_UINT64, sp->pa, NULL); 1749 } 1750 } 1751 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_MEM, 1752 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.ferr_nf_mem, NULL); 1753 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_MEM, 1754 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.nerr_nf_mem, NULL); 1755 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECMEMA, 1756 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.recmema, NULL); 1757 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECMEMB, 1758 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.recmemb, NULL); 1759 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_REDMEMA, 1760 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.redmema, NULL); 1761 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_REDMEMB, 1762 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.redmemb, NULL); 1763 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECMEMA, 1764 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.nrecmema, NULL); 1765 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECMEMB, 1766 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.nrecmemb, NULL); 1767 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPS, 1768 DATA_TYPE_UINT8, nb_regs->nb.nf_mem_regs.spcps, NULL); 1769 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPC, 1770 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.spcpc, NULL); 1771 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT, 1772 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.cerrcnt, NULL); 1773 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT_LAST, 1774 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.cerrcnt_last, NULL); 1775 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT_EXT, 1776 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.cerrcnt_ext, NULL); 1777 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT_EXT_LAST, 1778 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.cerrcnt_ext_last, NULL); 1779 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAM, 1780 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.badram, NULL); 1781 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADCNT, 1782 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.badcnt, NULL); 1783 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_VALIDLOG, 1784 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.validlog, NULL); 1785 1786 if (sp->intel_error_list >= 0) 1787 (void) snprintf(buf, sizeof (buf), "M%d", sp->intel_error_list); 1788 else 1789 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error"); 1790 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO, 1791 DATA_TYPE_STRING, buf, NULL); 1792 } 1793 1794 static void 1795 nb_dma_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload) 1796 { 1797 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PCISTS, 1798 DATA_TYPE_UINT16, nb_regs->nb.dma_regs.pcists, NULL); 1799 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEXDEVSTS, 1800 DATA_TYPE_UINT16, nb_regs->nb.dma_regs.pexdevsts, NULL); 1801 } 1802 1803 static void 1804 nb_thr_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload, 1805 nb_scatchpad_t *data) 1806 { 1807 char buf[32]; 1808 1809 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_FAT_THR, 1810 DATA_TYPE_UINT8, nb_regs->nb.thr_regs.ferr_fat_thr, NULL); 1811 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_FAT_THR, 1812 DATA_TYPE_UINT8, nb_regs->nb.thr_regs.nerr_fat_thr, NULL); 1813 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_THR, 1814 DATA_TYPE_UINT8, nb_regs->nb.thr_regs.ferr_nf_thr, NULL); 1815 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_THR, 1816 DATA_TYPE_UINT8, nb_regs->nb.thr_regs.nerr_nf_thr, NULL); 1817 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CTSTS, 1818 DATA_TYPE_UINT8, nb_regs->nb.thr_regs.ctsts, NULL); 1819 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_THRTSTS, 1820 DATA_TYPE_UINT16, nb_regs->nb.thr_regs.thrtsts, NULL); 1821 if (data->intel_error_list >= 0) { 1822 (void) snprintf(buf, sizeof (buf), "TH%d", 1823 data->intel_error_list); 1824 } else { 1825 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error"); 1826 } 1827 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO, 1828 DATA_TYPE_STRING, buf, NULL); 1829 } 1830 1831 static void 1832 nb_ereport_add_logout(nvlist_t *payload, const nb_logout_t *acl, 1833 nb_scatchpad_t *data) 1834 { 1835 const nb_regs_t *nb_regs = &acl->nb_regs; 1836 1837 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_MC_TYPE, 1838 DATA_TYPE_STRING, acl->type, NULL); 1839 switch (nb_regs->flag) { 1840 case NB_REG_LOG_FSB: 1841 nb_fsb_err_payload(nb_regs, payload, data); 1842 break; 1843 case NB_REG_LOG_PEX: 1844 nb_pex_err_payload(nb_regs, payload, data); 1845 break; 1846 case NB_REG_LOG_INT: 1847 nb_int_err_payload(nb_regs, payload, data); 1848 break; 1849 case NB_REG_LOG_FAT_FBD: 1850 nb_fat_fbd_err_payload(nb_regs, payload, data); 1851 break; 1852 case NB_REG_LOG_NF_FBD: 1853 nb_nf_fbd_err_payload(nb_regs, payload, data); 1854 break; 1855 case NB_REG_LOG_DMA: 1856 nb_dma_err_payload(nb_regs, payload); 1857 break; 1858 case NB_REG_LOG_THR: 1859 nb_thr_err_payload(nb_regs, payload, data); 1860 break; 1861 case NB_REG_LOG_NF_MEM: 1862 nb_nf_mem_err_payload(nb_regs, payload, data); 1863 break; 1864 default: 1865 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_GLOBAL, 1866 DATA_TYPE_UINT64, nb_regs->ferr, NULL); 1867 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_GLOBAL, 1868 DATA_TYPE_UINT32, nb_regs->nerr, NULL); 1869 break; 1870 } 1871 } 1872 1873 void 1874 nb_fsb_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector, 1875 nb_scatchpad_t *data) 1876 { 1877 int chip; 1878 1879 if (nb_chipset == INTEL_NB_7300) 1880 chip = nb_regs->nb.fsb_regs.fsb * 2; 1881 else 1882 chip = nb_regs->nb.fsb_regs.fsb; 1883 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2, 1884 "motherboard", 0, "chip", chip); 1885 1886 if (nb_regs->nb.fsb_regs.ferr_fat_fsb == 0 && 1887 nb_regs->nb.fsb_regs.ferr_nf_fsb == 0) { 1888 data->intel_error_list = intel_fsb_err(nb_regs->nb.fsb_regs.fsb, 1889 nb_regs->nb.fsb_regs.nerr_fat_fsb, 1890 nb_regs->nb.fsb_regs.nerr_nf_fsb); 1891 } else { 1892 data->intel_error_list = intel_fsb_err(nb_regs->nb.fsb_regs.fsb, 1893 nb_regs->nb.fsb_regs.ferr_fat_fsb, 1894 nb_regs->nb.fsb_regs.ferr_nf_fsb); 1895 } 1896 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s", 1897 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "fsb"); 1898 } 1899 1900 void 1901 nb_pex_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector, 1902 nb_scatchpad_t *data) 1903 { 1904 int hostbridge; 1905 1906 if (nb_regs->nb.pex_regs.pex == 0) { 1907 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 1908 "motherboard", 0); 1909 } else { 1910 hostbridge = nb_regs->nb.pex_regs.pex - 1; 1911 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2, 1912 "motherboard", 0, 1913 "hostbridge", hostbridge); 1914 } 1915 1916 if (nb_regs->nb.pex_regs.pex_fat_ferr == 0 && 1917 nb_regs->nb.pex_regs.pex_nf_corr_ferr == 0) { 1918 if (nb_chipset == INTEL_NB_5400) { 1919 data->intel_error_list = 1920 intel_pex_5400_err( 1921 nb_regs->nb.pex_regs.pex_fat_nerr, 1922 nb_regs->nb.pex_regs.pex_nf_corr_nerr); 1923 } else { 1924 data->intel_error_list = 1925 intel_pex_err(nb_regs->nb.pex_regs.pex_fat_nerr, 1926 nb_regs->nb.pex_regs.pex_nf_corr_nerr); 1927 } 1928 } else { 1929 if (nb_chipset == INTEL_NB_5400) { 1930 data->intel_error_list = 1931 intel_pex_5400_err( 1932 nb_regs->nb.pex_regs.pex_fat_ferr, 1933 nb_regs->nb.pex_regs.pex_nf_corr_ferr); 1934 } else { 1935 data->intel_error_list = 1936 intel_pex_err(nb_regs->nb.pex_regs.pex_fat_ferr, 1937 nb_regs->nb.pex_regs.pex_nf_corr_ferr); 1938 } 1939 } 1940 1941 if (nb_regs->nb.pex_regs.pex == 0) { 1942 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s", 1943 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "esi"); 1944 } else { 1945 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s", 1946 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "pex"); 1947 } 1948 } 1949 1950 void 1951 nb_int_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector, 1952 void *data) 1953 { 1954 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 1955 "motherboard", 0); 1956 1957 if (nb_regs->nb.int_regs.ferr_fat_int == 0 && 1958 nb_regs->nb.int_regs.ferr_nf_int == 0) { 1959 ((nb_scatchpad_t *)data)->intel_error_list = 1960 intel_int_err(nb_regs->nb.int_regs.nerr_fat_int, 1961 nb_regs->nb.int_regs.nerr_nf_int); 1962 } else { 1963 ((nb_scatchpad_t *)data)->intel_error_list = 1964 intel_int_err(nb_regs->nb.int_regs.ferr_fat_int, 1965 nb_regs->nb.int_regs.ferr_nf_int); 1966 } 1967 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s", 1968 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "ie"); 1969 } 1970 1971 void 1972 nb_fat_fbd_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector, 1973 void *data) 1974 { 1975 char *intr; 1976 nb_mem_scatchpad_t *sp; 1977 1978 intr = fat_memory_error(nb_regs, data); 1979 sp = &((nb_scatchpad_t *)data)->ms; 1980 1981 if (sp->dimm != -1) { 1982 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 5, 1983 "motherboard", 0, 1984 "memory-controller", sp->branch, 1985 "dram-channel", sp->channel, 1986 "dimm", sp->dimm, 1987 "rank", sp->rank); 1988 } else if (sp->channel != -1) { 1989 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 3, 1990 "motherboard", 0, 1991 "memory-controller", sp->branch, 1992 "dram-channel", sp->channel); 1993 } else if (sp->branch != -1) { 1994 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2, 1995 "motherboard", 0, 1996 "memory-controller", sp->branch); 1997 } else { 1998 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 1999 "motherboard", 0); 2000 } 2001 2002 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s", 2003 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, intr); 2004 } 2005 2006 void 2007 nb_nf_fbd_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector, 2008 void *data) 2009 { 2010 char *intr; 2011 nb_mem_scatchpad_t *sp; 2012 2013 intr = nf_memory_error(nb_regs, data); 2014 sp = &((nb_scatchpad_t *)data)->ms; 2015 2016 if (sp->dimm != -1) { 2017 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 5, 2018 "motherboard", 0, 2019 "memory-controller", sp->branch, 2020 "dram-channel", sp->channel, 2021 "dimm", sp->dimm, 2022 "rank", sp->rank); 2023 } else if (sp->channel != -1) { 2024 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 3, 2025 "motherboard", 0, 2026 "memory-controller", sp->branch, 2027 "dram-channel", sp->channel); 2028 } else if (sp->branch != -1) { 2029 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2, 2030 "motherboard", 0, 2031 "memory-controller", sp->branch); 2032 } else { 2033 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 2034 "motherboard", 0); 2035 } 2036 2037 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s", 2038 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, intr); 2039 } 2040 2041 void 2042 nb_dma_report(char *class, nvlist_t *detector) 2043 { 2044 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 2045 "motherboard", 0); 2046 2047 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s", 2048 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "dma"); 2049 } 2050 2051 void 2052 nb_thr_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector, 2053 void *data) 2054 { 2055 ((nb_scatchpad_t *)data)->intel_error_list = 2056 intel_thr_err(nb_regs->nb.thr_regs.ferr_fat_thr, 2057 nb_regs->nb.thr_regs.ferr_nf_thr); 2058 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 2059 "motherboard", 0); 2060 2061 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s", 2062 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "otf"); 2063 } 2064 2065 void 2066 nb_nf_mem_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector, 2067 void *data) 2068 { 2069 char *intr; 2070 nb_mem_scatchpad_t *sp; 2071 2072 intr = nf_mem_error(nb_regs, data); 2073 sp = &((nb_scatchpad_t *)data)->ms; 2074 2075 if (sp->dimm != -1) { 2076 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 5, 2077 "motherboard", 0, 2078 "memory-controller", sp->branch, 2079 "dram-channel", sp->channel, 2080 "dimm", sp->dimm, 2081 "rank", sp->rank); 2082 } else if (sp->channel != -1) { 2083 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 3, 2084 "motherboard", 0, 2085 "memory-controller", sp->branch, 2086 "dram-channel", sp->channel); 2087 } else if (sp->branch != -1) { 2088 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2, 2089 "motherboard", 0, 2090 "memory-controller", sp->branch); 2091 } else { 2092 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 2093 "motherboard", 0); 2094 } 2095 2096 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s", 2097 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, intr); 2098 } 2099 2100 2101 nvlist_t * 2102 nb_report(const nb_regs_t *nb_regs, char *class, nv_alloc_t *nva, void *scratch) 2103 { 2104 nvlist_t *detector = fm_nvlist_create(nva); 2105 2106 switch (nb_regs->flag) { 2107 case NB_REG_LOG_FSB: 2108 nb_fsb_report(nb_regs, class, detector, scratch); 2109 break; 2110 case NB_REG_LOG_PEX: 2111 nb_pex_report(nb_regs, class, detector, scratch); 2112 break; 2113 case NB_REG_LOG_INT: 2114 nb_int_report(nb_regs, class, detector, scratch); 2115 break; 2116 case NB_REG_LOG_FAT_FBD: 2117 nb_fat_fbd_report(nb_regs, class, detector, scratch); 2118 break; 2119 case NB_REG_LOG_NF_FBD: 2120 nb_nf_fbd_report(nb_regs, class, detector, scratch); 2121 break; 2122 case NB_REG_LOG_DMA: 2123 nb_dma_report(class, detector); 2124 break; 2125 case NB_REG_LOG_THR: 2126 nb_thr_report(nb_regs, class, detector, scratch); 2127 break; 2128 case NB_REG_LOG_NF_MEM: 2129 nb_nf_mem_report(nb_regs, class, detector, scratch); 2130 break; 2131 default: 2132 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 2133 "motherboard", 0); 2134 2135 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s", 2136 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "unknown"); 2137 } 2138 return (detector); 2139 } 2140 2141 /*ARGSUSED*/ 2142 void 2143 nb_drain(void *ignored, const void *data, const errorq_elem_t *eqe) 2144 { 2145 nb_logout_t *acl = (nb_logout_t *)data; 2146 errorq_elem_t *eqep, *scr_eqep; 2147 nvlist_t *ereport, *detector; 2148 nv_alloc_t *nva = NULL; 2149 char buf[FM_MAX_CLASS]; 2150 nb_scatchpad_t nb_scatchpad; 2151 2152 if (panicstr) { 2153 if ((eqep = errorq_reserve(ereport_errorq)) == NULL) 2154 return; 2155 ereport = errorq_elem_nvl(ereport_errorq, eqep); 2156 /* 2157 * Now try to allocate another element for scratch space and 2158 * use that for further scratch space (eg for constructing 2159 * nvlists to add the main ereport). If we can't reserve 2160 * a scratch element just fallback to working within the 2161 * element we already have, and hope for the best. All this 2162 * is necessary because the fixed buffer nv allocator does 2163 * not reclaim freed space and nvlist construction is 2164 * expensive. 2165 */ 2166 if ((scr_eqep = errorq_reserve(ereport_errorq)) != NULL) 2167 nva = errorq_elem_nva(ereport_errorq, scr_eqep); 2168 else 2169 nva = errorq_elem_nva(ereport_errorq, eqep); 2170 } else { 2171 ereport = fm_nvlist_create(NULL); 2172 } 2173 detector = nb_report(&acl->nb_regs, buf, nva, &nb_scatchpad); 2174 if (detector == NULL) 2175 return; 2176 fm_ereport_set(ereport, FM_EREPORT_VERSION, buf, 2177 fm_ena_generate(acl->acl_timestamp, FM_ENA_FMT1), detector, NULL); 2178 /* 2179 * We're done with 'detector' so reclaim the scratch space. 2180 */ 2181 if (panicstr) { 2182 fm_nvlist_destroy(detector, FM_NVA_RETAIN); 2183 nv_alloc_reset(nva); 2184 } else { 2185 fm_nvlist_destroy(detector, FM_NVA_FREE); 2186 } 2187 2188 /* 2189 * Encode the error-specific data that was saved in the logout area. 2190 */ 2191 nb_ereport_add_logout(ereport, acl, &nb_scatchpad); 2192 2193 if (panicstr) { 2194 errorq_commit(ereport_errorq, eqep, ERRORQ_SYNC); 2195 if (scr_eqep) 2196 errorq_cancel(ereport_errorq, scr_eqep); 2197 } else { 2198 (void) fm_ereport_post(ereport, EVCH_TRYHARD); 2199 fm_nvlist_destroy(ereport, FM_NVA_FREE); 2200 } 2201 } 2202