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
_init()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
_fini(void)126 _fini(void)
127 {
128 mutex_destroy(&sc_gptwo_config_list_lock);
129 return (mod_remove(&modlinkage));
130 }
131
132 int
_info(modinfop)133 _info(modinfop)
134 struct modinfo *modinfop;
135 {
136 return (mod_info(&modlinkage, modinfop));
137 }
138
139 static spcd_t *
sc_get_common_pcd(uint_t expander,uint_t prd_slot)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
sc_free_common_pcd(spcd_t * pcd)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
sc_probe_board(uint_t board)482 sc_probe_board(uint_t board)
483 {
484 return (sc_configure(board, 1));
485 }
486
487 static sc_gptwocfg_cookie_t
sc_configure(uint_t board,int create_nodes)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
sc_unprobe_board(uint_t board)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
sc_next_node(sc_gptwocfg_cookie_t c,dev_info_t * previous,dev_info_t ** next)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 *
sc_find_axq_node(uint_t axq_id)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
axq_set_prop(dev_info_t * axq_dip,void * arg,uint_t flags)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
get_axq_dip(dev_info_t * rdip,void * arg,uint_t flags)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 *
sc_gptwocfg_configure_axq(dev_info_t * ap,uint_t id,int create_nodes)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 *
sc_gptwocfg_unconfigure_axq(gptwocfg_config_t * config)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
sc_get_agent_id(spcd_t * pcd,uint_t expander,uint_t slot,uint_t prd_slot)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
dump_config(sc_gptwocfg_config_t * board_config)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
dump_pcd(spcd_t * pcd)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 *
get_memlayout(uint32_t cpuid,uint32_t * len)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 *
rsv_string(prdrsv_t rsv)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