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 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 *
25 * Opl Platform specific functions.
26 *
27 * called when :
28 * machine_type == MTYPE_OPL
29 */
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <ctype.h>
35 #include <string.h>
36 #include <varargs.h>
37 #include <fcntl.h>
38 #include <assert.h>
39 #include <sys/param.h>
40 #include <sys/stat.h>
41 #include <sys/types.h>
42 #include <sys/utsname.h>
43 #include <sys/systeminfo.h>
44 #include <sys/openpromio.h>
45 #include <libintl.h>
46 #include <syslog.h>
47 #include <sys/dkio.h>
48 #include <pdevinfo.h>
49 #include <libprtdiag.h>
50 #include <libdevinfo.h>
51 #include <kstat.h>
52
53 /*
54 * Globals and externs
55 */
56 #define KBYTE 1024
57 #define MBYTE (KBYTE * KBYTE)
58 #define HZ_TO_MHZ(x) ((((uint64_t)(x)) + 500000) / 1000000)
59 #define SCF_SECURE_MODE_KSTAT_NAMED "secure_mode"
60 #define SCF_STAT_MODE_UNLOCK 0
61 #define SCF_STAT_MODE_LOCK 1
62 #define SCF_SYSTEM_KSTAT_NAME "scf"
63 #ifndef TEXT_DOMAIN
64 #define TEXT_DOMAIN "SYS_TEST"
65 #endif /* TEXT_DOMAIN */
66
67 /*
68 * Global functions and variables
69 * these functions will overlay the symbol table of libprtdiag
70 * at runtime (Opl systems only)
71 */
72 struct cs_status {
73 int cs_number;
74 int status;
75 uint_t avail_hi;
76 uint_t avail_lo;
77 uint_t dimm_hi;
78 uint_t dimm_lo;
79 int dimms;
80 };
81
82 int do_prominfo(int syserrlog, char *pgname, int log_flag, int prt_flag);
83 void *get_prop_val(Prop *prop);
84 void display_ffb(Board_node *, int);
85 void display_sbus(Board_node *board);
86 void display_cpu_devices(Sys_tree *tree);
87 void display_cpus(Board_node *board);
88 void display_memoryconf(Sys_tree *tree, struct grp_info *grps);
89 void display_io_cards(struct io_card *list);
90 void display_io_devices(Sys_tree *tree);
91 void display_diaginfo(int flag, Prom_node *root, Sys_tree *tree,
92 struct system_kstat_data *kstats);
93 Prop *find_prop(Prom_node *pnode, char *name);
94 int do_piclinfo(int);
95 int get_proc_mode(void);
96
97 /* Local functions */
98 static void opl_disp_environ(void);
99 static void opl_disp_hw_revisions(Sys_tree *tree, Prom_node *root);
100 static uint64_t print_opl_memory_line(int lsb, struct cs_status *cs_stat,
101 int ngrps, int mirror_mode);
102 static uint64_t get_opl_mem_regs(Board_node *bnode);
103 void add_node(Sys_tree *root, Prom_node *pnode);
104 static int get_prop_size(Prop *prop);
105
106 static int v_flag = 0;
107
108 /*
109 * Linked list of IO card info for display.
110 * Using file scope for use in a recursive function.
111 */
112 static struct io_card *card_list = NULL;
113
114 /*
115 * Check prom node for a class-code. If it exists and it's not a bridge device
116 * then add an io_card to card_list. Then recursively call this function for
117 * its child and sibling nodes.
118 */
119 static void
walk_tree_for_pci_devices(Prom_node * node,int board_number)120 walk_tree_for_pci_devices(Prom_node *node, int board_number)
121 {
122 struct io_card card;
123 char *str;
124 void *val;
125 int ccode;
126
127 if (node == NULL) {
128 return;
129 }
130
131 /* Look for a class-code property. Skip, if it's a bridge */
132 ccode = -1;
133 val = get_prop_val(find_prop(node, "class-code"));
134 if (val != NULL) {
135 ccode = *(int *)val;
136 }
137 if ((ccode != -1) && (ccode < 0x60000 || ccode > 0x6ffff)) {
138 (void) memset(&card, 0, sizeof (card));
139 card.board = board_number;
140
141 str = (char *)get_prop_val(find_prop(node, "name"));
142 (void) strlcpy(card.name, (str == NULL ? "N/A":str),
143 sizeof (card.name));
144
145 str = (char *)get_prop_val(find_prop(node, "model"));
146 (void) strlcpy(card.model, (str == NULL ? "N/A":str),
147 sizeof (card.model));
148
149 /* insert card to the list */
150 card_list = insert_io_card(card_list, &card);
151 }
152 /* Call this function for its child/sibling */
153 walk_tree_for_pci_devices(node->child, board_number);
154 walk_tree_for_pci_devices(node->sibling, board_number);
155 }
156
157 /*
158 * For display of I/O devices for "prtdiag"
159 */
160 void
display_io_devices(Sys_tree * tree)161 display_io_devices(Sys_tree *tree)
162 {
163 Board_node *bnode;
164
165 if (v_flag) {
166 /*
167 * OPL's PICL interface for display of PCI I/O devices
168 * for "prtdiag -v"
169 */
170 (void) do_piclinfo(v_flag);
171 } else {
172 log_printf("\n", 0);
173 log_printf("=========================", 0);
174 log_printf(dgettext(TEXT_DOMAIN, " IO Cards "), 0);
175 log_printf("=========================", 0);
176 log_printf("\n", 0);
177 log_printf("\n", 0);
178 bnode = tree->bd_list;
179 while (bnode != NULL) {
180 walk_tree_for_pci_devices(bnode->nodes,
181 bnode->board_num);
182 bnode = bnode->next;
183 }
184 display_io_cards(card_list);
185 free_io_cards(card_list);
186 }
187 }
188
189 /*
190 * There are no FFB's on OPL.
191 */
192 /*ARGSUSED*/
193 void
display_ffb(Board_node * board,int table)194 display_ffb(Board_node *board, int table)
195 {
196 }
197
198 /*
199 * There are no Sbus's on OPL.
200 */
201 /*ARGSUSED*/
202 void
display_sbus(Board_node * board)203 display_sbus(Board_node *board)
204 {
205 }
206
207 /*
208 * Details of I/O information. Print out all the io cards.
209 */
210 void
display_io_cards(struct io_card * list)211 display_io_cards(struct io_card *list)
212 {
213 char *hdrfmt = "%-6.6s %-14.14s %-12.12s\n";
214
215 struct io_card *p;
216
217 if (list == NULL)
218 return;
219
220 (void) textdomain(TEXT_DOMAIN);
221
222 log_printf(hdrfmt, gettext("LSB"), gettext("Name"), gettext("Model"),
223 0);
224
225 log_printf(hdrfmt, "---", "-----------------", "------------", 0);
226
227 for (p = list; p != NULL; p = p->next) {
228
229 /* Board number */
230 log_printf(" %02d ", p->board, 0);
231
232 /* Card name */
233 log_printf("%-15.15s", p->name, 0);
234
235 /* Card model */
236 log_printf("%-12.12s", p->model, 0);
237
238 log_printf("\n", 0);
239 }
240 log_printf("\n", 0);
241 }
242
243 /*
244 * Details of CPU information.
245 */
246 void
display_cpu_devices(Sys_tree * tree)247 display_cpu_devices(Sys_tree *tree)
248 {
249 Board_node *bnode;
250 char *hdrfmt =
251 "%-4.4s %-4.4s %-40.40s %-5.5s %-5.5s %-5.5s %-4.4s\n";
252
253 (void) textdomain(TEXT_DOMAIN);
254
255 /*
256 * Display the table header for CPUs . Then display the CPU
257 * frequency, cache size, and processor revision of all cpus.
258 */
259 log_printf("\n", 0);
260 log_printf("====================================", 0);
261 log_printf(gettext(" CPUs "), 0);
262 log_printf("====================================", 0);
263 log_printf("\n\n", 0);
264
265 log_printf(hdrfmt,
266 "",
267 gettext("CPU"),
268 gettext(" CPU "),
269 gettext("Run"),
270 gettext("L2$"),
271 gettext("CPU"),
272 gettext("CPU"), 0);
273
274 log_printf(hdrfmt,
275 gettext("LSB"),
276 gettext("Chip"),
277 gettext(" ID "),
278 gettext("MHz"),
279 gettext(" MB"),
280 gettext("Impl."),
281 gettext("Mask"), 0);
282
283 log_printf(hdrfmt,
284 "---", "----", "----------------------------------------", "----",
285 "---", "-----", "----", 0);
286
287 /* Now display all of the cpus on each board */
288 for (bnode = tree->bd_list; bnode != NULL; bnode = bnode->next) {
289 display_cpus(bnode);
290 }
291
292 log_printf("\n", 0);
293 }
294
295 /*
296 * Display the CPUs present on this board.
297 */
298 void
display_cpus(Board_node * board)299 display_cpus(Board_node *board)
300 {
301 int *impl, *mask, *cpuid, *portid, *l2cache_size;
302 uint_t freq; /* CPU clock frequency */
303 Prom_node *pnode, *cpu;
304 char *name;
305
306 (void) textdomain(TEXT_DOMAIN);
307
308 /*
309 * Get the Cpus' properties for display
310 */
311 for (pnode = board->nodes; pnode != NULL; pnode = pnode->sibling) {
312 char cpu_str[MAXSTRLEN], fcpu_str[MAXSTRLEN] = {0};
313
314 name = get_node_name(pnode);
315 if ((name == NULL) || (strncmp(name, "cmp", 3) != 0)) {
316 continue;
317 }
318
319 portid = (int *)get_prop_val(find_prop(pnode, "portid"));
320 freq = (HZ_TO_MHZ(get_cpu_freq(pnode->child)));
321 l2cache_size = (int *)get_prop_val(find_prop(pnode->child,
322 "l2-cache-size"));
323 impl = (int *)get_prop_val(find_prop(pnode->child,
324 "implementation#"));
325 mask = (int *)get_prop_val(find_prop(pnode->child, "mask#"));
326
327 /* Lsb id */
328 log_printf(" %02d ", board->board_num, 0);
329
330 if (portid != NULL)
331 log_printf("%3d ", (((*portid)>>3)&0x3), 0);
332
333 /*
334 * OPL
335 * Specific parsing of the CMP/CORE/CPU chain.
336 * The internal cpu tree built by walk_di_tree()
337 * in common code can be illustrated by the diagram
338 * below:
339 *
340 * Olympus:
341 *
342 * cmp->cpu->cpu->cpu->cpu->(next board nodes)
343 * / \
344 * core core
345 *
346 * Jupiter:
347 *
348 * cmp->cpu->cpu->cpu->cpu->cpu->cpu->cpu->cpu->(board nodes)
349 * |
350 * _____________
351 * / \ \ \
352 * core core core core
353 *
354 *
355 * where "/" or "\" are children
356 * and "->" are siblings
357 *
358 */
359 for (cpu = pnode->sibling; cpu != NULL; ) {
360 Prom_node *cpu_next = NULL;
361
362 name = get_node_name(cpu);
363 if ((name == NULL) || (strncmp(name, "cpu", 3) != 0)) {
364 break;
365 }
366
367 /* Id assigned to Virtual processor core */
368 cpuid = (int *)get_prop_val(find_prop(cpu, "cpuid"));
369 cpu_next = cpu->sibling;
370
371 if (cpu_next != NULL) {
372 name = get_node_name(cpu_next);
373
374 if ((name == NULL) ||
375 (strncmp(name, "cpu", 3) != 0)) {
376 cpu_next = NULL;
377 }
378 }
379
380 if (cpuid != NULL) {
381 /* Used for printing in comma format */
382 (void) sprintf(cpu_str, "%4d", *cpuid);
383 (void) strlcat(fcpu_str, cpu_str, MAXSTRLEN);
384
385 if (cpu_next != NULL) {
386 (void) strlcat(fcpu_str, ",",
387 MAXSTRLEN);
388 }
389 } else {
390 (void) sprintf(cpu_str, "%4s", "N/A");
391 (void) strlcat(fcpu_str, cpu_str, MAXSTRLEN);
392
393 if (cpu_next != NULL) {
394 (void) strlcat(fcpu_str, ",",
395 MAXSTRLEN);
396 }
397 }
398 cpu = cpu_next;
399 }
400
401 log_printf("%-40.40s", fcpu_str, 0);
402
403 /* Running frequency */
404 if (freq != 0)
405 log_printf(" %4ld ", freq, 0);
406 else
407 log_printf(" %4s ", "N/A", 0);
408
409 /* L2 cache size */
410 if (l2cache_size == NULL)
411 log_printf(" %3s ", "N/A", 0);
412 else {
413 log_printf("%4.1f ",
414 (float)(*l2cache_size) / (float)(1<<20), 0);
415 }
416
417
418 /* Implementation number of processor */
419 if (impl != NULL)
420 log_printf(" %4d ", *impl, 0);
421 else
422 log_printf(" %4s ", "N/A", 0);
423
424 /* Mask Set version */
425 /* Bits 31:24 of VER register is mask. */
426 /* Mask value : Non MTP mode - 00-7f, MTP mode - 80-ff */
427 if (mask == NULL)
428 log_printf("%3s", "N/A", 0);
429 else
430 log_printf("%-3d", (*mask)&0xff, 0);
431
432 log_printf("\n", 0);
433
434 }
435 }
436
437 /*
438 * Gather memory information: Details of memory information.
439 */
440 static uint64_t
get_opl_mem_regs(Board_node * bnode)441 get_opl_mem_regs(Board_node *bnode)
442 {
443 Prom_node *pnode;
444 struct cs_status *cs_stat;
445 uint64_t total_mem = 0;
446 int cs_size, ngrps;
447
448 pnode = dev_find_node(bnode->nodes, "pseudo-mc");
449 while (pnode != NULL) {
450
451 cs_size = get_prop_size(find_prop(pnode, "cs-status"));
452
453 if (cs_size > 0) {
454 int *mirror_mode = NULL;
455 int mode = 0;
456
457 /* OBP returns lists of 7 ints */
458 cs_stat = (struct cs_status *)get_prop_val
459 (find_prop(pnode, "cs-status"));
460
461 mirror_mode = (int *)(get_prop_val
462 (find_prop(pnode, "mirror-mode")));
463
464 if (mirror_mode != NULL)
465 mode = (*mirror_mode);
466
467 /*
468 * The units of cs_size will be either number of bytes
469 * or number of int array elements as this is derived
470 * from the libprtdiag Prop node size field which has
471 * inconsistent units. Until this is addressed in
472 * libprtdiag, we need a heuristic to determine the
473 * number of CS groups. Given that the maximum number
474 * of CS groups is 2, the maximum number of cs-status
475 * array elements will be 2*7=14. Since this is smaller
476 * than the byte size of a single struct status, we use
477 * this to decide if we are dealing with bytes or array
478 * elements in determining the number of CS groups.
479 */
480 if (cs_size < sizeof (struct cs_status)) {
481 /* cs_size is number of total int [] elements */
482 ngrps = cs_size / 7;
483 } else {
484 /* cs_size is total byte count */
485 ngrps = cs_size/sizeof (struct cs_status);
486 }
487
488 if (cs_stat != NULL) {
489 total_mem +=
490 print_opl_memory_line(bnode->board_num,
491 cs_stat, ngrps, mode);
492 }
493 }
494
495 pnode = dev_next_node(pnode, "pseudo-mc");
496 }
497 return (total_mem);
498 }
499
500 /*
501 * Display memory information.
502 */
503 /*ARGSUSED*/
504 void
display_memoryconf(Sys_tree * tree,struct grp_info * grps)505 display_memoryconf(Sys_tree *tree, struct grp_info *grps)
506 {
507 Board_node *bnode = tree->bd_list;
508 uint64_t total_mem = 0, total_sys_mem = 0;
509 char *hdrfmt = "\n%-5.5s %-6.6s %-18.18s %-10.10s"
510 " %-6.6s %-5.5s %-7.7s %-10.10s";
511
512 (void) textdomain(TEXT_DOMAIN);
513
514 log_printf("============================", 0);
515 log_printf(gettext(" Memory Configuration "), 0);
516 log_printf("============================", 0);
517 log_printf("\n", 0);
518
519 log_printf(hdrfmt,
520 "",
521 gettext("Memory"),
522 gettext("Available"),
523 gettext("Memory"),
524 gettext("DIMM"),
525 gettext("# of"),
526 gettext("Mirror"),
527 gettext("Interleave"),
528 0);
529
530 log_printf(hdrfmt,
531 gettext("LSB"),
532 gettext("Group"),
533 gettext("Size"),
534 gettext("Status"),
535 gettext("Size"),
536 gettext("DIMMs"),
537 gettext("Mode"),
538 gettext("Factor"), 0);
539
540 log_printf(hdrfmt,
541 "---", "-------", "------------------", "-------", "------",
542 "-----", "-------", "----------", 0);
543
544 log_printf("\n", 0);
545
546 for (bnode = tree->bd_list; bnode != NULL; bnode = bnode->next) {
547 total_mem += get_opl_mem_regs(bnode);
548 }
549
550 /*
551 * Sanity check to ensure that the total amount of system
552 * memory matches the total number of memory that
553 * we find here. Display error message if there is a mis-match.
554 */
555 total_sys_mem = (((uint64_t)sysconf(_SC_PAGESIZE) * (uint64_t)sysconf
556 (_SC_PHYS_PAGES)) / MBYTE);
557
558 if (total_mem != total_sys_mem) {
559 log_printf(dgettext(TEXT_DOMAIN, "\nError:total available "
560 "size [%lldMB] does not match total system memory "
561 "[%lldMB]\n"), total_mem, total_sys_mem, 0);
562 }
563
564 }
565
566 /*
567 * This function provides Opl's formatting of the memory config
568 * information that get_opl_mem_regs() has gathered.
569 */
570 static uint64_t
print_opl_memory_line(int lsb,struct cs_status * cs_stat,int ngrps,int mirror_mode)571 print_opl_memory_line(int lsb, struct cs_status *cs_stat, int ngrps,
572 int mirror_mode)
573 {
574 int i;
575 uint64_t total_board_mem = 0;
576 int i_factor = 2; /* default to non-mirror mode */
577 int interleave;
578
579 (void) textdomain(TEXT_DOMAIN);
580
581 if (mirror_mode)
582 i_factor *= 2;
583
584 /*
585 * Interleave factor calculation:
586 * Obtain "mirror-mode" property from pseudo-mc.
587 * cs_stat[0].dimms/i_factor represents interleave factor per
588 * pseudo-mc node. Must use cs_stat[0].dimms since this will yield
589 * interleave factor even if some DIMMs are isolated, except for
590 * the case where the entire memory group has been deconfigured (eg. due
591 * to DIMM failure); in this case, we use the second memory group
592 * (i.e. cs_stat[1]).
593 *
594 * Mirror mode:
595 * interleave factor = (# of DIMMs on cs_stat[0]/4)
596 *
597 * Non-mirror mode:
598 * interleave factor = (# of DIMMs on cs_stat[0]/2)
599 */
600
601 if (cs_stat[0].dimms == 0)
602 interleave = cs_stat[1].dimms/i_factor;
603 else
604 interleave = cs_stat[0].dimms/i_factor;
605
606
607 for (i = 0; i < ngrps; i++) {
608 uint64_t mem_size;
609
610 mem_size = ((((uint64_t)cs_stat[i].avail_hi)<<32) +
611 cs_stat[i].avail_lo);
612
613 if (mem_size == 0)
614 continue;
615
616 /* Lsb Id */
617 log_printf(" %02d ", lsb, 0);
618
619 /* Memory Group Number */
620 if ((cs_stat[i].cs_number) == 0)
621 log_printf("%-6.6s", "A", 0);
622 else
623 log_printf("%-6.6s", "B", 0);
624
625 /* Memory Group Size */
626 log_printf("%8lldMB ", mem_size/MBYTE, 0);
627
628 total_board_mem += (mem_size/MBYTE);
629
630 /* Memory Group Status */
631 log_printf("%-11.11s",
632 cs_stat[i].status ? "partial": "okay", 0);
633
634 /* DIMM Size */
635 log_printf("%4lldMB ",
636 ((((uint64_t)cs_stat[i].dimm_hi)<<32)
637 + cs_stat[i].dimm_lo)/MBYTE, 0);
638
639 /* Number of DIMMs */
640 log_printf(" %2d", cs_stat[i].dimms);
641
642 /* Mirror Mode */
643 if (mirror_mode) {
644 log_printf("%-4.4s", " yes");
645 } else
646 log_printf("%-4.4s", " no ");
647
648 /* Interleave Factor */
649 if (interleave)
650 log_printf(" %d-way\n", interleave);
651 else
652 log_printf(" None\n");
653 }
654 return (total_board_mem);
655 }
656
657 /*
658 * Details of hardware revision and environmental status.
659 */
660 /*ARGSUSED*/
661 void
display_diaginfo(int flag,Prom_node * root,Sys_tree * tree,struct system_kstat_data * kstats)662 display_diaginfo(int flag, Prom_node *root, Sys_tree *tree,
663 struct system_kstat_data *kstats)
664 {
665 /* Print the PROM revisions */
666 opl_disp_hw_revisions(tree, root);
667 }
668
669 /*
670 * Gather and display hardware revision and environmental status
671 */
672 /*ARGSUSED*/
673 static void
opl_disp_hw_revisions(Sys_tree * tree,Prom_node * root)674 opl_disp_hw_revisions(Sys_tree *tree, Prom_node *root)
675 {
676 char *version;
677 Prom_node *pnode;
678 int value;
679
680 (void) textdomain(TEXT_DOMAIN);
681
682 /* Print the header */
683 log_printf("\n", 0);
684 log_printf("====================", 0);
685 log_printf(gettext(" Hardware Revisions "), 0);
686 log_printf("====================", 0);
687 log_printf("\n\n", 0);
688
689 /* Display Prom revision header */
690 log_printf(gettext("System PROM revisions:"), 0);
691 log_printf("\n----------------------\n", 0);
692 log_printf("\n", 0);
693
694 /* Display OBP version info */
695 pnode = dev_find_node(root, "openprom");
696 if (pnode != NULL) {
697 version = (char *)get_prop_val(find_prop(pnode, "version"));
698 if (version != NULL)
699 log_printf("%s\n\n", version, 0);
700 else
701 log_printf("%s\n\n", "N/A", 0);
702 }
703
704 /* Print the header */
705 log_printf("\n", 0);
706 log_printf("===================", 0);
707 log_printf(gettext(" Environmental Status "), 0);
708 log_printf("===================", 0);
709 log_printf("\n\n", 0);
710
711 opl_disp_environ();
712
713 /*
714 * PICL interface needs to be used for system processor mode display.
715 * Check existence of OBP property "SPARC64-VII-mode".
716 * No display if property does not exist.
717 * If property exists then system is in (Jupiter) SPARC64-VII-mode.
718 */
719 value = get_proc_mode();
720
721 if (value == 0) {
722 /* Print the header */
723 log_printf("\n", 0);
724 log_printf("===================", 0);
725 log_printf(gettext(" System Processor Mode "), 0);
726 log_printf("===================", 0);
727 log_printf("\n\n", 0);
728
729 /* Jupiter mode */
730 log_printf("%s\n\n", "SPARC64-VII mode");
731 }
732 }
733
734 /*
735 * Gather environmental information
736 */
737 static void
opl_disp_environ(void)738 opl_disp_environ(void)
739 {
740 kstat_ctl_t *kc;
741 kstat_t *ksp;
742 kstat_named_t *k;
743
744 if ((kc = kstat_open()) == NULL)
745 return;
746
747 if ((ksp = kstat_lookup
748 (kc, "scfd", 0, SCF_SYSTEM_KSTAT_NAME)) == NULL) {
749 (void) kstat_close(kc);
750 return;
751 }
752
753 if (kstat_read(kc, ksp, NULL) == -1) {
754 (void) kstat_close(kc);
755 return;
756 }
757
758 if ((k = (kstat_named_t *)kstat_data_lookup
759 (ksp, SCF_SECURE_MODE_KSTAT_NAMED)) == NULL) {
760 (void) kstat_close(kc);
761 return;
762 }
763
764 if (k->value.c[0] == SCF_STAT_MODE_LOCK)
765 log_printf("Mode switch is in LOCK mode ", 0);
766 else if (k->value.c[0] == SCF_STAT_MODE_UNLOCK)
767 log_printf("Mode switch is in UNLOCK mode", 0);
768 else
769 log_printf("Mode switch is in UNKNOWN mode", 0);
770
771 log_printf("\n", 0);
772
773 (void) kstat_close(kc);
774 }
775
776
777 /*
778 * Calls do_devinfo() in order to use the libdevinfo device tree
779 * instead of OBP's device tree.
780 */
781 int
do_prominfo(int syserrlog,char * pgname,int log_flag,int prt_flag)782 do_prominfo(int syserrlog, char *pgname, int log_flag, int prt_flag)
783 {
784 v_flag = syserrlog;
785 return (do_devinfo(syserrlog, pgname, log_flag, prt_flag));
786 }
787
788 /*
789 * Return the property value for the Prop
790 * passed in. (When using libdevinfo)
791 */
792 void *
get_prop_val(Prop * prop)793 get_prop_val(Prop *prop)
794 {
795 if (prop == NULL)
796 return (NULL);
797
798 return ((void *)(prop->value.val_ptr));
799 }
800
801 /*
802 * Return the property size for the Prop
803 * passed in. (When using libdevinfo)
804 */
805 static int
get_prop_size(Prop * prop)806 get_prop_size(Prop *prop)
807 {
808
809 if ((prop != NULL) && (prop->size > 0))
810 return (prop->size);
811 else
812 return (0);
813 }
814
815
816 /*
817 * Search a Prom node and retrieve the property with the correct
818 * name. (When using libdevinfo)
819 */
820 Prop *
find_prop(Prom_node * pnode,char * name)821 find_prop(Prom_node *pnode, char *name)
822 {
823 Prop *prop;
824
825 if (pnode == NULL)
826 return (NULL);
827
828 for (prop = pnode->props; prop != NULL; prop = prop->next) {
829 if (prop->name.val_ptr != NULL &&
830 strcmp((char *)(prop->name.val_ptr), name) == 0)
831 break;
832 }
833
834 return (prop);
835 }
836
837 /*
838 * This function adds a board node to the board structure where that
839 * that node's physical component lives.
840 */
841 void
add_node(Sys_tree * root,Prom_node * pnode)842 add_node(Sys_tree *root, Prom_node *pnode)
843 {
844 int board;
845 Board_node *bnode;
846 Prom_node *p;
847 char *type;
848
849 if ((board = get_board_num(pnode)) == -1) {
850 type = get_node_type(pnode);
851 if ((type != NULL) && (strcmp(type, "cpu") == 0))
852 board = get_board_num((pnode->parent)->parent);
853 }
854
855 /* find the node with the same board number */
856 if ((bnode = find_board(root, board)) == NULL) {
857 bnode = insert_board(root, board);
858 bnode->board_type = UNKNOWN_BOARD;
859 }
860
861 /* now attach this prom node to the board list */
862 /* Insert this node at the end of the list */
863 pnode->sibling = NULL;
864 if (bnode->nodes == NULL)
865 bnode->nodes = pnode;
866 else {
867 p = bnode->nodes;
868 while (p->sibling != NULL)
869 p = p->sibling;
870 p->sibling = pnode;
871 }
872
873 }
874