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