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 /* 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", (void *)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", (void *)pcd->memory_layout, 450 pcd->memory_layout_size)); 451 kmem_free(pcd->memory_layout, pcd->memory_layout_size); 452 } 453 454 for (i = 0; i < MAX_BANKS_PER_PORT; i++) { 455 if (pcd->sprd_bank_rsv[i]) { 456 kmem_free(pcd->sprd_bank_rsv[i], 457 strlen(pcd->sprd_bank_rsv[i]) + 1); 458 459 pcd->sprd_bank_rsv[i] = NULL; 460 } 461 } 462 463 for (i = 0; i < MAX_DIMMS_PER_PORT; i++) { 464 if (pcd->sprd_dimm[i]) { 465 kmem_free(pcd->sprd_dimm[i], 466 strlen(pcd->sprd_dimm[i]) + 1); 467 468 pcd->sprd_dimm[i] = NULL; 469 } 470 if (pcd->sprd_ecache_dimm_label[i]) { 471 kmem_free(pcd->sprd_ecache_dimm_label[i], 472 strlen(pcd->sprd_ecache_dimm_label[i]) + 1); 473 474 pcd->sprd_ecache_dimm_label[i] = NULL; 475 } 476 } 477 478 kmem_free(pcd, sizeof (spcd_t)); 479 } 480 481 sc_gptwocfg_cookie_t 482 sc_probe_board(uint_t board) 483 { 484 return (sc_configure(board, 1)); 485 } 486 487 static sc_gptwocfg_cookie_t 488 sc_configure(uint_t board, int create_nodes) 489 { 490 spcd_t *pcd; 491 dev_info_t *ap, *axq_dip; 492 uint_t agent_id; 493 uint_t prd_slot, prd_slot_start, prd_slot_end; 494 uint_t expander, slot; 495 gptwo_new_nodes_t *new_nodes; 496 gptwocfg_config_t *port_cookie; 497 struct sc_gptwocfg_config *board_config, *last, *new; 498 int created_node = 0; 499 uint32_t size; 500 501 SC_DEBUG(1, (CE_WARN, "sc_configure: board=%d, create_nodes=%d\n", 502 board, create_nodes)); 503 504 if (board > 35) { 505 SC_DEBUG(1, (CE_WARN, "sc_gptwocfg - probe_board - " 506 "invalid board 0x%x\n", board)); 507 return (NULL); 508 } 509 510 slot = board & 1; /* Extract Slot Number */ 511 expander = board >> 1; /* Extract Expander Number */ 512 513 SC_DEBUG(1, (CE_WARN, "sc_configure: exp=0x%x slot=0x%x\n", 514 expander, slot)); 515 516 /* 517 * Get the Attachment Point. For Starcat the parent of all 518 * Safari children is root node. 519 */ 520 ap = ddi_root_node(); 521 522 /* 523 * Get the agent id of the AXQ. 524 */ 525 agent_id = (expander << 5) | 0x1e | slot; 526 527 /* 528 * Look to see if the board is already configured by searching for 529 * its AXQ. 530 */ 531 if (create_nodes && (axq_dip = sc_find_axq_node(agent_id))) { 532 ddi_release_devi(axq_dip); 533 cmn_err(CE_WARN, "Board %d AXQ is already configured\n", 534 board); 535 return (NULL); 536 } 537 538 /* 539 * Probe AXQ first 540 */ 541 SC_DEBUG(1, (CE_WARN, "sc_configure: Probing AXQ exp=0x%x brd=0x%x\n", 542 expander, slot)); 543 544 /* 545 * The generic gptwocfg does not support the AXQ, so we need 546 * to configure it. The AXQ branch is returned held. 547 */ 548 new_nodes = sc_gptwocfg_configure_axq(ap, agent_id, create_nodes); 549 550 if (new_nodes == NULL) { 551 SC_DEBUG(1, (CE_WARN, "sc_configure: Can not probe AXQ\n")); 552 return (NULL); 553 } 554 555 port_cookie = kmem_zalloc(sizeof (gptwocfg_config_t), KM_SLEEP); 556 557 /* 558 * Build a cookie for the AXQ. 559 */ 560 port_cookie->gptwo_ap = ap; 561 port_cookie->gptwo_portid = agent_id; 562 port_cookie->gptwo_nodes = new_nodes; 563 564 board_config = kmem_zalloc(sizeof (sc_gptwocfg_config_t), KM_SLEEP); 565 566 board_config->port_cookie = port_cookie; 567 board_config->board = board; 568 board_config->portid = agent_id; 569 board_config->link = NULL; 570 last = board_config; 571 572 mutex_enter(&sc_gptwo_config_list_lock); 573 board_config->next = sc_gptwo_config_list; 574 sc_gptwo_config_list = board_config; 575 mutex_exit(&sc_gptwo_config_list_lock); 576 577 SC_DEBUG(1, (CE_WARN, "sc_configure: AXQ Probing Complete. " 578 "%d nodes added\n", new_nodes->gptwo_number_of_nodes)); 579 580 /* 581 * Determine the starting ending slots of the PRD array. 582 */ 583 switch (slot) { 584 case 0: /* Full Bandwidth Slot */ 585 prd_slot_start = 0; 586 prd_slot_end = 3; 587 break; 588 case 1: /* Half Bandwidth Slot */ 589 prd_slot_start = 4; 590 prd_slot_end = 5; 591 break; 592 default: 593 SC_DEBUG(1, (CE_WARN, "Unknown Board Address - " 594 "Can not probe\n")); 595 return (board_config); 596 } 597 598 /* 599 * For each valid PRD entry, determine the agent id which is based 600 * on what type of device is described by the slot, and then 601 * call the safari configurator. 602 */ 603 for (prd_slot = prd_slot_start; prd_slot <= prd_slot_end; prd_slot++) { 604 605 pcd = sc_get_common_pcd(expander, prd_slot); 606 607 if (pcd == NULL) { 608 609 /* 610 * We can not get a PCD for this port so skip it. 611 */ 612 cmn_err(CE_WARN, "sc_gptwocfg: Can not get PCD " 613 "expander 0x%x prd slot 0x%x\n", 614 expander, prd_slot); 615 616 return (board_config); 617 } 618 619 /* 620 * Only configure good devices. 621 */ 622 if (pcd->spcd_prsv == SPCD_RSV_PASS) { 623 /* 624 * Determine the agent id. 625 */ 626 agent_id = sc_get_agent_id( 627 pcd, expander, slot, prd_slot); 628 629 pcd->memory_layout = get_memlayout(agent_id, &size); 630 pcd->memory_layout_size = size; 631 632 /* 633 * Call Platform Independent gptwo configurator to 634 * create node and properties. 635 */ 636 if (create_nodes) { 637 port_cookie = 638 gptwocfg_configure(ap, pcd, agent_id); 639 if (port_cookie) 640 created_node++; 641 } 642 643 new = kmem_zalloc 644 (sizeof (sc_gptwocfg_config_t), KM_SLEEP); 645 646 /* 647 * XXX Shouldn't port_cookie be NULL if 648 * !create_nodes ? 649 */ 650 new->port_cookie = port_cookie; 651 new->portid = agent_id; 652 new->link = NULL; 653 last->link = new; 654 last = new; 655 } else { 656 SC_DEBUG(1, (CE_WARN, "sc_configure: Bad Agent " 657 "Exp=0x%x PRD Slot=0x%x prsv Status=0x%x\n", 658 expander, prd_slot, pcd->spcd_prsv)); 659 } 660 661 sc_free_common_pcd(pcd); 662 663 } /* for loop */ 664 665 dump_config(board_config); 666 667 if (create_nodes && !created_node) { 668 SC_DEBUG(1, (CE_WARN, "sc_configure: GPTWO Devices failed " 669 "to configure - unprobing board %d\n", board)); 670 board_config = sc_unprobe_board(board); 671 } 672 673 SC_DEBUG(1, (CE_WARN, "sc_configure: Returning 0x%p\n", 674 (void *)board_config)); 675 676 return (board_config); 677 } 678 679 sc_gptwocfg_cookie_t 680 sc_unprobe_board(uint_t board) 681 { 682 sc_gptwocfg_config_t *board_config, *axq_config, *prior_config; 683 gptwocfg_cookie_t port_cookie; 684 685 SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: board=%d\n", board)); 686 687 if (board > 35) { 688 SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: " 689 "invalid board 0x%x\n", board)); 690 return (NULL); 691 } 692 mutex_enter(&sc_gptwo_config_list_lock); 693 board_config = sc_gptwo_config_list; 694 while (board_config != NULL) { 695 if (board_config->board == board) { 696 break; 697 } 698 board_config = board_config->next; 699 } 700 mutex_exit(&sc_gptwo_config_list_lock); 701 702 if (board_config == NULL) { 703 704 SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: No " 705 "config structure board=0x%x\n", board)); 706 707 /* 708 * Configure the board without creating nodes. 709 */ 710 board_config = sc_configure(board, 0); 711 712 if (board_config == NULL) { 713 714 cmn_err(CE_WARN, "sc_gptwocfg: sc_unprobe_board: " 715 "Unable to unconfigure board %d - board is not " 716 "configured\n", board); 717 718 return (NULL); 719 } 720 } 721 722 axq_config = board_config; 723 724 /* 725 * Walk the link of ports on this board and unconfigure them. 726 * Save the AXQ for last. 727 */ 728 while (board_config->link != NULL) { 729 prior_config = board_config; 730 board_config = board_config->link; 731 732 SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: " 733 "calling gptwocfg_unconfigure(ap=0x%p portid=0x%x)\n", 734 (void *)ddi_root_node(), board_config->portid)); 735 736 port_cookie = gptwocfg_unconfigure(ddi_root_node(), 737 board_config->portid); 738 739 SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: " 740 "gptwocfg_unconfigure returned cookie=0x%p\n", 741 port_cookie)); 742 743 if (port_cookie == NULL) { 744 /* 745 * Can be removed from list. 746 */ 747 prior_config->link = board_config->link; 748 kmem_free(board_config, sizeof (sc_gptwocfg_config_t)); 749 board_config = prior_config; 750 } else { 751 board_config->port_cookie = port_cookie; 752 } 753 } 754 755 if (axq_config->link == NULL) { 756 757 /* 758 * If all the other Safari devices have been successfully 759 * unconfigured, then the AXQ can be unconfigured. 760 */ 761 axq_config->port_cookie = 762 sc_gptwocfg_unconfigure_axq(axq_config->port_cookie); 763 764 if (axq_config->port_cookie == NULL) { 765 766 /* 767 * If the AXQ was successfully unconfigured, then 768 * the board is removed from the configured list. 769 */ 770 mutex_enter(&sc_gptwo_config_list_lock); 771 if (sc_gptwo_config_list == axq_config) { 772 sc_gptwo_config_list = axq_config->next; 773 } else { 774 board_config = sc_gptwo_config_list; 775 while (board_config->next != axq_config) { 776 board_config = board_config->next; 777 } 778 board_config->next = axq_config->next; 779 } 780 mutex_exit(&sc_gptwo_config_list_lock); 781 kmem_free(axq_config, sizeof (sc_gptwocfg_config_t)); 782 axq_config = NULL; 783 } 784 } 785 dump_config(axq_config); 786 return (axq_config); 787 } 788 789 int 790 sc_next_node(sc_gptwocfg_cookie_t c, dev_info_t *previous, dev_info_t **next) 791 { 792 dev_info_t *dip; 793 sc_gptwocfg_config_t *cookie; 794 795 SC_DEBUG(1, (CE_WARN, "sccfg: sccfg_next_node" 796 "(c=0x%p, previous=0x%p, next=0x%p)\n", (void *)c, 797 (void *)previous, (void *)next)); 798 799 cookie = (sc_gptwocfg_config_t *)c; 800 801 if (cookie == NULL) { 802 cmn_err(CE_WARN, "sccfg: sccfg_next_node - " 803 "Invalid Cookie\n"); 804 return (0); 805 } 806 if (previous == NULL) { 807 /* 808 * Start with the AXQ node. 809 */ 810 if (gptwocfg_next_node(cookie->port_cookie, NULL, &dip)) { 811 *next = dip; 812 return (1); 813 } else { 814 return (0); 815 } 816 } 817 818 while (cookie != NULL) { 819 if (gptwocfg_next_node(cookie->port_cookie, previous, &dip)) { 820 if ((dip == NULL) && (cookie->link == NULL)) { 821 *next = NULL; 822 return (1); 823 } 824 if (dip != NULL) { 825 *next = dip; 826 return (1); 827 } 828 829 /* dip == NULL */ 830 831 previous = NULL; 832 } 833 cookie = cookie->link; 834 } 835 836 return (0); 837 } 838 839 static dev_info_t * 840 sc_find_axq_node(uint_t axq_id) 841 { 842 char *name; 843 int size; 844 gptwo_regspec_t *reg; 845 dev_info_t *dip; 846 uint_t id; 847 int circ; 848 849 SC_DEBUG(1, (CE_CONT, "sc_find_axq_node: id=0x%x\n", axq_id)); 850 851 /* 852 * Hold root node busy to walk its child list 853 */ 854 ndi_devi_enter(ddi_root_node(), &circ); 855 856 dip = ddi_get_child(ddi_root_node()); 857 858 while (dip != NULL) { 859 860 SC_DEBUG(1, (CE_CONT, "Searching dip=0x%p for our AXQ\n", 861 (void *)dip)); 862 863 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, 864 DDI_PROP_DONTPASS, "name", (caddr_t)&name, &size) 865 != DDI_PROP_SUCCESS) { 866 867 /* 868 * This node does not have a name property. 869 */ 870 SC_DEBUG(1, (CE_CONT, "dip=0x%p does not have a " 871 "'name' property\n", (void *)dip)); 872 873 dip = ddi_get_next_sibling(dip); 874 continue; 875 } 876 877 SC_DEBUG(1, (CE_CONT, "dip=0x%p name=%s\n", (void *)dip, name)); 878 879 if (strcmp(name, "address-extender-queue")) { 880 881 /* 882 * This node is not a AXQ node. 883 */ 884 SC_DEBUG(1, (CE_CONT, "dip=0x%p is not an AXQ " 885 "node\n", (void *)dip)); 886 kmem_free(name, size); 887 dip = ddi_get_next_sibling(dip); 888 continue; 889 } 890 kmem_free(name, size); 891 892 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, 893 DDI_PROP_DONTPASS, "reg", (caddr_t)®, &size) 894 != DDI_PROP_SUCCESS) { 895 896 /* 897 * This AXQ node does not have a reg property. 898 */ 899 SC_DEBUG(1, (CE_CONT, "dip=0x%p (AXQ Node) does " 900 "have a 'reg' property\n", (void *)dip)); 901 dip = ddi_get_next_sibling(dip); 902 continue; 903 } 904 905 id = ((reg[0].gptwo_phys_hi & 1) << 9) | 906 ((reg[0].gptwo_phys_low & 0xff800000) >> 23); 907 908 kmem_free(reg, size); 909 910 if (axq_id != id) { 911 912 /* 913 * This is the wrong AXQ node. 914 */ 915 SC_DEBUG(1, (CE_CONT, "dip=0x%p Wrong node id=0x%x\n", 916 (void *)dip, id)); 917 918 dip = ddi_get_next_sibling(dip); 919 continue; 920 921 } 922 923 /* 924 * The correct AXQ node was found. 925 */ 926 SC_DEBUG(1, (CE_CONT, "dip=0x%p Found AXQ Node\n", 927 (void *)dip)); 928 ndi_hold_devi(dip); 929 break; 930 } 931 ndi_devi_exit(ddi_root_node(), circ); 932 933 SC_DEBUG(1, (CE_CONT, "sc_find_axq_node: Returning 0x%p\n", 934 (void *)dip)); 935 936 return (dip); 937 } 938 939 struct axq_arg { 940 uint_t id; 941 dev_info_t *axq_dip; 942 }; 943 944 /*ARGSUSED*/ 945 static int 946 axq_set_prop(dev_info_t *axq_dip, void *arg, uint_t flags) 947 { 948 struct axq_arg *aqp = (struct axq_arg *)arg; 949 gptwo_regspec_t reg[2]; 950 uint_t id; 951 952 ASSERT(aqp); 953 954 id = aqp->id; 955 956 if (ndi_prop_update_string(DDI_DEV_T_NONE, axq_dip, 957 "name", "address-extender-queue") != DDI_SUCCESS) { 958 SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_pci: failed " 959 "to create name property\n")); 960 return (DDI_WALK_ERROR); 961 } 962 963 if (ndi_prop_update_string(DDI_DEV_T_NONE, axq_dip, 964 "device_type", "address-extender-queue") != DDI_SUCCESS) { 965 SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_pci: failed " 966 "to create device_type property\n")); 967 return (DDI_WALK_ERROR); 968 } 969 970 if (ndi_prop_update_string(DDI_DEV_T_NONE, axq_dip, 971 "compatible", "SUNW,axq") != DDI_SUCCESS) { 972 SC_DEBUG(1, (CE_CONT, "sc_gptwocfg: failed " 973 "to create compatible property\n")); 974 return (DDI_WALK_ERROR); 975 } 976 977 if (ndi_prop_update_int(DDI_DEV_T_NONE, axq_dip, 978 "portid", id) != DDI_SUCCESS) { 979 SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_pci: failed " 980 "to create portid property\n")); 981 return (DDI_WALK_ERROR); 982 } 983 984 reg[0].gptwo_phys_hi = 0x400 | (id >> 9); 985 reg[0].gptwo_phys_low = (id << 23); 986 reg[0].gptwo_size_hi = 0; 987 reg[0].gptwo_size_low = 0x520; 988 989 reg[1].gptwo_phys_hi = 0x401; 990 reg[1].gptwo_phys_low = 0xf0000000; 991 reg[1].gptwo_size_hi = 0; 992 reg[1].gptwo_size_low = 0x520; 993 994 if (ndi_prop_update_int_array(DDI_DEV_T_NONE, 995 axq_dip, "reg", (int *)®, 996 (sizeof (gptwo_regspec_t) * 2)/sizeof (int)) != DDI_SUCCESS) { 997 SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_pci: failed " 998 "to create reg property\n")); 999 return (DDI_WALK_ERROR); 1000 } 1001 1002 return (DDI_WALK_TERMINATE); 1003 } 1004 1005 /*ARGSUSED*/ 1006 static void 1007 get_axq_dip(dev_info_t *rdip, void *arg, uint_t flags) 1008 { 1009 struct axq_arg *aqp = (struct axq_arg *)arg; 1010 1011 ASSERT(aqp); 1012 1013 aqp->axq_dip = rdip; 1014 } 1015 1016 static gptwo_new_nodes_t * 1017 sc_gptwocfg_configure_axq(dev_info_t *ap, uint_t id, int create_nodes) 1018 { 1019 struct axq_arg arg = {0}; 1020 devi_branch_t b = {0}; 1021 dev_info_t *axq_dip, *fdip = NULL; 1022 gptwo_new_nodes_t *new_nodes = NULL; 1023 int rv; 1024 1025 SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_axq: id=0x%x " 1026 "create_nodes=%d\n", id, create_nodes)); 1027 1028 if (!create_nodes) { 1029 axq_dip = sc_find_axq_node(id); 1030 1031 if (axq_dip) { 1032 new_nodes = gptwocfg_allocate_node_list(1); 1033 new_nodes->gptwo_nodes[0] = axq_dip; 1034 ASSERT(!e_ddi_branch_held(axq_dip)); 1035 e_ddi_branch_hold(axq_dip); 1036 /* 1037 * Release hold from sc_find_axq_node() 1038 */ 1039 ddi_release_devi(axq_dip); 1040 } 1041 1042 SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_axq: " 1043 "Returning 0x%p\n", (void *)new_nodes)); 1044 1045 return (new_nodes); 1046 } 1047 1048 arg.id = id; 1049 arg.axq_dip = NULL; 1050 1051 b.arg = &arg; 1052 b.type = DEVI_BRANCH_SID; 1053 b.create.sid_branch_create = axq_set_prop; 1054 b.devi_branch_callback = get_axq_dip; 1055 1056 rv = e_ddi_branch_create(ap, &b, &fdip, DEVI_BRANCH_CONFIGURE); 1057 if (rv != 0) { 1058 char *path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 1059 1060 /* 1061 * If non-NULL, fdip is held and must be released. 1062 */ 1063 if (fdip != NULL) { 1064 (void) ddi_pathname(fdip, path); 1065 ddi_release_devi(fdip); 1066 } else { 1067 (void) ddi_pathname(ap, path); 1068 } 1069 1070 SC_DEBUG(1, (CE_WARN, "e_ddi_branch_create failed: " 1071 "path=%s, dip=%p, rv=%d", path, fdip ? (void *)fdip : 1072 (void *)ap, rv)); 1073 1074 kmem_free(path, MAXPATHLEN); 1075 1076 return (NULL); 1077 } 1078 1079 axq_dip = arg.axq_dip; 1080 1081 new_nodes = gptwocfg_allocate_node_list(1); 1082 new_nodes->gptwo_nodes[0] = axq_dip; 1083 1084 return (new_nodes); 1085 } 1086 1087 static gptwocfg_config_t * 1088 sc_gptwocfg_unconfigure_axq(gptwocfg_config_t *config) 1089 { 1090 int i; 1091 int failure = 0; 1092 dev_info_t *saf_dip; 1093 1094 if (config == NULL) { 1095 cmn_err(CE_WARN, "sc_gptwocfg: sc_gptwocfg_unconfigure_axq: " 1096 "Invalid AXQ\n"); 1097 return (NULL); 1098 } 1099 for (i = 0; i < config->gptwo_nodes->gptwo_number_of_nodes; i++) { 1100 int rv; 1101 dev_info_t *fdip = NULL; 1102 1103 saf_dip = config->gptwo_nodes->gptwo_nodes[i]; 1104 ASSERT(e_ddi_branch_held(saf_dip)); 1105 rv = e_ddi_branch_destroy(saf_dip, &fdip, 0); 1106 if (rv != 0) { 1107 char *path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 1108 1109 /* 1110 * If non-NULL, fdip is held and must be released. 1111 */ 1112 if (fdip != NULL) { 1113 (void) ddi_pathname(fdip, path); 1114 ddi_release_devi(fdip); 1115 } else { 1116 (void) ddi_pathname(saf_dip, path); 1117 } 1118 1119 cmn_err(CE_CONT, "AXQ node removal failed: " 1120 "path=%s, dip=%p, rv=%d\n", path, 1121 fdip ? (void *)fdip : (void *)saf_dip, rv); 1122 1123 kmem_free(path, MAXPATHLEN); 1124 failure = 1; 1125 } else { 1126 config->gptwo_nodes->gptwo_nodes[i] = NULL; 1127 } 1128 } 1129 if (!failure) { 1130 gptwocfg_free_node_list(config->gptwo_nodes); 1131 1132 kmem_free(config, sizeof (gptwocfg_config_t)); 1133 config = NULL; 1134 } 1135 return (config); 1136 } 1137 1138 static uint_t 1139 sc_get_agent_id(spcd_t *pcd, uint_t expander, uint_t slot, uint_t prd_slot) 1140 { 1141 uint_t agent_id; 1142 1143 switch (pcd->spcd_ptype) { 1144 case SAFPTYPE_CPU: 1145 if (slot == 0) { 1146 agent_id = prd_slot; 1147 } else { 1148 if (prd_slot == 4) { 1149 agent_id = 8; 1150 } else { 1151 agent_id = 9; 1152 } 1153 } 1154 break; 1155 1156 case SAFPTYPE_sPCI: 1157 case SAFPTYPE_cPCI: 1158 case SAFPTYPE_PCIX: 1159 if (prd_slot == 4) { 1160 agent_id = 0x1c; 1161 } else { 1162 agent_id = 0x1d; 1163 } 1164 break; 1165 case SAFPTYPE_WCI: 1166 agent_id = 0x1d; 1167 break; 1168 default: 1169 cmn_err(CE_WARN, "sc_gptwocfg: Invalid Safari Port " 1170 "Type 0x%x Slot 0x%x\n", 1171 pcd->spcd_ptype, prd_slot); 1172 } /* switch */ 1173 1174 agent_id |= (expander << 5); 1175 1176 SC_DEBUG(1, (CE_CONT, "sc_get_agent_id(pcd=0x%p, expander=0x%x, " 1177 "prd_slot=0x%x) Returning agent_id=0x%x\n", (void *)pcd, expander, 1178 prd_slot, agent_id)); 1179 1180 return (agent_id); 1181 } 1182 1183 static void 1184 dump_config(sc_gptwocfg_config_t *board_config) 1185 { 1186 gptwocfg_config_t *port; 1187 1188 SC_DEBUG(1, (CE_CONT, "dump_config 0x%p", (void *)board_config)); 1189 while (board_config != NULL) { 1190 SC_DEBUG(1, (CE_CONT, "************* 0x%p ************\n", 1191 (void *)board_config)); 1192 SC_DEBUG(1, (CE_CONT, "port_cookie - 0x%p\n", 1193 (void *)board_config->port_cookie)); 1194 1195 port = board_config->port_cookie; 1196 if (port) { 1197 SC_DEBUG(1, (CE_CONT, " ap - 0x%p\n", 1198 (void *)port->gptwo_ap)); 1199 SC_DEBUG(1, (CE_CONT, " portid - 0x%x\n", 1200 port->gptwo_portid)); 1201 } 1202 SC_DEBUG(1, (CE_CONT, "portid - 0x%x\n", 1203 board_config->portid)); 1204 SC_DEBUG(1, (CE_CONT, "board - 0x%x\n", 1205 board_config->board)); 1206 SC_DEBUG(1, (CE_CONT, "link - 0x%p\n", 1207 (void *)board_config->link)); 1208 SC_DEBUG(1, (CE_CONT, "next - 0x%p\n", 1209 (void *)board_config->next)); 1210 board_config = board_config->link; 1211 } 1212 } 1213 1214 static void 1215 dump_pcd(spcd_t *pcd) 1216 { 1217 int i; 1218 1219 SC_DEBUG(1, (CE_CONT, "dump_pcd 0x%p", (void *)pcd)); 1220 SC_DEBUG(1, (CE_CONT, " magic - 0x%x\n", pcd->spcd_magic)); 1221 SC_DEBUG(1, (CE_CONT, " version - 0x%x\n", pcd->spcd_version)); 1222 SC_DEBUG(1, (CE_CONT, " ver.reg - 0x%lx\n", pcd->spcd_ver_reg)); 1223 SC_DEBUG(1, (CE_CONT, " afreq - %d\n", pcd->spcd_afreq)); 1224 switch (pcd->spcd_ptype) { 1225 case SAFPTYPE_CPU: 1226 SC_DEBUG(1, (CE_CONT, " ptype - CPU\n")); 1227 break; 1228 case SAFPTYPE_sPCI: 1229 SC_DEBUG(1, (CE_CONT, " ptype - sPCI\n")); 1230 break; 1231 case SAFPTYPE_cPCI: 1232 SC_DEBUG(1, (CE_CONT, " ptype - cPCI\n")); 1233 break; 1234 case SAFPTYPE_PCIX: 1235 SC_DEBUG(1, (CE_CONT, " ptype - sPCI+\n")); 1236 break; 1237 case SAFPTYPE_WCI: 1238 SC_DEBUG(1, (CE_CONT, " ptype - WIC\n")); 1239 break; 1240 default: 1241 SC_DEBUG(1, (CE_CONT, " ptype - 0x%x\n", 1242 pcd->spcd_ptype)); 1243 break; 1244 } 1245 SC_DEBUG(1, (CE_CONT, " cache - %d\n", pcd->spcd_cache)); 1246 1247 if (pcd->spcd_prsv == SPCD_RSV_PASS) { 1248 SC_DEBUG(1, (CE_CONT, " prsv - SPCD_RSV_PASS\n")); 1249 } else { 1250 SC_DEBUG(1, (CE_CONT, " prsv - 0x%x (FAIL)\n", 1251 pcd->spcd_prsv)); 1252 } 1253 1254 for (i = 0; i < AGENTS_PER_PORT; i++) { 1255 if (pcd->spcd_agent[i] == SPCD_RSV_PASS) { 1256 SC_DEBUG(1, (CE_CONT, " agent[%d] " 1257 "- SPCD_RSV_PASS\n", i)); 1258 } else { 1259 SC_DEBUG(1, (CE_CONT, " agent[%d] " 1260 "- 0x%x (FAIL)\n", i, pcd->spcd_agent[i])); 1261 } 1262 } 1263 1264 if (pcd->spcd_ptype == SAFPTYPE_CPU) { 1265 for (i = 0; i < AGENTS_PER_PORT; i++) { 1266 SC_DEBUG(1, (CE_CONT, " cpuid[%d] - 0x%x\n", 1267 i, pcd->spcd_cpuid[i])); 1268 } 1269 } 1270 1271 SC_DEBUG(1, (CE_CONT, " Banks\n")); 1272 for (i = 0; i < MAX_BANKS_PER_PORT; i++) { 1273 if (pcd->sprd_bank_rsv[i]) { 1274 SC_DEBUG(1, (CE_CONT, " %d %s\n", i, 1275 pcd->sprd_bank_rsv[i])); 1276 } 1277 } 1278 1279 SC_DEBUG(1, (CE_CONT, " Dimms\n")); 1280 for (i = 0; i < MAX_DIMMS_PER_PORT; i++) { 1281 if (pcd->sprd_dimm[i]) { 1282 SC_DEBUG(1, (CE_CONT, " %d %s\n", i, 1283 pcd->sprd_dimm[i])); 1284 } 1285 } 1286 SC_DEBUG(1, (CE_CONT, " Ecache Dimm Labels\n")); 1287 for (i = 0; i < MAX_DIMMS_PER_PORT; i++) { 1288 if (pcd->sprd_ecache_dimm_label[i]) { 1289 SC_DEBUG(1, (CE_CONT, " %d %s\n", i, 1290 pcd->sprd_ecache_dimm_label[i])); 1291 } 1292 } 1293 } 1294 1295 1296 typedef struct { 1297 char Jnumber[8][8]; 1298 uint8_t sym_flag; 1299 uint8_t d_dimmtable[144]; 1300 uint8_t d_pintable[576]; 1301 }m_layout; 1302 1303 /* 1304 * Use 2 bits to represent each bit at a cache line. The table 1305 * is in big endian order, i.e. 1306 * dimmtable[0], ... , dimmtable[143] 1307 * Q0:data-bits[127 126 125 124], ... , MtagEcc[3 2 1 0] 1308 * . 1309 * . 1310 * Q3:data-bits[127 126 125 124], ... , MtagEcc[3 2 1 0] 1311 */ 1312 uint8_t J_dimm_pinTable[] = { 1313 /* Jnumber */ 1314 /* 0 */ 0x4a, 0x31, 0x33, 0x33, 0x30, 0x30, 0x00, 0x00, 1315 /* 1 */ 0x4a, 0x31, 0x33, 0x34, 0x30, 0x30, 0x00, 0x00, 1316 /* 2 */ 0x4a, 0x31, 0x33, 0x35, 0x30, 0x30, 0x00, 0x00, 1317 /* 3 */ 0x4a, 0x31, 0x33, 0x36, 0x30, 0x30, 0x00, 0x00, 1318 /* 4 */ 0x4a, 0x31, 0x33, 0x33, 0x30, 0x31, 0x00, 0x00, 1319 /* 5 */ 0x4a, 0x31, 0x33, 0x34, 0x30, 0x31, 0x00, 0x00, 1320 /* 6 */ 0x4a, 0x31, 0x33, 0x35, 0x30, 0x31, 0x00, 0x00, 1321 /* 7 */ 0x4a, 0x31, 0x33, 0x36, 0x30, 0x31, 0x00, 0x00, 1322 /* flag */ 0x01, 1323 /* -- Q0 -- */ 1324 /* 0 */ 0x00, 0x55, 0xaa, 0xff, 0x00, 0x55, 0xaa, 0xff, 1325 /* 1 */ 0x00, 0xaa, 0xff, 0x00, 0x56, 0xaf, 0x00, 0x55, 1326 /* 2 */ 0xaa, 0x55, 0xaf, 0xc0, 0x55, 0xaa, 0xff, 0x00, 1327 /* 3 */ 0x55, 0xff, 0x00, 0x55, 0xaa, 0xff, 0x6d, 0x80, 1328 /* 4 */ 0xe7, 0xe3, 0x9b, 0x1b, 1329 /* -- Q1 -- */ 1330 /* 0 */ 0x00, 0x55, 0xaa, 0xff, 0x00, 0x55, 0xaa, 0xff, 1331 /* 1 */ 0x00, 0xaa, 0xff, 0x00, 0x56, 0xaf, 0x00, 0x55, 1332 /* 2 */ 0xaa, 0x55, 0xaf, 0xc0, 0x55, 0xaa, 0xff, 0x00, 1333 /* 3 */ 0x55, 0xff, 0x00, 0x55, 0xaa, 0xff, 0x6d, 0x80, 1334 /* 4 */ 0xe7, 0xe3, 0x9b, 0x1b, 1335 /* -- Q2 -- */ 1336 /* 0 */ 0x00, 0x55, 0xaa, 0xff, 0x00, 0x55, 0xaa, 0xff, 1337 /* 1 */ 0x00, 0xaa, 0xff, 0x00, 0x56, 0xaf, 0x00, 0x55, 1338 /* 2 */ 0xaa, 0x55, 0xaf, 0xc0, 0x55, 0xaa, 0xff, 0x00, 1339 /* 3 */ 0x55, 0xff, 0x00, 0x55, 0xaa, 0xff, 0x6d, 0x80, 1340 /* 4 */ 0xe7, 0xe3, 0x9b, 0x1b, 1341 /* -- Q3 -- */ 1342 /* 0 */ 0x00, 0x55, 0xaa, 0xff, 0x00, 0x55, 0xaa, 0xff, 1343 /* 1 */ 0x00, 0xaa, 0xff, 0x00, 0x56, 0xaf, 0x00, 0x55, 1344 /* 2 */ 0xaa, 0x55, 0xaf, 0xc0, 0x55, 0xaa, 0xff, 0x00, 1345 /* 3 */ 0x55, 0xff, 0x00, 0x55, 0xaa, 0xff, 0x6d, 0x80, 1346 /* 4 */ 0xe7, 0xe3, 0x9b, 0x1b, 1347 /* 1348 * In the following order 1349 * pintable[0], ..., pintable[575] 1350 * Quadword3, Quadword2, Quadword1, Quadword0 1351 * MtagEcc, Mtag, Ecc, Data 1352 */ 1353 /* -- Q3 -- */ 1354 /* 0 */ 227, 227, 227, 227, 111, 111, 111, 22, 1355 /* 1 */ 22, 32, 138, 222, 81, 117, 117, 117, 1356 /* 2 */ 111, 222, 106, 222, 222, 106, 106, 106, 1357 /* 3 */ 217, 101, 212, 96, 217, 101, 212, 96, 1358 /* 4 */ 217, 101, 212, 96, 217, 101, 212, 96, 1359 /* 5 */ 207, 91, 202, 86, 187, 71, 158, 42, 1360 /* 6 */ 187, 71, 158, 42, 153, 37, 148, 32, 1361 /* 7 */ 153, 37, 148, 32, 153, 37, 148, 32, 1362 /* 8 */ 153, 37, 148, 143, 27, 138, 143, 27, 1363 /* 9 */ 143, 27, 138, 22, 207, 91, 202, 86, 1364 /* 10 */ 207, 91, 202, 86, 207, 91, 202, 86, 1365 /* 11 */ 192, 76, 81, 192, 76, 81, 192, 76, 1366 /* 12 */ 197, 81, 192, 76, 187, 71, 158, 42, 1367 /* 13 */ 187, 71, 158, 42, 143, 27, 138, 22, 1368 /* 14 */ 133, 17, 128, 12, 133, 17, 128, 12, 1369 /* 15 */ 133, 17, 128, 12, 133, 17, 128, 12, 1370 /* 16 */ 123, 07, 118, 2, 123, 07, 118, 2, 1371 /* 17 */ 123, 07, 118, 2, 123, 07, 118, 2, 1372 /* -- Q2 -- */ 1373 /* 0 */ 228, 228, 228, 228, 112, 112, 112, 23, 1374 /* 1 */ 23, 33, 139, 223, 82, 118, 118, 118, 1375 /* 2 */ 112, 223, 107, 223, 223, 107, 107, 107, 1376 /* 3 */ 218, 102, 213, 97, 218, 102, 213, 97, 1377 /* 4 */ 218, 102, 213, 97, 218, 102, 213, 97, 1378 /* 5 */ 208, 92, 203, 87, 188, 72, 159, 43, 1379 /* 6 */ 188, 72, 159, 43, 154, 38, 149, 33, 1380 /* 7 */ 154, 38, 149, 33, 154, 38, 149, 33, 1381 /* 8 */ 154, 38, 149, 144, 28, 139, 144, 28, 1382 /* 9 */ 144, 28, 139, 23, 208, 92, 203, 87, 1383 /* 10 */ 208, 92, 203, 87, 208, 92, 203, 87, 1384 /* 11 */ 193, 77, 82, 193, 77, 82, 193, 77, 1385 /* 12 */ 198, 82, 193, 77, 188, 72, 159, 43, 1386 /* 13 */ 188, 72, 159, 43, 144, 28, 139, 23, 1387 /* 14 */ 134, 18, 129, 13, 134, 18, 129, 13, 1388 /* 15 */ 134, 18, 129, 13, 134, 18, 129, 13, 1389 /* 16 */ 124, 8, 119, 3, 124, 8, 119, 3, 1390 /* 17 */ 124, 8, 119, 3, 124, 8, 119, 3, 1391 /* -- Q1 -- */ 1392 /* 0 */ 229, 229, 229, 229, 113, 113, 113, 24, 1393 /* 1 */ 24, 34, 140, 224, 83, 119, 119, 119, 1394 /* 2 */ 113, 224, 108, 224, 224, 108, 108, 108, 1395 /* 3 */ 219, 103, 214, 98, 219, 103, 214, 98, 1396 /* 4 */ 219, 103, 214, 98, 219, 103, 214, 98, 1397 /* 5 */ 209, 93, 204, 88, 189, 73, 160, 44, 1398 /* 6 */ 189, 73, 160, 44, 155, 39, 150, 34, 1399 /* 7 */ 155, 39, 150, 34, 155, 39, 150, 34, 1400 /* 8 */ 155, 39, 150, 145, 29, 140, 145, 29, 1401 /* 9 */ 145, 29, 140, 24, 209, 93, 204, 88, 1402 /* 10 */ 209, 93, 204, 88, 209, 93, 204, 88, 1403 /* 11 */ 194, 78, 83, 194, 78, 83, 194, 78, 1404 /* 12 */ 199, 83, 194, 78, 189, 73, 160, 44, 1405 /* 13 */ 189, 73, 160, 44, 145, 29, 140, 24, 1406 /* 14 */ 135, 19, 130, 14, 135, 19, 130, 14, 1407 /* 15 */ 135, 19, 130, 14, 135, 19, 130, 14, 1408 /* 16 */ 125, 9, 120, 4, 125, 9, 120, 4, 1409 /* 17 */ 125, 9, 120, 4, 125, 9, 120, 4, 1410 /* -- Q0 -- */ 1411 /* 0 */ 230, 230, 230, 230, 114, 114, 114, 25, 1412 /* 1 */ 25, 35, 141, 225, 84, 200, 200, 200, 1413 /* 2 */ 114, 225, 109, 225, 225, 109, 109, 109, 1414 /* 3 */ 220, 104, 215, 99, 220, 104, 215, 99, 1415 /* 4 */ 220, 104, 215, 99, 220, 104, 215, 99, 1416 /* 5 */ 210, 94, 205, 89, 190, 74, 161, 45, 1417 /* 6 */ 190, 74, 161, 45, 156, 40, 151, 35, 1418 /* 7 */ 156, 40, 151, 35, 156, 40, 151, 35, 1419 /* 8 */ 156, 40, 151, 146, 30, 141, 146, 30, 1420 /* 9 */ 146, 30, 141, 25, 210, 94, 205, 89, 1421 /* 10 */ 210, 94, 205, 89, 210, 94, 205, 89, 1422 /* 11 */ 195, 79, 84, 195, 79, 84, 195, 79, 1423 /* 12 */ 200, 84, 195, 79, 190, 74, 161, 45, 1424 /* 13 */ 190, 74, 161, 45, 146, 30, 141, 25, 1425 /* 14 */ 136, 20, 131, 15, 136, 20, 131, 15, 1426 /* 15 */ 136, 20, 131, 15, 136, 20, 131, 15, 1427 /* 16 */ 126, 10, 121, 5, 126, 10, 121, 5, 1428 /* 17 */ 126, 10, 121, 5, 126, 10, 121, 5 1429 }; 1430 1431 /* 1432 * This table is for internal reference 1433 * 1434 * pintable_internal[]= { 1435 * -- Q0 -- 1436 * 0 143,143,143,143,139,139,139,35 1437 * 1 35,51,39,135,91,95,95,95 1438 * 2 139,135,131,135,135,131,131,131 1439 * 3 127,123,119,115,127,123,119,115 1440 * 4 127,123,119,115,127,123,119,115 1441 * 5 111,107,103,99,79,75,71,67 1442 * 6 79,75,71,67,63,59,55,51 1443 * 7 63,59,55,51,63,59,55,51 1444 * 8 63,59,55,47,43,39,47,43 1445 * 9 47,43,39,35,111,107,103,99 1446 * 10 111,107,103,99,111,107,103,99 1447 * 11 87,83,91,87,83,91,87,83 1448 * 12 95,91,87,83,79,75,71,67 1449 * 13 79,75,71,67,47,43,39,35 1450 * 14 31,27,23,19,31,27,23,19 1451 * 15 31,27,23,19,31,27,23,19 1452 * 16 15,11,7,3,15,11,7,3 1453 * 17 15,11,7,3,15,11,7,3 1454 * } 1455 */ 1456 1457 char *dimm_Jno[] = { 1458 /* P0 */ "J13300", "J13400", "J13500", "J13600", 1459 "J13301", "J13401", "J13501", "J13601", 1460 /* P1 */ "J14300", "J14400", "J14500", "J14600", 1461 "J14301", "J14401", "J14501", "J14601", 1462 /* P2 */ "J15300", "J15400", "J15500", "J15600", 1463 "J15301", "J15401", "J15501", "J15601", 1464 /* P3 */ "J16300", "J16400", "J16500", "J16600", 1465 "J16301", "J16401", "J16501", "J16601", 1466 NULL 1467 }; 1468 1469 1470 static uint8_t * 1471 get_memlayout(uint32_t cpuid, uint32_t *len) 1472 { 1473 m_layout *LayoutBuf; 1474 1475 if ((LayoutBuf = (m_layout *)kmem_zalloc(sizeof (m_layout), 1476 KM_SLEEP)) == NULL) { 1477 *len = 0; 1478 return (NULL); 1479 } 1480 1481 bcopy(J_dimm_pinTable, LayoutBuf, sizeof (m_layout)); 1482 1483 *len = sizeof (m_layout); 1484 cpuid &= 0x03; /* last 2 bits of a 10 bit number */ 1485 1486 bcopy(dimm_Jno[cpuid << 3], LayoutBuf->Jnumber[0], 64); 1487 1488 return ((uint8_t *)LayoutBuf); 1489 } 1490 1491 static char * 1492 rsv_string(prdrsv_t rsv) 1493 { 1494 char *buffer; 1495 char *status; 1496 1497 switch (rsv) { 1498 case RSV_UNKNOWN: 1499 buffer = "unknown"; 1500 break; 1501 case RSV_PRESENT: 1502 buffer = "okay"; 1503 break; 1504 case RSV_CRUNCH: 1505 buffer = "disabled"; 1506 break; 1507 case RSV_UNDEFINED: 1508 buffer = "undefined"; 1509 break; 1510 case RSV_MISS: 1511 buffer = "missing"; 1512 break; 1513 case RSV_EMPTY_CASSETTE: 1514 buffer = "disabled"; 1515 break; 1516 case RSV_MISCONFIG: 1517 buffer = "misconfigured"; 1518 break; 1519 case RSV_FAIL_OBP: 1520 buffer = "fail-obp"; 1521 break; 1522 case RSV_BLACK: 1523 buffer = "blacklisted"; 1524 break; 1525 case RSV_RED: 1526 buffer = "redlisted"; 1527 break; 1528 case RSV_EXCLUDED: 1529 buffer = "disabled"; 1530 break; 1531 case RSV_UNCONFIG: 1532 buffer = "disabled"; 1533 break; 1534 case RSV_PASS: 1535 buffer = "okay"; 1536 break; 1537 case RSV_FAIL: 1538 default: 1539 buffer = "fail"; 1540 break; 1541 } 1542 1543 status = kmem_alloc(strlen(buffer) + 1, KM_SLEEP); 1544 (void) strcpy(status, buffer); 1545 1546 return (status); 1547 } 1548