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 int 1260 log_nf_mem_err(nb_regs_t *rp, int willpanic, int *interpose) 1261 { 1262 int channel, branch; 1263 int t = 0; 1264 int rt = 0; 1265 1266 rp->flag = NB_REG_LOG_NF_MEM; 1267 1268 /* Memmory err registers */ 1269 rp->nb.nf_mem_regs.ferr_nf_mem = FERR_NF_MEM_RD(interpose); 1270 channel = (rp->nb.nf_mem_regs.ferr_nf_mem >> 28) & 0x1; 1271 branch = channel; 1272 rp->nb.nf_mem_regs.nerr_nf_mem = NERR_NF_MEM_RD(&t); 1273 *interpose |= t; 1274 rp->nb.nf_mem_regs.redmema = MEM_REDMEMA_RD(branch); 1275 rp->nb.nf_mem_regs.redmemb = MEM_REDMEMB_RD(branch); 1276 rp->nb.nf_mem_regs.recmema = MEM_RECMEMA_RD(branch); 1277 rp->nb.nf_mem_regs.recmemb = MEM_RECMEMB_RD(branch); 1278 rp->nb.nf_mem_regs.nrecmema = MEM_NRECMEMA_RD(branch); 1279 rp->nb.nf_mem_regs.nrecmemb = MEM_NRECMEMB_RD(branch); 1280 1281 /* spare rank */ 1282 rp->nb.nf_mem_regs.spcps = SPCPS_RD(branch); 1283 rp->nb.nf_mem_regs.spcpc = SPCPC_RD(branch); 1284 1285 /* RAS registers */ 1286 rp->nb.nf_mem_regs.cerrcnt = MEM_CERRCNT_RD(branch); 1287 rp->nb.nf_mem_regs.cerrcnt_ext = (uint32_t)MEM_CERRCNT_EXT_RD(branch); 1288 rp->nb.nf_mem_regs.cerrcnt_last = cerrcnta[branch][channel & 1]; 1289 rp->nb.nf_mem_regs.cerrcnt_ext_last = cerrcntb[branch][channel & 1]; 1290 cerrcnta[branch][channel & 1] = rp->nb.nf_mem_regs.cerrcnt; 1291 cerrcntb[branch][channel & 1] = rp->nb.nf_mem_regs.cerrcnt_ext; 1292 rp->nb.nf_mem_regs.badram = BADRAMA_RD(branch); 1293 rp->nb.nf_mem_regs.badcnt = BADCNT_RD(branch); 1294 rp->nb.nf_mem_regs.validlog = VALIDLOG_RD(branch); 1295 1296 if (!willpanic) { 1297 if (rp->nb.nf_mem_regs.ferr_nf_mem || *interpose) 1298 FERR_NF_MEM_WR(rp->nb.nf_mem_regs.ferr_nf_mem); 1299 if (rp->nb.nf_mem_regs.nerr_nf_mem) 1300 NERR_NF_MEM_WR(rp->nb.nf_mem_regs.nerr_nf_mem); 1301 /* 1302 * if interpose, write read-only registers to clear from pci 1303 * cache 1304 */ 1305 if (*interpose) { 1306 MEM_NRECMEMA_WR(branch); 1307 MEM_NRECMEMB_WR(branch); 1308 MEM_REDMEMA_WR(branch); 1309 MEM_REDMEMB_WR(branch); 1310 MEM_RECMEMA_WR(branch); 1311 MEM_RECMEMB_WR(branch); 1312 SPCPS_WR(branch); 1313 } 1314 } 1315 if (nb_mode == NB_MEMORY_SINGLE_CHANNEL && channel != 0) { 1316 /* 1317 * In the single channel mode, all dimms are on the channel 0. 1318 * Invalidate this error if the channel number is invalid. 1319 */ 1320 rt = 1; 1321 } 1322 return (rt); 1323 } 1324 1325 static void 1326 log_ferr(uint64_t ferr, uint32_t *nerrp, nb_logout_t *log, int willpanic) 1327 { 1328 nb_regs_t *rp = &log->nb_regs; 1329 uint32_t nerr = *nerrp; 1330 int interpose = 0; 1331 int spurious = 0; 1332 1333 log->acl_timestamp = gethrtime_waitfree(); 1334 if ((ferr & (GE_PCIEX_FATAL | GE_PCIEX_NF)) != 0) { 1335 log_pex_err(ferr, rp, willpanic, &interpose); 1336 *nerrp = nerr & ~(GE_PCIEX_FATAL | GE_PCIEX_NF); 1337 } else if ((ferr & GE_FBD_FATAL) != 0) { 1338 log_fat_fbd_err(rp, willpanic, &interpose); 1339 *nerrp = nerr & ~GE_NERR_FBD_FATAL; 1340 } else if ((ferr & GE_FBD_NF) != 0) { 1341 log_nf_fbd_err(rp, willpanic, &interpose); 1342 *nerrp = nerr & ~GE_NERR_FBD_NF; 1343 } else if ((ferr & GE_MEM_NF) != 0) { 1344 spurious = log_nf_mem_err(rp, willpanic, &interpose); 1345 *nerrp = nerr & ~GE_NERR_MEM_NF; 1346 } else if ((ferr & (GE_FERR_FSB_FATAL | GE_FERR_FSB_NF)) != 0) { 1347 log_fsb_err(ferr, rp, willpanic, &interpose); 1348 *nerrp = nerr & ~(GE_NERR_FSB_FATAL | GE_NERR_FSB_NF); 1349 } else if ((ferr & (GE_DMA_FATAL | GE_DMA_NF)) != 0) { 1350 log_dma_err(rp, &interpose); 1351 *nerrp = nerr & ~(GE_DMA_FATAL | GE_DMA_NF); 1352 } else if ((ferr & (GE_INT_FATAL | GE_INT_NF)) != 0) { 1353 spurious = log_int_err(rp, willpanic, &interpose); 1354 *nerrp = nerr & ~(GE_INT_FATAL | GE_INT_NF); 1355 } else if (nb_chipset == INTEL_NB_5400 && 1356 (ferr & (GE_FERR_THERMAL_FATAL | GE_FERR_THERMAL_NF)) != 0) { 1357 log_thermal_err(rp, willpanic, &interpose); 1358 *nerrp = nerr & ~(GE_FERR_THERMAL_FATAL | GE_FERR_THERMAL_NF); 1359 } 1360 if (interpose) 1361 log->type = "inject"; 1362 else 1363 log->type = "error"; 1364 if (!spurious) { 1365 errorq_dispatch(nb_queue, log, sizeof (nb_logout_t), 1366 willpanic ? ERRORQ_SYNC : ERRORQ_ASYNC); 1367 } 1368 } 1369 1370 static void 1371 log_nerr(uint32_t *errp, nb_logout_t *log, int willpanic) 1372 { 1373 uint32_t err; 1374 nb_regs_t *rp = &log->nb_regs; 1375 int interpose = 0; 1376 int spurious = 0; 1377 1378 err = *errp; 1379 log->acl_timestamp = gethrtime_waitfree(); 1380 if ((err & (GE_PCIEX_FATAL | GE_PCIEX_NF)) != 0) { 1381 log_pex_err(err, rp, willpanic, &interpose); 1382 *errp = err & ~(GE_PCIEX_FATAL | GE_PCIEX_NF); 1383 } else if ((err & GE_NERR_FBD_FATAL) != 0) { 1384 log_fat_fbd_err(rp, willpanic, &interpose); 1385 *errp = err & ~GE_NERR_FBD_FATAL; 1386 } else if ((err & GE_NERR_FBD_NF) != 0) { 1387 log_nf_fbd_err(rp, willpanic, &interpose); 1388 *errp = err & ~GE_NERR_FBD_NF; 1389 } else if ((err & GE_NERR_MEM_NF) != 0) { 1390 spurious = log_nf_mem_err(rp, willpanic, &interpose); 1391 *errp = err & ~GE_NERR_MEM_NF; 1392 } else if ((err & (GE_NERR_FSB_FATAL | GE_NERR_FSB_NF)) != 0) { 1393 log_fsb_err(GE_NERR_TO_FERR_FSB(err), rp, willpanic, 1394 &interpose); 1395 *errp = err & ~(GE_NERR_FSB_FATAL | GE_NERR_FSB_NF); 1396 } else if ((err & (GE_DMA_FATAL | GE_DMA_NF)) != 0) { 1397 log_dma_err(rp, &interpose); 1398 *errp = err & ~(GE_DMA_FATAL | GE_DMA_NF); 1399 } else if ((err & (GE_INT_FATAL | GE_INT_NF)) != 0) { 1400 spurious = log_int_err(rp, willpanic, &interpose); 1401 *errp = err & ~(GE_INT_FATAL | GE_INT_NF); 1402 } 1403 if (interpose) 1404 log->type = "inject"; 1405 else 1406 log->type = "error"; 1407 if (!spurious) { 1408 errorq_dispatch(nb_queue, log, sizeof (nb_logout_t), 1409 willpanic ? ERRORQ_SYNC : ERRORQ_ASYNC); 1410 } 1411 } 1412 1413 /*ARGSUSED*/ 1414 void 1415 nb_error_trap(cmi_hdl_t hdl, boolean_t ismc, boolean_t willpanic) 1416 { 1417 uint64_t ferr; 1418 uint32_t nerr, err; 1419 int nmc = 0; 1420 int i; 1421 1422 if (mutex_tryenter(&nb_mutex) == 0) 1423 return; 1424 1425 nerr = NERR_GLOBAL_RD(); 1426 err = nerr; 1427 for (i = 0; i < NB_MAX_ERRORS; i++) { 1428 ferr = FERR_GLOBAL_RD(); 1429 nb_log.nb_regs.chipset = nb_chipset; 1430 nb_log.nb_regs.ferr = ferr; 1431 nb_log.nb_regs.nerr = nerr; 1432 if (ferr) { 1433 log_ferr(ferr, &err, &nb_log, willpanic); 1434 FERR_GLOBAL_WR(ferr); 1435 nmc++; 1436 } else if (err) { 1437 log_nerr(&err, &nb_log, willpanic); 1438 nmc++; 1439 } 1440 } 1441 if (nerr) { 1442 NERR_GLOBAL_WR(nerr); 1443 } 1444 if (nmc == 0 && nb_mask_mc_set) 1445 nb_mask_mc_reset(); 1446 mutex_exit(&nb_mutex); 1447 } 1448 1449 static void 1450 nb_fsb_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload, 1451 nb_scatchpad_t *data) 1452 { 1453 int intel_error_list; 1454 char buf[32]; 1455 1456 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FSB, 1457 DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.fsb, NULL); 1458 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_FAT_FSB, 1459 DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.ferr_fat_fsb, NULL); 1460 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_FAT_FSB, 1461 DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.nerr_fat_fsb, NULL); 1462 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_FSB, 1463 DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.ferr_nf_fsb, NULL); 1464 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_FSB, 1465 DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.nerr_nf_fsb, NULL); 1466 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFSB, 1467 DATA_TYPE_UINT32, nb_regs->nb.fsb_regs.nrecfsb, NULL); 1468 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFSB_ADDR, 1469 DATA_TYPE_UINT64, nb_regs->nb.fsb_regs.nrecfsb_addr, NULL); 1470 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFSB, 1471 DATA_TYPE_UINT32, nb_regs->nb.fsb_regs.recfsb, NULL); 1472 intel_error_list = data->intel_error_list; 1473 if (intel_error_list >= 0) 1474 (void) snprintf(buf, sizeof (buf), "F%d", intel_error_list); 1475 else 1476 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error"); 1477 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO, 1478 DATA_TYPE_STRING, buf, NULL); 1479 } 1480 1481 static void 1482 nb_pex_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload, 1483 nb_scatchpad_t *data) 1484 { 1485 int intel_error_list; 1486 char buf[32]; 1487 1488 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX, 1489 DATA_TYPE_UINT8, nb_regs->nb.pex_regs.pex, NULL); 1490 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX_FAT_FERR, 1491 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.pex_fat_ferr, NULL); 1492 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX_FAT_NERR, 1493 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.pex_fat_nerr, NULL); 1494 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX_NF_CORR_FERR, 1495 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.pex_nf_corr_ferr, NULL); 1496 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX_NF_CORR_NERR, 1497 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.pex_nf_corr_nerr, NULL); 1498 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_UNCERRSEV, 1499 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.uncerrsev, NULL); 1500 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RPERRSTS, 1501 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.rperrsts, NULL); 1502 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RPERRSID, 1503 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.rperrsid, NULL); 1504 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_UNCERRSTS, 1505 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.uncerrsts, NULL); 1506 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_AERRCAPCTRL, 1507 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.aerrcapctrl, NULL); 1508 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CORERRSTS, 1509 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.corerrsts, NULL); 1510 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEXDEVSTS, 1511 DATA_TYPE_UINT16, nb_regs->nb.pex_regs.pexdevsts, NULL); 1512 intel_error_list = data->intel_error_list; 1513 if (intel_error_list >= 0) 1514 (void) snprintf(buf, sizeof (buf), "IO%d", intel_error_list); 1515 else 1516 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error"); 1517 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO, 1518 DATA_TYPE_STRING, buf, NULL); 1519 } 1520 1521 static void 1522 nb_int_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload, 1523 nb_scatchpad_t *data) 1524 { 1525 int intel_error_list; 1526 char buf[32]; 1527 1528 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_FAT_INT, 1529 DATA_TYPE_UINT16, nb_regs->nb.int_regs.ferr_fat_int, NULL); 1530 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_INT, 1531 DATA_TYPE_UINT16, nb_regs->nb.int_regs.ferr_nf_int, NULL); 1532 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_FAT_INT, 1533 DATA_TYPE_UINT16, nb_regs->nb.int_regs.nerr_fat_int, NULL); 1534 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_INT, 1535 DATA_TYPE_UINT16, nb_regs->nb.int_regs.nerr_nf_int, NULL); 1536 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECINT, 1537 DATA_TYPE_UINT32, nb_regs->nb.int_regs.nrecint, NULL); 1538 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECINT, 1539 DATA_TYPE_UINT32, nb_regs->nb.int_regs.recint, NULL); 1540 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECSF, 1541 DATA_TYPE_UINT64, nb_regs->nb.int_regs.nrecsf, NULL); 1542 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECSF, 1543 DATA_TYPE_UINT64, nb_regs->nb.int_regs.recsf, NULL); 1544 intel_error_list = data->intel_error_list; 1545 if (intel_error_list >= 0) 1546 (void) snprintf(buf, sizeof (buf), "B%d", intel_error_list); 1547 else 1548 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error"); 1549 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO, 1550 DATA_TYPE_STRING, buf, NULL); 1551 } 1552 1553 static void 1554 nb_fat_fbd_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload, 1555 nb_scatchpad_t *data) 1556 { 1557 nb_mem_scatchpad_t *sp; 1558 char buf[32]; 1559 1560 sp = &((nb_scatchpad_t *)data)->ms; 1561 1562 if (sp->ras != -1) { 1563 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BANK, 1564 DATA_TYPE_INT32, sp->bank, NULL); 1565 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CAS, 1566 DATA_TYPE_INT32, sp->cas, NULL); 1567 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RAS, 1568 DATA_TYPE_INT32, sp->ras, NULL); 1569 if (sp->offset != -1LL) { 1570 fm_payload_set(payload, FM_FMRI_MEM_OFFSET, 1571 DATA_TYPE_UINT64, sp->offset, NULL); 1572 } 1573 if (sp->pa != -1LL) { 1574 fm_payload_set(payload, FM_FMRI_MEM_PHYSADDR, 1575 DATA_TYPE_UINT64, sp->pa, NULL); 1576 } 1577 } 1578 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_FAT_FBD, 1579 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.ferr_fat_fbd, NULL); 1580 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_FAT_FBD, 1581 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nerr_fat_fbd, NULL); 1582 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECMEMA, 1583 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecmema, NULL); 1584 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECMEMB, 1585 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecmemb, NULL); 1586 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFGLOG, 1587 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfglog, NULL); 1588 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDA, 1589 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbda, NULL); 1590 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDB, 1591 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbdb, NULL); 1592 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDC, 1593 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbdc, NULL); 1594 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDD, 1595 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbdd, NULL); 1596 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDE, 1597 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbde, NULL); 1598 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDF, 1599 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbdf, NULL); 1600 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPS, 1601 DATA_TYPE_UINT8, nb_regs->nb.fat_fbd_regs.spcps, NULL); 1602 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPC, 1603 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.spcpc, NULL); 1604 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_UERRCNT, 1605 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.uerrcnt, NULL); 1606 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_UERRCNT_LAST, 1607 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.uerrcnt_last, NULL); 1608 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAMA, 1609 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.badrama, NULL); 1610 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAMB, 1611 DATA_TYPE_UINT16, nb_regs->nb.fat_fbd_regs.badramb, NULL); 1612 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADCNT, 1613 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.badcnt, NULL); 1614 1615 if (sp->intel_error_list >= 0) 1616 (void) snprintf(buf, sizeof (buf), "M%d", sp->intel_error_list); 1617 else 1618 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error"); 1619 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO, 1620 DATA_TYPE_STRING, buf, NULL); 1621 } 1622 1623 static void 1624 nb_nf_fbd_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload, 1625 nb_scatchpad_t *data) 1626 { 1627 nb_mem_scatchpad_t *sp; 1628 char buf[32]; 1629 1630 sp = &((nb_scatchpad_t *)data)->ms; 1631 1632 if (sp->dimm == -1 && sp->rank != -1) { 1633 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RANK, 1634 DATA_TYPE_INT32, sp->rank, NULL); 1635 } 1636 if (sp->ras != -1) { 1637 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BANK, 1638 DATA_TYPE_INT32, sp->bank, NULL); 1639 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CAS, 1640 DATA_TYPE_INT32, sp->cas, NULL); 1641 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RAS, 1642 DATA_TYPE_INT32, sp->ras, NULL); 1643 if (sp->offset != -1LL) { 1644 fm_payload_set(payload, FM_FMRI_MEM_OFFSET, 1645 DATA_TYPE_UINT64, sp->offset, NULL); 1646 } 1647 if (sp->pa != -1LL) { 1648 fm_payload_set(payload, FM_FMRI_MEM_PHYSADDR, 1649 DATA_TYPE_UINT64, sp->pa, NULL); 1650 } 1651 } 1652 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_FBD, 1653 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.ferr_nf_fbd, NULL); 1654 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_FBD, 1655 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.nerr_nf_fbd, NULL); 1656 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECMEMA, 1657 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recmema, NULL); 1658 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECMEMB, 1659 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recmemb, NULL); 1660 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFGLOG, 1661 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfglog, NULL); 1662 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDA, 1663 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbda, NULL); 1664 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDB, 1665 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbdb, NULL); 1666 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDC, 1667 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbdc, NULL); 1668 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDD, 1669 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbdd, NULL); 1670 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDE, 1671 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbde, NULL); 1672 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDF, 1673 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbdf, NULL); 1674 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPS, 1675 DATA_TYPE_UINT8, nb_regs->nb.nf_fbd_regs.spcps, NULL); 1676 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPC, 1677 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.spcpc, NULL); 1678 if (nb_chipset == INTEL_NB_7300 || nb_chipset == INTEL_NB_5400) { 1679 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNTA, 1680 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcnta, NULL); 1681 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNTB, 1682 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcntb, NULL); 1683 if (nb_chipset == INTEL_NB_7300) { 1684 fm_payload_set(payload, 1685 FM_EREPORT_PAYLOAD_NAME_CERRCNTC, 1686 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcntc, 1687 NULL); 1688 fm_payload_set(payload, 1689 FM_EREPORT_PAYLOAD_NAME_CERRCNTD, 1690 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcntd, 1691 NULL); 1692 } 1693 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNTA_LAST, 1694 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcnta_last, 1695 NULL); 1696 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNTB_LAST, 1697 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcntb_last, 1698 NULL); 1699 if (nb_chipset == INTEL_NB_7300) { 1700 fm_payload_set(payload, 1701 FM_EREPORT_PAYLOAD_NAME_CERRCNTC_LAST, 1702 DATA_TYPE_UINT32, 1703 nb_regs->nb.nf_fbd_regs.cerrcntc_last, NULL); 1704 fm_payload_set(payload, 1705 FM_EREPORT_PAYLOAD_NAME_CERRCNTD_LAST, 1706 DATA_TYPE_UINT32, 1707 nb_regs->nb.nf_fbd_regs.cerrcntd_last, NULL); 1708 } 1709 } else { 1710 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT, 1711 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcnta, NULL); 1712 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT_LAST, 1713 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcnta_last, 1714 NULL); 1715 } 1716 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAMA, 1717 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.badrama, NULL); 1718 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAMB, 1719 DATA_TYPE_UINT16, nb_regs->nb.nf_fbd_regs.badramb, NULL); 1720 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADCNT, 1721 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.badcnt, NULL); 1722 1723 if (sp->intel_error_list >= 0) 1724 (void) snprintf(buf, sizeof (buf), "M%d", sp->intel_error_list); 1725 else 1726 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error"); 1727 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO, 1728 DATA_TYPE_STRING, buf, NULL); 1729 } 1730 1731 static void 1732 nb_nf_mem_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload, 1733 nb_scatchpad_t *data) 1734 { 1735 nb_mem_scatchpad_t *sp; 1736 char buf[32]; 1737 1738 sp = &((nb_scatchpad_t *)data)->ms; 1739 1740 if (sp->dimm == -1 && sp->rank != -1) { 1741 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RANK, 1742 DATA_TYPE_INT32, sp->rank, NULL); 1743 } 1744 if (sp->ras != -1) { 1745 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BANK, 1746 DATA_TYPE_INT32, sp->bank, NULL); 1747 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CAS, 1748 DATA_TYPE_INT32, sp->cas, NULL); 1749 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RAS, 1750 DATA_TYPE_INT32, sp->ras, NULL); 1751 if (sp->offset != -1LL) { 1752 fm_payload_set(payload, FM_FMRI_MEM_OFFSET, 1753 DATA_TYPE_UINT64, sp->offset, NULL); 1754 } 1755 if (sp->pa != -1LL) { 1756 fm_payload_set(payload, FM_FMRI_MEM_PHYSADDR, 1757 DATA_TYPE_UINT64, sp->pa, NULL); 1758 } 1759 } 1760 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_MEM, 1761 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.ferr_nf_mem, NULL); 1762 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_MEM, 1763 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.nerr_nf_mem, NULL); 1764 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECMEMA, 1765 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.recmema, NULL); 1766 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECMEMB, 1767 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.recmemb, NULL); 1768 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_REDMEMA, 1769 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.redmema, NULL); 1770 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_REDMEMB, 1771 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.redmemb, NULL); 1772 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECMEMA, 1773 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.nrecmema, NULL); 1774 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECMEMB, 1775 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.nrecmemb, NULL); 1776 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPS, 1777 DATA_TYPE_UINT8, nb_regs->nb.nf_mem_regs.spcps, NULL); 1778 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPC, 1779 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.spcpc, NULL); 1780 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT, 1781 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.cerrcnt, NULL); 1782 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT_LAST, 1783 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.cerrcnt_last, NULL); 1784 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT_EXT, 1785 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.cerrcnt_ext, NULL); 1786 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT_EXT_LAST, 1787 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.cerrcnt_ext_last, NULL); 1788 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAM, 1789 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.badram, NULL); 1790 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADCNT, 1791 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.badcnt, NULL); 1792 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_VALIDLOG, 1793 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.validlog, NULL); 1794 1795 if (sp->intel_error_list >= 0) 1796 (void) snprintf(buf, sizeof (buf), "M%d", sp->intel_error_list); 1797 else 1798 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error"); 1799 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO, 1800 DATA_TYPE_STRING, buf, NULL); 1801 } 1802 1803 static void 1804 nb_dma_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload) 1805 { 1806 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PCISTS, 1807 DATA_TYPE_UINT16, nb_regs->nb.dma_regs.pcists, NULL); 1808 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEXDEVSTS, 1809 DATA_TYPE_UINT16, nb_regs->nb.dma_regs.pexdevsts, NULL); 1810 } 1811 1812 static void 1813 nb_thr_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload, 1814 nb_scatchpad_t *data) 1815 { 1816 char buf[32]; 1817 1818 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_FAT_THR, 1819 DATA_TYPE_UINT8, nb_regs->nb.thr_regs.ferr_fat_thr, NULL); 1820 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_FAT_THR, 1821 DATA_TYPE_UINT8, nb_regs->nb.thr_regs.nerr_fat_thr, NULL); 1822 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_THR, 1823 DATA_TYPE_UINT8, nb_regs->nb.thr_regs.ferr_nf_thr, NULL); 1824 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_THR, 1825 DATA_TYPE_UINT8, nb_regs->nb.thr_regs.nerr_nf_thr, NULL); 1826 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CTSTS, 1827 DATA_TYPE_UINT8, nb_regs->nb.thr_regs.ctsts, NULL); 1828 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_THRTSTS, 1829 DATA_TYPE_UINT16, nb_regs->nb.thr_regs.thrtsts, NULL); 1830 if (data->intel_error_list >= 0) { 1831 (void) snprintf(buf, sizeof (buf), "TH%d", 1832 data->intel_error_list); 1833 } else { 1834 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error"); 1835 } 1836 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO, 1837 DATA_TYPE_STRING, buf, NULL); 1838 } 1839 1840 static void 1841 nb_ereport_add_logout(nvlist_t *payload, const nb_logout_t *acl, 1842 nb_scatchpad_t *data) 1843 { 1844 const nb_regs_t *nb_regs = &acl->nb_regs; 1845 1846 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_MC_TYPE, 1847 DATA_TYPE_STRING, acl->type, NULL); 1848 switch (nb_regs->flag) { 1849 case NB_REG_LOG_FSB: 1850 nb_fsb_err_payload(nb_regs, payload, data); 1851 break; 1852 case NB_REG_LOG_PEX: 1853 nb_pex_err_payload(nb_regs, payload, data); 1854 break; 1855 case NB_REG_LOG_INT: 1856 nb_int_err_payload(nb_regs, payload, data); 1857 break; 1858 case NB_REG_LOG_FAT_FBD: 1859 nb_fat_fbd_err_payload(nb_regs, payload, data); 1860 break; 1861 case NB_REG_LOG_NF_FBD: 1862 nb_nf_fbd_err_payload(nb_regs, payload, data); 1863 break; 1864 case NB_REG_LOG_DMA: 1865 nb_dma_err_payload(nb_regs, payload); 1866 break; 1867 case NB_REG_LOG_THR: 1868 nb_thr_err_payload(nb_regs, payload, data); 1869 break; 1870 case NB_REG_LOG_NF_MEM: 1871 nb_nf_mem_err_payload(nb_regs, payload, data); 1872 break; 1873 default: 1874 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_GLOBAL, 1875 DATA_TYPE_UINT64, nb_regs->ferr, NULL); 1876 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_GLOBAL, 1877 DATA_TYPE_UINT32, nb_regs->nerr, NULL); 1878 break; 1879 } 1880 } 1881 1882 void 1883 nb_fsb_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector, 1884 nb_scatchpad_t *data) 1885 { 1886 int chip; 1887 1888 if (nb_chipset == INTEL_NB_7300) 1889 chip = nb_regs->nb.fsb_regs.fsb * 2; 1890 else 1891 chip = nb_regs->nb.fsb_regs.fsb; 1892 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2, 1893 "motherboard", 0, "chip", chip); 1894 1895 if (nb_regs->nb.fsb_regs.ferr_fat_fsb == 0 && 1896 nb_regs->nb.fsb_regs.ferr_nf_fsb == 0) { 1897 data->intel_error_list = intel_fsb_err(nb_regs->nb.fsb_regs.fsb, 1898 nb_regs->nb.fsb_regs.nerr_fat_fsb, 1899 nb_regs->nb.fsb_regs.nerr_nf_fsb); 1900 } else { 1901 data->intel_error_list = intel_fsb_err(nb_regs->nb.fsb_regs.fsb, 1902 nb_regs->nb.fsb_regs.ferr_fat_fsb, 1903 nb_regs->nb.fsb_regs.ferr_nf_fsb); 1904 } 1905 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s", 1906 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "fsb"); 1907 } 1908 1909 void 1910 nb_pex_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector, 1911 nb_scatchpad_t *data) 1912 { 1913 int hostbridge; 1914 1915 if (nb_regs->nb.pex_regs.pex == 0) { 1916 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 1917 "motherboard", 0); 1918 } else { 1919 hostbridge = nb_regs->nb.pex_regs.pex - 1; 1920 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2, 1921 "motherboard", 0, 1922 "hostbridge", hostbridge); 1923 } 1924 1925 if (nb_regs->nb.pex_regs.pex_fat_ferr == 0 && 1926 nb_regs->nb.pex_regs.pex_nf_corr_ferr == 0) { 1927 if (nb_chipset == INTEL_NB_5400) { 1928 data->intel_error_list = 1929 intel_pex_5400_err( 1930 nb_regs->nb.pex_regs.pex_fat_nerr, 1931 nb_regs->nb.pex_regs.pex_nf_corr_nerr); 1932 } else { 1933 data->intel_error_list = 1934 intel_pex_err(nb_regs->nb.pex_regs.pex_fat_nerr, 1935 nb_regs->nb.pex_regs.pex_nf_corr_nerr); 1936 } 1937 } else { 1938 if (nb_chipset == INTEL_NB_5400) { 1939 data->intel_error_list = 1940 intel_pex_5400_err( 1941 nb_regs->nb.pex_regs.pex_fat_ferr, 1942 nb_regs->nb.pex_regs.pex_nf_corr_ferr); 1943 } else { 1944 data->intel_error_list = 1945 intel_pex_err(nb_regs->nb.pex_regs.pex_fat_ferr, 1946 nb_regs->nb.pex_regs.pex_nf_corr_ferr); 1947 } 1948 } 1949 1950 if (nb_regs->nb.pex_regs.pex == 0) { 1951 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s", 1952 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "esi"); 1953 } else { 1954 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s", 1955 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "pex"); 1956 } 1957 } 1958 1959 void 1960 nb_int_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector, 1961 void *data) 1962 { 1963 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 1964 "motherboard", 0); 1965 1966 if (nb_regs->nb.int_regs.ferr_fat_int == 0 && 1967 nb_regs->nb.int_regs.ferr_nf_int == 0) { 1968 ((nb_scatchpad_t *)data)->intel_error_list = 1969 intel_int_err(nb_regs->nb.int_regs.nerr_fat_int, 1970 nb_regs->nb.int_regs.nerr_nf_int); 1971 } else { 1972 ((nb_scatchpad_t *)data)->intel_error_list = 1973 intel_int_err(nb_regs->nb.int_regs.ferr_fat_int, 1974 nb_regs->nb.int_regs.ferr_nf_int); 1975 } 1976 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s", 1977 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "ie"); 1978 } 1979 1980 void 1981 nb_fat_fbd_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector, 1982 void *data) 1983 { 1984 char *intr; 1985 nb_mem_scatchpad_t *sp; 1986 1987 intr = fat_memory_error(nb_regs, data); 1988 sp = &((nb_scatchpad_t *)data)->ms; 1989 1990 if (sp->dimm != -1) { 1991 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 5, 1992 "motherboard", 0, 1993 "memory-controller", sp->branch, 1994 "dram-channel", sp->channel, 1995 "dimm", sp->dimm, 1996 "rank", sp->rank); 1997 } else if (sp->channel != -1) { 1998 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 3, 1999 "motherboard", 0, 2000 "memory-controller", sp->branch, 2001 "dram-channel", sp->channel); 2002 } else if (sp->branch != -1) { 2003 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2, 2004 "motherboard", 0, 2005 "memory-controller", sp->branch); 2006 } else { 2007 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 2008 "motherboard", 0); 2009 } 2010 2011 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s", 2012 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, intr); 2013 } 2014 2015 void 2016 nb_nf_fbd_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector, 2017 void *data) 2018 { 2019 char *intr; 2020 nb_mem_scatchpad_t *sp; 2021 2022 intr = nf_memory_error(nb_regs, data); 2023 sp = &((nb_scatchpad_t *)data)->ms; 2024 2025 if (sp->dimm != -1) { 2026 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 5, 2027 "motherboard", 0, 2028 "memory-controller", sp->branch, 2029 "dram-channel", sp->channel, 2030 "dimm", sp->dimm, 2031 "rank", sp->rank); 2032 } else if (sp->channel != -1) { 2033 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 3, 2034 "motherboard", 0, 2035 "memory-controller", sp->branch, 2036 "dram-channel", sp->channel); 2037 } else if (sp->branch != -1) { 2038 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2, 2039 "motherboard", 0, 2040 "memory-controller", sp->branch); 2041 } else { 2042 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 2043 "motherboard", 0); 2044 } 2045 2046 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s", 2047 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, intr); 2048 } 2049 2050 void 2051 nb_dma_report(char *class, nvlist_t *detector) 2052 { 2053 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 2054 "motherboard", 0); 2055 2056 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s", 2057 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "dma"); 2058 } 2059 2060 void 2061 nb_thr_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector, 2062 void *data) 2063 { 2064 ((nb_scatchpad_t *)data)->intel_error_list = 2065 intel_thr_err(nb_regs->nb.thr_regs.ferr_fat_thr, 2066 nb_regs->nb.thr_regs.ferr_nf_thr); 2067 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 2068 "motherboard", 0); 2069 2070 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s", 2071 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "otf"); 2072 } 2073 2074 void 2075 nb_nf_mem_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector, 2076 void *data) 2077 { 2078 char *intr; 2079 nb_mem_scatchpad_t *sp; 2080 2081 intr = nf_mem_error(nb_regs, data); 2082 sp = &((nb_scatchpad_t *)data)->ms; 2083 2084 if (sp->dimm != -1) { 2085 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 5, 2086 "motherboard", 0, 2087 "memory-controller", sp->branch, 2088 "dram-channel", sp->channel, 2089 "dimm", sp->dimm, 2090 "rank", sp->rank); 2091 } else if (sp->channel != -1) { 2092 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 3, 2093 "motherboard", 0, 2094 "memory-controller", sp->branch, 2095 "dram-channel", sp->channel); 2096 } else if (sp->branch != -1) { 2097 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2, 2098 "motherboard", 0, 2099 "memory-controller", sp->branch); 2100 } else { 2101 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 2102 "motherboard", 0); 2103 } 2104 2105 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s", 2106 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, intr); 2107 } 2108 2109 2110 nvlist_t * 2111 nb_report(const nb_regs_t *nb_regs, char *class, nv_alloc_t *nva, void *scratch) 2112 { 2113 nvlist_t *detector = fm_nvlist_create(nva); 2114 2115 switch (nb_regs->flag) { 2116 case NB_REG_LOG_FSB: 2117 nb_fsb_report(nb_regs, class, detector, scratch); 2118 break; 2119 case NB_REG_LOG_PEX: 2120 nb_pex_report(nb_regs, class, detector, scratch); 2121 break; 2122 case NB_REG_LOG_INT: 2123 nb_int_report(nb_regs, class, detector, scratch); 2124 break; 2125 case NB_REG_LOG_FAT_FBD: 2126 nb_fat_fbd_report(nb_regs, class, detector, scratch); 2127 break; 2128 case NB_REG_LOG_NF_FBD: 2129 nb_nf_fbd_report(nb_regs, class, detector, scratch); 2130 break; 2131 case NB_REG_LOG_DMA: 2132 nb_dma_report(class, detector); 2133 break; 2134 case NB_REG_LOG_THR: 2135 nb_thr_report(nb_regs, class, detector, scratch); 2136 break; 2137 case NB_REG_LOG_NF_MEM: 2138 nb_nf_mem_report(nb_regs, class, detector, scratch); 2139 break; 2140 default: 2141 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 2142 "motherboard", 0); 2143 2144 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s", 2145 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "unknown"); 2146 } 2147 return (detector); 2148 } 2149 2150 /*ARGSUSED*/ 2151 void 2152 nb_drain(void *ignored, const void *data, const errorq_elem_t *eqe) 2153 { 2154 nb_logout_t *acl = (nb_logout_t *)data; 2155 errorq_elem_t *eqep, *scr_eqep; 2156 nvlist_t *ereport, *detector; 2157 nv_alloc_t *nva = NULL; 2158 char buf[FM_MAX_CLASS]; 2159 nb_scatchpad_t nb_scatchpad; 2160 2161 if (panicstr) { 2162 if ((eqep = errorq_reserve(ereport_errorq)) == NULL) 2163 return; 2164 ereport = errorq_elem_nvl(ereport_errorq, eqep); 2165 /* 2166 * Now try to allocate another element for scratch space and 2167 * use that for further scratch space (eg for constructing 2168 * nvlists to add the main ereport). If we can't reserve 2169 * a scratch element just fallback to working within the 2170 * element we already have, and hope for the best. All this 2171 * is necessary because the fixed buffer nv allocator does 2172 * not reclaim freed space and nvlist construction is 2173 * expensive. 2174 */ 2175 if ((scr_eqep = errorq_reserve(ereport_errorq)) != NULL) 2176 nva = errorq_elem_nva(ereport_errorq, scr_eqep); 2177 else 2178 nva = errorq_elem_nva(ereport_errorq, eqep); 2179 } else { 2180 ereport = fm_nvlist_create(NULL); 2181 } 2182 detector = nb_report(&acl->nb_regs, buf, nva, &nb_scatchpad); 2183 if (detector == NULL) 2184 return; 2185 fm_ereport_set(ereport, FM_EREPORT_VERSION, buf, 2186 fm_ena_generate(acl->acl_timestamp, FM_ENA_FMT1), detector, NULL); 2187 /* 2188 * We're done with 'detector' so reclaim the scratch space. 2189 */ 2190 if (panicstr) { 2191 fm_nvlist_destroy(detector, FM_NVA_RETAIN); 2192 nv_alloc_reset(nva); 2193 } else { 2194 fm_nvlist_destroy(detector, FM_NVA_FREE); 2195 } 2196 2197 /* 2198 * Encode the error-specific data that was saved in the logout area. 2199 */ 2200 nb_ereport_add_logout(ereport, acl, &nb_scatchpad); 2201 2202 if (panicstr) { 2203 errorq_commit(ereport_errorq, eqep, ERRORQ_SYNC); 2204 if (scr_eqep) 2205 errorq_cancel(ereport_errorq, scr_eqep); 2206 } else { 2207 (void) fm_ereport_post(ereport, EVCH_TRYHARD); 2208 fm_nvlist_destroy(ereport, FM_NVA_FREE); 2209 } 2210 } 2211