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