nb5000_init.c revision 10650:5195e7d7a5f4
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27#include <sys/types.h> 28#include <sys/cmn_err.h> 29#include <sys/errno.h> 30#include <sys/log.h> 31#include <sys/systm.h> 32#include <sys/modctl.h> 33#include <sys/errorq.h> 34#include <sys/controlregs.h> 35#include <sys/fm/util.h> 36#include <sys/fm/protocol.h> 37#include <sys/sysevent.h> 38#include <sys/pghw.h> 39#include <sys/cyclic.h> 40#include <sys/pci_cfgspace.h> 41#include <sys/mc_intel.h> 42#include <sys/smbios.h> 43#include <sys/pci.h> 44#include <sys/pcie.h> 45#include "nb5000.h" 46#include "nb_log.h" 47#include "dimm_phys.h" 48#include "rank.h" 49 50int nb_hw_memory_scrub_enable = 1; 51static int nb_sw_scrub_disabled = 0; 52 53int nb_5000_memory_controller = 0; 54int nb_number_memory_controllers = NB_5000_MAX_MEM_CONTROLLERS; 55int nb_channels_per_branch = NB_MAX_CHANNELS_PER_BRANCH; 56int nb_dimms_per_channel = 0; 57 58nb_dimm_t **nb_dimms; 59int nb_ndimm; 60uint32_t nb_chipset; 61enum nb_memory_mode nb_mode; 62bank_select_t nb_banks[NB_MAX_MEM_BRANCH_SELECT]; 63rank_select_t nb_ranks[NB_5000_MAX_MEM_CONTROLLERS][NB_MAX_MEM_RANK_SELECT]; 64uint32_t top_of_low_memory; 65uint8_t spare_rank[NB_5000_MAX_MEM_CONTROLLERS]; 66 67extern int nb_no_smbios; 68 69errorq_t *nb_queue; 70kmutex_t nb_mutex; 71 72static int nb_dimm_slots; 73 74static uint32_t nb_err0_int; 75static uint32_t nb_err1_int; 76static uint32_t nb_err2_int; 77static uint32_t nb_mcerr_int; 78static uint32_t nb_emask_int; 79 80static uint32_t nb_err0_fbd; 81static uint32_t nb_err1_fbd; 82static uint32_t nb_err2_fbd; 83static uint32_t nb_mcerr_fbd; 84static uint32_t nb_emask_fbd; 85 86static uint32_t nb_err0_mem; 87static uint32_t nb_err1_mem; 88static uint32_t nb_err2_mem; 89static uint32_t nb_mcerr_mem; 90static uint32_t nb_emask_mem; 91 92static uint16_t nb_err0_fsb; 93static uint16_t nb_err1_fsb; 94static uint16_t nb_err2_fsb; 95static uint16_t nb_mcerr_fsb; 96static uint16_t nb_emask_fsb; 97 98static uint16_t nb_err0_thr; 99static uint16_t nb_err1_thr; 100static uint16_t nb_err2_thr; 101static uint16_t nb_mcerr_thr; 102static uint16_t nb_emask_thr; 103 104static uint32_t emask_uncor_pex[NB_PCI_DEV]; 105static uint32_t emask_cor_pex[NB_PCI_DEV]; 106static uint32_t emask_rp_pex[NB_PCI_DEV]; 107static uint32_t docmd_pex[NB_PCI_DEV]; 108static uint32_t uncerrsev[NB_PCI_DEV]; 109 110static uint32_t l_mcerr_int; 111static uint32_t l_mcerr_fbd; 112static uint32_t l_mcerr_mem; 113static uint16_t l_mcerr_fsb; 114static uint16_t l_mcerr_thr; 115 116uint_t nb5000_emask_fbd = EMASK_5000_FBD_RES; 117uint_t nb5400_emask_fbd = 0; 118int nb5000_reset_emask_fbd = 1; 119uint_t nb5000_mask_poll_fbd = EMASK_FBD_NF; 120uint_t nb5000_mask_bios_fbd = EMASK_FBD_FATAL; 121uint_t nb5400_mask_poll_fbd = EMASK_5400_FBD_NF; 122uint_t nb5400_mask_bios_fbd = EMASK_5400_FBD_FATAL; 123 124int nb5100_reset_emask_mem = 1; 125uint_t nb5100_mask_poll_mem = EMASK_MEM_NF; 126 127uint_t nb5000_emask_fsb = 0; 128int nb5000_reset_emask_fsb = 1; 129uint_t nb5000_mask_poll_fsb = EMASK_FSB_NF; 130uint_t nb5000_mask_bios_fsb = EMASK_FSB_FATAL; 131 132uint_t nb5400_emask_int = EMASK_INT_5400; 133 134uint_t nb7300_emask_int = EMASK_INT_7300; 135uint_t nb7300_emask_int_step0 = EMASK_INT_7300_STEP_0; 136uint_t nb5000_emask_int = EMASK_INT_5000; 137int nb5000_reset_emask_int = 1; 138uint_t nb5000_mask_poll_int = EMASK_INT_NF; 139uint_t nb5000_mask_bios_int = EMASK_INT_FATAL; 140 141uint_t nb_mask_poll_thr = EMASK_THR_NF; 142uint_t nb_mask_bios_thr = EMASK_THR_FATAL; 143 144int nb5000_reset_uncor_pex = 0; 145uint_t nb5000_mask_uncor_pex = 0; 146int nb5000_reset_cor_pex = 0; 147uint_t nb5000_mask_cor_pex = 0xffffffff; 148uint32_t nb5000_rp_pex = 0x1; 149 150int nb_mask_mc_set; 151 152typedef struct find_dimm_label { 153 void (*label_function)(int, char *, int); 154} find_dimm_label_t; 155 156static void x8450_dimm_label(int, char *, int); 157static void cp3250_dimm_label(int, char *, int); 158 159static struct platform_label { 160 const char *sys_vendor; /* SMB_TYPE_SYSTEM vendor prefix */ 161 const char *sys_product; /* SMB_TYPE_SYSTEM product prefix */ 162 find_dimm_label_t dimm_label; 163 int dimms_per_channel; 164} platform_label[] = { 165 { "SUN MICROSYSTEMS", "SUN BLADE X8450 SERVER MODULE", 166 x8450_dimm_label, 8 }, 167 { "MiTAC,Shunde", "CP3250", cp3250_dimm_label, 0 }, 168 { NULL, NULL, NULL, 0 } 169}; 170 171static unsigned short 172read_spd(int bus) 173{ 174 unsigned short rt = 0; 175 int branch = bus >> 1; 176 int channel = bus & 1; 177 178 rt = SPD_RD(branch, channel); 179 180 return (rt); 181} 182 183static void 184write_spdcmd(int bus, uint32_t val) 185{ 186 int branch = bus >> 1; 187 int channel = bus & 1; 188 SPDCMD_WR(branch, channel, val); 189} 190 191static int 192read_spd_eeprom(int bus, int slave, int addr) 193{ 194 int retry = 4; 195 int wait; 196 int spd; 197 uint32_t cmd; 198 199 for (;;) { 200 wait = 1000; 201 for (;;) { 202 spd = read_spd(bus); 203 if ((spd & SPD_BUSY) == 0) 204 break; 205 if (--wait == 0) 206 return (-1); 207 drv_usecwait(10); 208 } 209 cmd = SPD_EEPROM_WRITE | SPD_ADDR(slave, addr); 210 write_spdcmd(bus, cmd); 211 wait = 1000; 212 for (;;) { 213 spd = read_spd(bus); 214 if ((spd & SPD_BUSY) == 0) 215 break; 216 if (--wait == 0) { 217 spd = SPD_BUS_ERROR; 218 break; 219 } 220 drv_usecwait(10); 221 } 222 while ((spd & SPD_BUS_ERROR) == 0 && 223 (spd & (SPD_READ_DATA_VALID|SPD_BUSY)) != 224 SPD_READ_DATA_VALID) { 225 spd = read_spd(bus); 226 if (--wait == 0) 227 return (-1); 228 } 229 if ((spd & SPD_BUS_ERROR) == 0) 230 break; 231 if (--retry == 0) 232 return (-1); 233 } 234 return (spd & 0xff); 235} 236 237static void 238nb_fini() 239{ 240 int i, j; 241 int nchannels = nb_number_memory_controllers * nb_channels_per_branch; 242 nb_dimm_t **dimmpp; 243 nb_dimm_t *dimmp; 244 245 dimmpp = nb_dimms; 246 for (i = 0; i < nchannels; i++) { 247 for (j = 0; j < nb_dimms_per_channel; j++) { 248 dimmp = *dimmpp; 249 if (dimmp) { 250 kmem_free(dimmp, sizeof (nb_dimm_t)); 251 *dimmpp = NULL; 252 } 253 dimmp++; 254 } 255 } 256 kmem_free(nb_dimms, sizeof (nb_dimm_t *) * nb_dimm_slots); 257 nb_dimms = NULL; 258 dimm_fini(); 259} 260 261void 262nb_scrubber_enable() 263{ 264 uint32_t mc; 265 266 if (!nb_hw_memory_scrub_enable) 267 return; 268 269 mc = MC_RD(); 270 if ((mc & MC_MIRROR) != 0) /* mirror mode */ 271 mc |= MC_PATROL_SCRUB; 272 else 273 mc |= MC_PATROL_SCRUB|MC_DEMAND_SCRUB; 274 MC_WR(mc); 275 276 if (nb_sw_scrub_disabled++) 277 cmi_mc_sw_memscrub_disable(); 278} 279 280static void 281fbd_eeprom(int channel, int dimm, nb_dimm_t *dp) 282{ 283 int i, t; 284 int spd_sz; 285 286 t = read_spd_eeprom(channel, dimm, 0) & 0xf; 287 if (t == 1) 288 spd_sz = 128; 289 else if (t == 2) 290 spd_sz = 176; 291 else 292 spd_sz = 256; 293 dp->manufacture_id = read_spd_eeprom(channel, dimm, 117) | 294 (read_spd_eeprom(channel, dimm, 118) << 8); 295 dp->manufacture_location = read_spd_eeprom(channel, dimm, 119); 296 dp->serial_number = 297 (read_spd_eeprom(channel, dimm, 122) << 24) | 298 (read_spd_eeprom(channel, dimm, 123) << 16) | 299 (read_spd_eeprom(channel, dimm, 124) << 8) | 300 read_spd_eeprom(channel, dimm, 125); 301 t = read_spd_eeprom(channel, dimm, 121); 302 dp->manufacture_week = (t >> 4) * 10 + (t & 0xf); 303 dp->manufacture_year = read_spd_eeprom(channel, dimm, 120); 304 if (spd_sz > 128) { 305 for (i = 0; i < sizeof (dp->part_number); i++) { 306 dp->part_number[i] = 307 read_spd_eeprom(channel, dimm, 128 + i); 308 } 309 for (i = 0; i < sizeof (dp->revision); i++) { 310 dp->revision[i] = 311 read_spd_eeprom(channel, dimm, 146 + i); 312 } 313 } 314} 315 316/* read the manR of the DDR2 dimm */ 317static void 318ddr2_eeprom(int channel, int dimm, nb_dimm_t *dp) 319{ 320 int i, t; 321 int slave; 322 323 slave = channel & 0x1 ? dimm + 4 : dimm; 324 325 /* byte[3]: number of row addresses */ 326 dp->nrow = read_spd_eeprom(channel, slave, 3) & 0x1f; 327 328 /* byte[4]: number of column addresses */ 329 dp->ncolumn = read_spd_eeprom(channel, slave, 4) & 0xf; 330 331 /* byte[5]: numranks; 0 means one rank */ 332 dp->nranks = (read_spd_eeprom(channel, slave, 5) & 0x3) + 1; 333 334 /* byte[6]: data width */ 335 dp->width = (read_spd_eeprom(channel, slave, 6) >> 5) << 2; 336 337 /* byte[17]: number of banks */ 338 dp->nbanks = read_spd_eeprom(channel, slave, 17); 339 340 dp->dimm_size = DIMMSIZE(dp->nrow, dp->ncolumn, dp->nranks, dp->nbanks, 341 dp->width); 342 343 /* manufacture-id - byte[64-65] */ 344 dp->manufacture_id = read_spd_eeprom(channel, slave, 64) | 345 (read_spd_eeprom(channel, dimm, 65) << 8); 346 347 /* location - byte[72] */ 348 dp->manufacture_location = read_spd_eeprom(channel, slave, 72); 349 350 /* serial number - byte[95-98] */ 351 dp->serial_number = 352 (read_spd_eeprom(channel, slave, 98) << 24) | 353 (read_spd_eeprom(channel, slave, 97) << 16) | 354 (read_spd_eeprom(channel, slave, 96) << 8) | 355 read_spd_eeprom(channel, slave, 95); 356 357 /* week - byte[94] */ 358 t = read_spd_eeprom(channel, slave, 94); 359 dp->manufacture_week = (t >> 4) * 10 + (t & 0xf); 360 /* week - byte[93] */ 361 t = read_spd_eeprom(channel, slave, 93); 362 dp->manufacture_year = (t >> 4) * 10 + (t & 0xf) + 2000; 363 364 /* part number - byte[73-81] */ 365 for (i = 0; i < 8; i++) { 366 dp->part_number[i] = read_spd_eeprom(channel, slave, 73 + i); 367 } 368 369 /* revision - byte[91-92] */ 370 for (i = 0; i < 2; i++) { 371 dp->revision[i] = read_spd_eeprom(channel, slave, 91 + i); 372 } 373} 374 375static boolean_t 376nb_dimm_present(int channel, int dimm) 377{ 378 boolean_t rc = B_FALSE; 379 380 if (nb_chipset == INTEL_NB_5100) { 381 int t, slave; 382 slave = channel & 0x1 ? dimm + 4 : dimm; 383 /* read the type field from the dimm and check for DDR2 type */ 384 if ((t = read_spd_eeprom(channel, slave, SPD_MEM_TYPE)) == -1) 385 return (B_FALSE); 386 rc = (t & 0xf) == SPD_DDR2; 387 } else { 388 rc = MTR_PRESENT(MTR_RD(channel, dimm)) != 0; 389 } 390 391 return (rc); 392} 393 394static nb_dimm_t * 395nb_ddr2_dimm_init(int channel, int dimm, int start_rank) 396{ 397 nb_dimm_t *dp; 398 399 if (nb_dimm_present(channel, dimm) == B_FALSE) 400 return (NULL); 401 402 dp = kmem_zalloc(sizeof (nb_dimm_t), KM_SLEEP); 403 404 ddr2_eeprom(channel, dimm, dp); 405 406 /* The 1st rank of the dimm takes on this value */ 407 dp->start_rank = (uint8_t)start_rank; 408 409 dp->mtr_present = 1; 410 411 return (dp); 412} 413 414static nb_dimm_t * 415nb_fbd_dimm_init(int channel, int dimm, uint16_t mtr) 416{ 417 nb_dimm_t *dp; 418 int t; 419 420 if (MTR_PRESENT(mtr) == 0) 421 return (NULL); 422 t = read_spd_eeprom(channel, dimm, SPD_MEM_TYPE) & 0xf; 423 424 /* check for the dimm type */ 425 if (t != SPD_FBDIMM) 426 return (NULL); 427 428 dp = kmem_zalloc(sizeof (nb_dimm_t), KM_SLEEP); 429 430 fbd_eeprom(channel, dimm, dp); 431 432 dp->mtr_present = MTR_PRESENT(mtr); 433 dp->start_rank = dimm << 1; 434 dp->nranks = MTR_NUMRANK(mtr); 435 dp->nbanks = MTR_NUMBANK(mtr); 436 dp->ncolumn = MTR_NUMCOL(mtr); 437 dp->nrow = MTR_NUMROW(mtr); 438 dp->width = MTR_WIDTH(mtr); 439 dp->dimm_size = MTR_DIMMSIZE(mtr); 440 441 return (dp); 442} 443 444static uint64_t 445mc_range(int controller, uint64_t base) 446{ 447 int i; 448 uint64_t limit = 0; 449 450 for (i = 0; i < NB_MEM_BRANCH_SELECT; i++) { 451 if (nb_banks[i].way[controller] && base >= nb_banks[i].base && 452 base < nb_banks[i].limit) { 453 limit = nb_banks[i].limit; 454 if (base <= top_of_low_memory && 455 limit > top_of_low_memory) { 456 limit -= TLOW_MAX - top_of_low_memory; 457 } 458 if (nb_banks[i].way[0] && nb_banks[i].way[1] && 459 nb_mode != NB_MEMORY_MIRROR) { 460 limit = limit / 2; 461 } 462 } 463 } 464 return (limit); 465} 466 467void 468nb_mc_init() 469{ 470 uint16_t tolm; 471 uint16_t mir; 472 uint32_t hole_base; 473 uint32_t hole_size; 474 uint32_t dmir; 475 uint64_t base; 476 uint64_t limit; 477 uint8_t way0, way1, rank0, rank1, rank2, rank3, branch_interleave; 478 int i, j, k; 479 uint8_t interleave; 480 481 base = 0; 482 tolm = TOLM_RD(); 483 top_of_low_memory = ((uint32_t)(tolm >> 12) & 0xf) << 28; 484 for (i = 0; i < NB_MEM_BRANCH_SELECT; i++) { 485 mir = MIR_RD(i); 486 limit = (uint64_t)(mir >> 4) << 28; 487 way0 = mir & 1; 488 way1 = (mir >> 1) & 1; 489 if (way0 == 0 && way1 == 0) { 490 way0 = 1; 491 way1 = 1; 492 } 493 if (limit > top_of_low_memory) 494 limit += TLOW_MAX - top_of_low_memory; 495 nb_banks[i].base = base; 496 nb_banks[i].limit = limit; 497 nb_banks[i].way[0] = way0; 498 nb_banks[i].way[1] = way1; 499 base = limit; 500 } 501 for (i = 0; i < nb_number_memory_controllers; i++) { 502 base = 0; 503 504 for (j = 0; j < NB_MEM_RANK_SELECT; j++) { 505 dmir = DMIR_RD(i, j); 506 limit = ((uint64_t)(dmir >> 16) & 0xff) << 28; 507 if (limit == 0) { 508 limit = mc_range(i, base); 509 } 510 branch_interleave = 0; 511 hole_base = 0; 512 hole_size = 0; 513 DMIR_RANKS(dmir, rank0, rank1, rank2, rank3); 514 if (rank0 == rank1) 515 interleave = 1; 516 else if (rank0 == rank2) 517 interleave = 2; 518 else 519 interleave = 4; 520 if (nb_mode != NB_MEMORY_MIRROR && 521 nb_mode != NB_MEMORY_SINGLE_CHANNEL) { 522 for (k = 0; k < NB_MEM_BRANCH_SELECT; k++) { 523 if (base >= nb_banks[k].base && 524 base < nb_banks[k].limit) { 525 if (nb_banks[i].way[0] && 526 nb_banks[i].way[1]) { 527 interleave *= 2; 528 limit *= 2; 529 branch_interleave = 1; 530 } 531 break; 532 } 533 } 534 } 535 if (base < top_of_low_memory && 536 limit > top_of_low_memory) { 537 hole_base = top_of_low_memory; 538 hole_size = TLOW_MAX - top_of_low_memory; 539 limit += hole_size; 540 } else if (base > top_of_low_memory) { 541 limit += TLOW_MAX - top_of_low_memory; 542 } 543 nb_ranks[i][j].base = base; 544 nb_ranks[i][j].limit = limit; 545 nb_ranks[i][j].rank[0] = rank0; 546 nb_ranks[i][j].rank[1] = rank1; 547 nb_ranks[i][j].rank[2] = rank2; 548 nb_ranks[i][j].rank[3] = rank3; 549 nb_ranks[i][j].interleave = interleave; 550 nb_ranks[i][j].branch_interleave = branch_interleave; 551 nb_ranks[i][j].hole_base = hole_base; 552 nb_ranks[i][j].hole_size = hole_size; 553 if (limit > base) { 554 if (rank0 != rank1) { 555 dimm_add_rank(i, rank1, 556 branch_interleave, 1, base, 557 hole_base, hole_size, interleave, 558 limit); 559 if (rank0 != rank2) { 560 dimm_add_rank(i, rank2, 561 branch_interleave, 2, base, 562 hole_base, hole_size, 563 interleave, limit); 564 dimm_add_rank(i, rank3, 565 branch_interleave, 3, base, 566 hole_base, hole_size, 567 interleave, limit); 568 } 569 } 570 } 571 base = limit; 572 } 573 } 574} 575 576void 577nb_used_spare_rank(int branch, int bad_rank) 578{ 579 int i; 580 int j; 581 582 for (i = 0; i < NB_MEM_RANK_SELECT; i++) { 583 for (j = 0; j < NB_RANKS_IN_SELECT; j++) { 584 if (nb_ranks[branch][i].rank[j] == bad_rank) { 585 nb_ranks[branch][i].rank[j] = 586 spare_rank[branch]; 587 i = NB_MEM_RANK_SELECT; 588 break; 589 } 590 } 591 } 592} 593 594find_dimm_label_t * 595find_dimms_per_channel() 596{ 597 struct platform_label *pl; 598 smbios_info_t si; 599 smbios_system_t sy; 600 id_t id; 601 int i, j; 602 find_dimm_label_t *rt = NULL; 603 604 if (ksmbios != NULL && nb_no_smbios == 0) { 605 if ((id = smbios_info_system(ksmbios, &sy)) != SMB_ERR && 606 smbios_info_common(ksmbios, id, &si) != SMB_ERR) { 607 for (pl = platform_label; pl->sys_vendor; pl++) { 608 if (strncmp(pl->sys_vendor, 609 si.smbi_manufacturer, 610 strlen(pl->sys_vendor)) == 0 && 611 strncmp(pl->sys_product, si.smbi_product, 612 strlen(pl->sys_product)) == 0) { 613 nb_dimms_per_channel = 614 pl->dimms_per_channel; 615 rt = &pl->dimm_label; 616 break; 617 } 618 } 619 } 620 } 621 if (nb_dimms_per_channel == 0) { 622 /* 623 * Scan all memory channels if we find a channel which has more 624 * dimms then we have seen before set nb_dimms_per_channel to 625 * the number of dimms on the channel 626 */ 627 for (i = 0; i < nb_number_memory_controllers; i++) { 628 for (j = nb_dimms_per_channel; 629 j < NB_MAX_DIMMS_PER_CHANNEL; j++) { 630 if (nb_dimm_present(i, j)) 631 nb_dimms_per_channel = j + 1; 632 } 633 } 634 } 635 return (rt); 636} 637 638struct smb_dimm_rec { 639 int dimms; 640 int slots; 641 int populated; 642 nb_dimm_t **dimmpp; 643}; 644 645static int 646dimm_label(smbios_hdl_t *shp, const smbios_struct_t *sp, void *arg) 647{ 648 struct smb_dimm_rec *rp = (struct smb_dimm_rec *)arg; 649 nb_dimm_t ***dimmpp; 650 nb_dimm_t *dimmp; 651 smbios_memdevice_t md; 652 653 dimmpp = &rp->dimmpp; 654 if (sp->smbstr_type == SMB_TYPE_MEMDEVICE) { 655 if (*dimmpp >= &nb_dimms[nb_dimm_slots]) 656 return (-1); 657 dimmp = **dimmpp; 658 if (smbios_info_memdevice(shp, sp->smbstr_id, &md) == 0 && 659 md.smbmd_dloc != NULL) { 660 if (md.smbmd_size) { 661 if (dimmp == NULL && 662 (rp->slots == nb_dimm_slots || 663 rp->dimms < rp->populated)) { 664 (*dimmpp)++; 665 return (0); 666 } 667 /* 668 * if there is no physical dimm for this smbios 669 * record it is because this system has less 670 * physical slots than the controller supports 671 * so skip empty slots to find the slot this 672 * smbios record belongs too 673 */ 674 while (dimmp == NULL) { 675 (*dimmpp)++; 676 if (*dimmpp >= &nb_dimms[nb_dimm_slots]) 677 return (-1); 678 dimmp = **dimmpp; 679 } 680 (void) snprintf(dimmp->label, 681 sizeof (dimmp->label), "%s", md.smbmd_dloc); 682 (*dimmpp)++; 683 } 684 } 685 } 686 return (0); 687} 688 689static int 690check_memdevice(smbios_hdl_t *shp, const smbios_struct_t *sp, void *arg) 691{ 692 struct smb_dimm_rec *rp = (struct smb_dimm_rec *)arg; 693 smbios_memdevice_t md; 694 695 if (sp->smbstr_type == SMB_TYPE_MEMDEVICE) { 696 if (smbios_info_memdevice(shp, sp->smbstr_id, &md) == 0) { 697 rp->slots++; 698 if (md.smbmd_size) { 699 rp->populated++; 700 } 701 } 702 } 703 return (0); 704} 705 706void 707nb_smbios() 708{ 709 struct smb_dimm_rec r; 710 int i; 711 712 if (ksmbios != NULL && nb_no_smbios == 0) { 713 r.dimms = 0; 714 r.slots = 0; 715 r.populated = 0; 716 r.dimmpp = nb_dimms; 717 for (i = 0; i < nb_dimm_slots; i++) { 718 if (nb_dimms[i] != NULL) 719 r.dimms++; 720 } 721 (void) smbios_iter(ksmbios, check_memdevice, &r); 722 (void) smbios_iter(ksmbios, dimm_label, &r); 723 } 724} 725 726static void 727x8450_dimm_label(int dimm, char *label, int label_sz) 728{ 729 int channel = dimm >> 3; 730 731 dimm = dimm & 0x7; 732 (void) snprintf(label, label_sz, "D%d", (dimm * 4) + channel); 733} 734 735/* 736 * CP3250 DIMM labels 737 * Channel Dimm Label 738 * 0 0 A0 739 * 1 0 B0 740 * 0 1 A1 741 * 1 1 B1 742 * 0 2 A2 743 * 1 2 B2 744 */ 745static void 746cp3250_dimm_label(int dimm, char *label, int label_sz) 747{ 748 int channel = dimm / nb_dimms_per_channel; 749 750 dimm = dimm % nb_dimms_per_channel; 751 (void) snprintf(label, label_sz, "%c%d", channel == 0 ? 'A' : 'B', 752 dimm); 753} 754 755/* 756 * Map the rank id to dimm id of a channel 757 * For the 5100 chipset, walk through the dimm list of channel the check if 758 * the given rank id is within the rank range assigned to the dimm. 759 * For other chipsets, the dimm is rank/2. 760 */ 761int 762nb_rank2dimm(int channel, int rank) 763{ 764 int i; 765 nb_dimm_t **dimmpp = nb_dimms; 766 767 if (nb_chipset != INTEL_NB_5100) 768 return (rank >> 1); 769 770 dimmpp += channel * nb_dimms_per_channel; 771 for (i = 0; i < nb_dimms_per_channel; i++) { 772 if ((rank >= dimmpp[i]->start_rank) && 773 (rank < dimmpp[i]->start_rank + dimmpp[i]->nranks)) { 774 return (i); 775 } 776 } 777 return (-1); 778} 779 780static void 781nb_ddr2_dimms_init(find_dimm_label_t *label_function) 782{ 783 int i, j; 784 int start_rank; 785 uint32_t spcpc; 786 uint8_t spcps; 787 nb_dimm_t **dimmpp; 788 789 nb_dimm_slots = nb_number_memory_controllers * nb_channels_per_branch * 790 nb_dimms_per_channel; 791 nb_dimms = (nb_dimm_t **)kmem_zalloc(sizeof (nb_dimm_t *) * 792 nb_dimm_slots, KM_SLEEP); 793 dimmpp = nb_dimms; 794 nb_mode = NB_MEMORY_NORMAL; 795 for (i = 0; i < nb_number_memory_controllers; i++) { 796 if (nb_mode == NB_MEMORY_NORMAL) { 797 spcpc = SPCPC_RD(i); 798 spcps = SPCPS_RD(i); 799 if ((spcpc & SPCPC_SPARE_ENABLE) != 0 && 800 (spcps & SPCPS_SPARE_DEPLOYED) != 0) 801 nb_mode = NB_MEMORY_SPARE_RANK; 802 spare_rank[i] = SPCPC_SPRANK(spcpc); 803 } 804 805 /* The 1st dimm of a channel starts at rank 0 */ 806 start_rank = 0; 807 808 for (j = 0; j < nb_dimms_per_channel; j++) { 809 dimmpp[j] = nb_ddr2_dimm_init(i, j, start_rank); 810 if (dimmpp[j]) { 811 nb_ndimm ++; 812 if (label_function) { 813 label_function->label_function( 814 (i * nb_dimms_per_channel) + j, 815 dimmpp[j]->label, 816 sizeof (dimmpp[j]->label)); 817 } 818 start_rank += dimmpp[j]->nranks; 819 /* 820 * add an extra rank because 821 * single-ranked dimm still takes on two ranks. 822 */ 823 if (dimmpp[j]->nranks & 0x1) 824 start_rank++; 825 } 826 } 827 dimmpp += nb_dimms_per_channel; 828 } 829 830 /* 831 * single channel is supported. 832 */ 833 if (nb_ndimm > 0 && nb_ndimm <= nb_dimms_per_channel) { 834 nb_mode = NB_MEMORY_SINGLE_CHANNEL; 835 } 836} 837 838static void 839nb_fbd_dimms_init(find_dimm_label_t *label_function) 840{ 841 int i, j, k, l; 842 uint16_t mtr; 843 uint32_t mc, mca; 844 uint32_t spcpc; 845 uint8_t spcps; 846 nb_dimm_t **dimmpp; 847 848 mca = MCA_RD(); 849 mc = MC_RD(); 850 if (mca & MCA_SCHDIMM) /* single-channel mode */ 851 nb_mode = NB_MEMORY_SINGLE_CHANNEL; 852 else if ((mc & MC_MIRROR) != 0) /* mirror mode */ 853 nb_mode = NB_MEMORY_MIRROR; 854 else 855 nb_mode = NB_MEMORY_NORMAL; 856 nb_dimm_slots = nb_number_memory_controllers * 2 * nb_dimms_per_channel; 857 nb_dimms = (nb_dimm_t **)kmem_zalloc(sizeof (nb_dimm_t *) * 858 nb_dimm_slots, KM_SLEEP); 859 dimmpp = nb_dimms; 860 for (i = 0; i < nb_number_memory_controllers; i++) { 861 if (nb_mode == NB_MEMORY_NORMAL) { 862 spcpc = SPCPC_RD(i); 863 spcps = SPCPS_RD(i); 864 if ((spcpc & SPCPC_SPARE_ENABLE) != 0 && 865 (spcps & SPCPS_SPARE_DEPLOYED) != 0) 866 nb_mode = NB_MEMORY_SPARE_RANK; 867 spare_rank[i] = SPCPC_SPRANK(spcpc); 868 } 869 for (j = 0; j < nb_dimms_per_channel; j++) { 870 mtr = MTR_RD(i, j); 871 k = i * 2; 872 dimmpp[j] = nb_fbd_dimm_init(k, j, mtr); 873 if (dimmpp[j]) { 874 nb_ndimm ++; 875 if (label_function) { 876 label_function->label_function( 877 (k * nb_dimms_per_channel) + j, 878 dimmpp[j]->label, 879 sizeof (dimmpp[j]->label)); 880 } 881 } 882 dimmpp[j + nb_dimms_per_channel] = 883 nb_fbd_dimm_init(k + 1, j, mtr); 884 l = j + nb_dimms_per_channel; 885 if (dimmpp[l]) { 886 if (label_function) { 887 label_function->label_function( 888 (k * nb_dimms_per_channel) + l, 889 dimmpp[l]->label, 890 sizeof (dimmpp[l]->label)); 891 } 892 nb_ndimm ++; 893 } 894 } 895 dimmpp += nb_dimms_per_channel * 2; 896 } 897} 898 899static void 900nb_dimms_init(find_dimm_label_t *label_function) 901{ 902 if (nb_chipset == INTEL_NB_5100) 903 nb_ddr2_dimms_init(label_function); 904 else 905 nb_fbd_dimms_init(label_function); 906 907 if (label_function == NULL) 908 nb_smbios(); 909} 910 911/* Setup the ESI port registers to enable SERR for southbridge */ 912static void 913nb_pex_init() 914{ 915 int i = 0; /* ESI port */ 916 uint16_t regw; 917 918 emask_uncor_pex[i] = EMASK_UNCOR_PEX_RD(i); 919 emask_cor_pex[i] = EMASK_COR_PEX_RD(i); 920 emask_rp_pex[i] = EMASK_RP_PEX_RD(i); 921 docmd_pex[i] = PEX_ERR_DOCMD_RD(i); 922 uncerrsev[i] = UNCERRSEV_RD(i); 923 924 if (nb5000_reset_uncor_pex) 925 EMASK_UNCOR_PEX_WR(i, nb5000_mask_uncor_pex); 926 if (nb5000_reset_cor_pex) 927 EMASK_COR_PEX_WR(i, nb5000_mask_cor_pex); 928 if (nb_chipset == INTEL_NB_5400) { 929 /* disable masking of ERR pins used by DOCMD */ 930 PEX_ERR_PIN_MASK_WR(i, 0x10); 931 } 932 933 /* RP error message (CE/NFE/FE) detect mask */ 934 EMASK_RP_PEX_WR(i, nb5000_rp_pex); 935 936 /* Command Register - Enable SERR */ 937 regw = nb_pci_getw(0, i, 0, PCI_CONF_COMM, 0); 938 nb_pci_putw(0, i, 0, PCI_CONF_COMM, 939 regw | PCI_COMM_SERR_ENABLE); 940 941 /* Root Control Register - SERR on NFE/FE */ 942 PEXROOTCTL_WR(i, PCIE_ROOTCTL_SYS_ERR_ON_NFE_EN | 943 PCIE_ROOTCTL_SYS_ERR_ON_FE_EN); 944 945 /* AER UE Mask - Mask UR */ 946 UNCERRMSK_WR(i, PCIE_AER_UCE_UR); 947} 948 949static void 950nb_pex_fini() 951{ 952 int i = 0; /* ESI port */ 953 954 EMASK_UNCOR_PEX_WR(i, emask_uncor_pex[i]); 955 EMASK_COR_PEX_WR(i, emask_cor_pex[i]); 956 EMASK_RP_PEX_WR(i, emask_rp_pex[i]); 957 PEX_ERR_DOCMD_WR(i, docmd_pex[i]); 958 959 if (nb5000_reset_uncor_pex) 960 EMASK_UNCOR_PEX_WR(i, nb5000_mask_uncor_pex); 961 if (nb5000_reset_cor_pex) 962 EMASK_COR_PEX_WR(i, nb5000_mask_cor_pex); 963} 964 965void 966nb_int_init() 967{ 968 uint32_t err0_int; 969 uint32_t err1_int; 970 uint32_t err2_int; 971 uint32_t mcerr_int; 972 uint32_t emask_int; 973 uint16_t stepping; 974 975 err0_int = ERR0_INT_RD(); 976 err1_int = ERR1_INT_RD(); 977 err2_int = ERR2_INT_RD(); 978 mcerr_int = MCERR_INT_RD(); 979 emask_int = EMASK_INT_RD(); 980 981 nb_err0_int = err0_int; 982 nb_err1_int = err1_int; 983 nb_err2_int = err2_int; 984 nb_mcerr_int = mcerr_int; 985 nb_emask_int = emask_int; 986 987 ERR0_INT_WR(ERR_INT_ALL); 988 ERR1_INT_WR(ERR_INT_ALL); 989 ERR2_INT_WR(ERR_INT_ALL); 990 MCERR_INT_WR(ERR_INT_ALL); 991 EMASK_INT_WR(ERR_INT_ALL); 992 993 mcerr_int &= ~nb5000_mask_bios_int; 994 mcerr_int |= nb5000_mask_bios_int & (~err0_int | ~err1_int | ~err2_int); 995 mcerr_int |= nb5000_mask_poll_int; 996 err0_int |= nb5000_mask_poll_int; 997 err1_int |= nb5000_mask_poll_int; 998 err2_int |= nb5000_mask_poll_int; 999 1000 l_mcerr_int = mcerr_int; 1001 ERR0_INT_WR(err0_int); 1002 ERR1_INT_WR(err1_int); 1003 ERR2_INT_WR(err2_int); 1004 MCERR_INT_WR(mcerr_int); 1005 if (nb5000_reset_emask_int) { 1006 if (nb_chipset == INTEL_NB_7300) { 1007 stepping = NB5000_STEPPING(); 1008 if (stepping == 0) 1009 EMASK_5000_INT_WR(nb7300_emask_int_step0); 1010 else 1011 EMASK_5000_INT_WR(nb7300_emask_int); 1012 } else if (nb_chipset == INTEL_NB_5400) { 1013 EMASK_5400_INT_WR(nb5400_emask_int | 1014 (emask_int & EMASK_INT_RES)); 1015 } else { 1016 EMASK_5000_INT_WR(nb5000_emask_int); 1017 } 1018 } else { 1019 EMASK_INT_WR(nb_emask_int); 1020 } 1021} 1022 1023void 1024nb_int_fini() 1025{ 1026 ERR0_INT_WR(ERR_INT_ALL); 1027 ERR1_INT_WR(ERR_INT_ALL); 1028 ERR2_INT_WR(ERR_INT_ALL); 1029 MCERR_INT_WR(ERR_INT_ALL); 1030 EMASK_INT_WR(ERR_INT_ALL); 1031 1032 ERR0_INT_WR(nb_err0_int); 1033 ERR1_INT_WR(nb_err1_int); 1034 ERR2_INT_WR(nb_err2_int); 1035 MCERR_INT_WR(nb_mcerr_int); 1036 EMASK_INT_WR(nb_emask_int); 1037} 1038 1039void 1040nb_int_mask_mc(uint32_t mc_mask_int) 1041{ 1042 uint32_t emask_int; 1043 1044 emask_int = MCERR_INT_RD(); 1045 if ((emask_int & mc_mask_int) != mc_mask_int) { 1046 MCERR_INT_WR(emask_int|mc_mask_int); 1047 nb_mask_mc_set = 1; 1048 } 1049} 1050 1051static void 1052nb_fbd_init() 1053{ 1054 uint32_t err0_fbd; 1055 uint32_t err1_fbd; 1056 uint32_t err2_fbd; 1057 uint32_t mcerr_fbd; 1058 uint32_t emask_fbd; 1059 uint32_t emask_bios_fbd; 1060 uint32_t emask_poll_fbd; 1061 1062 err0_fbd = ERR0_FBD_RD(); 1063 err1_fbd = ERR1_FBD_RD(); 1064 err2_fbd = ERR2_FBD_RD(); 1065 mcerr_fbd = MCERR_FBD_RD(); 1066 emask_fbd = EMASK_FBD_RD(); 1067 1068 nb_err0_fbd = err0_fbd; 1069 nb_err1_fbd = err1_fbd; 1070 nb_err2_fbd = err2_fbd; 1071 nb_mcerr_fbd = mcerr_fbd; 1072 nb_emask_fbd = emask_fbd; 1073 1074 ERR0_FBD_WR(0xffffffff); 1075 ERR1_FBD_WR(0xffffffff); 1076 ERR2_FBD_WR(0xffffffff); 1077 MCERR_FBD_WR(0xffffffff); 1078 EMASK_FBD_WR(0xffffffff); 1079 1080 if (nb_chipset == INTEL_NB_7300 && nb_mode == NB_MEMORY_MIRROR) { 1081 /* MCH 7300 errata 34 */ 1082 emask_bios_fbd = nb5000_mask_bios_fbd & ~EMASK_FBD_M23; 1083 emask_poll_fbd = nb5000_mask_poll_fbd; 1084 mcerr_fbd |= EMASK_FBD_M23; 1085 } else if (nb_chipset == INTEL_NB_5400) { 1086 emask_bios_fbd = nb5400_mask_bios_fbd; 1087 emask_poll_fbd = nb5400_mask_poll_fbd; 1088 } else { 1089 emask_bios_fbd = nb5000_mask_bios_fbd; 1090 emask_poll_fbd = nb5000_mask_poll_fbd; 1091 } 1092 mcerr_fbd &= ~emask_bios_fbd; 1093 mcerr_fbd |= emask_bios_fbd & (~err0_fbd | ~err1_fbd | ~err2_fbd); 1094 mcerr_fbd |= emask_poll_fbd; 1095 err0_fbd |= emask_poll_fbd; 1096 err1_fbd |= emask_poll_fbd; 1097 err2_fbd |= emask_poll_fbd; 1098 1099 l_mcerr_fbd = mcerr_fbd; 1100 ERR0_FBD_WR(err0_fbd); 1101 ERR1_FBD_WR(err1_fbd); 1102 ERR2_FBD_WR(err2_fbd); 1103 MCERR_FBD_WR(mcerr_fbd); 1104 if (nb5000_reset_emask_fbd) { 1105 if (nb_chipset == INTEL_NB_5400) 1106 EMASK_FBD_WR(nb5400_emask_fbd); 1107 else 1108 EMASK_FBD_WR(nb5000_emask_fbd); 1109 } else { 1110 EMASK_FBD_WR(nb_emask_fbd); 1111 } 1112} 1113 1114void 1115nb_fbd_mask_mc(uint32_t mc_mask_fbd) 1116{ 1117 uint32_t emask_fbd; 1118 1119 emask_fbd = MCERR_FBD_RD(); 1120 if ((emask_fbd & mc_mask_fbd) != mc_mask_fbd) { 1121 MCERR_FBD_WR(emask_fbd|mc_mask_fbd); 1122 nb_mask_mc_set = 1; 1123 } 1124} 1125 1126static void 1127nb_fbd_fini() 1128{ 1129 ERR0_FBD_WR(0xffffffff); 1130 ERR1_FBD_WR(0xffffffff); 1131 ERR2_FBD_WR(0xffffffff); 1132 MCERR_FBD_WR(0xffffffff); 1133 EMASK_FBD_WR(0xffffffff); 1134 1135 ERR0_FBD_WR(nb_err0_fbd); 1136 ERR1_FBD_WR(nb_err1_fbd); 1137 ERR2_FBD_WR(nb_err2_fbd); 1138 MCERR_FBD_WR(nb_mcerr_fbd); 1139 EMASK_FBD_WR(nb_emask_fbd); 1140} 1141 1142static void 1143nb_mem_init() 1144{ 1145 uint32_t err0_mem; 1146 uint32_t err1_mem; 1147 uint32_t err2_mem; 1148 uint32_t mcerr_mem; 1149 uint32_t emask_mem; 1150 uint32_t emask_poll_mem; 1151 1152 err0_mem = ERR0_MEM_RD(); 1153 err1_mem = ERR1_MEM_RD(); 1154 err2_mem = ERR2_MEM_RD(); 1155 mcerr_mem = MCERR_MEM_RD(); 1156 emask_mem = EMASK_MEM_RD(); 1157 1158 nb_err0_mem = err0_mem; 1159 nb_err1_mem = err1_mem; 1160 nb_err2_mem = err2_mem; 1161 nb_mcerr_mem = mcerr_mem; 1162 nb_emask_mem = emask_mem; 1163 1164 ERR0_MEM_WR(0xffffffff); 1165 ERR1_MEM_WR(0xffffffff); 1166 ERR2_MEM_WR(0xffffffff); 1167 MCERR_MEM_WR(0xffffffff); 1168 EMASK_MEM_WR(0xffffffff); 1169 1170 emask_poll_mem = nb5100_mask_poll_mem; 1171 mcerr_mem |= emask_poll_mem; 1172 err0_mem |= emask_poll_mem; 1173 err1_mem |= emask_poll_mem; 1174 err2_mem |= emask_poll_mem; 1175 1176 l_mcerr_mem = mcerr_mem; 1177 ERR0_MEM_WR(err0_mem); 1178 ERR1_MEM_WR(err1_mem); 1179 ERR2_MEM_WR(err2_mem); 1180 MCERR_MEM_WR(mcerr_mem); 1181 if (nb5100_reset_emask_mem) { 1182 EMASK_MEM_WR(~nb5100_mask_poll_mem); 1183 } else { 1184 EMASK_MEM_WR(nb_emask_mem); 1185 } 1186} 1187 1188void 1189nb_mem_mask_mc(uint32_t mc_mask_mem) 1190{ 1191 uint32_t emask_mem; 1192 1193 emask_mem = MCERR_MEM_RD(); 1194 if ((emask_mem & mc_mask_mem) != mc_mask_mem) { 1195 MCERR_MEM_WR(emask_mem|mc_mask_mem); 1196 nb_mask_mc_set = 1; 1197 } 1198} 1199 1200static void 1201nb_mem_fini() 1202{ 1203 ERR0_MEM_WR(0xffffffff); 1204 ERR1_MEM_WR(0xffffffff); 1205 ERR2_MEM_WR(0xffffffff); 1206 MCERR_MEM_WR(0xffffffff); 1207 EMASK_MEM_WR(0xffffffff); 1208 1209 ERR0_MEM_WR(nb_err0_mem); 1210 ERR1_MEM_WR(nb_err1_mem); 1211 ERR2_MEM_WR(nb_err2_mem); 1212 MCERR_MEM_WR(nb_mcerr_mem); 1213 EMASK_MEM_WR(nb_emask_mem); 1214} 1215 1216static void 1217nb_fsb_init() 1218{ 1219 uint16_t err0_fsb; 1220 uint16_t err1_fsb; 1221 uint16_t err2_fsb; 1222 uint16_t mcerr_fsb; 1223 uint16_t emask_fsb; 1224 1225 err0_fsb = ERR0_FSB_RD(0); 1226 err1_fsb = ERR1_FSB_RD(0); 1227 err2_fsb = ERR2_FSB_RD(0); 1228 mcerr_fsb = MCERR_FSB_RD(0); 1229 emask_fsb = EMASK_FSB_RD(0); 1230 1231 ERR0_FSB_WR(0, 0xffff); 1232 ERR1_FSB_WR(0, 0xffff); 1233 ERR2_FSB_WR(0, 0xffff); 1234 MCERR_FSB_WR(0, 0xffff); 1235 EMASK_FSB_WR(0, 0xffff); 1236 1237 ERR0_FSB_WR(1, 0xffff); 1238 ERR1_FSB_WR(1, 0xffff); 1239 ERR2_FSB_WR(1, 0xffff); 1240 MCERR_FSB_WR(1, 0xffff); 1241 EMASK_FSB_WR(1, 0xffff); 1242 1243 nb_err0_fsb = err0_fsb; 1244 nb_err1_fsb = err1_fsb; 1245 nb_err2_fsb = err2_fsb; 1246 nb_mcerr_fsb = mcerr_fsb; 1247 nb_emask_fsb = emask_fsb; 1248 1249 mcerr_fsb &= ~nb5000_mask_bios_fsb; 1250 mcerr_fsb |= nb5000_mask_bios_fsb & (~err2_fsb | ~err1_fsb | ~err0_fsb); 1251 mcerr_fsb |= nb5000_mask_poll_fsb; 1252 err0_fsb |= nb5000_mask_poll_fsb; 1253 err1_fsb |= nb5000_mask_poll_fsb; 1254 err2_fsb |= nb5000_mask_poll_fsb; 1255 1256 l_mcerr_fsb = mcerr_fsb; 1257 ERR0_FSB_WR(0, err0_fsb); 1258 ERR1_FSB_WR(0, err1_fsb); 1259 ERR2_FSB_WR(0, err2_fsb); 1260 MCERR_FSB_WR(0, mcerr_fsb); 1261 if (nb5000_reset_emask_fsb) { 1262 EMASK_FSB_WR(0, nb5000_emask_fsb); 1263 } else { 1264 EMASK_FSB_WR(0, nb_emask_fsb); 1265 } 1266 1267 ERR0_FSB_WR(1, err0_fsb); 1268 ERR1_FSB_WR(1, err1_fsb); 1269 ERR2_FSB_WR(1, err2_fsb); 1270 MCERR_FSB_WR(1, mcerr_fsb); 1271 if (nb5000_reset_emask_fsb) { 1272 EMASK_FSB_WR(1, nb5000_emask_fsb); 1273 } else { 1274 EMASK_FSB_WR(1, nb_emask_fsb); 1275 } 1276 1277 if (nb_chipset == INTEL_NB_7300) { 1278 ERR0_FSB_WR(2, 0xffff); 1279 ERR1_FSB_WR(2, 0xffff); 1280 ERR2_FSB_WR(2, 0xffff); 1281 MCERR_FSB_WR(2, 0xffff); 1282 EMASK_FSB_WR(2, 0xffff); 1283 1284 ERR0_FSB_WR(3, 0xffff); 1285 ERR1_FSB_WR(3, 0xffff); 1286 ERR2_FSB_WR(3, 0xffff); 1287 MCERR_FSB_WR(3, 0xffff); 1288 EMASK_FSB_WR(3, 0xffff); 1289 1290 ERR0_FSB_WR(2, err0_fsb); 1291 ERR1_FSB_WR(2, err1_fsb); 1292 ERR2_FSB_WR(2, err2_fsb); 1293 MCERR_FSB_WR(2, mcerr_fsb); 1294 if (nb5000_reset_emask_fsb) { 1295 EMASK_FSB_WR(2, nb5000_emask_fsb); 1296 } else { 1297 EMASK_FSB_WR(2, nb_emask_fsb); 1298 } 1299 1300 ERR0_FSB_WR(3, err0_fsb); 1301 ERR1_FSB_WR(3, err1_fsb); 1302 ERR2_FSB_WR(3, err2_fsb); 1303 MCERR_FSB_WR(3, mcerr_fsb); 1304 if (nb5000_reset_emask_fsb) { 1305 EMASK_FSB_WR(3, nb5000_emask_fsb); 1306 } else { 1307 EMASK_FSB_WR(3, nb_emask_fsb); 1308 } 1309 } 1310} 1311 1312static void 1313nb_fsb_fini() { 1314 ERR0_FSB_WR(0, 0xffff); 1315 ERR1_FSB_WR(0, 0xffff); 1316 ERR2_FSB_WR(0, 0xffff); 1317 MCERR_FSB_WR(0, 0xffff); 1318 EMASK_FSB_WR(0, 0xffff); 1319 1320 ERR0_FSB_WR(0, nb_err0_fsb); 1321 ERR1_FSB_WR(0, nb_err1_fsb); 1322 ERR2_FSB_WR(0, nb_err2_fsb); 1323 MCERR_FSB_WR(0, nb_mcerr_fsb); 1324 EMASK_FSB_WR(0, nb_emask_fsb); 1325 1326 ERR0_FSB_WR(1, 0xffff); 1327 ERR1_FSB_WR(1, 0xffff); 1328 ERR2_FSB_WR(1, 0xffff); 1329 MCERR_FSB_WR(1, 0xffff); 1330 EMASK_FSB_WR(1, 0xffff); 1331 1332 ERR0_FSB_WR(1, nb_err0_fsb); 1333 ERR1_FSB_WR(1, nb_err1_fsb); 1334 ERR2_FSB_WR(1, nb_err2_fsb); 1335 MCERR_FSB_WR(1, nb_mcerr_fsb); 1336 EMASK_FSB_WR(1, nb_emask_fsb); 1337 1338 if (nb_chipset == INTEL_NB_7300) { 1339 ERR0_FSB_WR(2, 0xffff); 1340 ERR1_FSB_WR(2, 0xffff); 1341 ERR2_FSB_WR(2, 0xffff); 1342 MCERR_FSB_WR(2, 0xffff); 1343 EMASK_FSB_WR(2, 0xffff); 1344 1345 ERR0_FSB_WR(2, nb_err0_fsb); 1346 ERR1_FSB_WR(2, nb_err1_fsb); 1347 ERR2_FSB_WR(2, nb_err2_fsb); 1348 MCERR_FSB_WR(2, nb_mcerr_fsb); 1349 EMASK_FSB_WR(2, nb_emask_fsb); 1350 1351 ERR0_FSB_WR(3, 0xffff); 1352 ERR1_FSB_WR(3, 0xffff); 1353 ERR2_FSB_WR(3, 0xffff); 1354 MCERR_FSB_WR(3, 0xffff); 1355 EMASK_FSB_WR(3, 0xffff); 1356 1357 ERR0_FSB_WR(3, nb_err0_fsb); 1358 ERR1_FSB_WR(3, nb_err1_fsb); 1359 ERR2_FSB_WR(3, nb_err2_fsb); 1360 MCERR_FSB_WR(3, nb_mcerr_fsb); 1361 EMASK_FSB_WR(3, nb_emask_fsb); 1362 } 1363} 1364 1365void 1366nb_fsb_mask_mc(int fsb, uint16_t mc_mask_fsb) 1367{ 1368 uint16_t emask_fsb; 1369 1370 emask_fsb = MCERR_FSB_RD(fsb); 1371 if ((emask_fsb & mc_mask_fsb) != mc_mask_fsb) { 1372 MCERR_FSB_WR(fsb, emask_fsb|mc_mask_fsb|EMASK_FBD_RES); 1373 nb_mask_mc_set = 1; 1374 } 1375} 1376 1377static void 1378nb_thr_init() 1379{ 1380 uint16_t err0_thr; 1381 uint16_t err1_thr; 1382 uint16_t err2_thr; 1383 uint16_t mcerr_thr; 1384 uint16_t emask_thr; 1385 1386 if (nb_chipset == INTEL_NB_5400) { 1387 err0_thr = ERR0_THR_RD(0); 1388 err1_thr = ERR1_THR_RD(0); 1389 err2_thr = ERR2_THR_RD(0); 1390 mcerr_thr = MCERR_THR_RD(0); 1391 emask_thr = EMASK_THR_RD(0); 1392 1393 ERR0_THR_WR(0xffff); 1394 ERR1_THR_WR(0xffff); 1395 ERR2_THR_WR(0xffff); 1396 MCERR_THR_WR(0xffff); 1397 EMASK_THR_WR(0xffff); 1398 1399 nb_err0_thr = err0_thr; 1400 nb_err1_thr = err1_thr; 1401 nb_err2_thr = err2_thr; 1402 nb_mcerr_thr = mcerr_thr; 1403 nb_emask_thr = emask_thr; 1404 1405 mcerr_thr &= ~nb_mask_bios_thr; 1406 mcerr_thr |= nb_mask_bios_thr & 1407 (~err2_thr | ~err1_thr | ~err0_thr); 1408 mcerr_thr |= nb_mask_poll_thr; 1409 err0_thr |= nb_mask_poll_thr; 1410 err1_thr |= nb_mask_poll_thr; 1411 err2_thr |= nb_mask_poll_thr; 1412 1413 l_mcerr_thr = mcerr_thr; 1414 ERR0_THR_WR(err0_thr); 1415 ERR1_THR_WR(err1_thr); 1416 ERR2_THR_WR(err2_thr); 1417 MCERR_THR_WR(mcerr_thr); 1418 EMASK_THR_WR(nb_emask_thr); 1419 } 1420} 1421 1422static void 1423nb_thr_fini() 1424{ 1425 if (nb_chipset == INTEL_NB_5400) { 1426 ERR0_THR_WR(0xffff); 1427 ERR1_THR_WR(0xffff); 1428 ERR2_THR_WR(0xffff); 1429 MCERR_THR_WR(0xffff); 1430 EMASK_THR_WR(0xffff); 1431 1432 ERR0_THR_WR(nb_err0_thr); 1433 ERR1_THR_WR(nb_err1_thr); 1434 ERR2_THR_WR(nb_err2_thr); 1435 MCERR_THR_WR(nb_mcerr_thr); 1436 EMASK_THR_WR(nb_emask_thr); 1437 } 1438} 1439 1440void 1441nb_thr_mask_mc(uint16_t mc_mask_thr) 1442{ 1443 uint16_t emask_thr; 1444 1445 emask_thr = MCERR_THR_RD(0); 1446 if ((emask_thr & mc_mask_thr) != mc_mask_thr) { 1447 MCERR_THR_WR(emask_thr|mc_mask_thr); 1448 nb_mask_mc_set = 1; 1449 } 1450} 1451 1452void 1453nb_mask_mc_reset() 1454{ 1455 if (nb_chipset == INTEL_NB_5100) 1456 MCERR_MEM_WR(l_mcerr_mem); 1457 else 1458 MCERR_FBD_WR(l_mcerr_fbd); 1459 MCERR_INT_WR(l_mcerr_int); 1460 MCERR_FSB_WR(0, l_mcerr_fsb); 1461 MCERR_FSB_WR(1, l_mcerr_fsb); 1462 if (nb_chipset == INTEL_NB_7300) { 1463 MCERR_FSB_WR(2, l_mcerr_fsb); 1464 MCERR_FSB_WR(3, l_mcerr_fsb); 1465 } 1466 if (nb_chipset == INTEL_NB_5400) { 1467 MCERR_THR_WR(l_mcerr_thr); 1468 } 1469} 1470 1471int 1472nb_dev_init() 1473{ 1474 find_dimm_label_t *label_function_p; 1475 1476 label_function_p = find_dimms_per_channel(); 1477 mutex_init(&nb_mutex, NULL, MUTEX_DRIVER, NULL); 1478 nb_queue = errorq_create("nb_queue", nb_drain, NULL, NB_MAX_ERRORS, 1479 sizeof (nb_logout_t), 1, ERRORQ_VITAL); 1480 if (nb_queue == NULL) { 1481 mutex_destroy(&nb_mutex); 1482 return (EAGAIN); 1483 } 1484 nb_int_init(); 1485 nb_thr_init(); 1486 dimm_init(); 1487 nb_dimms_init(label_function_p); 1488 nb_mc_init(); 1489 nb_pex_init(); 1490 if (nb_chipset == INTEL_NB_5100) 1491 nb_mem_init(); 1492 else 1493 nb_fbd_init(); 1494 nb_fsb_init(); 1495 nb_scrubber_enable(); 1496 return (0); 1497} 1498 1499int 1500nb_init() 1501{ 1502 /* return ENOTSUP if there is no PCI config space support. */ 1503 if (pci_getl_func == NULL) 1504 return (ENOTSUP); 1505 1506 /* get vendor and device */ 1507 nb_chipset = (*pci_getl_func)(0, 0, 0, PCI_CONF_VENID); 1508 switch (nb_chipset) { 1509 default: 1510 if (nb_5000_memory_controller == 0) 1511 return (ENOTSUP); 1512 break; 1513 case INTEL_NB_7300: 1514 case INTEL_NB_5000P: 1515 case INTEL_NB_5000X: 1516 break; 1517 case INTEL_NB_5000V: 1518 case INTEL_NB_5000Z: 1519 nb_number_memory_controllers = 1; 1520 break; 1521 case INTEL_NB_5100: 1522 nb_channels_per_branch = 1; 1523 break; 1524 case INTEL_NB_5400: 1525 case INTEL_NB_5400A: 1526 case INTEL_NB_5400B: 1527 nb_chipset = INTEL_NB_5400; 1528 break; 1529 } 1530 return (0); 1531} 1532 1533void 1534nb_dev_reinit() 1535{ 1536 int i, j; 1537 int nchannels = nb_number_memory_controllers * 2; 1538 nb_dimm_t **dimmpp; 1539 nb_dimm_t *dimmp; 1540 nb_dimm_t **old_nb_dimms; 1541 int old_nb_dimms_per_channel; 1542 find_dimm_label_t *label_function_p; 1543 int dimm_slot = nb_dimm_slots; 1544 1545 old_nb_dimms = nb_dimms; 1546 old_nb_dimms_per_channel = nb_dimms_per_channel; 1547 1548 dimm_fini(); 1549 nb_dimms_per_channel = 0; 1550 label_function_p = find_dimms_per_channel(); 1551 dimm_init(); 1552 nb_dimms_init(label_function_p); 1553 nb_mc_init(); 1554 nb_pex_init(); 1555 nb_int_init(); 1556 nb_thr_init(); 1557 if (nb_chipset == INTEL_NB_5100) 1558 nb_mem_init(); 1559 else 1560 nb_fbd_init(); 1561 nb_fsb_init(); 1562 nb_scrubber_enable(); 1563 1564 dimmpp = old_nb_dimms; 1565 for (i = 0; i < nchannels; i++) { 1566 for (j = 0; j < old_nb_dimms_per_channel; j++) { 1567 dimmp = *dimmpp; 1568 if (dimmp) { 1569 kmem_free(dimmp, sizeof (nb_dimm_t)); 1570 *dimmpp = NULL; 1571 } 1572 dimmp++; 1573 } 1574 } 1575 kmem_free(old_nb_dimms, sizeof (nb_dimm_t *) * dimm_slot); 1576} 1577 1578void 1579nb_dev_unload() 1580{ 1581 errorq_destroy(nb_queue); 1582 nb_queue = NULL; 1583 mutex_destroy(&nb_mutex); 1584 nb_int_fini(); 1585 nb_thr_fini(); 1586 if (nb_chipset == INTEL_NB_5100) 1587 nb_mem_fini(); 1588 else 1589 nb_fbd_fini(); 1590 nb_fsb_fini(); 1591 nb_pex_fini(); 1592 nb_fini(); 1593} 1594 1595void 1596nb_unload() 1597{ 1598} 1599