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 * Copyright 2020 Peter Tribble.
25 *
26 * Opl Platform specific functions.
27 *
28 * called when :
29 * machine_type == MTYPE_OPL
30 */
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include <ctype.h>
36 #include <string.h>
37 #include <varargs.h>
38 #include <fcntl.h>
39 #include <assert.h>
40 #include <sys/param.h>
41 #include <sys/stat.h>
42 #include <sys/types.h>
43 #include <sys/utsname.h>
44 #include <sys/systeminfo.h>
45 #include <sys/openpromio.h>
46 #include <libintl.h>
47 #include <syslog.h>
48 #include <sys/dkio.h>
49 #include <pdevinfo.h>
50 #include <libprtdiag.h>
51 #include <libdevinfo.h>
52 #include <kstat.h>
53
54 /*
55 * Globals and externs
56 */
57 #define KBYTE 1024
58 #define MBYTE (KBYTE * KBYTE)
59 #define HZ_TO_MHZ(x) ((((uint64_t)(x)) + 500000) / 1000000)
60 #define SCF_SECURE_MODE_KSTAT_NAMED "secure_mode"
61 #define SCF_STAT_MODE_UNLOCK 0
62 #define SCF_STAT_MODE_LOCK 1
63 #define SCF_SYSTEM_KSTAT_NAME "scf"
64 #ifndef TEXT_DOMAIN
65 #define TEXT_DOMAIN "SYS_TEST"
66 #endif /* TEXT_DOMAIN */
67
68 /*
69 * Global functions and variables
70 * these functions will overlay the symbol table of libprtdiag
71 * at runtime (Opl systems only)
72 */
73 struct cs_status {
74 int cs_number;
75 int status;
76 uint_t avail_hi;
77 uint_t avail_lo;
78 uint_t dimm_hi;
79 uint_t dimm_lo;
80 int dimms;
81 };
82
83 int do_prominfo(int syserrlog, char *pgname, int log_flag, int prt_flag);
84 void *get_prop_val(Prop *prop);
85 void display_ffb(Board_node *, int);
86 void display_sbus(Board_node *board);
87 void display_cpu_devices(Sys_tree *tree);
88 void display_cpus(Board_node *board);
89 void display_memoryconf(Sys_tree *tree);
90 void display_io_cards(struct io_card *list);
91 void display_io_devices(Sys_tree *tree);
92 void display_diaginfo(int flag, Prom_node *root, Sys_tree *tree,
93 struct system_kstat_data *kstats);
94 Prop *find_prop(Prom_node *pnode, char *name);
95 int do_piclinfo(int);
96 int get_proc_mode(void);
97
98 /* Local functions */
99 static void opl_disp_environ(void);
100 static void opl_disp_hw_revisions(Sys_tree *tree, Prom_node *root);
101 static uint64_t print_opl_memory_line(int lsb, struct cs_status *cs_stat,
102 int ngrps, int mirror_mode);
103 static uint64_t get_opl_mem_regs(Board_node *bnode);
104 void add_node(Sys_tree *root, Prom_node *pnode);
105 static int get_prop_size(Prop *prop);
106
107 static int v_flag = 0;
108
109 /*
110 * Linked list of IO card info for display.
111 * Using file scope for use in a recursive function.
112 */
113 static struct io_card *card_list = NULL;
114
115 /*
116 * Check prom node for a class-code. If it exists and it's not a bridge device
117 * then add an io_card to card_list. Then recursively call this function for
118 * its child and sibling nodes.
119 */
120 static void
walk_tree_for_pci_devices(Prom_node * node,int board_number)121 walk_tree_for_pci_devices(Prom_node *node, int board_number)
122 {
123 struct io_card card;
124 char *str;
125 void *val;
126 int ccode;
127
128 if (node == NULL) {
129 return;
130 }
131
132 /* Look for a class-code property. Skip, if it's a bridge */
133 ccode = -1;
134 val = get_prop_val(find_prop(node, "class-code"));
135 if (val != NULL) {
136 ccode = *(int *)val;
137 }
138 if ((ccode != -1) && (ccode < 0x60000 || ccode > 0x6ffff)) {
139 (void) memset(&card, 0, sizeof (card));
140 card.board = board_number;
141
142 str = (char *)get_prop_val(find_prop(node, "name"));
143 (void) strlcpy(card.name, (str == NULL ? "N/A":str),
144 sizeof (card.name));
145
146 str = (char *)get_prop_val(find_prop(node, "model"));
147 (void) strlcpy(card.model, (str == NULL ? "N/A":str),
148 sizeof (card.model));
149
150 /* insert card to the list */
151 card_list = insert_io_card(card_list, &card);
152 }
153 /* Call this function for its child/sibling */
154 walk_tree_for_pci_devices(node->child, board_number);
155 walk_tree_for_pci_devices(node->sibling, board_number);
156 }
157
158 /*
159 * For display of I/O devices for "prtdiag"
160 */
161 void
display_io_devices(Sys_tree * tree)162 display_io_devices(Sys_tree *tree)
163 {
164 Board_node *bnode;
165
166 if (v_flag) {
167 /*
168 * OPL's PICL interface for display of PCI I/O devices
169 * for "prtdiag -v"
170 */
171 (void) do_piclinfo(v_flag);
172 } else {
173 log_printf("\n", 0);
174 log_printf("=========================", 0);
175 log_printf(dgettext(TEXT_DOMAIN, " IO Cards "), 0);
176 log_printf("=========================", 0);
177 log_printf("\n", 0);
178 log_printf("\n", 0);
179 bnode = tree->bd_list;
180 while (bnode != NULL) {
181 walk_tree_for_pci_devices(bnode->nodes,
182 bnode->board_num);
183 bnode = bnode->next;
184 }
185 display_io_cards(card_list);
186 free_io_cards(card_list);
187 }
188 }
189
190 /*
191 * There are no FFB's on OPL.
192 */
193 /*ARGSUSED*/
194 void
display_ffb(Board_node * board,int table)195 display_ffb(Board_node *board, int table)
196 {
197 }
198
199 /*
200 * There are no Sbus's on OPL.
201 */
202 /*ARGSUSED*/
203 void
display_sbus(Board_node * board)204 display_sbus(Board_node *board)
205 {
206 }
207
208 /*
209 * Details of I/O information. Print out all the io cards.
210 */
211 void
display_io_cards(struct io_card * list)212 display_io_cards(struct io_card *list)
213 {
214 char *hdrfmt = "%-6.6s %-14.14s %-12.12s\n";
215
216 struct io_card *p;
217
218 if (list == NULL)
219 return;
220
221 (void) textdomain(TEXT_DOMAIN);
222
223 log_printf(hdrfmt, gettext("LSB"), gettext("Name"), gettext("Model"),
224 0);
225
226 log_printf(hdrfmt, "---", "-----------------", "------------", 0);
227
228 for (p = list; p != NULL; p = p->next) {
229
230 /* Board number */
231 log_printf(" %02d ", p->board, 0);
232
233 /* Card name */
234 log_printf("%-15.15s", p->name, 0);
235
236 /* Card model */
237 log_printf("%-12.12s", p->model, 0);
238
239 log_printf("\n", 0);
240 }
241 log_printf("\n", 0);
242 }
243
244 /*
245 * Details of CPU information.
246 */
247 void
display_cpu_devices(Sys_tree * tree)248 display_cpu_devices(Sys_tree *tree)
249 {
250 Board_node *bnode;
251 char *hdrfmt =
252 "%-4.4s %-4.4s %-40.40s %-5.5s %-5.5s %-5.5s %-4.4s\n";
253
254 (void) textdomain(TEXT_DOMAIN);
255
256 /*
257 * Display the table header for CPUs . Then display the CPU
258 * frequency, cache size, and processor revision of all cpus.
259 */
260 log_printf("\n", 0);
261 log_printf("====================================", 0);
262 log_printf(gettext(" CPUs "), 0);
263 log_printf("====================================", 0);
264 log_printf("\n\n", 0);
265
266 log_printf(hdrfmt,
267 "",
268 gettext("CPU"),
269 gettext(" CPU "),
270 gettext("Run"),
271 gettext("L2$"),
272 gettext("CPU"),
273 gettext("CPU"), 0);
274
275 log_printf(hdrfmt,
276 gettext("LSB"),
277 gettext("Chip"),
278 gettext(" ID "),
279 gettext("MHz"),
280 gettext(" MB"),
281 gettext("Impl."),
282 gettext("Mask"), 0);
283
284 log_printf(hdrfmt,
285 "---", "----", "----------------------------------------", "----",
286 "---", "-----", "----", 0);
287
288 /* Now display all of the cpus on each board */
289 for (bnode = tree->bd_list; bnode != NULL; bnode = bnode->next) {
290 display_cpus(bnode);
291 }
292
293 log_printf("\n", 0);
294 }
295
296 /*
297 * Display the CPUs present on this board.
298 */
299 void
display_cpus(Board_node * board)300 display_cpus(Board_node *board)
301 {
302 int *impl, *mask, *cpuid, *portid, *l2cache_size;
303 uint_t freq; /* CPU clock frequency */
304 Prom_node *pnode, *cpu;
305 char *name;
306
307 (void) textdomain(TEXT_DOMAIN);
308
309 /*
310 * Get the Cpus' properties for display
311 */
312 for (pnode = board->nodes; pnode != NULL; pnode = pnode->sibling) {
313 char cpu_str[MAXSTRLEN], fcpu_str[MAXSTRLEN] = {0};
314
315 name = get_node_name(pnode);
316 if ((name == NULL) || (strncmp(name, "cmp", 3) != 0)) {
317 continue;
318 }
319
320 portid = (int *)get_prop_val(find_prop(pnode, "portid"));
321 freq = (HZ_TO_MHZ(get_cpu_freq(pnode->child)));
322 l2cache_size = (int *)get_prop_val(find_prop(pnode->child,
323 "l2-cache-size"));
324 impl = (int *)get_prop_val(find_prop(pnode->child,
325 "implementation#"));
326 mask = (int *)get_prop_val(find_prop(pnode->child, "mask#"));
327
328 /* Lsb id */
329 log_printf(" %02d ", board->board_num, 0);
330
331 if (portid != NULL)
332 log_printf("%3d ", (((*portid)>>3)&0x3), 0);
333
334 /*
335 * OPL
336 * Specific parsing of the CMP/CORE/CPU chain.
337 * The internal cpu tree built by walk_di_tree()
338 * in common code can be illustrated by the diagram
339 * below:
340 *
341 * Olympus:
342 *
343 * cmp->cpu->cpu->cpu->cpu->(next board nodes)
344 * / \
345 * core core
346 *
347 * Jupiter:
348 *
349 * cmp->cpu->cpu->cpu->cpu->cpu->cpu->cpu->cpu->(board nodes)
350 * |
351 * _____________
352 * / \ \ \
353 * core core core core
354 *
355 *
356 * where "/" or "\" are children
357 * and "->" are siblings
358 *
359 */
360 for (cpu = pnode->sibling; cpu != NULL; ) {
361 Prom_node *cpu_next = NULL;
362
363 name = get_node_name(cpu);
364 if ((name == NULL) || (strncmp(name, "cpu", 3) != 0)) {
365 break;
366 }
367
368 /* Id assigned to Virtual processor core */
369 cpuid = (int *)get_prop_val(find_prop(cpu, "cpuid"));
370 cpu_next = cpu->sibling;
371
372 if (cpu_next != NULL) {
373 name = get_node_name(cpu_next);
374
375 if ((name == NULL) ||
376 (strncmp(name, "cpu", 3) != 0)) {
377 cpu_next = NULL;
378 }
379 }
380
381 if (cpuid != NULL) {
382 /* Used for printing in comma format */
383 (void) sprintf(cpu_str, "%4d", *cpuid);
384 (void) strlcat(fcpu_str, cpu_str, MAXSTRLEN);
385
386 if (cpu_next != NULL) {
387 (void) strlcat(fcpu_str, ",",
388 MAXSTRLEN);
389 }
390 } else {
391 (void) sprintf(cpu_str, "%4s", "N/A");
392 (void) strlcat(fcpu_str, cpu_str, MAXSTRLEN);
393
394 if (cpu_next != NULL) {
395 (void) strlcat(fcpu_str, ",",
396 MAXSTRLEN);
397 }
398 }
399 cpu = cpu_next;
400 }
401
402 log_printf("%-40.40s", fcpu_str, 0);
403
404 /* Running frequency */
405 if (freq != 0)
406 log_printf(" %4ld ", freq, 0);
407 else
408 log_printf(" %4s ", "N/A", 0);
409
410 /* L2 cache size */
411 if (l2cache_size == NULL)
412 log_printf(" %3s ", "N/A", 0);
413 else {
414 log_printf("%4.1f ",
415 (float)(*l2cache_size) / (float)(1<<20), 0);
416 }
417
418
419 /* Implementation number of processor */
420 if (impl != NULL)
421 log_printf(" %4d ", *impl, 0);
422 else
423 log_printf(" %4s ", "N/A", 0);
424
425 /* Mask Set version */
426 /* Bits 31:24 of VER register is mask. */
427 /* Mask value : Non MTP mode - 00-7f, MTP mode - 80-ff */
428 if (mask == NULL)
429 log_printf("%3s", "N/A", 0);
430 else
431 log_printf("%-3d", (*mask)&0xff, 0);
432
433 log_printf("\n", 0);
434
435 }
436 }
437
438 /*
439 * Gather memory information: Details of memory information.
440 */
441 static uint64_t
get_opl_mem_regs(Board_node * bnode)442 get_opl_mem_regs(Board_node *bnode)
443 {
444 Prom_node *pnode;
445 struct cs_status *cs_stat;
446 uint64_t total_mem = 0;
447 int cs_size, ngrps;
448
449 pnode = dev_find_node(bnode->nodes, "pseudo-mc");
450 while (pnode != NULL) {
451
452 cs_size = get_prop_size(find_prop(pnode, "cs-status"));
453
454 if (cs_size > 0) {
455 int *mirror_mode = NULL;
456 int mode = 0;
457
458 /* OBP returns lists of 7 ints */
459 cs_stat = (struct cs_status *)get_prop_val
460 (find_prop(pnode, "cs-status"));
461
462 mirror_mode = (int *)(get_prop_val
463 (find_prop(pnode, "mirror-mode")));
464
465 if (mirror_mode != NULL)
466 mode = (*mirror_mode);
467
468 /*
469 * The units of cs_size will be either number of bytes
470 * or number of int array elements as this is derived
471 * from the libprtdiag Prop node size field which has
472 * inconsistent units. Until this is addressed in
473 * libprtdiag, we need a heuristic to determine the
474 * number of CS groups. Given that the maximum number
475 * of CS groups is 2, the maximum number of cs-status
476 * array elements will be 2*7=14. Since this is smaller
477 * than the byte size of a single struct status, we use
478 * this to decide if we are dealing with bytes or array
479 * elements in determining the number of CS groups.
480 */
481 if (cs_size < sizeof (struct cs_status)) {
482 /* cs_size is number of total int [] elements */
483 ngrps = cs_size / 7;
484 } else {
485 /* cs_size is total byte count */
486 ngrps = cs_size/sizeof (struct cs_status);
487 }
488
489 if (cs_stat != NULL) {
490 total_mem +=
491 print_opl_memory_line(bnode->board_num,
492 cs_stat, ngrps, mode);
493 }
494 }
495
496 pnode = dev_next_node(pnode, "pseudo-mc");
497 }
498 return (total_mem);
499 }
500
501 /*
502 * Display memory information.
503 */
504 void
display_memoryconf(Sys_tree * tree)505 display_memoryconf(Sys_tree *tree)
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