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 (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 #include <sys/types.h> 27 #include <sys/cmn_err.h> 28 #include <sys/errno.h> 29 #include <sys/log.h> 30 #include <sys/systm.h> 31 #include <sys/modctl.h> 32 #include <sys/errorq.h> 33 #include <sys/controlregs.h> 34 #include <sys/fm/util.h> 35 #include <sys/fm/protocol.h> 36 #include <sys/sysevent.h> 37 #include <sys/pghw.h> 38 #include <sys/cyclic.h> 39 #include <sys/pci_cfgspace.h> 40 #include <sys/mc_intel.h> 41 #include <sys/smbios.h> 42 #include "nb5000.h" 43 #include "nb_log.h" 44 #include "dimm_phys.h" 45 46 int nb_check_validlog = 1; 47 48 static uint32_t uerrcnt[2]; 49 static uint32_t cerrcnta[2][2]; 50 static uint32_t cerrcntb[2][2]; 51 static uint32_t cerrcntc[2][2]; 52 static uint32_t cerrcntd[2][2]; 53 static nb_logout_t nb_log; 54 55 struct mch_error_code { 56 int intel_error_list; /* error number in Chipset Error List */ 57 uint32_t emask; /* mask for machine check */ 58 uint32_t error_bit; /* error bit in fault register */ 59 }; 60 61 static struct mch_error_code fat_fbd_error_code[] = { 62 { 23, EMASK_FBD_M23, ERR_FAT_FBD_M23 }, 63 { 3, EMASK_FBD_M3, ERR_FAT_FBD_M3 }, 64 { 2, EMASK_FBD_M2, ERR_FAT_FBD_M2 }, 65 { 1, EMASK_FBD_M1, ERR_FAT_FBD_M1 } 66 }; 67 68 static int 69 intel_fat_fbd_err(uint32_t fat_fbd) 70 { 71 int rt = -1; 72 int nerr = 0; 73 uint32_t emask_fbd = 0; 74 int i; 75 int sz; 76 77 sz = sizeof (fat_fbd_error_code) / sizeof (struct mch_error_code); 78 79 for (i = 0; i < sz; i++) { 80 if (fat_fbd & fat_fbd_error_code[i].error_bit) { 81 rt = fat_fbd_error_code[i].intel_error_list; 82 emask_fbd |= fat_fbd_error_code[i].emask; 83 nerr++; 84 } 85 } 86 87 if (emask_fbd) 88 nb_fbd_mask_mc(emask_fbd); 89 if (nerr > 1) 90 rt = -1; 91 return (rt); 92 } 93 94 static char * 95 fat_memory_error(const nb_regs_t *rp, void *data) 96 { 97 int channel; 98 uint32_t ferr_fat_fbd, nrecmemb; 99 uint32_t nrecmema; 100 char *intr = "nb.unknown"; 101 nb_mem_scatchpad_t *sp = &((nb_scatchpad_t *)data)->ms; 102 103 ferr_fat_fbd = rp->nb.fat_fbd_regs.ferr_fat_fbd; 104 if ((ferr_fat_fbd & ERR_FAT_FBD_MASK) == 0) { 105 sp->intel_error_list = 106 intel_fat_fbd_err(rp->nb.fat_fbd_regs.nerr_fat_fbd); 107 sp->branch = -1; 108 sp->channel = -1; 109 sp->rank = -1; 110 sp->dimm = -1; 111 sp->bank = -1; 112 sp->cas = -1; 113 sp->ras = -1; 114 sp->pa = -1LL; 115 sp->offset = -1; 116 return (intr); 117 } 118 sp->intel_error_list = intel_fat_fbd_err(ferr_fat_fbd); 119 channel = (ferr_fat_fbd >> 28) & 3; 120 sp->branch = channel >> 1; 121 sp->channel = channel; 122 if ((ferr_fat_fbd & (ERR_FAT_FBD_M2|ERR_FAT_FBD_M1)) != 0) { 123 if ((ferr_fat_fbd & ERR_FAT_FBD_M1) != 0) 124 intr = "nb.fbd.alert"; /* Alert on FB-DIMM M1 */ 125 else 126 intr = "nb.fbd.crc"; /* CRC error FB_DIMM M2 */ 127 nrecmema = rp->nb.fat_fbd_regs.nrecmema; 128 nrecmemb = rp->nb.fat_fbd_regs.nrecmemb; 129 sp->rank = (nrecmema >> 8) & RANK_MASK; 130 sp->dimm = sp->rank >> 1; 131 sp->bank = (nrecmema >> 12) & BANK_MASK; 132 sp->cas = (nrecmemb >> 16) & CAS_MASK; 133 sp->ras = nrecmemb & RAS_MASK; 134 /* 135 * If driver was built with closed tree present then we will 136 * have Intel proprietary code for finding physaddr 137 */ 138 if (&dimm_getphys) { 139 sp->pa = dimm_getphys((uint16_t)sp->branch, 140 (uint16_t)sp->rank, (uint64_t)sp->bank, 141 (uint64_t)sp->ras, (uint64_t)sp->cas); 142 if (sp->pa >= MAXPHYS_ADDR) 143 sp->pa = -1ULL; 144 } else { 145 sp->pa = -1ULL; 146 } 147 /* 148 * If there is an offset decoder use it otherwise encode 149 * rank/bank/ras/cas 150 */ 151 if (&dimm_getoffset) { 152 sp->offset = dimm_getoffset(sp->branch, sp->rank, 153 sp->bank, sp->ras, sp->cas); 154 } else { 155 sp->offset = TCODE_OFFSET(sp->rank, sp->bank, sp->ras, 156 sp->cas); 157 } 158 } else { 159 if ((ferr_fat_fbd & ERR_FAT_FBD_M3) != 0) 160 intr = "nb.fbd.otf"; /* thermal temp > Tmid M3 */ 161 else if ((ferr_fat_fbd & ERR_FAT_FBD_M23) != 0) { 162 intr = "nb.fbd.reset_timeout"; 163 sp->channel = -1; 164 } 165 sp->rank = -1; 166 sp->dimm = -1; 167 sp->bank = -1; 168 sp->cas = -1; 169 sp->ras = -1; 170 sp->pa = -1LL; 171 sp->offset = -1; 172 } 173 return (intr); 174 } 175 176 177 static struct mch_error_code nf_fbd_error_code[] = { 178 { 29, EMASK_FBD_M29, ERR_NF_FBD_M29 }, 179 { 28, EMASK_FBD_M28, ERR_NF_FBD_M28 }, 180 { 27, EMASK_FBD_M27, ERR_NF_FBD_M27 }, 181 { 26, EMASK_FBD_M26, ERR_NF_FBD_M26 }, 182 { 25, EMASK_FBD_M25, ERR_NF_FBD_M25 }, 183 { 24, EMASK_FBD_M24, ERR_NF_FBD_M24 }, 184 { 22, EMASK_FBD_M22, ERR_NF_FBD_M22 }, 185 { 21, EMASK_FBD_M21, ERR_NF_FBD_M21 }, 186 { 20, EMASK_FBD_M20, ERR_NF_FBD_M20 }, 187 { 19, EMASK_FBD_M19, ERR_NF_FBD_M19 }, 188 { 18, EMASK_FBD_M18, ERR_NF_FBD_M18 }, 189 { 17, EMASK_FBD_M17, ERR_NF_FBD_M17 }, 190 { 16, EMASK_FBD_M16, ERR_NF_FBD_M16 }, 191 { 15, EMASK_FBD_M15, ERR_NF_FBD_M15 }, 192 { 14, EMASK_FBD_M14, ERR_NF_FBD_M14 }, 193 { 13, EMASK_FBD_M13, ERR_NF_FBD_M13 }, 194 { 12, EMASK_FBD_M12, ERR_NF_FBD_M12 }, 195 { 11, EMASK_FBD_M11, ERR_NF_FBD_M11 }, 196 { 10, EMASK_FBD_M10, ERR_NF_FBD_M10 }, 197 { 9, EMASK_FBD_M9, ERR_NF_FBD_M9 }, 198 { 8, EMASK_FBD_M8, ERR_NF_FBD_M8 }, 199 { 7, EMASK_FBD_M7, ERR_NF_FBD_M7 }, 200 { 6, EMASK_FBD_M6, ERR_NF_FBD_M6 }, 201 { 5, EMASK_FBD_M5, ERR_NF_FBD_M5 }, 202 { 4, EMASK_FBD_M4, ERR_NF_FBD_M4 } 203 }; 204 205 static int 206 intel_nf_fbd_err(uint32_t nf_fbd) 207 { 208 int rt = -1; 209 int nerr = 0; 210 uint32_t emask_fbd = 0; 211 int i; 212 int sz; 213 214 sz = sizeof (nf_fbd_error_code) / sizeof (struct mch_error_code); 215 216 for (i = 0; i < sz; i++) { 217 if (nf_fbd & nf_fbd_error_code[i].error_bit) { 218 rt = nf_fbd_error_code[i].intel_error_list; 219 emask_fbd |= nf_fbd_error_code[i].emask; 220 nerr++; 221 } 222 } 223 if (emask_fbd) 224 nb_fbd_mask_mc(emask_fbd); 225 if (nerr > 1) 226 rt = -1; 227 return (rt); 228 } 229 230 static char * 231 nf_memory_error(const nb_regs_t *rp, void *data) 232 { 233 uint32_t ferr_nf_fbd, recmemb, redmemb; 234 uint32_t recmema; 235 int branch, channel, ecc_locator; 236 char *intr = "nb.unknown"; 237 nb_mem_scatchpad_t *sp = &((nb_scatchpad_t *)data)->ms; 238 239 sp->rank = -1; 240 sp->dimm = -1; 241 sp->bank = -1; 242 sp->cas = -1; 243 sp->ras = -1LL; 244 sp->pa = -1LL; 245 sp->offset = -1; 246 ferr_nf_fbd = rp->nb.nf_fbd_regs.ferr_nf_fbd; 247 if ((ferr_nf_fbd & ERR_NF_FBD_MASK) == 0) { 248 /* unknown ereport if a recognizable error was not found */ 249 sp->branch = -1; 250 sp->channel = -1; 251 sp->intel_error_list = -1; 252 return (intr); 253 } 254 sp->intel_error_list = intel_nf_fbd_err(ferr_nf_fbd); 255 channel = (ferr_nf_fbd >> ERR_FBD_CH_SHIFT) & 3; 256 branch = channel >> 1; 257 sp->branch = branch; 258 sp->channel = channel; 259 if (ferr_nf_fbd & ERR_NF_FBD_MASK) { 260 if (ferr_nf_fbd & ERR_NF_FBD_ECC_UE) { 261 /* 262 * uncorrectable ECC M4 - M12 263 * we can only isolate to pair of dimms 264 * for single dimm configuration let eversholt 265 * sort it out with out needing a special rule 266 */ 267 sp->channel = -1; 268 recmema = rp->nb.nf_fbd_regs.recmema; 269 recmemb = rp->nb.nf_fbd_regs.recmemb; 270 sp->rank = (recmema >> 8) & RANK_MASK; 271 sp->bank = (recmema >> 12) & BANK_MASK; 272 sp->cas = (recmemb >> 16) & CAS_MASK; 273 sp->ras = recmemb & RAS_MASK; 274 intr = "nb.mem_ue"; 275 } else if (ferr_nf_fbd & ERR_NF_FBD_M13) { 276 /* 277 * write error M13 278 * we can only isolate to pair of dimms 279 */ 280 sp->channel = -1; 281 if (nb_mode != NB_MEMORY_MIRROR) { 282 recmema = rp->nb.nf_fbd_regs.recmema; 283 recmemb = rp->nb.nf_fbd_regs.recmemb; 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 int 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 if (rp->nb.pex_regs.pex_fat_ferr == 0 && 1109 rp->nb.pex_regs.pex_fat_nerr == 0 && 1110 rp->nb.pex_regs.pex_nf_corr_ferr == 0 && 1111 rp->nb.pex_regs.pex_nf_corr_nerr == 0) 1112 return (0); 1113 rp->nb.pex_regs.uncerrsev = UNCERRSEV_RD(pex); 1114 rp->nb.pex_regs.rperrsts = RPERRSTS_RD(pex); 1115 rp->nb.pex_regs.rperrsid = RPERRSID_RD(pex); 1116 if (pex != (uint8_t)-1) 1117 rp->nb.pex_regs.uncerrsts = UNCERRSTS_RD(pex); 1118 else 1119 rp->nb.pex_regs.uncerrsts = 0; 1120 rp->nb.pex_regs.aerrcapctrl = AERRCAPCTRL_RD(pex); 1121 rp->nb.pex_regs.corerrsts = CORERRSTS_RD(pex); 1122 rp->nb.pex_regs.pexdevsts = PEXDEVSTS_RD(pex); 1123 1124 if (!willpanic) { 1125 if (rp->nb.pex_regs.pex_fat_ferr || *interpose) 1126 PEX_FAT_FERR_WR(pex, rp->nb.pex_regs.pex_fat_ferr); 1127 if (rp->nb.pex_regs.pex_fat_nerr) 1128 PEX_FAT_NERR_WR(pex, rp->nb.pex_regs.pex_fat_nerr); 1129 if (rp->nb.pex_regs.pex_nf_corr_ferr || *interpose) 1130 PEX_NF_FERR_WR(pex, rp->nb.pex_regs.pex_nf_corr_ferr); 1131 if (rp->nb.pex_regs.pex_nf_corr_nerr) 1132 PEX_NF_NERR_WR(pex, rp->nb.pex_regs.pex_nf_corr_nerr); 1133 if (*interpose) 1134 UNCERRSTS_WR(pex, rp->nb.pex_regs.uncerrsts); 1135 if (*interpose) 1136 RPERRSTS_WR(pex, rp->nb.pex_regs.rperrsts); 1137 if (*interpose) 1138 PEXDEVSTS_WR(pex, 0); 1139 } 1140 return (1); 1141 } 1142 1143 static void 1144 log_fat_fbd_err(nb_regs_t *rp, int willpanic, int *interpose) 1145 { 1146 int channel, branch; 1147 int t = 0; 1148 1149 rp->flag = NB_REG_LOG_FAT_FBD; 1150 rp->nb.fat_fbd_regs.ferr_fat_fbd = FERR_FAT_FBD_RD(interpose); 1151 channel = (rp->nb.fat_fbd_regs.ferr_fat_fbd >> 28) & 3; 1152 branch = channel >> 1; 1153 rp->nb.fat_fbd_regs.nerr_fat_fbd = NERR_FAT_FBD_RD(&t); 1154 *interpose |= t; 1155 rp->nb.fat_fbd_regs.nrecmema = NRECMEMA_RD(branch); 1156 rp->nb.fat_fbd_regs.nrecmemb = NRECMEMB_RD(branch); 1157 rp->nb.fat_fbd_regs.nrecfglog = NRECFGLOG_RD(branch); 1158 rp->nb.fat_fbd_regs.nrecfbda = NRECFBDA_RD(branch); 1159 rp->nb.fat_fbd_regs.nrecfbdb = NRECFBDB_RD(branch); 1160 rp->nb.fat_fbd_regs.nrecfbdc = NRECFBDC_RD(branch); 1161 rp->nb.fat_fbd_regs.nrecfbdd = NRECFBDD_RD(branch); 1162 rp->nb.fat_fbd_regs.nrecfbde = NRECFBDE_RD(branch); 1163 rp->nb.fat_fbd_regs.nrecfbdf = NRECFBDF_RD(branch); 1164 rp->nb.fat_fbd_regs.spcps = SPCPS_RD(branch); 1165 rp->nb.fat_fbd_regs.spcpc = SPCPC_RD(branch); 1166 rp->nb.fat_fbd_regs.uerrcnt = UERRCNT_RD(branch); 1167 rp->nb.fat_fbd_regs.uerrcnt_last = uerrcnt[branch]; 1168 uerrcnt[branch] = rp->nb.fat_fbd_regs.uerrcnt; 1169 rp->nb.fat_fbd_regs.badrama = BADRAMA_RD(branch); 1170 rp->nb.fat_fbd_regs.badramb = BADRAMB_RD(branch); 1171 rp->nb.fat_fbd_regs.badcnt = BADCNT_RD(branch); 1172 if (!willpanic) { 1173 if (rp->nb.fat_fbd_regs.ferr_fat_fbd || *interpose) 1174 FERR_FAT_FBD_WR(rp->nb.fat_fbd_regs.ferr_fat_fbd); 1175 if (rp->nb.fat_fbd_regs.nerr_fat_fbd) 1176 NERR_FAT_FBD_WR(rp->nb.fat_fbd_regs.nerr_fat_fbd); 1177 /* 1178 * if interpose write read-only registers to clear from pcii 1179 * cache 1180 */ 1181 if (*interpose) { 1182 NRECMEMA_WR(branch); 1183 NRECMEMB_WR(branch); 1184 NRECFGLOG_WR(branch); 1185 NRECFBDA_WR(branch); 1186 NRECFBDB_WR(branch); 1187 NRECFBDC_WR(branch); 1188 NRECFBDD_WR(branch); 1189 NRECFBDE_WR(branch); 1190 NRECFBDF_WR(branch); 1191 } 1192 } 1193 } 1194 1195 static void 1196 log_nf_fbd_err(nb_regs_t *rp, int willpanic, int *interpose) 1197 { 1198 int channel, branch; 1199 int t = 0; 1200 1201 rp->flag = NB_REG_LOG_NF_FBD; 1202 rp->nb.nf_fbd_regs.ferr_nf_fbd = FERR_NF_FBD_RD(interpose); 1203 channel = (rp->nb.nf_fbd_regs.ferr_nf_fbd >> 28) & 3; 1204 branch = channel >> 1; 1205 rp->nb.nf_fbd_regs.nerr_nf_fbd = NERR_NF_FBD_RD(&t); 1206 *interpose |= t; 1207 rp->nb.nf_fbd_regs.redmemb = REDMEMB_RD(); 1208 rp->nb.nf_fbd_regs.recmema = RECMEMA_RD(branch); 1209 rp->nb.nf_fbd_regs.recmemb = RECMEMB_RD(branch); 1210 rp->nb.nf_fbd_regs.recfglog = RECFGLOG_RD(branch); 1211 rp->nb.nf_fbd_regs.recfbda = RECFBDA_RD(branch); 1212 rp->nb.nf_fbd_regs.recfbdb = RECFBDB_RD(branch); 1213 rp->nb.nf_fbd_regs.recfbdc = RECFBDC_RD(branch); 1214 rp->nb.nf_fbd_regs.recfbdd = RECFBDD_RD(branch); 1215 rp->nb.nf_fbd_regs.recfbde = RECFBDE_RD(branch); 1216 rp->nb.nf_fbd_regs.recfbdf = RECFBDF_RD(branch); 1217 rp->nb.nf_fbd_regs.spcps = SPCPS_RD(branch); 1218 rp->nb.nf_fbd_regs.spcpc = SPCPC_RD(branch); 1219 if (nb_chipset == INTEL_NB_7300 || nb_chipset == INTEL_NB_5400) { 1220 rp->nb.nf_fbd_regs.cerrcnta = CERRCNTA_RD(branch, channel); 1221 rp->nb.nf_fbd_regs.cerrcntb = CERRCNTB_RD(branch, channel); 1222 rp->nb.nf_fbd_regs.cerrcntc = CERRCNTC_RD(branch, channel); 1223 rp->nb.nf_fbd_regs.cerrcntd = CERRCNTD_RD(branch, channel); 1224 } else { 1225 rp->nb.nf_fbd_regs.cerrcnta = CERRCNT_RD(branch); 1226 rp->nb.nf_fbd_regs.cerrcntb = 0; 1227 rp->nb.nf_fbd_regs.cerrcntc = 0; 1228 rp->nb.nf_fbd_regs.cerrcntd = 0; 1229 } 1230 rp->nb.nf_fbd_regs.cerrcnta_last = cerrcnta[branch][channel & 1]; 1231 rp->nb.nf_fbd_regs.cerrcntb_last = cerrcntb[branch][channel & 1]; 1232 rp->nb.nf_fbd_regs.cerrcntc_last = cerrcntc[branch][channel & 1]; 1233 rp->nb.nf_fbd_regs.cerrcntd_last = cerrcntd[branch][channel & 1]; 1234 cerrcnta[branch][channel & 1] = rp->nb.nf_fbd_regs.cerrcnta; 1235 cerrcntb[branch][channel & 1] = rp->nb.nf_fbd_regs.cerrcntb; 1236 cerrcntc[branch][channel & 1] = rp->nb.nf_fbd_regs.cerrcntc; 1237 cerrcntd[branch][channel & 1] = rp->nb.nf_fbd_regs.cerrcntd; 1238 rp->nb.nf_fbd_regs.badrama = BADRAMA_RD(branch); 1239 rp->nb.nf_fbd_regs.badramb = BADRAMB_RD(branch); 1240 rp->nb.nf_fbd_regs.badcnt = BADCNT_RD(branch); 1241 if (!willpanic) { 1242 if (rp->nb.nf_fbd_regs.ferr_nf_fbd || *interpose) 1243 FERR_NF_FBD_WR(rp->nb.nf_fbd_regs.ferr_nf_fbd); 1244 if (rp->nb.nf_fbd_regs.nerr_nf_fbd) 1245 NERR_NF_FBD_WR(rp->nb.nf_fbd_regs.nerr_nf_fbd); 1246 /* 1247 * if interpose write read-only registers to clear from pcii 1248 * cache 1249 */ 1250 if (*interpose) { 1251 RECMEMA_WR(branch); 1252 RECMEMB_WR(branch); 1253 RECFGLOG_WR(branch); 1254 RECFBDA_WR(branch); 1255 RECFBDB_WR(branch); 1256 RECFBDC_WR(branch); 1257 RECFBDD_WR(branch); 1258 RECFBDE_WR(branch); 1259 RECFBDF_WR(branch); 1260 SPCPS_WR(branch); 1261 } 1262 } 1263 } 1264 1265 static int 1266 log_nf_mem_err(nb_regs_t *rp, int willpanic, int *interpose) 1267 { 1268 int channel, branch; 1269 int t = 0; 1270 int rt = 0; 1271 1272 rp->flag = NB_REG_LOG_NF_MEM; 1273 1274 /* Memmory err registers */ 1275 rp->nb.nf_mem_regs.ferr_nf_mem = FERR_NF_MEM_RD(interpose); 1276 channel = (rp->nb.nf_mem_regs.ferr_nf_mem >> 28) & 0x1; 1277 branch = channel; 1278 rp->nb.nf_mem_regs.nerr_nf_mem = NERR_NF_MEM_RD(&t); 1279 *interpose |= t; 1280 rp->nb.nf_mem_regs.redmema = MEM_REDMEMA_RD(branch); 1281 rp->nb.nf_mem_regs.redmemb = MEM_REDMEMB_RD(branch); 1282 rp->nb.nf_mem_regs.recmema = MEM_RECMEMA_RD(branch); 1283 rp->nb.nf_mem_regs.recmemb = MEM_RECMEMB_RD(branch); 1284 rp->nb.nf_mem_regs.nrecmema = MEM_NRECMEMA_RD(branch); 1285 rp->nb.nf_mem_regs.nrecmemb = MEM_NRECMEMB_RD(branch); 1286 1287 /* spare rank */ 1288 rp->nb.nf_mem_regs.spcps = SPCPS_RD(branch); 1289 rp->nb.nf_mem_regs.spcpc = SPCPC_RD(branch); 1290 1291 /* RAS registers */ 1292 rp->nb.nf_mem_regs.cerrcnt = MEM_CERRCNT_RD(branch); 1293 rp->nb.nf_mem_regs.cerrcnt_ext = (uint32_t)MEM_CERRCNT_EXT_RD(branch); 1294 rp->nb.nf_mem_regs.cerrcnt_last = cerrcnta[branch][channel & 1]; 1295 rp->nb.nf_mem_regs.cerrcnt_ext_last = cerrcntb[branch][channel & 1]; 1296 cerrcnta[branch][channel & 1] = rp->nb.nf_mem_regs.cerrcnt; 1297 cerrcntb[branch][channel & 1] = rp->nb.nf_mem_regs.cerrcnt_ext; 1298 rp->nb.nf_mem_regs.badram = BADRAMA_RD(branch); 1299 rp->nb.nf_mem_regs.badcnt = BADCNT_RD(branch); 1300 rp->nb.nf_mem_regs.validlog = VALIDLOG_RD(branch); 1301 1302 if (!willpanic) { 1303 if (rp->nb.nf_mem_regs.ferr_nf_mem || *interpose) 1304 FERR_NF_MEM_WR(rp->nb.nf_mem_regs.ferr_nf_mem); 1305 if (rp->nb.nf_mem_regs.nerr_nf_mem) 1306 NERR_NF_MEM_WR(rp->nb.nf_mem_regs.nerr_nf_mem); 1307 /* 1308 * if interpose, write read-only registers to clear from pci 1309 * cache 1310 */ 1311 if (*interpose) { 1312 MEM_NRECMEMA_WR(branch); 1313 MEM_NRECMEMB_WR(branch); 1314 MEM_REDMEMA_WR(branch); 1315 MEM_REDMEMB_WR(branch); 1316 MEM_RECMEMA_WR(branch); 1317 MEM_RECMEMB_WR(branch); 1318 SPCPS_WR(branch); 1319 } 1320 } 1321 if (nb_mode == NB_MEMORY_SINGLE_CHANNEL && channel != 0) { 1322 /* 1323 * In the single channel mode, all dimms are on the channel 0. 1324 * Invalidate this error if the channel number is invalid. 1325 */ 1326 rt = 1; 1327 } 1328 return (rt); 1329 } 1330 1331 static void 1332 log_ferr(uint64_t ferr, uint32_t *nerrp, nb_logout_t *log, int willpanic) 1333 { 1334 nb_regs_t *rp = &log->nb_regs; 1335 uint32_t nerr = *nerrp; 1336 int interpose = 0; 1337 int spurious = 0; 1338 1339 log->acl_timestamp = gethrtime_waitfree(); 1340 if ((ferr & (GE_PCIEX_FATAL | GE_PCIEX_NF)) != 0) { 1341 *nerrp = nerr & ~(GE_PCIEX_FATAL | GE_PCIEX_NF); 1342 if (log_pex_err(ferr, rp, willpanic, &interpose) == 0) 1343 return; 1344 } else if ((ferr & GE_FBD_FATAL) != 0) { 1345 log_fat_fbd_err(rp, willpanic, &interpose); 1346 *nerrp = nerr & ~GE_NERR_FBD_FATAL; 1347 } else if ((ferr & GE_FBD_NF) != 0) { 1348 log_nf_fbd_err(rp, willpanic, &interpose); 1349 *nerrp = nerr & ~GE_NERR_FBD_NF; 1350 } else if ((ferr & GE_MEM_NF) != 0) { 1351 spurious = log_nf_mem_err(rp, willpanic, &interpose); 1352 *nerrp = nerr & ~GE_NERR_MEM_NF; 1353 } else if ((ferr & (GE_FERR_FSB_FATAL | GE_FERR_FSB_NF)) != 0) { 1354 log_fsb_err(ferr, rp, willpanic, &interpose); 1355 *nerrp = nerr & ~(GE_NERR_FSB_FATAL | GE_NERR_FSB_NF); 1356 } else if ((ferr & (GE_DMA_FATAL | GE_DMA_NF)) != 0) { 1357 log_dma_err(rp, &interpose); 1358 *nerrp = nerr & ~(GE_DMA_FATAL | GE_DMA_NF); 1359 } else if ((ferr & (GE_INT_FATAL | GE_INT_NF)) != 0) { 1360 spurious = log_int_err(rp, willpanic, &interpose); 1361 *nerrp = nerr & ~(GE_INT_FATAL | GE_INT_NF); 1362 } else if (nb_chipset == INTEL_NB_5400 && 1363 (ferr & (GE_FERR_THERMAL_FATAL | GE_FERR_THERMAL_NF)) != 0) { 1364 log_thermal_err(rp, willpanic, &interpose); 1365 *nerrp = nerr & ~(GE_FERR_THERMAL_FATAL | GE_FERR_THERMAL_NF); 1366 } 1367 if (interpose) 1368 log->type = "inject"; 1369 else 1370 log->type = "error"; 1371 if (!spurious) { 1372 errorq_dispatch(nb_queue, log, sizeof (nb_logout_t), 1373 willpanic ? ERRORQ_SYNC : ERRORQ_ASYNC); 1374 } 1375 } 1376 1377 static void 1378 log_nerr(uint32_t *errp, nb_logout_t *log, int willpanic) 1379 { 1380 uint32_t err; 1381 nb_regs_t *rp = &log->nb_regs; 1382 int interpose = 0; 1383 int spurious = 0; 1384 1385 err = *errp; 1386 log->acl_timestamp = gethrtime_waitfree(); 1387 if ((err & (GE_PCIEX_FATAL | GE_PCIEX_NF)) != 0) { 1388 *errp = err & ~(GE_PCIEX_FATAL | GE_PCIEX_NF); 1389 if (log_pex_err(err, rp, willpanic, &interpose) == 0) 1390 return; 1391 } else if ((err & GE_NERR_FBD_FATAL) != 0) { 1392 log_fat_fbd_err(rp, willpanic, &interpose); 1393 *errp = err & ~GE_NERR_FBD_FATAL; 1394 } else if ((err & GE_NERR_FBD_NF) != 0) { 1395 log_nf_fbd_err(rp, willpanic, &interpose); 1396 *errp = err & ~GE_NERR_FBD_NF; 1397 } else if ((err & GE_NERR_MEM_NF) != 0) { 1398 spurious = log_nf_mem_err(rp, willpanic, &interpose); 1399 *errp = err & ~GE_NERR_MEM_NF; 1400 } else if ((err & (GE_NERR_FSB_FATAL | GE_NERR_FSB_NF)) != 0) { 1401 log_fsb_err(GE_NERR_TO_FERR_FSB(err), rp, willpanic, 1402 &interpose); 1403 *errp = err & ~(GE_NERR_FSB_FATAL | GE_NERR_FSB_NF); 1404 } else if ((err & (GE_DMA_FATAL | GE_DMA_NF)) != 0) { 1405 log_dma_err(rp, &interpose); 1406 *errp = err & ~(GE_DMA_FATAL | GE_DMA_NF); 1407 } else if ((err & (GE_INT_FATAL | GE_INT_NF)) != 0) { 1408 spurious = log_int_err(rp, willpanic, &interpose); 1409 *errp = err & ~(GE_INT_FATAL | GE_INT_NF); 1410 } 1411 if (interpose) 1412 log->type = "inject"; 1413 else 1414 log->type = "error"; 1415 if (!spurious) { 1416 errorq_dispatch(nb_queue, log, sizeof (nb_logout_t), 1417 willpanic ? ERRORQ_SYNC : ERRORQ_ASYNC); 1418 } 1419 } 1420 1421 /*ARGSUSED*/ 1422 void 1423 nb_error_trap(cmi_hdl_t hdl, boolean_t ismc, boolean_t willpanic) 1424 { 1425 uint64_t ferr; 1426 uint32_t nerr, err; 1427 int nmc = 0; 1428 int i; 1429 1430 if (mutex_tryenter(&nb_mutex) == 0) 1431 return; 1432 1433 nerr = NERR_GLOBAL_RD(); 1434 err = nerr; 1435 for (i = 0; i < NB_MAX_ERRORS; i++) { 1436 ferr = FERR_GLOBAL_RD(); 1437 nb_log.nb_regs.chipset = nb_chipset; 1438 nb_log.nb_regs.ferr = ferr; 1439 nb_log.nb_regs.nerr = nerr; 1440 if (ferr) { 1441 log_ferr(ferr, &err, &nb_log, willpanic); 1442 FERR_GLOBAL_WR(ferr); 1443 nmc++; 1444 } else if (err) { 1445 log_nerr(&err, &nb_log, willpanic); 1446 nmc++; 1447 } 1448 } 1449 if (nerr) { 1450 NERR_GLOBAL_WR(nerr); 1451 } 1452 if (nmc == 0 && nb_mask_mc_set) 1453 nb_mask_mc_reset(); 1454 mutex_exit(&nb_mutex); 1455 } 1456 1457 static void 1458 nb_fsb_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload, 1459 nb_scatchpad_t *data) 1460 { 1461 int intel_error_list; 1462 char buf[32]; 1463 1464 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FSB, 1465 DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.fsb, NULL); 1466 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_FAT_FSB, 1467 DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.ferr_fat_fsb, NULL); 1468 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_FAT_FSB, 1469 DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.nerr_fat_fsb, NULL); 1470 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_FSB, 1471 DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.ferr_nf_fsb, NULL); 1472 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_FSB, 1473 DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.nerr_nf_fsb, NULL); 1474 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFSB, 1475 DATA_TYPE_UINT32, nb_regs->nb.fsb_regs.nrecfsb, NULL); 1476 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFSB_ADDR, 1477 DATA_TYPE_UINT64, nb_regs->nb.fsb_regs.nrecfsb_addr, NULL); 1478 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFSB, 1479 DATA_TYPE_UINT32, nb_regs->nb.fsb_regs.recfsb, NULL); 1480 intel_error_list = data->intel_error_list; 1481 if (intel_error_list >= 0) 1482 (void) snprintf(buf, sizeof (buf), "F%d", intel_error_list); 1483 else 1484 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error"); 1485 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO, 1486 DATA_TYPE_STRING, buf, NULL); 1487 } 1488 1489 static void 1490 nb_pex_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload, 1491 nb_scatchpad_t *data) 1492 { 1493 int intel_error_list; 1494 char buf[32]; 1495 1496 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX, 1497 DATA_TYPE_UINT8, nb_regs->nb.pex_regs.pex, NULL); 1498 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX_FAT_FERR, 1499 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.pex_fat_ferr, NULL); 1500 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX_FAT_NERR, 1501 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.pex_fat_nerr, NULL); 1502 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX_NF_CORR_FERR, 1503 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.pex_nf_corr_ferr, NULL); 1504 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX_NF_CORR_NERR, 1505 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.pex_nf_corr_nerr, NULL); 1506 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_UNCERRSEV, 1507 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.uncerrsev, NULL); 1508 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RPERRSTS, 1509 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.rperrsts, NULL); 1510 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RPERRSID, 1511 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.rperrsid, NULL); 1512 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_UNCERRSTS, 1513 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.uncerrsts, NULL); 1514 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_AERRCAPCTRL, 1515 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.aerrcapctrl, NULL); 1516 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CORERRSTS, 1517 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.corerrsts, NULL); 1518 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEXDEVSTS, 1519 DATA_TYPE_UINT16, nb_regs->nb.pex_regs.pexdevsts, NULL); 1520 intel_error_list = data->intel_error_list; 1521 if (intel_error_list >= 0) 1522 (void) snprintf(buf, sizeof (buf), "IO%d", intel_error_list); 1523 else 1524 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error"); 1525 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO, 1526 DATA_TYPE_STRING, buf, NULL); 1527 } 1528 1529 static void 1530 nb_int_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload, 1531 nb_scatchpad_t *data) 1532 { 1533 int intel_error_list; 1534 char buf[32]; 1535 1536 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_FAT_INT, 1537 DATA_TYPE_UINT16, nb_regs->nb.int_regs.ferr_fat_int, NULL); 1538 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_INT, 1539 DATA_TYPE_UINT16, nb_regs->nb.int_regs.ferr_nf_int, NULL); 1540 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_FAT_INT, 1541 DATA_TYPE_UINT16, nb_regs->nb.int_regs.nerr_fat_int, NULL); 1542 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_INT, 1543 DATA_TYPE_UINT16, nb_regs->nb.int_regs.nerr_nf_int, NULL); 1544 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECINT, 1545 DATA_TYPE_UINT32, nb_regs->nb.int_regs.nrecint, NULL); 1546 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECINT, 1547 DATA_TYPE_UINT32, nb_regs->nb.int_regs.recint, NULL); 1548 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECSF, 1549 DATA_TYPE_UINT64, nb_regs->nb.int_regs.nrecsf, NULL); 1550 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECSF, 1551 DATA_TYPE_UINT64, nb_regs->nb.int_regs.recsf, NULL); 1552 intel_error_list = data->intel_error_list; 1553 if (intel_error_list >= 0) 1554 (void) snprintf(buf, sizeof (buf), "B%d", intel_error_list); 1555 else 1556 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error"); 1557 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO, 1558 DATA_TYPE_STRING, buf, NULL); 1559 } 1560 1561 static void 1562 nb_fat_fbd_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload, 1563 nb_scatchpad_t *data) 1564 { 1565 nb_mem_scatchpad_t *sp; 1566 char buf[32]; 1567 1568 sp = &((nb_scatchpad_t *)data)->ms; 1569 1570 if (sp->ras != -1) { 1571 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BANK, 1572 DATA_TYPE_INT32, sp->bank, NULL); 1573 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CAS, 1574 DATA_TYPE_INT32, sp->cas, NULL); 1575 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RAS, 1576 DATA_TYPE_INT32, sp->ras, NULL); 1577 if (sp->offset != -1LL) { 1578 fm_payload_set(payload, FM_FMRI_MEM_OFFSET, 1579 DATA_TYPE_UINT64, sp->offset, NULL); 1580 } 1581 if (sp->pa != -1LL) { 1582 fm_payload_set(payload, FM_FMRI_MEM_PHYSADDR, 1583 DATA_TYPE_UINT64, sp->pa, NULL); 1584 } 1585 } 1586 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_FAT_FBD, 1587 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.ferr_fat_fbd, NULL); 1588 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_FAT_FBD, 1589 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nerr_fat_fbd, NULL); 1590 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECMEMA, 1591 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecmema, NULL); 1592 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECMEMB, 1593 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecmemb, NULL); 1594 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFGLOG, 1595 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfglog, NULL); 1596 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDA, 1597 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbda, NULL); 1598 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDB, 1599 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbdb, NULL); 1600 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDC, 1601 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbdc, NULL); 1602 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDD, 1603 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbdd, NULL); 1604 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDE, 1605 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbde, NULL); 1606 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDF, 1607 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbdf, NULL); 1608 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPS, 1609 DATA_TYPE_UINT8, nb_regs->nb.fat_fbd_regs.spcps, NULL); 1610 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPC, 1611 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.spcpc, NULL); 1612 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_UERRCNT, 1613 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.uerrcnt, NULL); 1614 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_UERRCNT_LAST, 1615 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.uerrcnt_last, NULL); 1616 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAMA, 1617 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.badrama, NULL); 1618 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAMB, 1619 DATA_TYPE_UINT16, nb_regs->nb.fat_fbd_regs.badramb, NULL); 1620 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADCNT, 1621 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.badcnt, NULL); 1622 1623 if (sp->intel_error_list >= 0) 1624 (void) snprintf(buf, sizeof (buf), "M%d", sp->intel_error_list); 1625 else 1626 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error"); 1627 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO, 1628 DATA_TYPE_STRING, buf, NULL); 1629 } 1630 1631 static void 1632 nb_nf_fbd_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload, 1633 nb_scatchpad_t *data) 1634 { 1635 nb_mem_scatchpad_t *sp; 1636 char buf[32]; 1637 1638 sp = &((nb_scatchpad_t *)data)->ms; 1639 1640 if (sp->dimm == -1 && sp->rank != -1) { 1641 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RANK, 1642 DATA_TYPE_INT32, sp->rank, NULL); 1643 } 1644 if (sp->ras != -1) { 1645 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BANK, 1646 DATA_TYPE_INT32, sp->bank, NULL); 1647 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CAS, 1648 DATA_TYPE_INT32, sp->cas, NULL); 1649 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RAS, 1650 DATA_TYPE_INT32, sp->ras, NULL); 1651 if (sp->offset != -1LL) { 1652 fm_payload_set(payload, FM_FMRI_MEM_OFFSET, 1653 DATA_TYPE_UINT64, sp->offset, NULL); 1654 } 1655 if (sp->pa != -1LL) { 1656 fm_payload_set(payload, FM_FMRI_MEM_PHYSADDR, 1657 DATA_TYPE_UINT64, sp->pa, NULL); 1658 } 1659 } 1660 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_FBD, 1661 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.ferr_nf_fbd, NULL); 1662 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_FBD, 1663 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.nerr_nf_fbd, NULL); 1664 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECMEMA, 1665 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recmema, NULL); 1666 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECMEMB, 1667 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recmemb, NULL); 1668 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFGLOG, 1669 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfglog, NULL); 1670 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDA, 1671 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbda, NULL); 1672 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDB, 1673 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbdb, NULL); 1674 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDC, 1675 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbdc, NULL); 1676 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDD, 1677 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbdd, NULL); 1678 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDE, 1679 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbde, NULL); 1680 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDF, 1681 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbdf, NULL); 1682 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPS, 1683 DATA_TYPE_UINT8, nb_regs->nb.nf_fbd_regs.spcps, NULL); 1684 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPC, 1685 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.spcpc, NULL); 1686 if (nb_chipset == INTEL_NB_7300 || nb_chipset == INTEL_NB_5400) { 1687 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNTA, 1688 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcnta, NULL); 1689 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNTB, 1690 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcntb, NULL); 1691 if (nb_chipset == INTEL_NB_7300) { 1692 fm_payload_set(payload, 1693 FM_EREPORT_PAYLOAD_NAME_CERRCNTC, 1694 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcntc, 1695 NULL); 1696 fm_payload_set(payload, 1697 FM_EREPORT_PAYLOAD_NAME_CERRCNTD, 1698 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcntd, 1699 NULL); 1700 } 1701 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNTA_LAST, 1702 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcnta_last, 1703 NULL); 1704 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNTB_LAST, 1705 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcntb_last, 1706 NULL); 1707 if (nb_chipset == INTEL_NB_7300) { 1708 fm_payload_set(payload, 1709 FM_EREPORT_PAYLOAD_NAME_CERRCNTC_LAST, 1710 DATA_TYPE_UINT32, 1711 nb_regs->nb.nf_fbd_regs.cerrcntc_last, NULL); 1712 fm_payload_set(payload, 1713 FM_EREPORT_PAYLOAD_NAME_CERRCNTD_LAST, 1714 DATA_TYPE_UINT32, 1715 nb_regs->nb.nf_fbd_regs.cerrcntd_last, NULL); 1716 } 1717 } else { 1718 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT, 1719 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcnta, NULL); 1720 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT_LAST, 1721 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcnta_last, 1722 NULL); 1723 } 1724 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAMA, 1725 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.badrama, NULL); 1726 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAMB, 1727 DATA_TYPE_UINT16, nb_regs->nb.nf_fbd_regs.badramb, NULL); 1728 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADCNT, 1729 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.badcnt, NULL); 1730 1731 if (sp->intel_error_list >= 0) 1732 (void) snprintf(buf, sizeof (buf), "M%d", sp->intel_error_list); 1733 else 1734 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error"); 1735 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO, 1736 DATA_TYPE_STRING, buf, NULL); 1737 } 1738 1739 static void 1740 nb_nf_mem_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload, 1741 nb_scatchpad_t *data) 1742 { 1743 nb_mem_scatchpad_t *sp; 1744 char buf[32]; 1745 1746 sp = &((nb_scatchpad_t *)data)->ms; 1747 1748 if (sp->dimm == -1 && sp->rank != -1) { 1749 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RANK, 1750 DATA_TYPE_INT32, sp->rank, NULL); 1751 } 1752 if (sp->ras != -1) { 1753 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BANK, 1754 DATA_TYPE_INT32, sp->bank, NULL); 1755 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CAS, 1756 DATA_TYPE_INT32, sp->cas, NULL); 1757 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RAS, 1758 DATA_TYPE_INT32, sp->ras, NULL); 1759 if (sp->offset != -1LL) { 1760 fm_payload_set(payload, FM_FMRI_MEM_OFFSET, 1761 DATA_TYPE_UINT64, sp->offset, NULL); 1762 } 1763 if (sp->pa != -1LL) { 1764 fm_payload_set(payload, FM_FMRI_MEM_PHYSADDR, 1765 DATA_TYPE_UINT64, sp->pa, NULL); 1766 } 1767 } 1768 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_MEM, 1769 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.ferr_nf_mem, NULL); 1770 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_MEM, 1771 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.nerr_nf_mem, NULL); 1772 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECMEMA, 1773 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.recmema, NULL); 1774 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECMEMB, 1775 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.recmemb, NULL); 1776 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_REDMEMA, 1777 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.redmema, NULL); 1778 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_REDMEMB, 1779 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.redmemb, NULL); 1780 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECMEMA, 1781 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.nrecmema, NULL); 1782 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECMEMB, 1783 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.nrecmemb, NULL); 1784 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPS, 1785 DATA_TYPE_UINT8, nb_regs->nb.nf_mem_regs.spcps, NULL); 1786 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPC, 1787 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.spcpc, NULL); 1788 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT, 1789 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.cerrcnt, NULL); 1790 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT_LAST, 1791 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.cerrcnt_last, NULL); 1792 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT_EXT, 1793 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.cerrcnt_ext, NULL); 1794 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT_EXT_LAST, 1795 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.cerrcnt_ext_last, NULL); 1796 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAM, 1797 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.badram, NULL); 1798 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADCNT, 1799 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.badcnt, NULL); 1800 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_VALIDLOG, 1801 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.validlog, NULL); 1802 1803 if (sp->intel_error_list >= 0) 1804 (void) snprintf(buf, sizeof (buf), "M%d", sp->intel_error_list); 1805 else 1806 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error"); 1807 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO, 1808 DATA_TYPE_STRING, buf, NULL); 1809 } 1810 1811 static void 1812 nb_dma_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload) 1813 { 1814 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PCISTS, 1815 DATA_TYPE_UINT16, nb_regs->nb.dma_regs.pcists, NULL); 1816 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEXDEVSTS, 1817 DATA_TYPE_UINT16, nb_regs->nb.dma_regs.pexdevsts, NULL); 1818 } 1819 1820 static void 1821 nb_thr_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload, 1822 nb_scatchpad_t *data) 1823 { 1824 char buf[32]; 1825 1826 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_FAT_THR, 1827 DATA_TYPE_UINT8, nb_regs->nb.thr_regs.ferr_fat_thr, NULL); 1828 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_FAT_THR, 1829 DATA_TYPE_UINT8, nb_regs->nb.thr_regs.nerr_fat_thr, NULL); 1830 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_THR, 1831 DATA_TYPE_UINT8, nb_regs->nb.thr_regs.ferr_nf_thr, NULL); 1832 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_THR, 1833 DATA_TYPE_UINT8, nb_regs->nb.thr_regs.nerr_nf_thr, NULL); 1834 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CTSTS, 1835 DATA_TYPE_UINT8, nb_regs->nb.thr_regs.ctsts, NULL); 1836 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_THRTSTS, 1837 DATA_TYPE_UINT16, nb_regs->nb.thr_regs.thrtsts, NULL); 1838 if (data->intel_error_list >= 0) { 1839 (void) snprintf(buf, sizeof (buf), "TH%d", 1840 data->intel_error_list); 1841 } else { 1842 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error"); 1843 } 1844 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO, 1845 DATA_TYPE_STRING, buf, NULL); 1846 } 1847 1848 static void 1849 nb_ereport_add_logout(nvlist_t *payload, const nb_logout_t *acl, 1850 nb_scatchpad_t *data) 1851 { 1852 const nb_regs_t *nb_regs = &acl->nb_regs; 1853 1854 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_MC_TYPE, 1855 DATA_TYPE_STRING, acl->type, NULL); 1856 switch (nb_regs->flag) { 1857 case NB_REG_LOG_FSB: 1858 nb_fsb_err_payload(nb_regs, payload, data); 1859 break; 1860 case NB_REG_LOG_PEX: 1861 nb_pex_err_payload(nb_regs, payload, data); 1862 break; 1863 case NB_REG_LOG_INT: 1864 nb_int_err_payload(nb_regs, payload, data); 1865 break; 1866 case NB_REG_LOG_FAT_FBD: 1867 nb_fat_fbd_err_payload(nb_regs, payload, data); 1868 break; 1869 case NB_REG_LOG_NF_FBD: 1870 nb_nf_fbd_err_payload(nb_regs, payload, data); 1871 break; 1872 case NB_REG_LOG_DMA: 1873 nb_dma_err_payload(nb_regs, payload); 1874 break; 1875 case NB_REG_LOG_THR: 1876 nb_thr_err_payload(nb_regs, payload, data); 1877 break; 1878 case NB_REG_LOG_NF_MEM: 1879 nb_nf_mem_err_payload(nb_regs, payload, data); 1880 break; 1881 default: 1882 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_GLOBAL, 1883 DATA_TYPE_UINT64, nb_regs->ferr, NULL); 1884 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_GLOBAL, 1885 DATA_TYPE_UINT32, nb_regs->nerr, NULL); 1886 break; 1887 } 1888 } 1889 1890 void 1891 nb_fsb_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector, 1892 nb_scatchpad_t *data) 1893 { 1894 int chip; 1895 1896 if (nb_chipset == INTEL_NB_7300) 1897 chip = nb_regs->nb.fsb_regs.fsb * 2; 1898 else 1899 chip = nb_regs->nb.fsb_regs.fsb; 1900 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2, 1901 "motherboard", 0, "chip", chip); 1902 1903 if (nb_regs->nb.fsb_regs.ferr_fat_fsb == 0 && 1904 nb_regs->nb.fsb_regs.ferr_nf_fsb == 0) { 1905 data->intel_error_list = intel_fsb_err(nb_regs->nb.fsb_regs.fsb, 1906 nb_regs->nb.fsb_regs.nerr_fat_fsb, 1907 nb_regs->nb.fsb_regs.nerr_nf_fsb); 1908 } else { 1909 data->intel_error_list = intel_fsb_err(nb_regs->nb.fsb_regs.fsb, 1910 nb_regs->nb.fsb_regs.ferr_fat_fsb, 1911 nb_regs->nb.fsb_regs.ferr_nf_fsb); 1912 } 1913 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s", 1914 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "fsb"); 1915 } 1916 1917 void 1918 nb_pex_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector, 1919 nb_scatchpad_t *data) 1920 { 1921 int hostbridge; 1922 1923 if (nb_regs->nb.pex_regs.pex == 0) { 1924 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 1925 "motherboard", 0); 1926 } else { 1927 hostbridge = nb_regs->nb.pex_regs.pex - 1; 1928 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2, 1929 "motherboard", 0, 1930 "hostbridge", hostbridge); 1931 } 1932 1933 if (nb_regs->nb.pex_regs.pex_fat_ferr == 0 && 1934 nb_regs->nb.pex_regs.pex_nf_corr_ferr == 0) { 1935 if (nb_chipset == INTEL_NB_5400) { 1936 data->intel_error_list = 1937 intel_pex_5400_err( 1938 nb_regs->nb.pex_regs.pex_fat_nerr, 1939 nb_regs->nb.pex_regs.pex_nf_corr_nerr); 1940 } else { 1941 data->intel_error_list = 1942 intel_pex_err(nb_regs->nb.pex_regs.pex_fat_nerr, 1943 nb_regs->nb.pex_regs.pex_nf_corr_nerr); 1944 } 1945 } else { 1946 if (nb_chipset == INTEL_NB_5400) { 1947 data->intel_error_list = 1948 intel_pex_5400_err( 1949 nb_regs->nb.pex_regs.pex_fat_ferr, 1950 nb_regs->nb.pex_regs.pex_nf_corr_ferr); 1951 } else { 1952 data->intel_error_list = 1953 intel_pex_err(nb_regs->nb.pex_regs.pex_fat_ferr, 1954 nb_regs->nb.pex_regs.pex_nf_corr_ferr); 1955 } 1956 } 1957 1958 if (nb_regs->nb.pex_regs.pex == 0) { 1959 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s", 1960 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "esi"); 1961 } else { 1962 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s", 1963 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "pex"); 1964 } 1965 } 1966 1967 void 1968 nb_int_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector, 1969 void *data) 1970 { 1971 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 1972 "motherboard", 0); 1973 1974 if (nb_regs->nb.int_regs.ferr_fat_int == 0 && 1975 nb_regs->nb.int_regs.ferr_nf_int == 0) { 1976 ((nb_scatchpad_t *)data)->intel_error_list = 1977 intel_int_err(nb_regs->nb.int_regs.nerr_fat_int, 1978 nb_regs->nb.int_regs.nerr_nf_int); 1979 } else { 1980 ((nb_scatchpad_t *)data)->intel_error_list = 1981 intel_int_err(nb_regs->nb.int_regs.ferr_fat_int, 1982 nb_regs->nb.int_regs.ferr_nf_int); 1983 } 1984 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s", 1985 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "ie"); 1986 } 1987 1988 void 1989 nb_fat_fbd_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector, 1990 void *data) 1991 { 1992 char *intr; 1993 nb_mem_scatchpad_t *sp; 1994 1995 intr = fat_memory_error(nb_regs, data); 1996 sp = &((nb_scatchpad_t *)data)->ms; 1997 1998 if (sp->dimm != -1) { 1999 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 5, 2000 "motherboard", 0, 2001 "memory-controller", sp->branch, 2002 "dram-channel", sp->channel, 2003 "dimm", sp->dimm, 2004 "rank", sp->rank); 2005 } else if (sp->channel != -1) { 2006 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 3, 2007 "motherboard", 0, 2008 "memory-controller", sp->branch, 2009 "dram-channel", sp->channel); 2010 } else if (sp->branch != -1) { 2011 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2, 2012 "motherboard", 0, 2013 "memory-controller", sp->branch); 2014 } else { 2015 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 2016 "motherboard", 0); 2017 } 2018 2019 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s", 2020 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, intr); 2021 } 2022 2023 void 2024 nb_nf_fbd_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector, 2025 void *data) 2026 { 2027 char *intr; 2028 nb_mem_scatchpad_t *sp; 2029 2030 intr = nf_memory_error(nb_regs, data); 2031 sp = &((nb_scatchpad_t *)data)->ms; 2032 2033 if (sp->dimm != -1) { 2034 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 5, 2035 "motherboard", 0, 2036 "memory-controller", sp->branch, 2037 "dram-channel", sp->channel, 2038 "dimm", sp->dimm, 2039 "rank", sp->rank); 2040 } else if (sp->channel != -1) { 2041 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 3, 2042 "motherboard", 0, 2043 "memory-controller", sp->branch, 2044 "dram-channel", sp->channel); 2045 } else if (sp->branch != -1) { 2046 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2, 2047 "motherboard", 0, 2048 "memory-controller", sp->branch); 2049 } else { 2050 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 2051 "motherboard", 0); 2052 } 2053 2054 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s", 2055 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, intr); 2056 } 2057 2058 void 2059 nb_dma_report(char *class, nvlist_t *detector) 2060 { 2061 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 2062 "motherboard", 0); 2063 2064 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s", 2065 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "dma"); 2066 } 2067 2068 void 2069 nb_thr_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector, 2070 void *data) 2071 { 2072 ((nb_scatchpad_t *)data)->intel_error_list = 2073 intel_thr_err(nb_regs->nb.thr_regs.ferr_fat_thr, 2074 nb_regs->nb.thr_regs.ferr_nf_thr); 2075 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 2076 "motherboard", 0); 2077 2078 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s", 2079 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "otf"); 2080 } 2081 2082 void 2083 nb_nf_mem_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector, 2084 void *data) 2085 { 2086 char *intr; 2087 nb_mem_scatchpad_t *sp; 2088 2089 intr = nf_mem_error(nb_regs, data); 2090 sp = &((nb_scatchpad_t *)data)->ms; 2091 2092 if (sp->dimm != -1) { 2093 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 5, 2094 "motherboard", 0, 2095 "memory-controller", sp->branch, 2096 "dram-channel", sp->channel, 2097 "dimm", sp->dimm, 2098 "rank", sp->rank); 2099 } else if (sp->channel != -1) { 2100 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 3, 2101 "motherboard", 0, 2102 "memory-controller", sp->branch, 2103 "dram-channel", sp->channel); 2104 } else if (sp->branch != -1) { 2105 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2, 2106 "motherboard", 0, 2107 "memory-controller", sp->branch); 2108 } else { 2109 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 2110 "motherboard", 0); 2111 } 2112 2113 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s", 2114 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, intr); 2115 } 2116 2117 2118 nvlist_t * 2119 nb_report(const nb_regs_t *nb_regs, char *class, nv_alloc_t *nva, void *scratch) 2120 { 2121 nvlist_t *detector = fm_nvlist_create(nva); 2122 2123 switch (nb_regs->flag) { 2124 case NB_REG_LOG_FSB: 2125 nb_fsb_report(nb_regs, class, detector, scratch); 2126 break; 2127 case NB_REG_LOG_PEX: 2128 nb_pex_report(nb_regs, class, detector, scratch); 2129 break; 2130 case NB_REG_LOG_INT: 2131 nb_int_report(nb_regs, class, detector, scratch); 2132 break; 2133 case NB_REG_LOG_FAT_FBD: 2134 nb_fat_fbd_report(nb_regs, class, detector, scratch); 2135 break; 2136 case NB_REG_LOG_NF_FBD: 2137 nb_nf_fbd_report(nb_regs, class, detector, scratch); 2138 break; 2139 case NB_REG_LOG_DMA: 2140 nb_dma_report(class, detector); 2141 break; 2142 case NB_REG_LOG_THR: 2143 nb_thr_report(nb_regs, class, detector, scratch); 2144 break; 2145 case NB_REG_LOG_NF_MEM: 2146 nb_nf_mem_report(nb_regs, class, detector, scratch); 2147 break; 2148 default: 2149 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1, 2150 "motherboard", 0); 2151 2152 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s", 2153 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "unknown"); 2154 } 2155 return (detector); 2156 } 2157 2158 /*ARGSUSED*/ 2159 void 2160 nb_drain(void *ignored, const void *data, const errorq_elem_t *eqe) 2161 { 2162 nb_logout_t *acl = (nb_logout_t *)data; 2163 errorq_elem_t *eqep, *scr_eqep; 2164 nvlist_t *ereport, *detector; 2165 nv_alloc_t *nva = NULL; 2166 char buf[FM_MAX_CLASS]; 2167 nb_scatchpad_t nb_scatchpad; 2168 2169 eqep = NULL; 2170 scr_eqep = NULL; 2171 if (panicstr) { 2172 if ((eqep = errorq_reserve(ereport_errorq)) == NULL) 2173 return; 2174 ereport = errorq_elem_nvl(ereport_errorq, eqep); 2175 /* 2176 * Now try to allocate another element for scratch space and 2177 * use that for further scratch space (eg for constructing 2178 * nvlists to add the main ereport). If we can't reserve 2179 * a scratch element just fallback to working within the 2180 * element we already have, and hope for the best. All this 2181 * is necessary because the fixed buffer nv allocator does 2182 * not reclaim freed space and nvlist construction is 2183 * expensive. 2184 */ 2185 if ((scr_eqep = errorq_reserve(ereport_errorq)) != NULL) 2186 nva = errorq_elem_nva(ereport_errorq, scr_eqep); 2187 else 2188 nva = errorq_elem_nva(ereport_errorq, eqep); 2189 } else { 2190 ereport = fm_nvlist_create(NULL); 2191 } 2192 detector = nb_report(&acl->nb_regs, buf, nva, &nb_scatchpad); 2193 if (detector == NULL) 2194 return; 2195 fm_ereport_set(ereport, FM_EREPORT_VERSION, buf, 2196 fm_ena_generate(acl->acl_timestamp, FM_ENA_FMT1), detector, NULL); 2197 /* 2198 * We're done with 'detector' so reclaim the scratch space. 2199 */ 2200 if (panicstr) { 2201 fm_nvlist_destroy(detector, FM_NVA_RETAIN); 2202 nv_alloc_reset(nva); 2203 } else { 2204 fm_nvlist_destroy(detector, FM_NVA_FREE); 2205 } 2206 2207 /* 2208 * Encode the error-specific data that was saved in the logout area. 2209 */ 2210 nb_ereport_add_logout(ereport, acl, &nb_scatchpad); 2211 2212 if (panicstr) { 2213 errorq_commit(ereport_errorq, eqep, ERRORQ_SYNC); 2214 if (scr_eqep) 2215 errorq_cancel(ereport_errorq, scr_eqep); 2216 } else { 2217 (void) fm_ereport_post(ereport, EVCH_TRYHARD); 2218 fm_nvlist_destroy(ereport, FM_NVA_FREE); 2219 } 2220 } 2221