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 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/types.h> 30 #include <sys/cmn_err.h> 31 #include <sys/errno.h> 32 #include <sys/log.h> 33 #include <sys/systm.h> 34 #include <sys/modctl.h> 35 #include <sys/errorq.h> 36 #include <sys/controlregs.h> 37 #include <sys/fm/util.h> 38 #include <sys/fm/protocol.h> 39 #include <sys/sysevent.h> 40 #include <sys/pghw.h> 41 #include <sys/cyclic.h> 42 #include <sys/pci_cfgspace.h> 43 #include <sys/mc_intel.h> 44 #include <sys/cpu_module_impl.h> 45 #include <sys/smbios.h> 46 #include <sys/pci.h> 47 #include <sys/machsystm.h> 48 #include "nb5000.h" 49 #include "nb_log.h" 50 #include "dimm_phys.h" 51 #include "rank.h" 52 53 int nb_hw_memory_scrub_enable = 1; 54 static int nb_sw_scrub_disabled = 0; 55 56 int nb_5000_memory_controller = 0; 57 int nb_number_memory_controllers = NB_5000_MAX_MEM_CONTROLLERS; 58 int nb_dimms_per_channel = 0; 59 static int ndimms = 0; 60 61 nb_dimm_t **nb_dimms; 62 int nb_ndimm; 63 uint32_t nb_chipset; 64 enum nb_memory_mode nb_mode; 65 bank_select_t nb_banks[NB_MAX_MEM_BRANCH_SELECT]; 66 rank_select_t nb_ranks[NB_5000_MAX_MEM_CONTROLLERS][NB_MAX_MEM_RANK_SELECT]; 67 uint32_t top_of_low_memory; 68 uint8_t spare_rank[NB_5000_MAX_MEM_CONTROLLERS]; 69 70 errorq_t *nb_queue; 71 kmutex_t nb_mutex; 72 73 static uint8_t nb_err0_int; 74 static uint8_t nb_err1_int; 75 static uint8_t nb_err2_int; 76 static uint8_t nb_mcerr_int; 77 static uint32_t nb_emask_int; 78 79 static uint32_t nb_err0_fbd; 80 static uint32_t nb_err1_fbd; 81 static uint32_t nb_err2_fbd; 82 static uint32_t nb_mcerr_fbd; 83 static uint32_t nb_emask_fbd; 84 85 static uint16_t nb_err0_fsb; 86 static uint16_t nb_err1_fsb; 87 static uint16_t nb_err2_fsb; 88 static uint16_t nb_mcerr_fsb; 89 static uint16_t nb_emask_fsb; 90 91 static uint16_t nb_err0_thr; 92 static uint16_t nb_err1_thr; 93 static uint16_t nb_err2_thr; 94 static uint16_t nb_mcerr_thr; 95 static uint16_t nb_emask_thr; 96 97 static uint32_t emask_uncor_pex[NB_PCI_DEV]; 98 static uint32_t emask_cor_pex[NB_PCI_DEV]; 99 static uint32_t emask_rp_pex[NB_PCI_DEV]; 100 static uint32_t docmd_pex[NB_PCI_DEV]; 101 static uint32_t uncerrsev[NB_PCI_DEV]; 102 103 static uint8_t l_mcerr_int; 104 static uint32_t l_mcerr_fbd; 105 static uint16_t l_mcerr_fsb; 106 static uint16_t l_mcerr_thr; 107 108 uint_t nb5000_emask_fbd = EMASK_5000_FBD_RES; 109 uint_t nb5400_emask_fbd = 0; 110 int nb5000_reset_emask_fbd = 1; 111 uint_t nb5000_mask_poll_fbd = EMASK_FBD_NF; 112 uint_t nb5000_mask_bios_fbd = EMASK_FBD_FATAL; 113 uint_t nb5400_mask_poll_fbd = EMASK_5400_FBD_NF; 114 uint_t nb5400_mask_bios_fbd = EMASK_5400_FBD_FATAL; 115 116 uint_t nb5000_emask_fsb = 0; 117 int nb5000_reset_emask_fsb = 1; 118 uint_t nb5000_mask_poll_fsb = EMASK_FSB_NF; 119 uint_t nb5000_mask_bios_fsb = EMASK_FSB_FATAL; 120 121 uint_t nb5400_emask_int = 0; 122 123 uint_t nb7300_emask_int = EMASK_INT_7300; 124 uint_t nb7300_emask_int_step0 = EMASK_INT_7300_STEP_0; 125 uint_t nb5000_emask_int = EMASK_INT_5000; 126 int nb5000_reset_emask_int = 1; 127 uint_t nb5000_mask_poll_int = EMASK_INT_NF; 128 uint_t nb5000_mask_bios_int = EMASK_INT_FATAL; 129 130 uint_t nb_mask_poll_thr = EMASK_THR_NF; 131 uint_t nb_mask_bios_thr = EMASK_THR_FATAL; 132 133 int nb5000_reset_uncor_pex = 0; 134 uint_t nb5000_mask_uncor_pex = 0; 135 int nb5000_reset_cor_pex = 0; 136 uint_t nb5000_mask_cor_pex = 0xffffffff; 137 int nb_set_docmd = 1; 138 uint32_t nb5000_docmd_pex_mask = DOCMD_PEX_MASK; 139 uint32_t nb5400_docmd_pex_mask = DOCMD_5400_PEX_MASK; 140 uint32_t nb5000_docmd_pex = DOCMD_PEX; 141 uint32_t nb5400_docmd_pex = DOCMD_5400_PEX; 142 143 int nb_mask_mc_set; 144 145 typedef struct find_dimm_label { 146 void (*label_function)(int, char *, int); 147 } find_dimm_label_t; 148 149 static void x8450_dimm_label(int, char *, int); 150 151 static struct platform_label { 152 const char *sys_vendor; /* SMB_TYPE_SYSTEM vendor prefix */ 153 const char *sys_product; /* SMB_TYPE_SYSTEM product prefix */ 154 find_dimm_label_t dimm_label; 155 int dimms_per_channel; 156 } platform_label[] = { 157 { "SUN MICROSYSTEMS", "SUN BLADE X8450 SERVER MODULE", 158 x8450_dimm_label, 8 }, 159 { NULL, NULL, NULL, 0 } 160 }; 161 162 static unsigned short 163 read_spd(int bus) 164 { 165 unsigned short rt = 0; 166 int branch = bus >> 1; 167 int channel = bus & 1; 168 169 rt = SPD_RD(branch, channel); 170 171 return (rt); 172 } 173 174 static void 175 write_spdcmd(int bus, uint32_t val) 176 { 177 int branch = bus >> 1; 178 int channel = bus & 1; 179 SPDCMD_WR(branch, channel, val); 180 } 181 182 static int 183 read_spd_eeprom(int bus, int slave, int addr) 184 { 185 int retry = 4; 186 int wait; 187 int spd; 188 uint32_t cmd; 189 190 for (;;) { 191 wait = 1000; 192 for (;;) { 193 spd = read_spd(bus); 194 if ((spd & SPD_BUSY) == 0) 195 break; 196 if (--wait == 0) 197 return (-1); 198 drv_usecwait(10); 199 } 200 cmd = SPD_EEPROM_WRITE | SPD_ADDR(slave, addr); 201 write_spdcmd(bus, cmd); 202 wait = 1000; 203 for (;;) { 204 spd = read_spd(bus); 205 if ((spd & SPD_BUSY) == 0) 206 break; 207 if (--wait == 0) { 208 spd = SPD_BUS_ERROR; 209 break; 210 } 211 drv_usecwait(10); 212 } 213 while ((spd & SPD_BUS_ERROR) == 0 && 214 (spd & (SPD_READ_DATA_VALID|SPD_BUSY)) != 215 SPD_READ_DATA_VALID) { 216 spd = read_spd(bus); 217 if (--wait == 0) 218 return (-1); 219 } 220 if ((spd & SPD_BUS_ERROR) == 0) 221 break; 222 if (--retry == 0) 223 return (-1); 224 } 225 return (spd & 0xff); 226 } 227 228 static void 229 nb_fini() 230 { 231 int i, j; 232 int nchannels = nb_number_memory_controllers * 2; 233 nb_dimm_t **dimmpp; 234 nb_dimm_t *dimmp; 235 236 dimmpp = nb_dimms; 237 for (i = 0; i < nchannels; i++) { 238 for (j = 0; j < nb_dimms_per_channel; j++) { 239 dimmp = *dimmpp; 240 if (dimmp) { 241 kmem_free(dimmp, sizeof (nb_dimm_t)); 242 *dimmpp = NULL; 243 } 244 dimmp++; 245 } 246 } 247 kmem_free(nb_dimms, sizeof (nb_dimm_t *) * 248 nb_number_memory_controllers * 2 * nb_dimms_per_channel); 249 nb_dimms = NULL; 250 dimm_fini(); 251 } 252 253 void 254 nb_scrubber_enable() 255 { 256 uint32_t mc; 257 258 if (!nb_hw_memory_scrub_enable) 259 return; 260 261 mc = MC_RD(); 262 if ((mc & MC_MIRROR) != 0) /* mirror mode */ 263 mc |= MC_PATROL_SCRUB; 264 else 265 mc |= MC_PATROL_SCRUB|MC_DEMAND_SCRUB; 266 MC_WR(mc); 267 268 if (nb_sw_scrub_disabled++) 269 memscrub_disable(); 270 } 271 272 static nb_dimm_t * 273 nb_dimm_init(int channel, int dimm, uint16_t mtr) 274 { 275 nb_dimm_t *dp; 276 int i, t; 277 int spd_sz; 278 279 if (MTR_PRESENT(mtr) == 0) 280 return (NULL); 281 t = read_spd_eeprom(channel, dimm, 2) & 0xf; 282 283 if (t != 9) 284 return (NULL); 285 286 dp = kmem_zalloc(sizeof (nb_dimm_t), KM_SLEEP); 287 288 t = read_spd_eeprom(channel, dimm, 0) & 0xf; 289 if (t == 1) 290 spd_sz = 128; 291 else if (t == 2) 292 spd_sz = 176; 293 else 294 spd_sz = 256; 295 dp->manufacture_id = read_spd_eeprom(channel, dimm, 117) | 296 (read_spd_eeprom(channel, dimm, 118) << 8); 297 dp->manufacture_location = read_spd_eeprom(channel, dimm, 119); 298 dp->serial_number = 299 (read_spd_eeprom(channel, dimm, 122) << 24) | 300 (read_spd_eeprom(channel, dimm, 123) << 16) | 301 (read_spd_eeprom(channel, dimm, 124) << 8) | 302 read_spd_eeprom(channel, dimm, 125); 303 t = read_spd_eeprom(channel, dimm, 121); 304 dp->manufacture_week = (t >> 4) * 10 + (t & 0xf); 305 dp->manufacture_year = read_spd_eeprom(channel, dimm, 120); 306 if (spd_sz > 128) { 307 for (i = 0; i < sizeof (dp->part_number); i++) { 308 dp->part_number[i] = 309 read_spd_eeprom(channel, dimm, 128 + i); 310 } 311 for (i = 0; i < sizeof (dp->revision); i++) { 312 dp->revision[i] = 313 read_spd_eeprom(channel, dimm, 146 + i); 314 } 315 } 316 dp->mtr_present = MTR_PRESENT(mtr); 317 dp->nranks = MTR_NUMRANK(mtr); 318 dp->nbanks = MTR_NUMBANK(mtr); 319 dp->ncolumn = MTR_NUMCOL(mtr); 320 dp->nrow = MTR_NUMROW(mtr); 321 dp->width = MTR_WIDTH(mtr); 322 dp->dimm_size = MTR_DIMMSIZE(mtr); 323 324 return (dp); 325 } 326 327 static uint64_t 328 mc_range(int controller, uint64_t base) 329 { 330 int i; 331 uint64_t limit = 0; 332 333 for (i = 0; i < NB_MEM_BRANCH_SELECT; i++) { 334 if (nb_banks[i].way[controller] && base >= nb_banks[i].base && 335 base < nb_banks[i].limit) { 336 limit = nb_banks[i].limit; 337 if (base <= top_of_low_memory && 338 limit > top_of_low_memory) { 339 limit -= TLOW_MAX - top_of_low_memory; 340 } 341 if (nb_banks[i].way[0] && nb_banks[i].way[1] && 342 nb_mode != NB_MEMORY_MIRROR) { 343 limit = limit / 2; 344 } 345 } 346 } 347 return (limit); 348 } 349 350 void 351 nb_mc_init() 352 { 353 uint16_t tolm; 354 uint16_t mir; 355 uint32_t hole_base; 356 uint32_t hole_size; 357 uint32_t dmir; 358 uint64_t base; 359 uint64_t limit; 360 uint8_t way0, way1, rank0, rank1, rank2, rank3, branch_interleave; 361 int i, j, k; 362 uint8_t interleave; 363 364 base = 0; 365 tolm = TOLM_RD(); 366 top_of_low_memory = ((uint32_t)(tolm >> 12) & 0xf) << 28; 367 for (i = 0; i < NB_MEM_BRANCH_SELECT; i++) { 368 mir = MIR_RD(i); 369 limit = (uint64_t)(mir >> 4) << 28; 370 way0 = mir & 1; 371 way1 = (mir >> 1) & 1; 372 if (way0 == 0 && way1 == 0) { 373 way0 = 1; 374 way1 = 1; 375 } 376 if (limit > top_of_low_memory) 377 limit += TLOW_MAX - top_of_low_memory; 378 nb_banks[i].base = base; 379 nb_banks[i].limit = limit; 380 nb_banks[i].way[0] = way0; 381 nb_banks[i].way[1] = way1; 382 base = limit; 383 } 384 for (i = 0; i < nb_number_memory_controllers; i++) { 385 base = 0; 386 387 for (j = 0; j < NB_MEM_RANK_SELECT; j++) { 388 dmir = DMIR_RD(i, j); 389 limit = ((uint64_t)(dmir >> 16) & 0xff) << 28; 390 if (limit == 0) { 391 limit = mc_range(i, base); 392 } 393 branch_interleave = 0; 394 hole_base = 0; 395 hole_size = 0; 396 DMIR_RANKS(dmir, rank0, rank1, rank2, rank3); 397 if (rank0 == rank1) 398 interleave = 1; 399 else if (rank0 == rank2) 400 interleave = 2; 401 else 402 interleave = 4; 403 if (nb_mode != NB_MEMORY_MIRROR && 404 nb_mode != NB_MEMORY_SINGLE_CHANNEL) { 405 for (k = 0; k < NB_MEM_BRANCH_SELECT; k++) { 406 if (base >= nb_banks[k].base && 407 base < nb_banks[k].limit) { 408 if (nb_banks[i].way[0] && 409 nb_banks[i].way[1]) { 410 interleave *= 2; 411 limit *= 2; 412 branch_interleave = 1; 413 } 414 break; 415 } 416 } 417 } 418 if (base < top_of_low_memory && 419 limit > top_of_low_memory) { 420 hole_base = top_of_low_memory; 421 hole_size = TLOW_MAX - top_of_low_memory; 422 limit += hole_size; 423 } else if (base > top_of_low_memory) { 424 limit += TLOW_MAX - top_of_low_memory; 425 } 426 nb_ranks[i][j].base = base; 427 nb_ranks[i][j].limit = limit; 428 nb_ranks[i][j].rank[0] = rank0; 429 nb_ranks[i][j].rank[1] = rank1; 430 nb_ranks[i][j].rank[2] = rank2; 431 nb_ranks[i][j].rank[3] = rank3; 432 nb_ranks[i][j].interleave = interleave; 433 nb_ranks[i][j].branch_interleave = branch_interleave; 434 nb_ranks[i][j].hole_base = hole_base; 435 nb_ranks[i][j].hole_size = hole_size; 436 if (limit > base) { 437 dimm_add_rank(i, rank0, branch_interleave, 0, 438 base, hole_base, hole_size, interleave, 439 limit); 440 if (rank0 != rank1) { 441 dimm_add_rank(i, rank1, 442 branch_interleave, 1, base, 443 hole_base, hole_size, interleave, 444 limit); 445 if (rank0 != rank2) { 446 dimm_add_rank(i, rank2, 447 branch_interleave, 2, base, 448 hole_base, hole_size, 449 interleave, limit); 450 dimm_add_rank(i, rank3, 451 branch_interleave, 3, base, 452 hole_base, hole_size, 453 interleave, limit); 454 } 455 } 456 } 457 base = limit; 458 } 459 } 460 } 461 462 void 463 nb_used_spare_rank(int branch, int bad_rank) 464 { 465 int i; 466 int j; 467 468 for (i = 0; i < NB_MEM_RANK_SELECT; i++) { 469 for (j = 0; j < NB_RANKS_IN_SELECT; j++) { 470 if (nb_ranks[branch][i].rank[j] == bad_rank) { 471 nb_ranks[branch][i].rank[j] = 472 spare_rank[branch]; 473 i = NB_MEM_RANK_SELECT; 474 break; 475 } 476 } 477 } 478 } 479 480 /*ARGSUSED*/ 481 static int 482 memoryarray(smbios_hdl_t *shp, const smbios_struct_t *sp, void *arg) 483 { 484 smbios_memarray_t ma; 485 486 if (sp->smbstr_type == SMB_TYPE_MEMARRAY && 487 smbios_info_memarray(shp, sp->smbstr_id, &ma) == 0) { 488 ndimms += ma.smbma_ndevs; 489 } 490 return (0); 491 } 492 493 find_dimm_label_t * 494 find_dimms_per_channel() 495 { 496 struct platform_label *pl; 497 smbios_info_t si; 498 smbios_system_t sy; 499 id_t id; 500 int read_memarray = 1; 501 find_dimm_label_t *rt = NULL; 502 503 if (ksmbios != NULL) { 504 if ((id = smbios_info_system(ksmbios, &sy)) != SMB_ERR && 505 smbios_info_common(ksmbios, id, &si) != SMB_ERR) { 506 for (pl = platform_label; pl->sys_vendor; pl++) { 507 if (strncmp(pl->sys_vendor, 508 si.smbi_manufacturer, 509 strlen(pl->sys_vendor)) == 0 && 510 strncmp(pl->sys_product, si.smbi_product, 511 strlen(pl->sys_product)) == 0) { 512 nb_dimms_per_channel = 513 pl->dimms_per_channel; 514 read_memarray = 0; 515 rt = &pl->dimm_label; 516 break; 517 } 518 } 519 } 520 if (read_memarray) 521 (void) smbios_iter(ksmbios, memoryarray, 0); 522 } 523 if (nb_dimms_per_channel == 0) { 524 if (ndimms) { 525 nb_dimms_per_channel = ndimms / 526 (nb_number_memory_controllers * 2); 527 } else { 528 nb_dimms_per_channel = NB_MAX_DIMMS_PER_CHANNEL; 529 } 530 } 531 return (rt); 532 } 533 534 static int 535 dimm_label(smbios_hdl_t *shp, const smbios_struct_t *sp, void *arg) 536 { 537 nb_dimm_t ***dimmpp = arg; 538 nb_dimm_t *dimmp; 539 smbios_memdevice_t md; 540 541 if (sp->smbstr_type == SMB_TYPE_MEMDEVICE) { 542 dimmp = **dimmpp; 543 if (dimmp && smbios_info_memdevice(shp, sp->smbstr_id, 544 &md) == 0 && md.smbmd_dloc != NULL) { 545 (void) snprintf(dimmp->label, 546 sizeof (dimmp->label), "%s", md.smbmd_dloc); 547 } 548 (*dimmpp)++; 549 } 550 return (0); 551 } 552 553 void 554 nb_smbios() 555 { 556 nb_dimm_t **dimmpp; 557 558 if (ksmbios != NULL) { 559 dimmpp = nb_dimms; 560 (void) smbios_iter(ksmbios, dimm_label, &dimmpp); 561 } 562 } 563 564 static void 565 x8450_dimm_label(int dimm, char *label, int label_sz) 566 { 567 int channel = dimm >> 3; 568 569 dimm = dimm & 0x7; 570 (void) snprintf(label, label_sz, "D%d", (dimm * 4) + channel); 571 } 572 573 static void 574 nb_dimms_init(find_dimm_label_t *label_function) 575 { 576 int i, j, k, l; 577 uint16_t mtr; 578 uint32_t mc, mca; 579 uint32_t spcpc; 580 uint8_t spcps; 581 nb_dimm_t **dimmpp; 582 583 mca = MCA_RD(); 584 mc = MC_RD(); 585 if (mca & MCA_SCHDIMM) /* single-channel mode */ 586 nb_mode = NB_MEMORY_SINGLE_CHANNEL; 587 else if ((mc & MC_MIRROR) != 0) /* mirror mode */ 588 nb_mode = NB_MEMORY_MIRROR; 589 else 590 nb_mode = NB_MEMORY_NORMAL; 591 nb_dimms = (nb_dimm_t **)kmem_zalloc(sizeof (nb_dimm_t *) * 592 nb_number_memory_controllers * 2 * nb_dimms_per_channel, KM_SLEEP); 593 dimmpp = nb_dimms; 594 for (i = 0; i < nb_number_memory_controllers; i++) { 595 if (nb_mode == NB_MEMORY_NORMAL) { 596 spcpc = SPCPC_RD(i); 597 spcps = SPCPS_RD(i); 598 if ((spcpc & SPCPC_SPARE_ENABLE) != 0 && 599 (spcps & SPCPS_SPARE_DEPLOYED) != 0) 600 nb_mode = NB_MEMORY_SPARE_RANK; 601 spare_rank[i] = SPCPC_SPRANK(spcpc); 602 } 603 for (j = 0; j < nb_dimms_per_channel; j++) { 604 mtr = MTR_RD(i, j); 605 k = i * 2; 606 dimmpp[j] = nb_dimm_init(k, j, mtr); 607 if (dimmpp[j]) { 608 nb_ndimm ++; 609 dimm_add_geometry(i, j, dimmpp[j]->nbanks, 610 dimmpp[j]->width, dimmpp[j]->ncolumn, 611 dimmpp[j]->nrow); 612 if (label_function) { 613 label_function->label_function( 614 (k * nb_dimms_per_channel) + j, 615 dimmpp[j]->label, 616 sizeof (dimmpp[j]->label)); 617 } 618 } 619 dimmpp[j + nb_dimms_per_channel] = 620 nb_dimm_init(k + 1, j, mtr); 621 l = j + nb_dimms_per_channel; 622 if (dimmpp[l]) { 623 if (label_function) { 624 label_function->label_function( 625 (k * nb_dimms_per_channel) + l, 626 dimmpp[l]->label, 627 sizeof (dimmpp[l]->label)); 628 } 629 nb_ndimm ++; 630 } 631 } 632 dimmpp += nb_dimms_per_channel * 2; 633 } 634 if (label_function == NULL) 635 nb_smbios(); 636 } 637 638 static void 639 nb_pex_init() 640 { 641 int i; 642 uint32_t mask; 643 644 for (i = 0; i < NB_PCI_DEV; i++) { 645 switch (nb_chipset) { 646 case INTEL_NB_5000P: 647 case INTEL_NB_5000X: 648 if (i == 1 || i > 8) 649 continue; 650 break; 651 case INTEL_NB_5000V: 652 if (i == 1 || i > 3) 653 continue; 654 break; 655 case INTEL_NB_5000Z: 656 if (i == 1 || i > 5) 657 continue; 658 break; 659 case INTEL_NB_5400: 660 break; 661 case INTEL_NB_7300: 662 if (i > 8) 663 continue; 664 break; 665 } 666 emask_uncor_pex[i] = EMASK_UNCOR_PEX_RD(i); 667 emask_cor_pex[i] = EMASK_COR_PEX_RD(i); 668 emask_rp_pex[i] = EMASK_RP_PEX_RD(i); 669 docmd_pex[i] = PEX_ERR_DOCMD_RD(i); 670 uncerrsev[i] = UNCERRSEV_RD(i); 671 672 if (nb5000_reset_uncor_pex) 673 EMASK_UNCOR_PEX_WR(i, nb5000_mask_uncor_pex); 674 if (nb5000_reset_cor_pex) 675 EMASK_COR_PEX_WR(i, nb5000_mask_cor_pex); 676 if (nb_set_docmd) { 677 if (nb_chipset == INTEL_NB_5400) { 678 mask = (docmd_pex[i] & nb5400_docmd_pex_mask) | 679 (nb5400_docmd_pex & ~nb5400_docmd_pex_mask); 680 } else { 681 mask = (docmd_pex[i] & nb5000_docmd_pex_mask) | 682 (nb5000_docmd_pex & ~nb5000_docmd_pex_mask); 683 } 684 PEX_ERR_DOCMD_WR(i, mask); 685 } 686 } 687 } 688 689 static void 690 nb_pex_fini() 691 { 692 int i; 693 694 for (i = 0; i < NB_PCI_DEV; i++) { 695 switch (nb_chipset) { 696 case INTEL_NB_5000P: 697 case INTEL_NB_5000X: 698 if (i == 1 && i > 8) 699 continue; 700 break; 701 case INTEL_NB_5000V: 702 if (i == 1 || i > 3) 703 continue; 704 break; 705 case INTEL_NB_5000Z: 706 if (i == 1 || i > 5) 707 continue; 708 break; 709 case INTEL_NB_5400: 710 break; 711 case INTEL_NB_7300: 712 if (i > 8) 713 continue; 714 break; 715 } 716 EMASK_UNCOR_PEX_WR(i, emask_uncor_pex[i]); 717 EMASK_COR_PEX_WR(i, emask_cor_pex[i]); 718 EMASK_RP_PEX_WR(i, emask_rp_pex[i]); 719 PEX_ERR_DOCMD_WR(i, docmd_pex[i]); 720 721 if (nb5000_reset_uncor_pex) 722 EMASK_UNCOR_PEX_WR(i, nb5000_mask_uncor_pex); 723 if (nb5000_reset_cor_pex) 724 EMASK_COR_PEX_WR(i, nb5000_mask_cor_pex); 725 } 726 } 727 728 void 729 nb_int_init() 730 { 731 uint8_t err0_int; 732 uint8_t err1_int; 733 uint8_t err2_int; 734 uint8_t mcerr_int; 735 uint32_t emask_int; 736 uint16_t stepping; 737 738 err0_int = ERR0_INT_RD(); 739 err1_int = ERR1_INT_RD(); 740 err2_int = ERR2_INT_RD(); 741 mcerr_int = MCERR_INT_RD(); 742 emask_int = EMASK_INT_RD(); 743 744 nb_err0_int = err0_int; 745 nb_err1_int = err1_int; 746 nb_err2_int = err2_int; 747 nb_mcerr_int = mcerr_int; 748 nb_emask_int = emask_int; 749 750 ERR0_INT_WR(0xff); 751 ERR1_INT_WR(0xff); 752 ERR2_INT_WR(0xff); 753 MCERR_INT_WR(0xff); 754 EMASK_INT_WR(0xff); 755 756 mcerr_int &= ~nb5000_mask_bios_int; 757 mcerr_int |= nb5000_mask_bios_int & (~err0_int | ~err1_int | ~err2_int); 758 mcerr_int |= nb5000_mask_poll_int; 759 err0_int |= nb5000_mask_poll_int; 760 err1_int |= nb5000_mask_poll_int; 761 err2_int |= nb5000_mask_poll_int; 762 763 l_mcerr_int = mcerr_int; 764 ERR0_INT_WR(err0_int); 765 ERR1_INT_WR(err1_int); 766 ERR2_INT_WR(err2_int); 767 MCERR_INT_WR(mcerr_int); 768 if (nb5000_reset_emask_int) { 769 if (nb_chipset == INTEL_NB_7300) { 770 stepping = NB5000_STEPPING(); 771 if (stepping == 0) 772 EMASK_5000_INT_WR(nb7300_emask_int_step0); 773 else 774 EMASK_5000_INT_WR(nb7300_emask_int); 775 } else if (nb_chipset == INTEL_NB_5400) { 776 EMASK_5400_INT_WR(nb5400_emask_int | 777 (emask_int & EMASK_INT_RES)); 778 } else { 779 EMASK_5000_INT_WR(nb5000_emask_int); 780 } 781 } else { 782 EMASK_INT_WR(nb_emask_int); 783 } 784 } 785 786 void 787 nb_int_fini() 788 { 789 ERR0_INT_WR(0xff); 790 ERR1_INT_WR(0xff); 791 ERR2_INT_WR(0xff); 792 MCERR_INT_WR(0xff); 793 EMASK_INT_WR(0xff); 794 795 ERR0_INT_WR(nb_err0_int); 796 ERR1_INT_WR(nb_err1_int); 797 ERR2_INT_WR(nb_err2_int); 798 MCERR_INT_WR(nb_mcerr_int); 799 EMASK_INT_WR(nb_emask_int); 800 } 801 802 void 803 nb_int_mask_mc(uint32_t mc_mask_int) 804 { 805 uint32_t emask_int; 806 807 emask_int = MCERR_INT_RD(); 808 if ((emask_int & mc_mask_int) != mc_mask_int) { 809 MCERR_INT_WR(emask_int|mc_mask_int); 810 nb_mask_mc_set = 1; 811 } 812 } 813 814 void 815 nb_fbd_init() 816 { 817 uint32_t err0_fbd; 818 uint32_t err1_fbd; 819 uint32_t err2_fbd; 820 uint32_t mcerr_fbd; 821 uint32_t emask_fbd; 822 uint32_t emask_bios_fbd; 823 uint32_t emask_poll_fbd; 824 825 err0_fbd = ERR0_FBD_RD(); 826 err1_fbd = ERR1_FBD_RD(); 827 err2_fbd = ERR2_FBD_RD(); 828 mcerr_fbd = MCERR_FBD_RD(); 829 emask_fbd = EMASK_FBD_RD(); 830 831 nb_err0_fbd = err0_fbd; 832 nb_err1_fbd = err1_fbd; 833 nb_err2_fbd = err2_fbd; 834 nb_mcerr_fbd = mcerr_fbd; 835 nb_emask_fbd = emask_fbd; 836 837 ERR0_FBD_WR(0xffffffff); 838 ERR1_FBD_WR(0xffffffff); 839 ERR2_FBD_WR(0xffffffff); 840 MCERR_FBD_WR(0xffffffff); 841 EMASK_FBD_WR(0xffffffff); 842 843 if (nb_chipset == INTEL_NB_7300 && nb_mode == NB_MEMORY_MIRROR) { 844 /* MCH 7300 errata 34 */ 845 emask_bios_fbd = nb5000_mask_bios_fbd & ~EMASK_FBD_M23; 846 emask_poll_fbd = nb5000_mask_poll_fbd; 847 mcerr_fbd |= EMASK_FBD_M23; 848 } else if (nb_chipset == INTEL_NB_5400) { 849 emask_bios_fbd = nb5400_mask_bios_fbd; 850 emask_poll_fbd = nb5400_mask_poll_fbd; 851 } else { 852 emask_bios_fbd = nb5000_mask_bios_fbd; 853 emask_poll_fbd = nb5000_mask_poll_fbd; 854 } 855 mcerr_fbd &= ~emask_bios_fbd; 856 mcerr_fbd |= emask_bios_fbd & (~err0_fbd | ~err1_fbd | ~err2_fbd); 857 mcerr_fbd |= emask_poll_fbd; 858 err0_fbd |= emask_poll_fbd; 859 err1_fbd |= emask_poll_fbd; 860 err2_fbd |= emask_poll_fbd; 861 862 l_mcerr_fbd = mcerr_fbd; 863 ERR0_FBD_WR(err0_fbd); 864 ERR1_FBD_WR(err1_fbd); 865 ERR2_FBD_WR(err2_fbd); 866 MCERR_FBD_WR(mcerr_fbd); 867 if (nb5000_reset_emask_fbd) { 868 if (nb_chipset == INTEL_NB_5400) 869 EMASK_FBD_WR(nb5400_emask_fbd); 870 else 871 EMASK_FBD_WR(nb5000_emask_fbd); 872 } else { 873 EMASK_FBD_WR(nb_emask_fbd); 874 } 875 } 876 877 void 878 nb_fbd_mask_mc(uint32_t mc_mask_fbd) 879 { 880 uint32_t emask_fbd; 881 882 emask_fbd = MCERR_FBD_RD(); 883 if ((emask_fbd & mc_mask_fbd) != mc_mask_fbd) { 884 MCERR_FBD_WR(emask_fbd|mc_mask_fbd); 885 nb_mask_mc_set = 1; 886 } 887 } 888 889 void 890 nb_fbd_fini() 891 { 892 ERR0_FBD_WR(0xffffffff); 893 ERR1_FBD_WR(0xffffffff); 894 ERR2_FBD_WR(0xffffffff); 895 MCERR_FBD_WR(0xffffffff); 896 EMASK_FBD_WR(0xffffffff); 897 898 ERR0_FBD_WR(nb_err0_fbd); 899 ERR1_FBD_WR(nb_err1_fbd); 900 ERR2_FBD_WR(nb_err2_fbd); 901 MCERR_FBD_WR(nb_mcerr_fbd); 902 EMASK_FBD_WR(nb_emask_fbd); 903 } 904 905 static void 906 nb_fsb_init() 907 { 908 uint16_t err0_fsb; 909 uint16_t err1_fsb; 910 uint16_t err2_fsb; 911 uint16_t mcerr_fsb; 912 uint16_t emask_fsb; 913 914 err0_fsb = ERR0_FSB_RD(0); 915 err1_fsb = ERR1_FSB_RD(0); 916 err2_fsb = ERR2_FSB_RD(0); 917 mcerr_fsb = MCERR_FSB_RD(0); 918 emask_fsb = EMASK_FSB_RD(0); 919 920 ERR0_FSB_WR(0, 0xffff); 921 ERR1_FSB_WR(0, 0xffff); 922 ERR2_FSB_WR(0, 0xffff); 923 MCERR_FSB_WR(0, 0xffff); 924 EMASK_FSB_WR(0, 0xffff); 925 926 ERR0_FSB_WR(1, 0xffff); 927 ERR1_FSB_WR(1, 0xffff); 928 ERR2_FSB_WR(1, 0xffff); 929 MCERR_FSB_WR(1, 0xffff); 930 EMASK_FSB_WR(1, 0xffff); 931 932 nb_err0_fsb = err0_fsb; 933 nb_err1_fsb = err1_fsb; 934 nb_err2_fsb = err2_fsb; 935 nb_mcerr_fsb = mcerr_fsb; 936 nb_emask_fsb = emask_fsb; 937 938 mcerr_fsb &= ~nb5000_mask_bios_fsb; 939 mcerr_fsb |= nb5000_mask_bios_fsb & (~err2_fsb | ~err1_fsb | ~err0_fsb); 940 mcerr_fsb |= nb5000_mask_poll_fsb; 941 err0_fsb |= nb5000_mask_poll_fsb; 942 err1_fsb |= nb5000_mask_poll_fsb; 943 err2_fsb |= nb5000_mask_poll_fsb; 944 945 l_mcerr_fsb = mcerr_fsb; 946 ERR0_FSB_WR(0, err0_fsb); 947 ERR1_FSB_WR(0, err1_fsb); 948 ERR2_FSB_WR(0, err2_fsb); 949 MCERR_FSB_WR(0, mcerr_fsb); 950 if (nb5000_reset_emask_fsb) { 951 EMASK_FSB_WR(0, nb5000_emask_fsb); 952 } else { 953 EMASK_FSB_WR(0, nb_emask_fsb); 954 } 955 956 ERR0_FSB_WR(1, err0_fsb); 957 ERR1_FSB_WR(1, err1_fsb); 958 ERR2_FSB_WR(1, err2_fsb); 959 MCERR_FSB_WR(1, mcerr_fsb); 960 if (nb5000_reset_emask_fsb) { 961 EMASK_FSB_WR(1, nb5000_emask_fsb); 962 } else { 963 EMASK_FSB_WR(1, nb_emask_fsb); 964 } 965 966 if (nb_chipset == INTEL_NB_7300) { 967 ERR0_FSB_WR(2, 0xffff); 968 ERR1_FSB_WR(2, 0xffff); 969 ERR2_FSB_WR(2, 0xffff); 970 MCERR_FSB_WR(2, 0xffff); 971 EMASK_FSB_WR(2, 0xffff); 972 973 ERR0_FSB_WR(3, 0xffff); 974 ERR1_FSB_WR(3, 0xffff); 975 ERR2_FSB_WR(3, 0xffff); 976 MCERR_FSB_WR(3, 0xffff); 977 EMASK_FSB_WR(3, 0xffff); 978 979 ERR0_FSB_WR(2, err0_fsb); 980 ERR1_FSB_WR(2, err1_fsb); 981 ERR2_FSB_WR(2, err2_fsb); 982 MCERR_FSB_WR(2, mcerr_fsb); 983 if (nb5000_reset_emask_fsb) { 984 EMASK_FSB_WR(2, nb5000_emask_fsb); 985 } else { 986 EMASK_FSB_WR(2, nb_emask_fsb); 987 } 988 989 ERR0_FSB_WR(3, err0_fsb); 990 ERR1_FSB_WR(3, err1_fsb); 991 ERR2_FSB_WR(3, err2_fsb); 992 MCERR_FSB_WR(3, mcerr_fsb); 993 if (nb5000_reset_emask_fsb) { 994 EMASK_FSB_WR(3, nb5000_emask_fsb); 995 } else { 996 EMASK_FSB_WR(3, nb_emask_fsb); 997 } 998 } 999 } 1000 1001 static void 1002 nb_fsb_fini() { 1003 ERR0_FSB_WR(0, 0xffff); 1004 ERR1_FSB_WR(0, 0xffff); 1005 ERR2_FSB_WR(0, 0xffff); 1006 MCERR_FSB_WR(0, 0xffff); 1007 EMASK_FSB_WR(0, 0xffff); 1008 1009 ERR0_FSB_WR(0, nb_err0_fsb); 1010 ERR1_FSB_WR(0, nb_err1_fsb); 1011 ERR2_FSB_WR(0, nb_err2_fsb); 1012 MCERR_FSB_WR(0, nb_mcerr_fsb); 1013 EMASK_FSB_WR(0, nb_emask_fsb); 1014 1015 ERR0_FSB_WR(1, 0xffff); 1016 ERR1_FSB_WR(1, 0xffff); 1017 ERR2_FSB_WR(1, 0xffff); 1018 MCERR_FSB_WR(1, 0xffff); 1019 EMASK_FSB_WR(1, 0xffff); 1020 1021 ERR0_FSB_WR(1, nb_err0_fsb); 1022 ERR1_FSB_WR(1, nb_err1_fsb); 1023 ERR2_FSB_WR(1, nb_err2_fsb); 1024 MCERR_FSB_WR(1, nb_mcerr_fsb); 1025 EMASK_FSB_WR(1, nb_emask_fsb); 1026 1027 if (nb_chipset == INTEL_NB_7300) { 1028 ERR0_FSB_WR(2, 0xffff); 1029 ERR1_FSB_WR(2, 0xffff); 1030 ERR2_FSB_WR(2, 0xffff); 1031 MCERR_FSB_WR(2, 0xffff); 1032 EMASK_FSB_WR(2, 0xffff); 1033 1034 ERR0_FSB_WR(2, nb_err0_fsb); 1035 ERR1_FSB_WR(2, nb_err1_fsb); 1036 ERR2_FSB_WR(2, nb_err2_fsb); 1037 MCERR_FSB_WR(2, nb_mcerr_fsb); 1038 EMASK_FSB_WR(2, nb_emask_fsb); 1039 1040 ERR0_FSB_WR(3, 0xffff); 1041 ERR1_FSB_WR(3, 0xffff); 1042 ERR2_FSB_WR(3, 0xffff); 1043 MCERR_FSB_WR(3, 0xffff); 1044 EMASK_FSB_WR(3, 0xffff); 1045 1046 ERR0_FSB_WR(3, nb_err0_fsb); 1047 ERR1_FSB_WR(3, nb_err1_fsb); 1048 ERR2_FSB_WR(3, nb_err2_fsb); 1049 MCERR_FSB_WR(3, nb_mcerr_fsb); 1050 EMASK_FSB_WR(3, nb_emask_fsb); 1051 } 1052 } 1053 1054 void 1055 nb_fsb_mask_mc(int fsb, uint16_t mc_mask_fsb) 1056 { 1057 uint16_t emask_fsb; 1058 1059 emask_fsb = MCERR_FSB_RD(fsb); 1060 if ((emask_fsb & mc_mask_fsb) != mc_mask_fsb) { 1061 MCERR_FSB_WR(fsb, emask_fsb|mc_mask_fsb|EMASK_FBD_RES); 1062 nb_mask_mc_set = 1; 1063 } 1064 } 1065 1066 static void 1067 nb_thr_init() 1068 { 1069 uint16_t err0_thr; 1070 uint16_t err1_thr; 1071 uint16_t err2_thr; 1072 uint16_t mcerr_thr; 1073 uint16_t emask_thr; 1074 1075 if (nb_chipset == INTEL_NB_5400) { 1076 err0_thr = ERR0_THR_RD(0); 1077 err1_thr = ERR1_THR_RD(0); 1078 err2_thr = ERR2_THR_RD(0); 1079 mcerr_thr = MCERR_THR_RD(0); 1080 emask_thr = EMASK_THR_RD(0); 1081 1082 ERR0_THR_WR(0xffff); 1083 ERR1_THR_WR(0xffff); 1084 ERR2_THR_WR(0xffff); 1085 MCERR_THR_WR(0xffff); 1086 EMASK_THR_WR(0xffff); 1087 1088 nb_err0_thr = err0_thr; 1089 nb_err1_thr = err1_thr; 1090 nb_err2_thr = err2_thr; 1091 nb_mcerr_thr = mcerr_thr; 1092 nb_emask_thr = emask_thr; 1093 1094 mcerr_thr &= ~nb_mask_bios_thr; 1095 mcerr_thr |= nb_mask_bios_thr & 1096 (~err2_thr | ~err1_thr | ~err0_thr); 1097 mcerr_thr |= nb_mask_poll_thr; 1098 err0_thr |= nb_mask_poll_thr; 1099 err1_thr |= nb_mask_poll_thr; 1100 err2_thr |= nb_mask_poll_thr; 1101 1102 l_mcerr_thr = mcerr_thr; 1103 ERR0_THR_WR(err0_thr); 1104 ERR1_THR_WR(err1_thr); 1105 ERR2_THR_WR(err2_thr); 1106 MCERR_THR_WR(mcerr_thr); 1107 EMASK_THR_WR(nb_emask_thr); 1108 } 1109 } 1110 1111 static void 1112 nb_thr_fini() 1113 { 1114 if (nb_chipset == INTEL_NB_5400) { 1115 ERR0_THR_WR(0xffff); 1116 ERR1_THR_WR(0xffff); 1117 ERR2_THR_WR(0xffff); 1118 MCERR_THR_WR(0xffff); 1119 EMASK_THR_WR(0xffff); 1120 1121 ERR0_THR_WR(nb_err0_thr); 1122 ERR1_THR_WR(nb_err1_thr); 1123 ERR2_THR_WR(nb_err2_thr); 1124 MCERR_THR_WR(nb_mcerr_thr); 1125 EMASK_THR_WR(nb_emask_thr); 1126 } 1127 } 1128 1129 void 1130 nb_thr_mask_mc(uint16_t mc_mask_thr) 1131 { 1132 uint16_t emask_thr; 1133 1134 emask_thr = MCERR_THR_RD(0); 1135 if ((emask_thr & mc_mask_thr) != mc_mask_thr) { 1136 MCERR_THR_WR(emask_thr|mc_mask_thr); 1137 nb_mask_mc_set = 1; 1138 } 1139 } 1140 1141 void 1142 nb_mask_mc_reset() 1143 { 1144 MCERR_FBD_WR(l_mcerr_fbd); 1145 MCERR_INT_WR(l_mcerr_int); 1146 MCERR_FSB_WR(0, l_mcerr_fsb); 1147 MCERR_FSB_WR(1, l_mcerr_fsb); 1148 if (nb_chipset == INTEL_NB_7300) { 1149 MCERR_FSB_WR(2, l_mcerr_fsb); 1150 MCERR_FSB_WR(3, l_mcerr_fsb); 1151 } 1152 if (nb_chipset == INTEL_NB_5400) { 1153 MCERR_THR_WR(l_mcerr_thr); 1154 } 1155 } 1156 1157 int 1158 nb_dev_init() 1159 { 1160 find_dimm_label_t *label_function_p; 1161 1162 label_function_p = find_dimms_per_channel(); 1163 mutex_init(&nb_mutex, NULL, MUTEX_DRIVER, NULL); 1164 nb_queue = errorq_create("nb_queue", nb_drain, NULL, NB_MAX_ERRORS, 1165 sizeof (nb_logout_t), 1, ERRORQ_VITAL); 1166 if (nb_queue == NULL) { 1167 mutex_destroy(&nb_mutex); 1168 return (EAGAIN); 1169 } 1170 nb_int_init(); 1171 nb_thr_init(); 1172 dimm_init(); 1173 nb_dimms_init(label_function_p); 1174 nb_mc_init(); 1175 nb_pex_init(); 1176 nb_fbd_init(); 1177 nb_fsb_init(); 1178 nb_scrubber_enable(); 1179 return (0); 1180 } 1181 1182 int 1183 nb_init() 1184 { 1185 /* get vendor and device */ 1186 nb_chipset = (*pci_getl_func)(0, 0, 0, PCI_CONF_VENID); 1187 switch (nb_chipset) { 1188 default: 1189 if (nb_5000_memory_controller == 0) 1190 return (ENOTSUP); 1191 break; 1192 case INTEL_NB_7300: 1193 case INTEL_NB_5000P: 1194 case INTEL_NB_5000X: 1195 break; 1196 case INTEL_NB_5000V: 1197 case INTEL_NB_5000Z: 1198 nb_number_memory_controllers = 1; 1199 break; 1200 case INTEL_NB_5400: 1201 case INTEL_NB_5400A: 1202 case INTEL_NB_5400B: 1203 nb_chipset = INTEL_NB_5400; 1204 break; 1205 } 1206 return (0); 1207 } 1208 1209 void 1210 nb_dev_reinit() 1211 { 1212 int i, j; 1213 int nchannels = nb_number_memory_controllers * 2; 1214 nb_dimm_t **dimmpp; 1215 nb_dimm_t *dimmp; 1216 nb_dimm_t **old_nb_dimms; 1217 int old_nb_dimms_per_channel; 1218 find_dimm_label_t *label_function_p; 1219 1220 old_nb_dimms = nb_dimms; 1221 old_nb_dimms_per_channel = nb_dimms_per_channel; 1222 1223 dimm_fini(); 1224 label_function_p = find_dimms_per_channel(); 1225 dimm_init(); 1226 nb_dimms_init(label_function_p); 1227 nb_mc_init(); 1228 nb_pex_init(); 1229 nb_int_init(); 1230 nb_thr_init(); 1231 nb_fbd_init(); 1232 nb_fsb_init(); 1233 nb_scrubber_enable(); 1234 1235 dimmpp = old_nb_dimms; 1236 for (i = 0; i < nchannels; i++) { 1237 for (j = 0; j < old_nb_dimms_per_channel; j++) { 1238 dimmp = *dimmpp; 1239 if (dimmp) { 1240 kmem_free(dimmp, sizeof (nb_dimm_t)); 1241 *dimmpp = NULL; 1242 } 1243 dimmp++; 1244 } 1245 } 1246 kmem_free(old_nb_dimms, sizeof (nb_dimm_t *) * 1247 nb_number_memory_controllers * 2 * old_nb_dimms_per_channel); 1248 } 1249 1250 void 1251 nb_dev_unload() 1252 { 1253 errorq_destroy(nb_queue); 1254 nb_queue = NULL; 1255 mutex_destroy(&nb_mutex); 1256 nb_int_fini(); 1257 nb_thr_fini(); 1258 nb_fbd_fini(); 1259 nb_fsb_fini(); 1260 nb_pex_fini(); 1261 nb_fini(); 1262 } 1263 1264 void 1265 nb_unload() 1266 { 1267 } 1268