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 /* 28 * Starcat Specific Glue for Safari Configurator 29 */ 30 31 #include <sys/isa_defs.h> 32 #include <sys/conf.h> 33 #include <sys/kmem.h> 34 #include <sys/debug.h> 35 #include <sys/modctl.h> 36 #include <sys/autoconf.h> 37 #include <sys/hwconf.h> 38 #include <sys/ddi_impldefs.h> 39 #include <sys/ddi.h> 40 #include <sys/sunddi.h> 41 #include <sys/sunndi.h> 42 #include <sys/ndi_impldefs.h> 43 #include <sys/safari_pcd.h> 44 #include <sys/gp2cfg.h> 45 #include <sys/gptwo_cpu.h> 46 #include <sys/gptwo_pci.h> 47 #include <sys/sc_gptwocfg.h> 48 #include <post/scat_dcd.h> 49 #include <sys/machsystm.h> 50 51 int sc_gptwocfg_debug = 0; 52 53 #define SC_DEBUG(level, args) if (sc_gptwocfg_debug >= level) cmn_err args 54 55 typedef struct sc_gptwocfg_config { 56 int board; 57 struct gptwocfg_config *port_cookie; 58 gptwo_aid_t portid; 59 struct sc_gptwocfg_config *link; 60 struct sc_gptwocfg_config *next; 61 } sc_gptwocfg_config_t; 62 63 static kmutex_t sc_gptwo_config_list_lock; 64 static sc_gptwocfg_config_t *sc_gptwo_config_list; 65 static dev_info_t *sc_find_axq_node(uint_t); 66 static sc_gptwocfg_cookie_t sc_configure(uint_t, int); 67 static spcd_t *sc_get_common_pcd(uint_t, uint_t); 68 static void sc_free_common_pcd(spcd_t *); 69 static gptwo_new_nodes_t *sc_gptwocfg_configure_axq(dev_info_t *, uint_t, int); 70 static gptwocfg_config_t *sc_gptwocfg_unconfigure_axq(gptwocfg_config_t *); 71 static void dump_config(sc_gptwocfg_config_t *); 72 static void dump_pcd(spcd_t *); 73 static uint_t sc_get_agent_id(spcd_t *, uint_t, uint_t, uint_t); 74 static char *rsv_string(prdrsv_t); 75 76 extern gptwo_new_nodes_t *gptwocfg_allocate_node_list(int); 77 extern void gptwocfg_free_node_list(gptwo_new_nodes_t *); 78 79 static uint8_t *get_memlayout(uint32_t, uint32_t *); 80 81 #ifdef NO_IOSRAM 82 int iosram_rd(uint32_t, uint32_t, uint32_t, caddr_t); 83 #else 84 extern int iosram_rd(uint32_t, uint32_t, uint32_t, caddr_t); 85 #endif 86 extern void gptwocfg_devi_attach_to_parent(dev_info_t *); 87 88 /* 89 * Module control operations 90 */ 91 92 extern struct mod_ops mod_miscops; 93 94 static struct modlmisc modlmisc = { 95 &mod_miscops, /* Type of module */ 96 "Sun Fire 15000 gptwocfg" 97 }; 98 99 static struct modlinkage modlinkage = { 100 MODREV_1, (void *)&modlmisc, NULL 101 }; 102 103 int 104 _init() 105 { 106 int err = 0; 107 108 mutex_init(&sc_gptwo_config_list_lock, NULL, MUTEX_DRIVER, NULL); 109 sc_gptwo_config_list = NULL; 110 111 /* 112 * CPU/PCI devices are already registered by their respective modules, 113 * so all we need to do now is install. 114 */ 115 if ((err = mod_install(&modlinkage)) != 0) { 116 SC_DEBUG(1, (CE_WARN, "sc_gptwocfg failed to load, error=%d\n", 117 err)); 118 mutex_destroy(&sc_gptwo_config_list_lock); 119 } else { 120 SC_DEBUG(1, (CE_WARN, "sc_gptwocfg has been loaded.\n")); 121 } 122 return (err); 123 } 124 125 int 126 _fini(void) 127 { 128 mutex_destroy(&sc_gptwo_config_list_lock); 129 return (mod_remove(&modlinkage)); 130 } 131 132 int 133 _info(modinfop) 134 struct modinfo *modinfop; 135 { 136 return (mod_info(&modlinkage, modinfop)); 137 } 138 139 static spcd_t * 140 sc_get_common_pcd(uint_t expander, uint_t prd_slot) 141 { 142 spcd_t *pcd; 143 gdcd_t *gdcd; 144 int portid; 145 int i, j, slot; 146 int dimm; 147 char *label1, *label2; 148 149 SC_DEBUG(1, (CE_WARN, "sc_get_common_pcd() expander=%d prd_slot=%d\n", 150 expander, prd_slot)); 151 152 gdcd = (gdcd_t *)kmem_zalloc(sizeof (gdcd_t), KM_SLEEP); 153 154 /* 155 * Get the Starcat Specific Global DCD Structure from the golden 156 * IOSRAM. 157 */ 158 if (iosram_rd(GDCD_MAGIC, 0, sizeof (gdcd_t), (caddr_t)gdcd)) { 159 cmn_err(CE_WARN, "sc_gptwocfg: Unable To Read GDCD " 160 "From IOSRAM\n"); 161 kmem_free(gdcd, sizeof (gdcd_t)); 162 return (NULL); 163 } 164 165 if (gdcd->h.dcd_magic != GDCD_MAGIC) { 166 167 cmn_err(CE_WARN, "sc_gptwocfg: GDCD Bad Magic 0x%x\n", 168 gdcd->h.dcd_magic); 169 170 kmem_free(gdcd, sizeof (gdcd_t)); 171 return (NULL); 172 } 173 174 if (gdcd->h.dcd_version != DCD_VERSION) { 175 cmn_err(CE_WARN, "sc_gptwocfg: GDCD Bad Version: " 176 "GDCD Version 0x%x Expecting 0x%x\n", 177 gdcd->h.dcd_version, DCD_VERSION); 178 179 kmem_free(gdcd, sizeof (gdcd_t)); 180 return (NULL); 181 } 182 183 pcd = (spcd_t *)kmem_zalloc(sizeof (spcd_t), KM_SLEEP); 184 185 /* 186 * Copy various information from the platform specific Port 187 * Resource Descriptor (PRD) To the platform independent 188 * Port Configuration Descriptor. 189 */ 190 pcd->spcd_magic = PCD_MAGIC; 191 pcd->spcd_version = PCD_VERSION; 192 pcd->spcd_ptype = gdcd->dcd_prd[expander][prd_slot].prd_ptype; 193 pcd->spcd_ver_reg = gdcd->dcd_prd[expander][prd_slot].prd_ver_reg; 194 195 if (pcd->spcd_ptype == SAFPTYPE_CPU) { 196 /* 197 * This will calculate the cpu speed based on the 198 * the actual frequency ratio * interconnect frequency 199 * converted to Mhz. 200 */ 201 pcd->spcd_afreq = gdcd->dcd_prd[expander][prd_slot]. 202 prd_afreq_ratio * 203 (uint16_t)((gdcd->dcd_intercon_freq + 500000) / 1000000); 204 } else { 205 /* 206 * For non-cpu devices, just pass through the frequency 207 * unchanged. 208 */ 209 pcd->spcd_afreq = 210 gdcd->dcd_prd[expander][prd_slot].prd_afreq_ratio; 211 } 212 213 pcd->spcd_cache = gdcd->dcd_prd[expander][prd_slot].prd_cache; 214 215 SC_DEBUG(1, (CE_WARN, "Safari Device Status status=0x%x\n", 216 gdcd->dcd_prd[expander][prd_slot].prd_prsv)); 217 218 /* 219 * Fill in the entire port status. 220 */ 221 if (RSV_GOOD(gdcd->dcd_prd[expander][prd_slot].prd_prsv)) { 222 pcd->spcd_prsv = SPCD_RSV_PASS; 223 } else { 224 pcd->spcd_prsv = SPCD_RSV_FAIL; 225 } 226 227 /* 228 * Fill in the per agent status. 229 */ 230 if (gdcd->dcd_prd[expander][prd_slot].prd_agent[1] == RSV_UNKNOWN) { 231 pcd->spcd_agent[0] = pcd->spcd_prsv; 232 pcd->spcd_agent[1] = SPCD_RSV_FAIL; 233 } else { 234 for (i = 0; i < AGENTS_PER_PORT; i++) { 235 236 if (RSV_GOOD( 237 gdcd->dcd_prd[expander][prd_slot].prd_agent[i])) 238 pcd->spcd_agent[i] = SPCD_RSV_PASS; 239 else 240 pcd->spcd_agent[i] = SPCD_RSV_FAIL; 241 } 242 } 243 244 /* 245 * If this is a CPU device calculate the cpuid for it. For Starcat 246 * the cpuid is in the following format. 247 * 248 * EEEEEPPAPP 249 * 250 * where: EEEEE is the expander 251 * PP_PP is the portid 252 * __A__ is the sub-agent identifier. 253 */ 254 if (pcd->spcd_ptype == SAFPTYPE_CPU) { 255 for (i = 0; i < AGENTS_PER_PORT; i++) { 256 switch (prd_slot) { 257 case 0: 258 case 1: 259 case 2: 260 case 3: 261 portid = (expander << 5) | prd_slot; 262 break; 263 case 4: /* Maxcat */ 264 portid = (expander << 5) | 8; 265 break; 266 case 5: /* Maxcat */ 267 portid = (expander << 5) | 9; 268 break; 269 default: 270 cmn_err(CE_WARN, "sc_gptwocfg: invalid " 271 "prd_slot=%d\n", prd_slot); 272 } 273 pcd->spcd_cpuid[i] = (i << 2) | portid; 274 } 275 } 276 277 /* 278 * Starcat does not have ports with UPA devices so 279 * spcd_upadev structure will not be filled in. 280 */ 281 282 /* 283 * Fill in IO Bus Status 284 */ 285 for (i = 0; i < IOBUS_PER_PORT; i++) { 286 287 SC_DEBUG(1, (CE_WARN, " IO Bus Status " 288 "bus=%d status=0x%x\n", i, 289 gdcd->dcd_prd[expander][prd_slot].prd_iobus_rsv[i])); 290 291 if (RSV_GOOD( 292 gdcd->dcd_prd[expander][prd_slot].prd_iobus_rsv[i])) { 293 pcd->spcd_iobus_rsv[i] = SPCD_RSV_PASS; 294 } else { 295 pcd->spcd_iobus_rsv[i] = SPCD_RSV_FAIL; 296 } 297 298 for (j = 0; j < IOCARD_PER_BUS; j++) 299 pcd->spcd_iocard_rsv[i][j] = SPCD_RSV_FAIL; 300 301 /* 302 * Fill in IO Card Status 303 */ 304 for (j = 0; j < IOCARD_PER_BUS; j++) { 305 306 SC_DEBUG(1, (CE_WARN, " Card Status bus=%d " 307 "slot=%d status=0x%x\n", i, j, 308 gdcd->dcd_prd[expander][prd_slot]. 309 prd_iocard_rsv[i][j])); 310 311 if (j == 1) 312 continue; 313 314 if (j == 0) 315 slot = 1; 316 else 317 slot = j; 318 319 /* 320 * If POST marked the card as GOOD or if the slot 321 * is empty, we want to probe for the device. 322 */ 323 if (RSV_GOOD(gdcd->dcd_prd[expander][prd_slot]. 324 prd_iocard_rsv[i][j]) || 325 (gdcd->dcd_prd[expander][prd_slot]. 326 prd_iocard_rsv[i][j] == RSV_MISS) || 327 (gdcd->dcd_prd[expander][prd_slot]. 328 prd_iocard_rsv[i][j] == RSV_EMPTY_CASSETTE)) 329 pcd->spcd_iocard_rsv[i][slot] = SPCD_RSV_PASS; 330 else 331 pcd->spcd_iocard_rsv[i][slot] = SPCD_RSV_FAIL; 332 } 333 } 334 335 /* 336 * Fill in WIC Link Status 337 */ 338 for (i = 0; i < LINKS_PER_PORT; i++) { 339 if (RSV_GOOD( 340 gdcd->dcd_prd[expander][prd_slot].prd_wic_links[i])) { 341 pcd->spcd_wic_links[i] = SPCD_RSV_PASS; 342 343 } else { 344 pcd->spcd_wic_links[i] = SPCD_RSV_FAIL; 345 } 346 } 347 348 /* 349 * Get data for the "bank-status" property. 350 */ 351 pcd->sprd_bank_rsv[0] = 352 rsv_string(gdcd->dcd_prd[expander][prd_slot].prd_bank_rsv[0][0]); 353 pcd->sprd_bank_rsv[1] = 354 rsv_string(gdcd->dcd_prd[expander][prd_slot].prd_bank_rsv[1][0]); 355 pcd->sprd_bank_rsv[2] = 356 rsv_string(gdcd->dcd_prd[expander][prd_slot].prd_bank_rsv[0][1]); 357 pcd->sprd_bank_rsv[3] = 358 rsv_string(gdcd->dcd_prd[expander][prd_slot].prd_bank_rsv[1][1]); 359 360 dimm = 0; 361 for (i = 0; i < PMBANKS_PER_PORT; i++) { 362 for (j = 0; j < DIMMS_PER_PMBANK; j++) { 363 if (dimm < MAX_DIMMS_PER_PORT) { 364 pcd->sprd_dimm[dimm] = rsv_string( 365 gdcd->dcd_prd[expander][prd_slot]. 366 prd_dimm[i][j]); 367 dimm++; 368 } 369 } 370 } 371 372 /* 373 * Get data for the "ecache-dimm-label" property. 374 * 375 * Right now it is hardcoded, but we should eventually get this 376 * from the SC. 377 */ 378 label1 = NULL; 379 label2 = NULL; 380 381 switch (prd_slot) { 382 case 0: 383 label1 = "4400"; 384 label2 = "4300"; 385 break; 386 case 1: 387 label1 = "5400"; 388 label2 = "5300"; 389 break; 390 case 2: 391 label1 = "6400"; 392 label2 = "6300"; 393 break; 394 case 3: 395 label1 = "7400"; 396 label2 = "7300"; 397 break; 398 399 /* 400 * Maxcat labels. 401 */ 402 case 4: 403 label1 = "6400"; 404 label2 = "6300"; 405 break; 406 case 5: 407 label1 = "7400"; 408 label2 = "7300"; 409 break; 410 } 411 412 i = 0; 413 if (label1) { 414 pcd->sprd_ecache_dimm_label[i] = 415 kmem_alloc(strlen(label1) + 1, KM_SLEEP); 416 417 (void) strcpy(pcd->sprd_ecache_dimm_label[i], label1); 418 419 i++; 420 } 421 if (label2) { 422 pcd->sprd_ecache_dimm_label[i] = 423 kmem_alloc(strlen(label2) + 1, KM_SLEEP); 424 425 (void) strcpy(pcd->sprd_ecache_dimm_label[i], label2); 426 427 i++; 428 429 } 430 431 kmem_free(gdcd, sizeof (gdcd_t)); 432 433 #ifdef DEBUG 434 dump_pcd(pcd); 435 #endif 436 437 return (pcd); 438 } 439 440 void 441 sc_free_common_pcd(spcd_t *pcd) 442 { 443 int i; 444 445 SC_DEBUG(1, (CE_WARN, "sc_free_common_pcd pcd=%p\n", pcd)); 446 447 if (pcd->memory_layout && pcd->memory_layout_size) { 448 SC_DEBUG(1, (CE_WARN, "sc_free_common_pcd: memory_layout %p " 449 "size=%x", pcd->memory_layout, pcd->memory_layout_size)); 450 kmem_free(pcd->memory_layout, pcd->memory_layout_size); 451 } 452 453 for (i = 0; i < MAX_BANKS_PER_PORT; i++) { 454 if (pcd->sprd_bank_rsv[i]) { 455 kmem_free(pcd->sprd_bank_rsv[i], 456 strlen(pcd->sprd_bank_rsv[i]) + 1); 457 458 pcd->sprd_bank_rsv[i] = NULL; 459 } 460 } 461 462 for (i = 0; i < MAX_DIMMS_PER_PORT; i++) { 463 if (pcd->sprd_dimm[i]) { 464 kmem_free(pcd->sprd_dimm[i], 465 strlen(pcd->sprd_dimm[i]) + 1); 466 467 pcd->sprd_dimm[i] = NULL; 468 } 469 if (pcd->sprd_ecache_dimm_label[i]) { 470 kmem_free(pcd->sprd_ecache_dimm_label[i], 471 strlen(pcd->sprd_ecache_dimm_label[i]) + 1); 472 473 pcd->sprd_ecache_dimm_label[i] = NULL; 474 } 475 } 476 477 kmem_free(pcd, sizeof (spcd_t)); 478 } 479 480 sc_gptwocfg_cookie_t 481 sc_probe_board(uint_t board) 482 { 483 return (sc_configure(board, 1)); 484 } 485 486 static sc_gptwocfg_cookie_t 487 sc_configure(uint_t board, int create_nodes) 488 { 489 spcd_t *pcd; 490 dev_info_t *ap, *axq_dip; 491 uint_t agent_id; 492 uint_t prd_slot, prd_slot_start, prd_slot_end; 493 uint_t expander, slot; 494 gptwo_new_nodes_t *new_nodes; 495 gptwocfg_config_t *port_cookie; 496 struct sc_gptwocfg_config *board_config, *last, *new; 497 int created_node = 0; 498 uint32_t size; 499 500 SC_DEBUG(1, (CE_WARN, "sc_configure: board=%d, create_nodes=%d\n", 501 board, create_nodes)); 502 503 if (board > 35) { 504 SC_DEBUG(1, (CE_WARN, "sc_gptwocfg - probe_board - " 505 "invalid board 0x%x\n", board)); 506 return (NULL); 507 } 508 509 slot = board & 1; /* Extract Slot Number */ 510 expander = board >> 1; /* Extract Expander Number */ 511 512 SC_DEBUG(1, (CE_WARN, "sc_configure: exp=0x%x slot=0x%x\n", 513 expander, slot)); 514 515 /* 516 * Get the Attachment Point. For Starcat the parent of all 517 * Safari children is root node. 518 */ 519 ap = ddi_root_node(); 520 521 /* 522 * Get the agent id of the AXQ. 523 */ 524 agent_id = (expander << 5) | 0x1e | slot; 525 526 /* 527 * Look to see if the board is already configured by searching for 528 * its AXQ. 529 */ 530 if (create_nodes && (axq_dip = sc_find_axq_node(agent_id))) { 531 ddi_release_devi(axq_dip); 532 cmn_err(CE_WARN, "Board %d AXQ is already configured\n", 533 board); 534 return (NULL); 535 } 536 537 /* 538 * Probe AXQ first 539 */ 540 SC_DEBUG(1, (CE_WARN, "sc_configure: Probing AXQ exp=0x%x brd=0x%x\n", 541 expander, slot)); 542 543 /* 544 * The generic gptwocfg does not support the AXQ, so we need 545 * to configure it. The AXQ branch is returned held. 546 */ 547 new_nodes = sc_gptwocfg_configure_axq(ap, agent_id, create_nodes); 548 549 if (new_nodes == NULL) { 550 SC_DEBUG(1, (CE_WARN, "sc_configure: Can not probe AXQ\n")); 551 return (NULL); 552 } 553 554 port_cookie = kmem_zalloc(sizeof (gptwocfg_config_t), KM_SLEEP); 555 556 /* 557 * Build a cookie for the AXQ. 558 */ 559 port_cookie->gptwo_ap = ap; 560 port_cookie->gptwo_portid = agent_id; 561 port_cookie->gptwo_nodes = new_nodes; 562 563 board_config = kmem_zalloc(sizeof (sc_gptwocfg_config_t), KM_SLEEP); 564 565 board_config->port_cookie = port_cookie; 566 board_config->board = board; 567 board_config->portid = agent_id; 568 board_config->link = NULL; 569 last = board_config; 570 571 mutex_enter(&sc_gptwo_config_list_lock); 572 board_config->next = sc_gptwo_config_list; 573 sc_gptwo_config_list = board_config; 574 mutex_exit(&sc_gptwo_config_list_lock); 575 576 SC_DEBUG(1, (CE_WARN, "sc_configure: AXQ Probing Complete. " 577 "%d nodes added\n", new_nodes->gptwo_number_of_nodes)); 578 579 /* 580 * Determine the starting ending slots of the PRD array. 581 */ 582 switch (slot) { 583 case 0: /* Full Bandwidth Slot */ 584 prd_slot_start = 0; 585 prd_slot_end = 3; 586 break; 587 case 1: /* Half Bandwidth Slot */ 588 prd_slot_start = 4; 589 prd_slot_end = 5; 590 break; 591 default: 592 SC_DEBUG(1, (CE_WARN, "Unknown Board Address - " 593 "Can not probe\n")); 594 return (board_config); 595 } 596 597 /* 598 * For each valid PRD entry, determine the agent id which is based 599 * on what type of device is described by the slot, and then 600 * call the safari configurator. 601 */ 602 for (prd_slot = prd_slot_start; prd_slot <= prd_slot_end; prd_slot++) { 603 604 pcd = sc_get_common_pcd(expander, prd_slot); 605 606 if (pcd == NULL) { 607 608 /* 609 * We can not get a PCD for this port so skip it. 610 */ 611 cmn_err(CE_WARN, "sc_gptwocfg: Can not get PCD " 612 "expander 0x%x prd slot 0x%x\n", 613 expander, prd_slot); 614 615 return (board_config); 616 } 617 618 /* 619 * Only configure good devices. 620 */ 621 if (pcd->spcd_prsv == SPCD_RSV_PASS) { 622 /* 623 * Determine the agent id. 624 */ 625 agent_id = sc_get_agent_id( 626 pcd, expander, slot, prd_slot); 627 628 pcd->memory_layout = get_memlayout(agent_id, &size); 629 pcd->memory_layout_size = size; 630 631 /* 632 * Call Platform Independent gptwo configurator to 633 * create node and properties. 634 */ 635 if (create_nodes) { 636 port_cookie = 637 gptwocfg_configure(ap, pcd, agent_id); 638 if (port_cookie) 639 created_node++; 640 } 641 642 new = kmem_zalloc 643 (sizeof (sc_gptwocfg_config_t), KM_SLEEP); 644 645 /* 646 * XXX Shouldn't port_cookie be NULL if 647 * !create_nodes ? 648 */ 649 new->port_cookie = port_cookie; 650 new->portid = agent_id; 651 new->link = NULL; 652 last->link = new; 653 last = new; 654 } else { 655 SC_DEBUG(1, (CE_WARN, "sc_configure: Bad Agent " 656 "Exp=0x%x PRD Slot=0x%x prsv Status=0x%x\n", 657 expander, prd_slot, pcd->spcd_prsv)); 658 } 659 660 sc_free_common_pcd(pcd); 661 662 } /* for loop */ 663 664 dump_config(board_config); 665 666 if (create_nodes && !created_node) { 667 SC_DEBUG(1, (CE_WARN, "sc_configure: GPTWO Devices failed " 668 "to configure - unprobing board %d\n", board)); 669 board_config = sc_unprobe_board(board); 670 } 671 672 SC_DEBUG(1, (CE_WARN, "sc_configure: Returning 0x%p\n", 673 board_config)); 674 675 return (board_config); 676 } 677 678 sc_gptwocfg_cookie_t 679 sc_unprobe_board(uint_t board) 680 { 681 sc_gptwocfg_config_t *board_config, *axq_config, *prior_config; 682 gptwocfg_cookie_t port_cookie; 683 684 SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: board=%d\n", board)); 685 686 if (board > 35) { 687 SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: " 688 "invalid board 0x%x\n", board)); 689 return (NULL); 690 } 691 mutex_enter(&sc_gptwo_config_list_lock); 692 board_config = sc_gptwo_config_list; 693 while (board_config != NULL) { 694 if (board_config->board == board) { 695 break; 696 } 697 board_config = board_config->next; 698 } 699 mutex_exit(&sc_gptwo_config_list_lock); 700 701 if (board_config == NULL) { 702 703 SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: No " 704 "config structure board=0x%x\n", board)); 705 706 /* 707 * Configure the board without creating nodes. 708 */ 709 board_config = sc_configure(board, 0); 710 711 if (board_config == NULL) { 712 713 cmn_err(CE_WARN, "sc_gptwocfg: sc_unprobe_board: " 714 "Unable to unconfigure board %d - board is not " 715 "configured\n", board); 716 717 return (NULL); 718 } 719 } 720 721 axq_config = board_config; 722 723 /* 724 * Walk the link of ports on this board and unconfigure them. 725 * Save the AXQ for last. 726 */ 727 while (board_config->link != NULL) { 728 prior_config = board_config; 729 board_config = board_config->link; 730 731 SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: " 732 "calling gptwocfg_unconfigure(ap=0x%p portid=0x%x)\n", 733 ddi_root_node(), board_config->portid)); 734 735 port_cookie = gptwocfg_unconfigure(ddi_root_node(), 736 board_config->portid); 737 738 SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: " 739 "gptwocfg_unconfigure returned cookie=0x%p\n", 740 port_cookie)); 741 742 if (port_cookie == NULL) { 743 /* 744 * Can be removed from list. 745 */ 746 prior_config->link = board_config->link; 747 kmem_free(board_config, sizeof (sc_gptwocfg_config_t)); 748 board_config = prior_config; 749 } else { 750 board_config->port_cookie = port_cookie; 751 } 752 } 753 754 if (axq_config->link == NULL) { 755 756 /* 757 * If all the other Safari devices have been successfully 758 * unconfigured, then the AXQ can be unconfigured. 759 */ 760 axq_config->port_cookie = 761 sc_gptwocfg_unconfigure_axq(axq_config->port_cookie); 762 763 if (axq_config->port_cookie == NULL) { 764 765 /* 766 * If the AXQ was successfully unconfigured, then 767 * the board is removed from the configured list. 768 */ 769 mutex_enter(&sc_gptwo_config_list_lock); 770 if (sc_gptwo_config_list == axq_config) { 771 sc_gptwo_config_list = axq_config->next; 772 } else { 773 board_config = sc_gptwo_config_list; 774 while (board_config->next != axq_config) { 775 board_config = board_config->next; 776 } 777 board_config->next = axq_config->next; 778 } 779 mutex_exit(&sc_gptwo_config_list_lock); 780 kmem_free(axq_config, sizeof (sc_gptwocfg_config_t)); 781 axq_config = NULL; 782 } 783 } 784 dump_config(axq_config); 785 return (axq_config); 786 } 787 788 int 789 sc_next_node(sc_gptwocfg_cookie_t c, dev_info_t *previous, dev_info_t **next) 790 { 791 dev_info_t *dip; 792 sc_gptwocfg_config_t *cookie; 793 794 SC_DEBUG(1, (CE_WARN, "sccfg: sccfg_next_node" 795 "(c=0x%p, previous=0x%p, next=0x%p)\n", c, previous, next)); 796 797 cookie = (sc_gptwocfg_config_t *)c; 798 799 if (cookie == NULL) { 800 cmn_err(CE_WARN, "sccfg: sccfg_next_node - " 801 "Invalid Cookie\n"); 802 return (0); 803 } 804 if (previous == NULL) { 805 /* 806 * Start with the AXQ node. 807 */ 808 if (gptwocfg_next_node(cookie->port_cookie, NULL, &dip)) { 809 *next = dip; 810 return (1); 811 } else { 812 return (0); 813 } 814 } 815 816 while (cookie != NULL) { 817 if (gptwocfg_next_node(cookie->port_cookie, previous, &dip)) { 818 if ((dip == NULL) && (cookie->link == NULL)) { 819 *next = NULL; 820 return (1); 821 } 822 if (dip != NULL) { 823 *next = dip; 824 return (1); 825 } 826 827 /* dip == NULL */ 828 829 previous = NULL; 830 } 831 cookie = cookie->link; 832 } 833 834 return (0); 835 } 836 837 static dev_info_t * 838 sc_find_axq_node(uint_t axq_id) 839 { 840 char *name; 841 int size; 842 gptwo_regspec_t *reg; 843 dev_info_t *dip; 844 uint_t id; 845 int circ; 846 847 SC_DEBUG(1, (CE_CONT, "sc_find_axq_node: id=0x%x\n", axq_id)); 848 849 /* 850 * Hold root node busy to walk its child list 851 */ 852 ndi_devi_enter(ddi_root_node(), &circ); 853 854 dip = ddi_get_child(ddi_root_node()); 855 856 while (dip != NULL) { 857 858 SC_DEBUG(1, (CE_CONT, "Searching dip=0x%p for our AXQ\n", 859 dip)); 860 861 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, 862 DDI_PROP_DONTPASS, "name", (caddr_t)&name, &size) 863 != DDI_PROP_SUCCESS) { 864 865 /* 866 * This node does not have a name property. 867 */ 868 SC_DEBUG(1, (CE_CONT, "dip=0x%p does not have a " 869 "'name' property\n", dip)); 870 871 dip = ddi_get_next_sibling(dip); 872 continue; 873 } 874 875 SC_DEBUG(1, (CE_CONT, "dip=0x%p name=%s\n", dip, name)); 876 877 if (strcmp(name, "address-extender-queue")) { 878 879 /* 880 * This node is not a AXQ node. 881 */ 882 SC_DEBUG(1, (CE_CONT, "dip=0x%p is not an AXQ " 883 "node\n", dip)); 884 kmem_free(name, size); 885 dip = ddi_get_next_sibling(dip); 886 continue; 887 } 888 kmem_free(name, size); 889 890 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, 891 DDI_PROP_DONTPASS, "reg", (caddr_t)®, &size) 892 != DDI_PROP_SUCCESS) { 893 894 /* 895 * This AXQ node does not have a reg property. 896 */ 897 SC_DEBUG(1, (CE_CONT, "dip=0x%p (AXQ Node) does " 898 "have a 'reg' property\n", dip)); 899 dip = ddi_get_next_sibling(dip); 900 continue; 901 } 902 903 id = ((reg[0].gptwo_phys_hi & 1) << 9) | 904 ((reg[0].gptwo_phys_low & 0xff800000) >> 23); 905 906 kmem_free(reg, size); 907 908 if (axq_id != id) { 909 910 /* 911 * This is the wrong AXQ node. 912 */ 913 SC_DEBUG(1, (CE_CONT, "dip=0x%p Wrong node id=0x%x\n", 914 dip, id)); 915 916 dip = ddi_get_next_sibling(dip); 917 continue; 918 919 } 920 921 /* 922 * The correct AXQ node was found. 923 */ 924 SC_DEBUG(1, (CE_CONT, "dip=0x%p Found AXQ Node\n", dip)); 925 ndi_hold_devi(dip); 926 break; 927 } 928 ndi_devi_exit(ddi_root_node(), circ); 929 930 SC_DEBUG(1, (CE_CONT, "sc_find_axq_node: Returning 0x%p\n", dip)); 931 932 return (dip); 933 } 934 935 struct axq_arg { 936 uint_t id; 937 dev_info_t *axq_dip; 938 }; 939 940 /*ARGSUSED*/ 941 static int 942 axq_set_prop(dev_info_t *axq_dip, void *arg, uint_t flags) 943 { 944 struct axq_arg *aqp = (struct axq_arg *)arg; 945 gptwo_regspec_t reg[2]; 946 uint_t id; 947 948 ASSERT(aqp); 949 950 id = aqp->id; 951 952 if (ndi_prop_update_string(DDI_DEV_T_NONE, axq_dip, 953 "name", "address-extender-queue") != DDI_SUCCESS) { 954 SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_pci: failed " 955 "to create name property\n")); 956 return (DDI_WALK_ERROR); 957 } 958 959 if (ndi_prop_update_string(DDI_DEV_T_NONE, axq_dip, 960 "device_type", "address-extender-queue") != DDI_SUCCESS) { 961 SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_pci: failed " 962 "to create device_type property\n")); 963 return (DDI_WALK_ERROR); 964 } 965 966 if (ndi_prop_update_string(DDI_DEV_T_NONE, axq_dip, 967 "compatible", "SUNW,axq") != DDI_SUCCESS) { 968 SC_DEBUG(1, (CE_CONT, "sc_gptwocfg: failed " 969 "to create compatible property\n")); 970 return (DDI_WALK_ERROR); 971 } 972 973 if (ndi_prop_update_int(DDI_DEV_T_NONE, axq_dip, 974 "portid", id) != DDI_SUCCESS) { 975 SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_pci: failed " 976 "to create portid property\n")); 977 return (DDI_WALK_ERROR); 978 } 979 980 reg[0].gptwo_phys_hi = 0x400 | (id >> 9); 981 reg[0].gptwo_phys_low = (id << 23); 982 reg[0].gptwo_size_hi = 0; 983 reg[0].gptwo_size_low = 0x520; 984 985 reg[1].gptwo_phys_hi = 0x401; 986 reg[1].gptwo_phys_low = 0xf0000000; 987 reg[1].gptwo_size_hi = 0; 988 reg[1].gptwo_size_low = 0x520; 989 990 if (ndi_prop_update_int_array(DDI_DEV_T_NONE, 991 axq_dip, "reg", (int *)®, 992 (sizeof (gptwo_regspec_t) * 2)/sizeof (int)) != DDI_SUCCESS) { 993 SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_pci: failed " 994 "to create reg property\n")); 995 return (DDI_WALK_ERROR); 996 } 997 998 return (DDI_WALK_TERMINATE); 999 } 1000 1001 /*ARGSUSED*/ 1002 static void 1003 get_axq_dip(dev_info_t *rdip, void *arg, uint_t flags) 1004 { 1005 struct axq_arg *aqp = (struct axq_arg *)arg; 1006 1007 ASSERT(aqp); 1008 1009 aqp->axq_dip = rdip; 1010 } 1011 1012 static gptwo_new_nodes_t * 1013 sc_gptwocfg_configure_axq(dev_info_t *ap, uint_t id, int create_nodes) 1014 { 1015 struct axq_arg arg = {0}; 1016 devi_branch_t b = {0}; 1017 dev_info_t *axq_dip, *fdip = NULL; 1018 gptwo_new_nodes_t *new_nodes = NULL; 1019 int rv; 1020 1021 SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_axq: id=0x%x " 1022 "create_nodes=%d\n", id, create_nodes)); 1023 1024 if (!create_nodes) { 1025 axq_dip = sc_find_axq_node(id); 1026 1027 if (axq_dip) { 1028 new_nodes = gptwocfg_allocate_node_list(1); 1029 new_nodes->gptwo_nodes[0] = axq_dip; 1030 ASSERT(!e_ddi_branch_held(axq_dip)); 1031 e_ddi_branch_hold(axq_dip); 1032 /* 1033 * Release hold from sc_find_axq_node() 1034 */ 1035 ddi_release_devi(axq_dip); 1036 } 1037 1038 SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_axq: " 1039 "Returning 0x%p\n", new_nodes)); 1040 1041 return (new_nodes); 1042 } 1043 1044 arg.id = id; 1045 arg.axq_dip = NULL; 1046 1047 b.arg = &arg; 1048 b.type = DEVI_BRANCH_SID; 1049 b.create.sid_branch_create = axq_set_prop; 1050 b.devi_branch_callback = get_axq_dip; 1051 1052 rv = e_ddi_branch_create(ap, &b, &fdip, DEVI_BRANCH_CONFIGURE); 1053 if (rv != 0) { 1054 char *path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 1055 1056 /* 1057 * If non-NULL, fdip is held and must be released. 1058 */ 1059 if (fdip != NULL) { 1060 (void) ddi_pathname(fdip, path); 1061 ddi_release_devi(fdip); 1062 } else { 1063 (void) ddi_pathname(ap, path); 1064 } 1065 1066 SC_DEBUG(1, (CE_WARN, "e_ddi_branch_create failed: " 1067 "path=%s, dip=%p, rv=%d", path, fdip ? (void *)fdip : 1068 (void *)ap, rv)); 1069 1070 kmem_free(path, MAXPATHLEN); 1071 1072 return (NULL); 1073 } 1074 1075 axq_dip = arg.axq_dip; 1076 1077 new_nodes = gptwocfg_allocate_node_list(1); 1078 new_nodes->gptwo_nodes[0] = axq_dip; 1079 1080 return (new_nodes); 1081 } 1082 1083 static gptwocfg_config_t * 1084 sc_gptwocfg_unconfigure_axq(gptwocfg_config_t *config) 1085 { 1086 int i; 1087 int failure = 0; 1088 dev_info_t *saf_dip; 1089 1090 if (config == NULL) { 1091 cmn_err(CE_WARN, "sc_gptwocfg: sc_gptwocfg_unconfigure_axq: " 1092 "Invalid AXQ\n"); 1093 return (NULL); 1094 } 1095 for (i = 0; i < config->gptwo_nodes->gptwo_number_of_nodes; i++) { 1096 int rv; 1097 dev_info_t *fdip = NULL; 1098 1099 saf_dip = config->gptwo_nodes->gptwo_nodes[i]; 1100 ASSERT(e_ddi_branch_held(saf_dip)); 1101 rv = e_ddi_branch_destroy(saf_dip, &fdip, 0); 1102 if (rv != 0) { 1103 char *path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 1104 1105 /* 1106 * If non-NULL, fdip is held and must be released. 1107 */ 1108 if (fdip != NULL) { 1109 (void) ddi_pathname(fdip, path); 1110 ddi_release_devi(fdip); 1111 } else { 1112 (void) ddi_pathname(saf_dip, path); 1113 } 1114 1115 cmn_err(CE_CONT, "AXQ node removal failed: " 1116 "path=%s, dip=%p, rv=%d\n", path, 1117 fdip ? (void *)fdip : (void *)saf_dip, rv); 1118 1119 kmem_free(path, MAXPATHLEN); 1120 failure = 1; 1121 } else { 1122 config->gptwo_nodes->gptwo_nodes[i] = NULL; 1123 } 1124 } 1125 if (!failure) { 1126 gptwocfg_free_node_list(config->gptwo_nodes); 1127 1128 kmem_free(config, sizeof (gptwocfg_config_t)); 1129 config = NULL; 1130 } 1131 return (config); 1132 } 1133 1134 static uint_t 1135 sc_get_agent_id(spcd_t *pcd, uint_t expander, uint_t slot, uint_t prd_slot) 1136 { 1137 uint_t agent_id; 1138 1139 switch (pcd->spcd_ptype) { 1140 case SAFPTYPE_CPU: 1141 if (slot == 0) { 1142 agent_id = prd_slot; 1143 } else { 1144 if (prd_slot == 4) { 1145 agent_id = 8; 1146 } else { 1147 agent_id = 9; 1148 } 1149 } 1150 break; 1151 1152 case SAFPTYPE_sPCI: 1153 case SAFPTYPE_cPCI: 1154 case SAFPTYPE_PCIX: 1155 if (prd_slot == 4) { 1156 agent_id = 0x1c; 1157 } else { 1158 agent_id = 0x1d; 1159 } 1160 break; 1161 case SAFPTYPE_WCI: 1162 agent_id = 0x1d; 1163 break; 1164 default: 1165 cmn_err(CE_WARN, "sc_gptwocfg: Invalid Safari Port " 1166 "Type 0x%x Slot 0x%x\n", 1167 pcd->spcd_ptype, prd_slot); 1168 } /* switch */ 1169 1170 agent_id |= (expander << 5); 1171 1172 SC_DEBUG(1, (CE_CONT, "sc_get_agent_id(pcd=0x%p, expander=0x%x, " 1173 "prd_slot=0x%x) Returning agent_id=0x%x\n", pcd, expander, 1174 prd_slot, agent_id)); 1175 1176 return (agent_id); 1177 } 1178 1179 static void 1180 dump_config(sc_gptwocfg_config_t *board_config) 1181 { 1182 gptwocfg_config_t *port; 1183 1184 SC_DEBUG(1, (CE_CONT, "dump_config 0x%p", board_config)); 1185 while (board_config != NULL) { 1186 SC_DEBUG(1, (CE_CONT, "************* 0x%p ************\n", 1187 board_config)); 1188 SC_DEBUG(1, (CE_CONT, "port_cookie - 0x%p\n", 1189 board_config->port_cookie)); 1190 1191 port = board_config->port_cookie; 1192 if (port) { 1193 SC_DEBUG(1, (CE_CONT, " ap - 0x%p\n", 1194 port->gptwo_ap)); 1195 SC_DEBUG(1, (CE_CONT, " portid - 0x%x\n", 1196 port->gptwo_portid)); 1197 } 1198 SC_DEBUG(1, (CE_CONT, "portid - 0x%x\n", 1199 board_config->portid)); 1200 SC_DEBUG(1, (CE_CONT, "board - 0x%x\n", 1201 board_config->board)); 1202 SC_DEBUG(1, (CE_CONT, "link - 0x%p\n", 1203 board_config->link)); 1204 SC_DEBUG(1, (CE_CONT, "next - 0x%p\n", 1205 board_config->next)); 1206 board_config = board_config->link; 1207 } 1208 } 1209 1210 static void 1211 dump_pcd(spcd_t *pcd) 1212 { 1213 int i; 1214 1215 SC_DEBUG(1, (CE_CONT, "dump_pcd 0x%p", pcd)); 1216 SC_DEBUG(1, (CE_CONT, " magic - 0x%x\n", pcd->spcd_magic)); 1217 SC_DEBUG(1, (CE_CONT, " version - 0x%x\n", pcd->spcd_version)); 1218 SC_DEBUG(1, (CE_CONT, " ver.reg - 0x%lx\n", pcd->spcd_ver_reg)); 1219 SC_DEBUG(1, (CE_CONT, " afreq - %d\n", pcd->spcd_afreq)); 1220 switch (pcd->spcd_ptype) { 1221 case SAFPTYPE_CPU: 1222 SC_DEBUG(1, (CE_CONT, " ptype - CPU\n")); 1223 break; 1224 case SAFPTYPE_sPCI: 1225 SC_DEBUG(1, (CE_CONT, " ptype - sPCI\n")); 1226 break; 1227 case SAFPTYPE_cPCI: 1228 SC_DEBUG(1, (CE_CONT, " ptype - cPCI\n")); 1229 break; 1230 case SAFPTYPE_PCIX: 1231 SC_DEBUG(1, (CE_CONT, " ptype - sPCI+\n")); 1232 break; 1233 case SAFPTYPE_WCI: 1234 SC_DEBUG(1, (CE_CONT, " ptype - WIC\n")); 1235 break; 1236 default: 1237 SC_DEBUG(1, (CE_CONT, " ptype - 0x%x\n", 1238 pcd->spcd_ptype)); 1239 break; 1240 } 1241 SC_DEBUG(1, (CE_CONT, " cache - %d\n", pcd->spcd_cache)); 1242 1243 if (pcd->spcd_prsv == SPCD_RSV_PASS) { 1244 SC_DEBUG(1, (CE_CONT, " prsv - SPCD_RSV_PASS\n")); 1245 } else { 1246 SC_DEBUG(1, (CE_CONT, " prsv - 0x%x (FAIL)\n", 1247 pcd->spcd_prsv)); 1248 } 1249 1250 for (i = 0; i < AGENTS_PER_PORT; i++) { 1251 if (pcd->spcd_agent[i] == SPCD_RSV_PASS) { 1252 SC_DEBUG(1, (CE_CONT, " agent[%d] " 1253 "- SPCD_RSV_PASS\n", i)); 1254 } else { 1255 SC_DEBUG(1, (CE_CONT, " agent[%d] " 1256 "- 0x%x (FAIL)\n", i, pcd->spcd_agent[i])); 1257 } 1258 } 1259 1260 if (pcd->spcd_ptype == SAFPTYPE_CPU) { 1261 for (i = 0; i < AGENTS_PER_PORT; i++) { 1262 SC_DEBUG(1, (CE_CONT, " cpuid[%d] - 0x%x\n", 1263 i, pcd->spcd_cpuid[i])); 1264 } 1265 } 1266 1267 SC_DEBUG(1, (CE_CONT, " Banks\n")); 1268 for (i = 0; i < MAX_BANKS_PER_PORT; i++) { 1269 if (pcd->sprd_bank_rsv[i]) { 1270 SC_DEBUG(1, (CE_CONT, " %d %s\n", i, 1271 pcd->sprd_bank_rsv[i])); 1272 } 1273 } 1274 1275 SC_DEBUG(1, (CE_CONT, " Dimms\n")); 1276 for (i = 0; i < MAX_DIMMS_PER_PORT; i++) { 1277 if (pcd->sprd_dimm[i]) { 1278 SC_DEBUG(1, (CE_CONT, " %d %s\n", i, 1279 pcd->sprd_dimm[i])); 1280 } 1281 } 1282 SC_DEBUG(1, (CE_CONT, " Ecache Dimm Labels\n")); 1283 for (i = 0; i < MAX_DIMMS_PER_PORT; i++) { 1284 if (pcd->sprd_ecache_dimm_label[i]) { 1285 SC_DEBUG(1, (CE_CONT, " %d %s\n", i, 1286 pcd->sprd_ecache_dimm_label[i])); 1287 } 1288 } 1289 } 1290 1291 1292 typedef struct { 1293 char Jnumber[8][8]; 1294 uint8_t sym_flag; 1295 uint8_t d_dimmtable[144]; 1296 uint8_t d_pintable[576]; 1297 }m_layout; 1298 1299 /* 1300 * Use 2 bits to represent each bit at a cache line. The table 1301 * is in big endian order, i.e. 1302 * dimmtable[0], ... , dimmtable[143] 1303 * Q0:data-bits[127 126 125 124], ... , MtagEcc[3 2 1 0] 1304 * . 1305 * . 1306 * Q3:data-bits[127 126 125 124], ... , MtagEcc[3 2 1 0] 1307 */ 1308 uint8_t J_dimm_pinTable[] = { 1309 /* Jnumber */ 1310 /* 0 */ 0x4a, 0x31, 0x33, 0x33, 0x30, 0x30, 0x00, 0x00, 1311 /* 1 */ 0x4a, 0x31, 0x33, 0x34, 0x30, 0x30, 0x00, 0x00, 1312 /* 2 */ 0x4a, 0x31, 0x33, 0x35, 0x30, 0x30, 0x00, 0x00, 1313 /* 3 */ 0x4a, 0x31, 0x33, 0x36, 0x30, 0x30, 0x00, 0x00, 1314 /* 4 */ 0x4a, 0x31, 0x33, 0x33, 0x30, 0x31, 0x00, 0x00, 1315 /* 5 */ 0x4a, 0x31, 0x33, 0x34, 0x30, 0x31, 0x00, 0x00, 1316 /* 6 */ 0x4a, 0x31, 0x33, 0x35, 0x30, 0x31, 0x00, 0x00, 1317 /* 7 */ 0x4a, 0x31, 0x33, 0x36, 0x30, 0x31, 0x00, 0x00, 1318 /* flag */ 0x01, 1319 /* -- Q0 -- */ 1320 /* 0 */ 0x00, 0x55, 0xaa, 0xff, 0x00, 0x55, 0xaa, 0xff, 1321 /* 1 */ 0x00, 0xaa, 0xff, 0x00, 0x56, 0xaf, 0x00, 0x55, 1322 /* 2 */ 0xaa, 0x55, 0xaf, 0xc0, 0x55, 0xaa, 0xff, 0x00, 1323 /* 3 */ 0x55, 0xff, 0x00, 0x55, 0xaa, 0xff, 0x6d, 0x80, 1324 /* 4 */ 0xe7, 0xe3, 0x9b, 0x1b, 1325 /* -- Q1 -- */ 1326 /* 0 */ 0x00, 0x55, 0xaa, 0xff, 0x00, 0x55, 0xaa, 0xff, 1327 /* 1 */ 0x00, 0xaa, 0xff, 0x00, 0x56, 0xaf, 0x00, 0x55, 1328 /* 2 */ 0xaa, 0x55, 0xaf, 0xc0, 0x55, 0xaa, 0xff, 0x00, 1329 /* 3 */ 0x55, 0xff, 0x00, 0x55, 0xaa, 0xff, 0x6d, 0x80, 1330 /* 4 */ 0xe7, 0xe3, 0x9b, 0x1b, 1331 /* -- Q2 -- */ 1332 /* 0 */ 0x00, 0x55, 0xaa, 0xff, 0x00, 0x55, 0xaa, 0xff, 1333 /* 1 */ 0x00, 0xaa, 0xff, 0x00, 0x56, 0xaf, 0x00, 0x55, 1334 /* 2 */ 0xaa, 0x55, 0xaf, 0xc0, 0x55, 0xaa, 0xff, 0x00, 1335 /* 3 */ 0x55, 0xff, 0x00, 0x55, 0xaa, 0xff, 0x6d, 0x80, 1336 /* 4 */ 0xe7, 0xe3, 0x9b, 0x1b, 1337 /* -- Q3 -- */ 1338 /* 0 */ 0x00, 0x55, 0xaa, 0xff, 0x00, 0x55, 0xaa, 0xff, 1339 /* 1 */ 0x00, 0xaa, 0xff, 0x00, 0x56, 0xaf, 0x00, 0x55, 1340 /* 2 */ 0xaa, 0x55, 0xaf, 0xc0, 0x55, 0xaa, 0xff, 0x00, 1341 /* 3 */ 0x55, 0xff, 0x00, 0x55, 0xaa, 0xff, 0x6d, 0x80, 1342 /* 4 */ 0xe7, 0xe3, 0x9b, 0x1b, 1343 /* 1344 * In the following order 1345 * pintable[0], ..., pintable[575] 1346 * Quadword3, Quadword2, Quadword1, Quadword0 1347 * MtagEcc, Mtag, Ecc, Data 1348 */ 1349 /* -- Q3 -- */ 1350 /* 0 */ 227, 227, 227, 227, 111, 111, 111, 22, 1351 /* 1 */ 22, 32, 138, 222, 81, 117, 117, 117, 1352 /* 2 */ 111, 222, 106, 222, 222, 106, 106, 106, 1353 /* 3 */ 217, 101, 212, 96, 217, 101, 212, 96, 1354 /* 4 */ 217, 101, 212, 96, 217, 101, 212, 96, 1355 /* 5 */ 207, 91, 202, 86, 187, 71, 158, 42, 1356 /* 6 */ 187, 71, 158, 42, 153, 37, 148, 32, 1357 /* 7 */ 153, 37, 148, 32, 153, 37, 148, 32, 1358 /* 8 */ 153, 37, 148, 143, 27, 138, 143, 27, 1359 /* 9 */ 143, 27, 138, 22, 207, 91, 202, 86, 1360 /* 10 */ 207, 91, 202, 86, 207, 91, 202, 86, 1361 /* 11 */ 192, 76, 81, 192, 76, 81, 192, 76, 1362 /* 12 */ 197, 81, 192, 76, 187, 71, 158, 42, 1363 /* 13 */ 187, 71, 158, 42, 143, 27, 138, 22, 1364 /* 14 */ 133, 17, 128, 12, 133, 17, 128, 12, 1365 /* 15 */ 133, 17, 128, 12, 133, 17, 128, 12, 1366 /* 16 */ 123, 07, 118, 2, 123, 07, 118, 2, 1367 /* 17 */ 123, 07, 118, 2, 123, 07, 118, 2, 1368 /* -- Q2 -- */ 1369 /* 0 */ 228, 228, 228, 228, 112, 112, 112, 23, 1370 /* 1 */ 23, 33, 139, 223, 82, 118, 118, 118, 1371 /* 2 */ 112, 223, 107, 223, 223, 107, 107, 107, 1372 /* 3 */ 218, 102, 213, 97, 218, 102, 213, 97, 1373 /* 4 */ 218, 102, 213, 97, 218, 102, 213, 97, 1374 /* 5 */ 208, 92, 203, 87, 188, 72, 159, 43, 1375 /* 6 */ 188, 72, 159, 43, 154, 38, 149, 33, 1376 /* 7 */ 154, 38, 149, 33, 154, 38, 149, 33, 1377 /* 8 */ 154, 38, 149, 144, 28, 139, 144, 28, 1378 /* 9 */ 144, 28, 139, 23, 208, 92, 203, 87, 1379 /* 10 */ 208, 92, 203, 87, 208, 92, 203, 87, 1380 /* 11 */ 193, 77, 82, 193, 77, 82, 193, 77, 1381 /* 12 */ 198, 82, 193, 77, 188, 72, 159, 43, 1382 /* 13 */ 188, 72, 159, 43, 144, 28, 139, 23, 1383 /* 14 */ 134, 18, 129, 13, 134, 18, 129, 13, 1384 /* 15 */ 134, 18, 129, 13, 134, 18, 129, 13, 1385 /* 16 */ 124, 8, 119, 3, 124, 8, 119, 3, 1386 /* 17 */ 124, 8, 119, 3, 124, 8, 119, 3, 1387 /* -- Q1 -- */ 1388 /* 0 */ 229, 229, 229, 229, 113, 113, 113, 24, 1389 /* 1 */ 24, 34, 140, 224, 83, 119, 119, 119, 1390 /* 2 */ 113, 224, 108, 224, 224, 108, 108, 108, 1391 /* 3 */ 219, 103, 214, 98, 219, 103, 214, 98, 1392 /* 4 */ 219, 103, 214, 98, 219, 103, 214, 98, 1393 /* 5 */ 209, 93, 204, 88, 189, 73, 160, 44, 1394 /* 6 */ 189, 73, 160, 44, 155, 39, 150, 34, 1395 /* 7 */ 155, 39, 150, 34, 155, 39, 150, 34, 1396 /* 8 */ 155, 39, 150, 145, 29, 140, 145, 29, 1397 /* 9 */ 145, 29, 140, 24, 209, 93, 204, 88, 1398 /* 10 */ 209, 93, 204, 88, 209, 93, 204, 88, 1399 /* 11 */ 194, 78, 83, 194, 78, 83, 194, 78, 1400 /* 12 */ 199, 83, 194, 78, 189, 73, 160, 44, 1401 /* 13 */ 189, 73, 160, 44, 145, 29, 140, 24, 1402 /* 14 */ 135, 19, 130, 14, 135, 19, 130, 14, 1403 /* 15 */ 135, 19, 130, 14, 135, 19, 130, 14, 1404 /* 16 */ 125, 9, 120, 4, 125, 9, 120, 4, 1405 /* 17 */ 125, 9, 120, 4, 125, 9, 120, 4, 1406 /* -- Q0 -- */ 1407 /* 0 */ 230, 230, 230, 230, 114, 114, 114, 25, 1408 /* 1 */ 25, 35, 141, 225, 84, 200, 200, 200, 1409 /* 2 */ 114, 225, 109, 225, 225, 109, 109, 109, 1410 /* 3 */ 220, 104, 215, 99, 220, 104, 215, 99, 1411 /* 4 */ 220, 104, 215, 99, 220, 104, 215, 99, 1412 /* 5 */ 210, 94, 205, 89, 190, 74, 161, 45, 1413 /* 6 */ 190, 74, 161, 45, 156, 40, 151, 35, 1414 /* 7 */ 156, 40, 151, 35, 156, 40, 151, 35, 1415 /* 8 */ 156, 40, 151, 146, 30, 141, 146, 30, 1416 /* 9 */ 146, 30, 141, 25, 210, 94, 205, 89, 1417 /* 10 */ 210, 94, 205, 89, 210, 94, 205, 89, 1418 /* 11 */ 195, 79, 84, 195, 79, 84, 195, 79, 1419 /* 12 */ 200, 84, 195, 79, 190, 74, 161, 45, 1420 /* 13 */ 190, 74, 161, 45, 146, 30, 141, 25, 1421 /* 14 */ 136, 20, 131, 15, 136, 20, 131, 15, 1422 /* 15 */ 136, 20, 131, 15, 136, 20, 131, 15, 1423 /* 16 */ 126, 10, 121, 5, 126, 10, 121, 5, 1424 /* 17 */ 126, 10, 121, 5, 126, 10, 121, 5 1425 }; 1426 1427 /* 1428 * This table is for internal reference 1429 * 1430 * pintable_internal[]= { 1431 * -- Q0 -- 1432 * 0 143,143,143,143,139,139,139,35 1433 * 1 35,51,39,135,91,95,95,95 1434 * 2 139,135,131,135,135,131,131,131 1435 * 3 127,123,119,115,127,123,119,115 1436 * 4 127,123,119,115,127,123,119,115 1437 * 5 111,107,103,99,79,75,71,67 1438 * 6 79,75,71,67,63,59,55,51 1439 * 7 63,59,55,51,63,59,55,51 1440 * 8 63,59,55,47,43,39,47,43 1441 * 9 47,43,39,35,111,107,103,99 1442 * 10 111,107,103,99,111,107,103,99 1443 * 11 87,83,91,87,83,91,87,83 1444 * 12 95,91,87,83,79,75,71,67 1445 * 13 79,75,71,67,47,43,39,35 1446 * 14 31,27,23,19,31,27,23,19 1447 * 15 31,27,23,19,31,27,23,19 1448 * 16 15,11,7,3,15,11,7,3 1449 * 17 15,11,7,3,15,11,7,3 1450 * } 1451 */ 1452 1453 char *dimm_Jno[] = { 1454 /* P0 */ "J13300", "J13400", "J13500", "J13600", 1455 "J13301", "J13401", "J13501", "J13601", 1456 /* P1 */ "J14300", "J14400", "J14500", "J14600", 1457 "J14301", "J14401", "J14501", "J14601", 1458 /* P2 */ "J15300", "J15400", "J15500", "J15600", 1459 "J15301", "J15401", "J15501", "J15601", 1460 /* P3 */ "J16300", "J16400", "J16500", "J16600", 1461 "J16301", "J16401", "J16501", "J16601", 1462 NULL 1463 }; 1464 1465 1466 static uint8_t * 1467 get_memlayout(uint32_t cpuid, uint32_t *len) 1468 { 1469 m_layout *LayoutBuf; 1470 1471 if ((LayoutBuf = (m_layout *)kmem_zalloc(sizeof (m_layout), 1472 KM_SLEEP)) == NULL) { 1473 *len = 0; 1474 return (NULL); 1475 } 1476 1477 bcopy(J_dimm_pinTable, LayoutBuf, sizeof (m_layout)); 1478 1479 *len = sizeof (m_layout); 1480 cpuid &= 0x03; /* last 2 bits of a 10 bit number */ 1481 1482 bcopy(dimm_Jno[cpuid << 3], LayoutBuf->Jnumber[0], 64); 1483 1484 return ((uint8_t *)LayoutBuf); 1485 } 1486 1487 static char * 1488 rsv_string(prdrsv_t rsv) 1489 { 1490 char *buffer; 1491 char *status; 1492 1493 switch (rsv) { 1494 case RSV_UNKNOWN: 1495 buffer = "unknown"; 1496 break; 1497 case RSV_PRESENT: 1498 buffer = "okay"; 1499 break; 1500 case RSV_CRUNCH: 1501 buffer = "disabled"; 1502 break; 1503 case RSV_UNDEFINED: 1504 buffer = "undefined"; 1505 break; 1506 case RSV_MISS: 1507 buffer = "missing"; 1508 break; 1509 case RSV_EMPTY_CASSETTE: 1510 buffer = "disabled"; 1511 break; 1512 case RSV_MISCONFIG: 1513 buffer = "misconfigured"; 1514 break; 1515 case RSV_FAIL_OBP: 1516 buffer = "fail-obp"; 1517 break; 1518 case RSV_BLACK: 1519 buffer = "blacklisted"; 1520 break; 1521 case RSV_RED: 1522 buffer = "redlisted"; 1523 break; 1524 case RSV_EXCLUDED: 1525 buffer = "disabled"; 1526 break; 1527 case RSV_UNCONFIG: 1528 buffer = "disabled"; 1529 break; 1530 case RSV_PASS: 1531 buffer = "okay"; 1532 break; 1533 case RSV_FAIL: 1534 default: 1535 buffer = "fail"; 1536 break; 1537 } 1538 1539 status = kmem_alloc(strlen(buffer) + 1, KM_SLEEP); 1540 (void) strcpy(status, buffer); 1541 1542 return (status); 1543 } 1544