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.
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.
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]
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
36 #include <sys/param.h>
38 #include <sys/types.h>
39 #include <sys/utsname.h>
40 #include <sys/openpromio.h>
44 #include <sys/systeminfo.h>
50 #include "display_sun4v.h"
51 #include "libprtdiag.h"
53 #if !defined(TEXT_DOMAIN)
54 #define TEXT_DOMAIN "SYS_TEST"
57 #define MOTHERBOARD "MB"
58 #define NETWORK "network"
59 #define SUN4V_MACHINE "sun4v"
60 #define PARENT_NAMES 10
63 * Additional OBP properties
65 #define OBP_PROP_COMPATIBLE "compatible"
66 #define OBP_PROP_MODEL "model"
67 #define OBP_PROP_SLOT_NAMES "slot-names"
68 #define OBP_PROP_VERSION "version"
70 #define PICL_NODE_PHYSICAL_PLATFORM "physical-platform"
71 #define PICL_NODE_CHASSIS "chassis"
72 #define MEMORY_SIZE_FIELD 11
73 #define INVALID_THRESHOLD 1000000
76 * Additional picl classes
78 #ifndef PICL_CLASS_SUN4V
79 #define PICL_CLASS_SUN4V "sun4v"
83 #define PICL_PROP_NAC "nac"
87 extern picl_errno_t
sun4v_get_node_by_name(picl_nodehdl_t
, char *,
90 static picl_nodehdl_t rooth
= 0, phyplatformh
= 0;
91 static picl_nodehdl_t chassish
= 0;
92 static int class_node_found
;
94 static int all_status_ok
;
97 static int sun4v_get_first_compatible_value(picl_nodehdl_t
, char **);
98 static void sun4v_display_memory_conf(picl_nodehdl_t
);
99 static int sun4v_disp_env_status();
100 static void sun4v_env_print_fan_sensors();
101 static void sun4v_env_print_fan_indicators();
102 static void sun4v_env_print_temp_sensors();
103 static void sun4v_env_print_temp_indicators();
104 static void sun4v_env_print_current_sensors();
105 static void sun4v_env_print_current_indicators();
106 static void sun4v_env_print_voltage_sensors();
107 static void sun4v_env_print_voltage_indicators();
108 static void sun4v_env_print_LEDs();
109 static void sun4v_print_fru_status();
110 static int is_fru_absent(picl_nodehdl_t
);
111 static void sun4v_print_fw_rev();
112 static void sun4v_print_chassis_serial_no();
113 static int openprom_callback(picl_nodehdl_t openpromh
, void *arg
);
114 static void sun4v_print_openprom_rev();
117 sun4v_display(Sys_tree
*tree
, Prom_node
*root
, int log
,
118 picl_nodehdl_t plafh
)
120 void *value
; /* used for opaque PROM data */
121 struct mem_total memory_total
; /* Total memory in system */
122 struct grp_info grps
; /* Info on all groups in system */
123 char machine
[MAXSTRLEN
];
126 if (sysinfo(SI_MACHINE
, machine
, sizeof (machine
)) == -1)
128 if (strncmp(machine
, SUN4V_MACHINE
, strlen(SUN4V_MACHINE
)) != 0)
131 sys_clk
= -1; /* System clock freq. (in MHz) */
134 * Now display the machine's configuration. We do this if we
138 struct utsname uts_buf
;
141 * Display system banner
143 (void) uname(&uts_buf
);
145 log_printf(dgettext(TEXT_DOMAIN
, "System Configuration: "
146 "Oracle Corporation %s %s\n"), uts_buf
.machine
,
147 get_prop_val(find_prop(root
, "banner-name")), 0);
149 /* display system clock frequency */
150 value
= get_prop_val(find_prop(root
, "clock-frequency"));
152 sys_clk
= ((*((int *)value
)) + 500000) / 1000000;
153 log_printf(dgettext(TEXT_DOMAIN
, "System clock "
154 "frequency: %d MHz\n"), sys_clk
, 0);
157 /* Display the Memory Size */
158 display_memorysize(tree
, NULL
, &grps
, &memory_total
);
160 /* Display the CPU devices */
161 sun4v_display_cpu_devices(plafh
);
163 /* Display the Memory configuration */
164 class_node_found
= 0;
165 sun4v_display_memory_conf(plafh
);
167 /* Display all the IO cards. */
168 (void) sun4v_display_pci(plafh
);
169 sun4v_display_diaginfo((log
|| (logging
)), root
, plafh
);
171 if (picl_get_root(&rooth
) != PICL_SUCCESS
)
175 * The physical-platform node may be missing on systems with
176 * older firmware so don't consider that an error.
178 if (sun4v_get_node_by_name(rooth
, PICL_NODE_PHYSICAL_PLATFORM
,
179 &phyplatformh
) != PICL_SUCCESS
)
182 if (picl_find_node(phyplatformh
, PICL_PROP_CLASSNAME
,
183 PICL_PTYPE_CHARSTRING
, (void *)PICL_CLASS_CHASSIS
,
184 strlen(PICL_CLASS_CHASSIS
), &chassish
) != PICL_SUCCESS
)
188 exit_code
= sun4v_disp_env_status();
194 * The binding-name property encodes the bus type.
197 get_bus_type(picl_nodehdl_t nodeh
, struct io_card
*card
)
199 char val
[PICL_PROPNAMELEN_MAX
], *p
, *q
;
201 card
->bus_type
[0] = '\0';
203 if (picl_get_propval_by_name(nodeh
, PICL_PROP_BINDING_NAME
, val
,
204 sizeof (val
)) == PICL_SUCCESS
) {
205 if (strstr(val
, PICL_CLASS_PCIEX
))
206 (void) strlcpy(card
->bus_type
, "PCIE",
207 sizeof (card
->bus_type
));
208 else if (strstr(val
, PICL_CLASS_PCI
))
209 (void) strlcpy(card
->bus_type
, "PCIX",
210 sizeof (card
->bus_type
));
213 * Not perfect: process the binding-name until
214 * we encounter something that we don't think would
215 * be part of a bus type. This may get confused a bit
216 * if a device or vendor id is encoded right after
217 * the bus class since there's no delimiter. If the
218 * id number begins with a hex digit [abcdef] then
219 * this will become part of the bus type string
220 * reported by prtdiag. This is all an effort to
221 * print something potentially useful for bus types
222 * other than PCI/PCIe.
224 * We do this because this code will get called for
225 * non-PCI class devices like the xaui (class sun4v.)
227 if (strstr(val
, "SUNW,") != NULL
)
228 p
= strchr(val
, ',') + 1;
233 if (isdigit((char)*p
) || ispunct((char)*p
)) {
237 *p
= (char)_toupper((int)*p
);
240 (void) strlcpy(card
->bus_type
, q
,
241 sizeof (card
->bus_type
));
247 * Fetch the Label property for this device. If none is found then
248 * search all the siblings with the same device ID for a
249 * Label and return that Label. The plug-in can only match the canonical
250 * path from the PRI with a specific devfs path. So we take care of
251 * devices with multiple functions here. A leaf device downstream of
252 * a bridge should fall out of here with PICL_PROPNOTFOUND, and the
253 * caller can walk back up the tree in search of the slot's Label.
256 get_slot_label(picl_nodehdl_t nodeh
, struct io_card
*card
)
258 char val
[PICL_PROPNAMELEN_MAX
];
260 picl_nodehdl_t pnodeh
;
261 uint32_t devid
, sib_devid
;
265 * If there's a Label at this node then return it - we're
268 err
= picl_get_propval_by_name(nodeh
, PICL_PROP_LABEL
, val
,
270 if (err
== PICL_SUCCESS
) {
271 (void) strlcpy(card
->slot_str
, val
, sizeof (card
->slot_str
));
273 } else if (err
!= PICL_PROPNOTFOUND
)
277 * At this point we're starting to extrapolate what the Label
278 * should be since there is none at this specific node.
279 * Note that until the value of "err" is overwritten in the
280 * loop below, its value should be PICL_PROPNOTFOUND.
284 * The device must be attached, and we can figure that out if
285 * the instance number is present and is not equal to -1.
286 * This will prevent is from returning a Label for a sibling
287 * node when the node passed in would have a unique Label if the
288 * device were attached. But if the device is downstream of a
289 * node with a Label then pci_callback() will still find that
292 if (picl_get_propval_by_name(nodeh
, PICL_PROP_INSTANCE
, &instance
,
293 sizeof (instance
)) != PICL_SUCCESS
)
299 * Narrow the search to just the one device ID.
301 if (picl_get_propval_by_name(nodeh
, PICL_PROP_DEVICE_ID
, &devid
,
302 sizeof (devid
)) != PICL_SUCCESS
)
306 * Go find the first child of the parent so we can search
307 * all of the siblings.
309 if (picl_get_propval_by_name(nodeh
, PICL_PROP_PARENT
, &pnodeh
,
310 sizeof (pnodeh
)) != PICL_SUCCESS
)
312 if (picl_get_propval_by_name(pnodeh
, PICL_PROP_CHILD
, &pnodeh
,
313 sizeof (pnodeh
)) != PICL_SUCCESS
)
317 * If the child's device ID matches, then fetch the Label and
318 * return it. The first child/device ID should have a Label
319 * associated with it.
322 if (picl_get_propval_by_name(pnodeh
, PICL_PROP_DEVICE_ID
,
323 &sib_devid
, sizeof (sib_devid
)) == PICL_SUCCESS
) {
324 if (sib_devid
== devid
) {
325 if ((err
= picl_get_propval_by_name(pnodeh
,
326 PICL_PROP_LABEL
, val
, sizeof (val
))) ==
328 (void) strlcpy(card
->slot_str
, val
,
329 sizeof (card
->slot_str
));
334 } while (picl_get_propval_by_name(pnodeh
, PICL_PROP_PEER
, &pnodeh
,
335 sizeof (pnodeh
)) == PICL_SUCCESS
);
341 get_slot_number(picl_nodehdl_t nodeh
, struct io_card
*card
)
344 picl_prophdl_t proph
;
345 picl_propinfo_t pinfo
;
346 picl_nodehdl_t pnodeh
;
349 char uaddr
[MAXSTRLEN
];
353 while (err
== PICL_SUCCESS
) {
354 if (picl_get_propval_by_name(nodeh
, PICL_PROP_PARENT
, &pnodeh
,
355 sizeof (pnodeh
)) != PICL_SUCCESS
) {
356 (void) strlcpy(card
->slot_str
, MOTHERBOARD
,
357 sizeof (card
->slot_str
));
361 if (picl_get_propinfo_by_name(pnodeh
, OBP_PROP_SLOT_NAMES
,
362 &pinfo
, &proph
) == PICL_SUCCESS
) {
367 if (picl_get_propval_by_name(nodeh
, PICL_PROP_UNIT_ADDRESS
, uaddr
,
368 sizeof (uaddr
)) != PICL_SUCCESS
) {
369 (void) strlcpy(card
->slot_str
, MOTHERBOARD
,
370 sizeof (card
->slot_str
));
374 pval
= (uint8_t *)malloc(pinfo
.size
);
376 (void) strlcpy(card
->slot_str
, MOTHERBOARD
,
377 sizeof (card
->slot_str
));
381 if (picl_get_propval(proph
, pval
, pinfo
.size
) != PICL_SUCCESS
) {
382 (void) strlcpy(card
->slot_str
, MOTHERBOARD
,
383 sizeof (card
->slot_str
));
390 for (i
= 0; i
< sizeof (dev_mask
); i
++)
391 dev_mask
|= (*(pval
+i
) << 8*(sizeof (dev_mask
)-1-i
));
392 for (i
= 0; i
< sizeof (uaddr
) && uaddr
[i
] != '\0'; i
++) {
393 if (uaddr
[i
] == ',') {
398 card
->slot
= atol(uaddr
);
399 if (((1 << card
->slot
) & dev_mask
) == 0) {
400 (void) strlcpy(card
->slot_str
, MOTHERBOARD
,
401 sizeof (card
->slot_str
));
404 char *p
= (char *)(pval
+sizeof (dev_mask
));
405 int shift
= sizeof (uint32_t)*8-1-card
->slot
;
406 uint32_t x
= (dev_mask
<< shift
) >> shift
;
407 int count
= 0; /* count # of 1's in x */
414 while (p
[i
++] != '\0')
418 (void) strlcpy(card
->slot_str
, (char *)(p
+i
),
419 sizeof (card
->slot_str
));
425 * add all io devices under pci in io list
429 sun4v_pci_callback(picl_nodehdl_t pcih
, void *args
)
431 char path
[PICL_PROPNAMELEN_MAX
];
432 char class[PICL_CLASSNAMELEN_MAX
];
433 char name
[PICL_PROPNAMELEN_MAX
];
434 char model
[PICL_PROPNAMELEN_MAX
];
435 char binding_name
[PICL_PROPNAMELEN_MAX
];
436 char val
[PICL_PROPNAMELEN_MAX
];
439 picl_nodehdl_t nodeh
, pnodeh
;
440 struct io_card pci_card
;
442 /* Walk through the children */
444 err
= picl_get_propval_by_name(pcih
, PICL_PROP_CHILD
, &nodeh
,
445 sizeof (picl_nodehdl_t
));
447 while (err
== PICL_SUCCESS
) {
448 err
= picl_get_propval_by_name(nodeh
, PICL_PROP_CLASSNAME
,
449 class, sizeof (class));
450 if (err
!= PICL_SUCCESS
)
455 if (strcmp(class, val
) == 0) {
456 err
= picl_get_propval_by_name(nodeh
,
457 PICL_PROP_PEER
, &nodeh
,
458 sizeof (picl_nodehdl_t
));
460 } else if (strcmp(val
, PICL_CLASS_PCIEX
) == 0 &&
461 strcmp(class, PICL_CLASS_PCI
) == 0) {
462 err
= picl_get_propval_by_name(nodeh
,
463 PICL_PROP_PEER
, &nodeh
,
464 sizeof (picl_nodehdl_t
));
466 } else if (strcmp(val
, PICL_CLASS_PCI
) == 0 &&
467 strcmp(class, PICL_CLASS_PCIEX
) == 0) {
468 err
= picl_get_propval_by_name(nodeh
,
469 PICL_PROP_PEER
, &nodeh
,
470 sizeof (picl_nodehdl_t
));
475 err
= picl_get_propval_by_name(nodeh
, PICL_PROP_DEVFS_PATH
,
476 path
, sizeof (path
));
477 if (err
!= PICL_SUCCESS
)
480 (void) strlcpy(pci_card
.notes
, path
, sizeof (pci_card
.notes
));
483 err
= get_slot_label(nodeh
, &pci_card
);
486 * No Label at this node, maybe we're looking at a device
487 * downstream of a bridge. Walk back up and find a Label and
488 * record that node in "pnodeh".
490 while (err
!= PICL_SUCCESS
) {
491 if (err
!= PICL_PROPNOTFOUND
)
493 else if (picl_get_propval_by_name(pnodeh
,
494 PICL_PROP_PARENT
, &pnodeh
, sizeof (pnodeh
)) ==
496 err
= get_slot_label(pnodeh
, &pci_card
);
502 * Can't find a Label for this device in the PCI heirarchy.
503 * Try to synthesize a slot name from atoms. This depends
504 * on the OBP slot_names property being implemented, and this
505 * so far doesn't seem to be on sun4v. But just in case that
506 * is resurrected, the code is here.
508 if (err
!= PICL_SUCCESS
) {
510 get_slot_number(nodeh
, &pci_card
);
514 * Passing in pnodeh instead of nodeh will cause prtdiag
515 * to display the type of IO slot for the leaf node. For
516 * built-in devices and a lot of IO cards these will be
517 * the same thing. But for IO cards with bridge chips or
518 * for things like expansion chassis, prtdiag will report
519 * the bus type of the IO slot and not the leaf, which
520 * could be different things.
522 get_bus_type(pnodeh
, &pci_card
);
524 err
= picl_get_propval_by_name(nodeh
, PICL_PROP_NAME
, name
,
526 if (err
== PICL_PROPNOTFOUND
)
527 (void) strlcpy(name
, "", sizeof (name
));
528 else if (err
!= PICL_SUCCESS
)
531 err
= picl_get_propval_by_name(nodeh
, PICL_PROP_STATUS
, val
,
533 if (err
== PICL_PROPNOTFOUND
)
534 (void) strlcpy(val
, "", sizeof (val
));
535 else if (err
!= PICL_SUCCESS
)
538 (void) snprintf(pci_card
.status
, sizeof (pci_card
.status
),
539 "%s", pci_card
.slot_str
);
542 * Get the name of this card. If binding_name is found,
543 * name will be <nodename>-<binding_name>.
545 err
= picl_get_propval_by_name(nodeh
, PICL_PROP_BINDING_NAME
,
546 binding_name
, sizeof (binding_name
));
547 if (err
== PICL_SUCCESS
) {
548 if (strcmp(name
, binding_name
) != 0) {
549 (void) strlcat(name
, "-", sizeof (name
));
550 (void) strlcat(name
, binding_name
,
553 } else if (err
== PICL_PROPNOTFOUND
) {
555 * if compatible prop is not found, name will be
556 * <nodename>-<compatible>
558 err
= sun4v_get_first_compatible_value(nodeh
,
560 if (err
== PICL_SUCCESS
) {
561 (void) strlcat(name
, "-", sizeof (name
));
562 (void) strlcat(name
, compatible
,
569 (void) strlcpy(pci_card
.name
, name
, sizeof (pci_card
.name
));
571 /* Get the model of this card */
573 err
= picl_get_propval_by_name(nodeh
, OBP_PROP_MODEL
,
574 model
, sizeof (model
));
575 if (err
== PICL_PROPNOTFOUND
)
576 (void) strlcpy(model
, "", sizeof (model
));
577 else if (err
!= PICL_SUCCESS
)
579 (void) strlcpy(pci_card
.model
, model
, sizeof (pci_card
.model
));
582 log_printf("%-18s", pci_card
.status
);
584 log_printf("%-6s", pci_card
.bus_type
);
585 /* Printf Card Name */
586 log_printf("%-34s", pci_card
.name
);
587 /* Print Card Model */
588 log_printf("%-8s", pci_card
.model
);
591 log_printf("%-18s", val
);
593 log_printf("%-6s", "");
594 /* Print Parent Path */
595 log_printf("%-44s", pci_card
.notes
);
598 err
= picl_get_propval_by_name(nodeh
, PICL_PROP_PEER
, &nodeh
,
599 sizeof (picl_nodehdl_t
));
601 return (PICL_WALK_CONTINUE
);
606 * Display all the PCI IO cards on this board.
609 sun4v_display_pci(picl_nodehdl_t plafh
)
611 char *fmt
= "%-17s %-5s %-33s %-8s";
612 /* Have we printed the column headings? */
613 static int banner
= FALSE
;
615 if (banner
== FALSE
) {
617 log_printf("================================");
618 log_printf(" IO Devices ");
619 log_printf("================================");
621 log_printf(fmt
, "Slot +", "Bus", "Name +", "Model", 0);
623 log_printf(fmt
, "Status", "Type", "Path", "", 0);
625 log_printf("---------------------------------"
626 "-------------------------------------------\n");
630 (void) picl_walk_tree_by_class(plafh
, PICL_CLASS_PCIEX
,
631 PICL_CLASS_PCIEX
, sun4v_pci_callback
);
632 (void) picl_walk_tree_by_class(plafh
, PICL_CLASS_PCI
,
633 PICL_CLASS_PCI
, sun4v_pci_callback
);
634 (void) picl_walk_tree_by_class(plafh
, PICL_CLASS_SUN4V
,
635 PICL_CLASS_SUN4V
, sun4v_pci_callback
);
639 * return the first compatible value
642 sun4v_get_first_compatible_value(picl_nodehdl_t nodeh
, char **outbuf
)
645 picl_prophdl_t proph
;
646 picl_propinfo_t pinfo
;
648 picl_prophdl_t rowproph
;
651 err
= picl_get_propinfo_by_name(nodeh
, OBP_PROP_COMPATIBLE
,
653 if (err
!= PICL_SUCCESS
)
656 if (pinfo
.type
== PICL_PTYPE_CHARSTRING
) {
657 pval
= malloc(pinfo
.size
);
659 return (PICL_FAILURE
);
660 err
= picl_get_propval(proph
, pval
, pinfo
.size
);
661 if (err
!= PICL_SUCCESS
) {
666 return (PICL_SUCCESS
);
669 if (pinfo
.type
!= PICL_PTYPE_TABLE
)
670 return (PICL_FAILURE
);
672 /* get first string from table */
673 err
= picl_get_propval(proph
, &tblh
, pinfo
.size
);
674 if (err
!= PICL_SUCCESS
)
677 err
= picl_get_next_by_row(tblh
, &rowproph
);
678 if (err
!= PICL_SUCCESS
)
681 err
= picl_get_propinfo(rowproph
, &pinfo
);
682 if (err
!= PICL_SUCCESS
)
685 pval
= malloc(pinfo
.size
);
687 return (PICL_FAILURE
);
689 err
= picl_get_propval(rowproph
, pval
, pinfo
.size
);
690 if (err
!= PICL_SUCCESS
) {
696 return (PICL_SUCCESS
);
700 * print size of a memory segment
703 print_memory_segment_size(uint64_t size
)
705 uint64_t kbyte
= 1024;
706 uint64_t mbyte
= kbyte
* kbyte
;
707 uint64_t gbyte
= kbyte
* mbyte
;
708 uint64_t tbyte
= kbyte
* gbyte
;
709 char buf
[MEMORY_SIZE_FIELD
];
712 if (size
% tbyte
== 0)
713 (void) snprintf(buf
, sizeof (buf
), "%d TB",
714 (int)(size
/ tbyte
));
716 (void) snprintf(buf
, sizeof (buf
), "%.2f TB",
717 (float)size
/ tbyte
);
718 } else if (size
>= gbyte
) {
719 if (size
% gbyte
== 0)
720 (void) snprintf(buf
, sizeof (buf
), "%d GB",
721 (int)(size
/ gbyte
));
723 (void) snprintf(buf
, sizeof (buf
), "%.2f GB",
724 (float)size
/ gbyte
);
725 } else if (size
>= mbyte
) {
726 if (size
% mbyte
== 0)
727 (void) snprintf(buf
, sizeof (buf
), "%d MB",
728 (int)(size
/ mbyte
));
730 (void) snprintf(buf
, sizeof (buf
), "%.2f MB",
731 (float)size
/ mbyte
);
733 if (size
% kbyte
== 0)
734 (void) snprintf(buf
, sizeof (buf
), "%d KB",
735 (int)(size
/ kbyte
));
737 (void) snprintf(buf
, sizeof (buf
), "%.2f KB",
738 (float)size
/ kbyte
);
740 log_printf("%-9s", buf
);
744 * Enumerate banks and dimms within a memory segment. We're handed
745 * the first bank within the segment - we assume there are dimms
746 * (memory-module) nodes underneath.
749 print_memory_segment_contain(picl_nodehdl_t bank_nodeh
)
751 char val
[PICL_PROPNAMELEN_MAX
];
752 picl_nodehdl_t module_nodeh
;
757 if (picl_get_propval_by_name(bank_nodeh
, PICL_PROP_CHILD
,
758 &module_nodeh
, sizeof (picl_nodehdl_t
)) != PICL_SUCCESS
)
760 if (picl_get_propval_by_name(bank_nodeh
, PICL_PROP_SIZE
,
761 &size
, sizeof (size
)) == PICL_SUCCESS
) {
763 print_memory_segment_size(size
);
767 print_memory_segment_size(size
);
772 if (picl_get_propval_by_name(module_nodeh
,
773 PICL_PROP_NAC
, val
, sizeof (val
)) !=
778 log_printf("%s\n", val
);
787 } while (picl_get_propval_by_name(module_nodeh
, PICL_PROP_PEER
,
788 &module_nodeh
, sizeof (picl_nodehdl_t
)) ==
790 } while (picl_get_propval_by_name(bank_nodeh
, PICL_PROP_PEER
,
791 &bank_nodeh
, sizeof (picl_nodehdl_t
)) == PICL_SUCCESS
);
795 * Search node where _class=="memory-segment"
796 * print "Base Address", "Size", etc
800 sun4v_memory_conf_callback(picl_nodehdl_t nodeh
, void *args
)
805 picl_errno_t err
= PICL_SUCCESS
;
807 if (class_node_found
== 0) {
808 class_node_found
= 1;
809 return (PICL_WALK_TERMINATE
);
811 while (err
== PICL_SUCCESS
) {
812 err
= picl_get_propval_by_name(nodeh
, PICL_PROP_BASEADDRESS
,
813 &base
, sizeof (base
));
814 if (err
!= PICL_SUCCESS
)
816 err
= picl_get_propval_by_name(nodeh
, PICL_PROP_SIZE
,
817 &size
, sizeof (size
));
818 if (err
!= PICL_SUCCESS
)
820 err
= picl_get_propval_by_name(nodeh
,
821 PICL_PROP_INTERLEAVE_FACTOR
, &ifactor
,
823 if (err
!= PICL_SUCCESS
)
825 log_printf("0x%-13llx", base
);
826 print_memory_segment_size(size
);
827 log_printf("%-12lld", ifactor
);
828 err
= picl_get_propval_by_name(nodeh
, PICL_PROP_CHILD
,
829 &nodeh
, sizeof (nodeh
));
830 if (err
== PICL_SUCCESS
)
831 print_memory_segment_contain(nodeh
);
833 err
= picl_get_propval_by_name(nodeh
, PICL_PROP_PEER
, &nodeh
,
834 sizeof (picl_nodehdl_t
));
837 return (PICL_WALK_CONTINUE
);
842 sun4v_display_memory_conf(picl_nodehdl_t plafh
)
844 char *fmt
= "%-14s %-8s %-11s %-8s %-s";
845 (void) picl_walk_tree_by_class(plafh
, PICL_CLASS_MEMORY_SEGMENT
,
846 NULL
, sun4v_memory_conf_callback
);
847 if (class_node_found
== 0)
850 log_printf("=======================");
851 log_printf(" Physical Memory Configuration ");
852 log_printf("========================");
854 log_printf("Segment Table:\n");
856 "--------------------------------------------------------------\n");
857 log_printf(fmt
, "Base", "Segment", "Interleave", "Bank", "Contains", 0);
859 log_printf(fmt
, "Address", "Size", "Factor", "Size", "Modules", 0);
862 "--------------------------------------------------------------\n");
863 (void) picl_walk_tree_by_class(plafh
, PICL_CLASS_MEMORY_SEGMENT
,
864 NULL
, sun4v_memory_conf_callback
);
868 sun4v_display_cpu_devices(picl_nodehdl_t plafh
)
870 char *fmt
= "%-6s %-9s %-22s %-6s";
873 * Display the table header for CPUs . Then display the CPU
874 * frequency, cache size, and processor revision of all cpus.
876 log_printf(dgettext(TEXT_DOMAIN
,
878 "================================"
880 "================================"
884 log_printf(fmt
, "CPU ID", "Frequency", "Implementation",
887 log_printf(fmt
, "------", "---------",
888 "----------------------", "-------", 0);
891 (void) picl_walk_tree_by_class(plafh
, PICL_CLASS_CPU
, PICL_CLASS_CPU
,
896 * Display the CPUs present on this board.
900 sun4v_display_cpus(picl_nodehdl_t cpuh
, void* args
)
903 picl_prophdl_t proph
;
905 picl_prophdl_t rowproph
;
906 picl_propinfo_t propinfo
;
910 char *no_prop_value
= " ";
911 char freq_str
[MAXSTRLEN
];
912 char state
[MAXSTRLEN
];
915 * Get cpuid property and print it and the NAC name
917 status
= picl_get_propinfo_by_name(cpuh
, OBP_PROP_CPUID
, &propinfo
,
919 if (status
== PICL_SUCCESS
) {
920 status
= picl_get_propval(proph
, &cpuid
, sizeof (cpuid
));
921 if (status
!= PICL_SUCCESS
) {
922 log_printf("%-7s", no_prop_value
);
924 log_printf("%-7d", cpuid
);
927 log_printf("%-7s", no_prop_value
);
931 status
= picl_get_propinfo_by_name(cpuh
, "clock-frequency", &propinfo
,
933 if (status
== PICL_SUCCESS
) {
934 int_value
= malloc(propinfo
.size
);
935 if (int_value
== NULL
) {
936 log_printf("%-10s", no_prop_value
);
939 status
= picl_get_propval(proph
, int_value
, propinfo
.size
);
940 if (status
!= PICL_SUCCESS
) {
941 log_printf("%-10s", no_prop_value
);
943 /* Running frequency */
944 (void) snprintf(freq_str
, sizeof (freq_str
), "%d MHz",
945 CLK_FREQ_TO_MHZ(*int_value
));
946 log_printf("%-10s", freq_str
);
950 log_printf("%-10s", no_prop_value
);
953 status
= picl_get_propinfo_by_name(cpuh
, "compatible", &propinfo
,
955 if (status
== PICL_SUCCESS
) {
956 if (propinfo
.type
== PICL_PTYPE_CHARSTRING
) {
958 * Compatible Property only has 1 value
960 comp_value
= malloc(propinfo
.size
);
961 if (comp_value
== NULL
) {
962 log_printf("%-23s", no_prop_value
, 0);
965 status
= picl_get_propval(proph
, comp_value
,
967 if (status
!= PICL_SUCCESS
)
968 log_printf("%-23s", no_prop_value
, 0);
970 log_printf("%-23s", comp_value
, 0);
972 } else if (propinfo
.type
== PICL_PTYPE_TABLE
) {
974 * Compatible Property has multiple values
976 status
= picl_get_propval(proph
, &tblh
, propinfo
.size
);
977 if (status
!= PICL_SUCCESS
) {
978 log_printf("%-23s", no_prop_value
, 0);
981 status
= picl_get_next_by_row(tblh
, &rowproph
);
982 if (status
!= PICL_SUCCESS
) {
983 log_printf("%-23s", no_prop_value
, 0);
987 status
= picl_get_propinfo(rowproph
, &propinfo
);
988 if (status
!= PICL_SUCCESS
) {
989 log_printf("%-23s", no_prop_value
, 0);
993 comp_value
= malloc(propinfo
.size
);
994 if (comp_value
== NULL
) {
995 log_printf("%-23s", no_prop_value
, 0);
998 status
= picl_get_propval(rowproph
, comp_value
,
1000 if (status
!= PICL_SUCCESS
)
1001 log_printf("%-23s", no_prop_value
, 0);
1003 log_printf("%-23s", comp_value
, 0);
1007 log_printf("%-23s", no_prop_value
, 0);
1010 status
= picl_get_propinfo_by_name(cpuh
, PICL_PROP_STATE
,
1012 if (status
== PICL_SUCCESS
) {
1013 status
= picl_get_propval(proph
, state
, sizeof (state
));
1014 if (status
!= PICL_SUCCESS
) {
1015 log_printf("%-9s", no_prop_value
);
1017 log_printf("%-9s", state
);
1020 log_printf("%-9s", no_prop_value
);
1024 return (PICL_WALK_CONTINUE
);
1028 sun4v_display_diaginfo(int flag
, Prom_node
*root
, picl_nodehdl_t plafh
)
1036 * This function is intentionally empty
1041 display_boardnum(int num
)
1043 log_printf("%2d ", num
, 0);
1047 sun4v_disp_env_status()
1051 if (phyplatformh
== 0)
1054 log_printf("============================");
1055 log_printf(" Environmental Status ");
1056 log_printf("============================");
1059 class_node_found
= 0;
1061 sun4v_env_print_fan_sensors();
1062 exit_code
|= (!all_status_ok
);
1064 class_node_found
= 0;
1066 sun4v_env_print_fan_indicators();
1067 exit_code
|= (!all_status_ok
);
1069 class_node_found
= 0;
1071 sun4v_env_print_temp_sensors();
1072 exit_code
|= (!all_status_ok
);
1074 class_node_found
= 0;
1076 sun4v_env_print_temp_indicators();
1077 exit_code
|= (!all_status_ok
);
1079 class_node_found
= 0;
1081 sun4v_env_print_current_sensors();
1082 exit_code
|= (!all_status_ok
);
1084 class_node_found
= 0;
1086 sun4v_env_print_current_indicators();
1087 exit_code
|= (!all_status_ok
);
1089 class_node_found
= 0;
1091 sun4v_env_print_voltage_sensors();
1092 exit_code
|= (!all_status_ok
);
1094 class_node_found
= 0;
1096 sun4v_env_print_voltage_indicators();
1097 exit_code
|= (!all_status_ok
);
1099 class_node_found
= 0;
1101 sun4v_env_print_LEDs();
1102 exit_code
|= (!all_status_ok
);
1104 class_node_found
= 0;
1106 sun4v_print_fru_status();
1107 exit_code
|= (!all_status_ok
);
1109 class_node_found
= 0;
1110 sun4v_print_fw_rev();
1112 class_node_found
= 0;
1113 sun4v_print_openprom_rev();
1115 sun4v_print_chassis_serial_no();
1122 sun4v_env_print_sensor_callback(picl_nodehdl_t nodeh
, void *args
)
1124 char val
[PICL_PROPNAMELEN_MAX
];
1125 picl_nodehdl_t parenth
;
1126 char *names
[PARENT_NAMES
];
1127 char *base_units
[PICL_PROPNAMELEN_MAX
];
1132 int32_t lo_warning
, lo_shutdown
, lo_poweroff
;
1133 int32_t hi_warning
, hi_shutdown
, hi_poweroff
;
1134 int32_t current_val
;
1137 typedef enum {SENSOR_OK
, SENSOR_WARN
, SENSOR_FAILED
,
1138 SENSOR_DISABLED
, SENSOR_UNKNOWN
} sensor_status_t
;
1139 sensor_status_t sensor_status
= SENSOR_OK
;
1141 if (class_node_found
== 0) {
1142 class_node_found
= 1;
1143 return (PICL_WALK_TERMINATE
);
1146 prop
= (char *)args
;
1148 sensor_status
= SENSOR_UNKNOWN
;
1151 err
= picl_get_propval_by_name(nodeh
,
1152 PICL_PROP_OPERATIONAL_STATUS
, val
,
1154 if (err
== PICL_SUCCESS
) {
1155 if (strcmp(val
, "disabled") == 0) {
1156 sensor_status
= SENSOR_DISABLED
;
1161 if (sensor_status
!= SENSOR_DISABLED
&&
1162 sensor_status
!= SENSOR_UNKNOWN
) {
1163 if (picl_get_propval_by_name(nodeh
, prop
, ¤t_val
,
1164 sizeof (current_val
)) != PICL_SUCCESS
) {
1165 sensor_status
= SENSOR_UNKNOWN
;
1167 if (picl_get_propval_by_name(nodeh
,
1168 PICL_PROP_LOW_WARNING
,
1169 &lo_warning
, sizeof (lo_warning
)) != PICL_SUCCESS
)
1170 lo_warning
= INVALID_THRESHOLD
;
1171 if (picl_get_propval_by_name(nodeh
,
1172 PICL_PROP_LOW_SHUTDOWN
,
1173 &lo_shutdown
, sizeof (lo_shutdown
)) != PICL_SUCCESS
)
1174 lo_shutdown
= INVALID_THRESHOLD
;
1175 if (picl_get_propval_by_name(nodeh
,
1176 PICL_PROP_LOW_POWER_OFF
,
1177 &lo_poweroff
, sizeof (lo_poweroff
)) != PICL_SUCCESS
)
1178 lo_poweroff
= INVALID_THRESHOLD
;
1179 if (picl_get_propval_by_name(nodeh
,
1180 PICL_PROP_HIGH_WARNING
,
1181 &hi_warning
, sizeof (hi_warning
)) != PICL_SUCCESS
)
1182 hi_warning
= INVALID_THRESHOLD
;
1183 if (picl_get_propval_by_name(nodeh
,
1184 PICL_PROP_HIGH_SHUTDOWN
,
1185 &hi_shutdown
, sizeof (hi_shutdown
)) != PICL_SUCCESS
)
1186 hi_shutdown
= INVALID_THRESHOLD
;
1187 if (picl_get_propval_by_name(nodeh
,
1188 PICL_PROP_HIGH_POWER_OFF
,
1189 &hi_poweroff
, sizeof (hi_poweroff
)) != PICL_SUCCESS
)
1190 hi_poweroff
= INVALID_THRESHOLD
;
1192 if ((lo_poweroff
!= INVALID_THRESHOLD
&&
1193 current_val
<= lo_poweroff
) ||
1194 (hi_poweroff
!= INVALID_THRESHOLD
&&
1195 current_val
>= hi_poweroff
)) {
1196 sensor_status
= SENSOR_FAILED
;
1197 } else if ((lo_shutdown
!= INVALID_THRESHOLD
&&
1198 current_val
<= lo_shutdown
) ||
1199 (hi_shutdown
!= INVALID_THRESHOLD
&&
1200 current_val
>= hi_shutdown
)) {
1201 sensor_status
= SENSOR_FAILED
;
1202 } else if ((lo_warning
!= INVALID_THRESHOLD
&&
1203 current_val
<= lo_warning
) ||
1204 (hi_warning
!= INVALID_THRESHOLD
&&
1205 current_val
>= hi_warning
)) {
1206 sensor_status
= SENSOR_WARN
;
1208 sensor_status
= SENSOR_OK
;
1213 if (syserrlog
== 0) {
1214 if (sensor_status
!= SENSOR_OK
&& all_status_ok
== 1) {
1216 return (PICL_WALK_TERMINATE
);
1218 if (sensor_status
== SENSOR_OK
) {
1219 return (PICL_WALK_CONTINUE
);
1222 if (sensor_status
!= SENSOR_OK
&& all_status_ok
== 1) {
1228 * If we're here then prtdiag was invoked with "-v" or we have
1229 * a sensor that is beyond a threshold, so give them a book to
1230 * read instead of the Cliff Notes.
1232 err
= picl_get_propval_by_name(nodeh
, PICL_PROP_PARENT
, &parenth
,
1234 if (err
!= PICL_SUCCESS
) {
1236 return (PICL_WALK_CONTINUE
);
1239 /* gather up the path name for the sensor */
1240 if ((loc
= (char *)malloc(PICL_PROPNAMELEN_MAX
*PARENT_NAMES
)) != NULL
) {
1241 for (i
= 0; i
< PARENT_NAMES
; i
++) {
1242 if ((names
[i
] = (char *)malloc(PICL_PROPNAMELEN_MAX
)) ==
1253 while (err
== PICL_SUCCESS
) {
1254 if (parenth
== phyplatformh
)
1256 err
= picl_get_propval_by_name(parenth
, PICL_PROP_NAME
,
1257 names
[i
++], PICL_PROPNAMELEN_MAX
);
1258 if (err
!= PICL_SUCCESS
) {
1262 if (i
== PARENT_NAMES
)
1264 err
= picl_get_propval_by_name(parenth
,
1265 PICL_PROP_PARENT
, &parenth
, sizeof (parenth
));
1269 (void) strlcat(loc
, names
[i
],
1270 PICL_PROPNAMELEN_MAX
* PARENT_NAMES
);
1273 (void) strlcat(loc
, "/", PICL_PROPNAMELEN_MAX
*
1275 (void) strlcat(loc
, names
[i
],
1276 PICL_PROPNAMELEN_MAX
* PARENT_NAMES
);
1278 log_printf("%-35s", loc
);
1279 for (i
= 0; i
< PARENT_NAMES
; i
++)
1283 log_printf("%-35s", " ");
1285 err
= picl_get_propval_by_name(nodeh
, PICL_PROP_LABEL
, val
,
1287 if (err
== PICL_SUCCESS
)
1288 log_printf("%-19s", val
);
1291 * Get the exponent if present, and do a little math so that
1292 * if we need to we can print a normalized value for the
1295 if (picl_get_propval_by_name(nodeh
, PICL_PROP_EXPONENT
,
1296 &exponent
, sizeof (exponent
)) != PICL_SUCCESS
)
1299 display_val
= (double)current_val
;
1301 display_val
= (double)current_val
*
1302 pow((double)10, (double)exponent
);
1305 * Sometimes ILOM will scale a sensor reading but
1306 * there will be nothing to the right of the decimal
1307 * once that value is normalized. Setting the
1308 * exponent to zero will prevent the printf below
1309 * from printing extraneous zeros. Otherwise a
1310 * negative exponent is used to set the precision
1313 if ((int)display_val
== display_val
|| exponent
> 0)
1317 err
= picl_get_propval_by_name(nodeh
, PICL_PROP_BASE_UNITS
,
1318 base_units
, sizeof (base_units
));
1319 if (err
!= PICL_SUCCESS
)
1320 base_units
[0] = '\0';
1322 switch (sensor_status
) {
1324 log_printf("%-s", "failed (");
1325 log_printf("%-.*f", abs(exponent
), display_val
);
1326 log_printf("%-s %s", base_units
, ")");
1329 log_printf("%-s", "warning (");
1330 log_printf("%-.*f", abs(exponent
), display_val
);
1331 log_printf("%-s %s", base_units
, ")");
1333 case SENSOR_DISABLED
:
1334 log_printf("%-s", "disabled");
1337 log_printf("%-s", "ok");
1340 log_printf("%-s", "unknown");
1345 return (PICL_WALK_CONTINUE
);
1350 sun4v_env_print_indicator_callback(picl_nodehdl_t nodeh
, void *args
)
1352 char current_val
[PICL_PROPNAMELEN_MAX
];
1353 char expected_val
[PICL_PROPNAMELEN_MAX
];
1354 char label
[PICL_PROPNAMELEN_MAX
];
1355 picl_nodehdl_t parenth
;
1356 char *names
[PARENT_NAMES
];
1359 char *prop
= (char *)args
;
1360 picl_errno_t err
= PICL_SUCCESS
;
1361 typedef enum {SENSOR_OK
, SENSOR_WARN
, SENSOR_FAILED
,
1362 SENSOR_DISABLED
, SENSOR_UNKNOWN
} sensor_status_t
;
1363 sensor_status_t sensor_status
= SENSOR_OK
;
1365 if (class_node_found
== 0) {
1366 class_node_found
= 1;
1367 return (PICL_WALK_TERMINATE
);
1370 prop
= (char *)args
;
1372 sensor_status
= SENSOR_UNKNOWN
;
1375 err
= picl_get_propval_by_name(nodeh
,
1376 PICL_PROP_OPERATIONAL_STATUS
, current_val
,
1377 sizeof (current_val
));
1378 if (err
== PICL_SUCCESS
) {
1379 if (strcmp(current_val
, "disabled") == 0) {
1380 sensor_status
= SENSOR_DISABLED
;
1385 if (sensor_status
!= SENSOR_DISABLED
&&
1386 sensor_status
!= SENSOR_UNKNOWN
) {
1387 if (picl_get_propval_by_name(nodeh
, prop
, ¤t_val
,
1388 sizeof (current_val
)) != PICL_SUCCESS
) {
1389 (void) strlcpy(current_val
, "unknown",
1390 sizeof (current_val
));
1391 sensor_status
= SENSOR_UNKNOWN
;
1393 if (picl_get_propval_by_name(nodeh
, PICL_PROP_EXPECTED
,
1394 &expected_val
, sizeof (expected_val
)) ==
1396 if (strncmp(current_val
, expected_val
,
1397 sizeof (current_val
)) == 0) {
1398 sensor_status
= SENSOR_OK
;
1400 sensor_status
= SENSOR_FAILED
;
1406 if (syserrlog
== 0) {
1407 if (sensor_status
!= SENSOR_OK
&& all_status_ok
== 1) {
1409 return (PICL_WALK_TERMINATE
);
1411 if (sensor_status
== SENSOR_OK
) {
1412 return (PICL_WALK_CONTINUE
);
1415 if (sensor_status
!= SENSOR_OK
&& all_status_ok
== 1) {
1421 * If we're here then prtdiag was invoked with "-v" or we have
1422 * a sensor that is beyond a threshold, so give them a book to
1423 * read instead of the Cliff Notes.
1425 err
= picl_get_propval_by_name(nodeh
, PICL_PROP_PARENT
, &parenth
,
1427 if (err
!= PICL_SUCCESS
) {
1429 return (PICL_WALK_CONTINUE
);
1431 if ((loc
= (char *)malloc(PICL_PROPNAMELEN_MAX
*PARENT_NAMES
)) != NULL
) {
1432 for (i
= 0; i
< PARENT_NAMES
; i
++) {
1433 if ((names
[i
] = (char *)malloc(PICL_PROPNAMELEN_MAX
)) ==
1444 while (err
== PICL_SUCCESS
) {
1445 if (parenth
== phyplatformh
)
1447 err
= picl_get_propval_by_name(parenth
, PICL_PROP_NAME
,
1448 names
[i
++], PICL_PROPNAMELEN_MAX
);
1449 if (err
!= PICL_SUCCESS
) {
1453 if (i
== PARENT_NAMES
)
1455 err
= picl_get_propval_by_name(parenth
,
1456 PICL_PROP_PARENT
, &parenth
, sizeof (parenth
));
1460 (void) strlcat(loc
, names
[i
],
1461 PICL_PROPNAMELEN_MAX
* PARENT_NAMES
);
1464 (void) strlcat(loc
, "/", PICL_PROPNAMELEN_MAX
*
1466 (void) strlcat(loc
, names
[i
],
1467 PICL_PROPNAMELEN_MAX
* PARENT_NAMES
);
1469 log_printf("%-35s", loc
);
1470 for (i
= 0; i
< PARENT_NAMES
; i
++)
1474 log_printf("%-35s", "");
1477 err
= picl_get_propval_by_name(nodeh
, PICL_PROP_LABEL
, label
,
1479 if (err
!= PICL_SUCCESS
)
1480 (void) strlcpy(label
, "", sizeof (label
));
1481 log_printf("%-19s", label
);
1483 log_printf("%-8s", current_val
);
1486 return (PICL_WALK_CONTINUE
);
1490 sun4v_env_print_fan_sensors()
1492 char *fmt
= "%-34s %-18s %-10s\n";
1494 * If there isn't any fan sensor node, return now.
1496 (void) picl_walk_tree_by_class(phyplatformh
,
1497 PICL_CLASS_RPM_SENSOR
, (void *)PICL_PROP_SPEED
,
1498 sun4v_env_print_sensor_callback
);
1499 if (!class_node_found
)
1501 log_printf("Fan sensors:\n");
1502 if (syserrlog
== 0) {
1503 (void) picl_walk_tree_by_class(phyplatformh
,
1504 PICL_CLASS_RPM_SENSOR
,
1505 PICL_PROP_SPEED
, sun4v_env_print_sensor_callback
);
1506 if (all_status_ok
) {
1507 log_printf("All fan sensors are OK.\n");
1511 log_printf("-------------------------------------------------"
1512 "---------------\n");
1513 log_printf(fmt
, "Location", "Sensor", "Status", 0);
1514 log_printf("-------------------------------------------------"
1515 "---------------\n");
1516 (void) picl_walk_tree_by_class(phyplatformh
, PICL_CLASS_RPM_SENSOR
,
1517 PICL_PROP_SPEED
, sun4v_env_print_sensor_callback
);
1521 sun4v_env_print_fan_indicators()
1523 char *fmt
= "%-34s %-18s %-10s\n";
1524 (void) picl_walk_tree_by_class(phyplatformh
,
1525 PICL_CLASS_RPM_INDICATOR
, (void *)PICL_PROP_CONDITION
,
1526 sun4v_env_print_indicator_callback
);
1527 if (!class_node_found
)
1529 log_printf("\nFan indicators:\n");
1530 if (syserrlog
== 0) {
1531 (void) picl_walk_tree_by_class(phyplatformh
,
1532 PICL_CLASS_RPM_INDICATOR
,
1533 (void *)PICL_PROP_CONDITION
,
1534 sun4v_env_print_indicator_callback
);
1535 if (all_status_ok
) {
1536 log_printf("All fan indicators are OK.\n");
1540 log_printf("-------------------------------------------------"
1541 "---------------\n");
1542 log_printf(fmt
, "Location", "Sensor", "Condition", 0);
1543 log_printf("-------------------------------------------------"
1544 "---------------\n");
1545 (void) picl_walk_tree_by_class(phyplatformh
, PICL_CLASS_RPM_INDICATOR
,
1546 (void *)PICL_PROP_CONDITION
, sun4v_env_print_indicator_callback
);
1550 sun4v_env_print_temp_sensors()
1552 char *fmt
= "%-34s %-18s %-10s\n";
1553 (void) picl_walk_tree_by_class(phyplatformh
,
1554 PICL_CLASS_TEMPERATURE_SENSOR
,
1555 (void *)PICL_PROP_TEMPERATURE
,
1556 sun4v_env_print_sensor_callback
);
1557 if (!class_node_found
)
1560 log_printf("\nTemperature sensors:\n");
1561 if (syserrlog
== 0) {
1562 (void) picl_walk_tree_by_class(phyplatformh
,
1563 PICL_CLASS_TEMPERATURE_SENSOR
,
1564 PICL_PROP_TEMPERATURE
, sun4v_env_print_sensor_callback
);
1565 if (all_status_ok
) {
1566 log_printf("All temperature sensors are OK.\n");
1570 log_printf("-------------------------------------------------"
1571 "---------------\n");
1572 log_printf(fmt
, "Location", "Sensor", "Status", 0);
1573 log_printf("-------------------------------------------------"
1574 "---------------\n");
1575 (void) picl_walk_tree_by_class(phyplatformh
,
1576 PICL_CLASS_TEMPERATURE_SENSOR
,
1577 (void *)PICL_PROP_TEMPERATURE
, sun4v_env_print_sensor_callback
);
1581 sun4v_env_print_temp_indicators()
1583 char *fmt
= "%-34s %-18s %-8s\n";
1584 (void) picl_walk_tree_by_class(phyplatformh
,
1585 PICL_CLASS_TEMPERATURE_INDICATOR
, (void *)PICL_PROP_CONDITION
,
1586 sun4v_env_print_indicator_callback
);
1587 if (!class_node_found
)
1589 log_printf("\nTemperature indicators:\n");
1590 if (syserrlog
== 0) {
1591 (void) picl_walk_tree_by_class(phyplatformh
,
1592 PICL_CLASS_TEMPERATURE_INDICATOR
,
1593 (void *)PICL_PROP_CONDITION
,
1594 sun4v_env_print_indicator_callback
);
1595 if (all_status_ok
) {
1596 log_printf("All temperature indicators are OK.\n");
1600 log_printf("-------------------------------------------------"
1601 "---------------\n");
1602 log_printf(fmt
, "Location", "Indicator", "Condition", 0);
1603 log_printf("-------------------------------------------------"
1604 "---------------\n");
1605 (void) picl_walk_tree_by_class(phyplatformh
,
1606 PICL_CLASS_TEMPERATURE_INDICATOR
,
1607 (void *)PICL_PROP_CONDITION
,
1608 sun4v_env_print_indicator_callback
);
1612 sun4v_env_print_current_sensors()
1614 char *fmt
= "%-34s %-18s %-10s\n";
1615 (void) picl_walk_tree_by_class(phyplatformh
, PICL_CLASS_CURRENT_SENSOR
,
1616 (void *)PICL_PROP_CURRENT
, sun4v_env_print_sensor_callback
);
1617 if (!class_node_found
)
1619 log_printf("\nCurrent sensors:\n");
1620 if (syserrlog
== 0) {
1621 (void) picl_walk_tree_by_class(phyplatformh
,
1622 PICL_CLASS_CURRENT_SENSOR
,
1623 PICL_PROP_CURRENT
, sun4v_env_print_sensor_callback
);
1624 if (all_status_ok
) {
1625 log_printf("All current sensors are OK.\n");
1629 log_printf("-------------------------------------------------"
1630 "---------------\n");
1631 log_printf(fmt
, "Location", "Sensor", "Status", 0);
1632 log_printf("-------------------------------------------------"
1633 "---------------\n");
1634 (void) picl_walk_tree_by_class(phyplatformh
,
1635 PICL_CLASS_CURRENT_SENSOR
, (void *)PICL_PROP_CURRENT
,
1636 sun4v_env_print_sensor_callback
);
1640 sun4v_env_print_current_indicators()
1642 char *fmt
= "%-34s %-18s %-8s\n";
1643 (void) picl_walk_tree_by_class(phyplatformh
,
1644 PICL_CLASS_CURRENT_INDICATOR
,
1645 (void *)PICL_PROP_CONDITION
,
1646 sun4v_env_print_indicator_callback
);
1647 if (!class_node_found
)
1649 log_printf("\nCurrent indicators:\n");
1650 if (syserrlog
== 0) {
1651 (void) picl_walk_tree_by_class(phyplatformh
,
1652 PICL_CLASS_CURRENT_INDICATOR
, (void *)PICL_PROP_CONDITION
,
1653 sun4v_env_print_indicator_callback
);
1654 if (all_status_ok
) {
1655 log_printf("All current indicators are OK.\n");
1659 log_printf("-------------------------------------------------"
1660 "---------------\n");
1661 log_printf(fmt
, "Location", "Indicator", "Condition", 0);
1662 log_printf("-------------------------------------------------"
1663 "---------------\n");
1664 (void) picl_walk_tree_by_class(phyplatformh
,
1665 PICL_CLASS_CURRENT_INDICATOR
,
1666 (void *)PICL_PROP_CONDITION
,
1667 sun4v_env_print_indicator_callback
);
1671 sun4v_env_print_voltage_sensors()
1673 char *fmt
= "%-34s %-18s %-10s\n";
1674 (void) picl_walk_tree_by_class(phyplatformh
,
1675 PICL_CLASS_VOLTAGE_SENSOR
,
1677 sun4v_env_print_sensor_callback
);
1678 if (!class_node_found
)
1680 log_printf("\nVoltage sensors:\n");
1681 if (syserrlog
== 0) {
1682 (void) picl_walk_tree_by_class(phyplatformh
,
1683 PICL_CLASS_VOLTAGE_SENSOR
,
1684 PICL_PROP_VOLTAGE
, sun4v_env_print_sensor_callback
);
1685 if (all_status_ok
) {
1686 log_printf("All voltage sensors are OK.\n");
1690 log_printf("-------------------------------------------------"
1691 "---------------\n");
1692 log_printf(fmt
, "Location", "Sensor", "Status", 0);
1693 log_printf("-------------------------------------------------"
1694 "---------------\n");
1695 (void) picl_walk_tree_by_class(phyplatformh
,
1696 PICL_CLASS_VOLTAGE_SENSOR
,
1697 (void *)PICL_PROP_VOLTAGE
,
1698 sun4v_env_print_sensor_callback
);
1702 sun4v_env_print_voltage_indicators()
1704 char *fmt
= "%-34s %-18s %-8s\n";
1705 (void) picl_walk_tree_by_class(phyplatformh
,
1706 PICL_CLASS_VOLTAGE_INDICATOR
,
1707 (void *)PICL_PROP_CONDITION
,
1708 sun4v_env_print_indicator_callback
);
1709 if (!class_node_found
)
1711 log_printf("\nVoltage indicators:\n");
1712 if (syserrlog
== 0) {
1713 (void) picl_walk_tree_by_class(phyplatformh
,
1714 PICL_CLASS_VOLTAGE_INDICATOR
, (void *)PICL_PROP_CONDITION
,
1715 sun4v_env_print_indicator_callback
);
1716 if (all_status_ok
) {
1717 log_printf("All voltage indicators are OK.\n");
1721 log_printf("-------------------------------------------------"
1722 "---------------\n");
1723 log_printf(fmt
, "Location", "Indicator", "Condition", 0);
1724 log_printf("-------------------------------------------------"
1725 "---------------\n");
1726 (void) picl_walk_tree_by_class(phyplatformh
,
1727 PICL_CLASS_VOLTAGE_INDICATOR
,
1728 (void *)PICL_PROP_CONDITION
,
1729 sun4v_env_print_indicator_callback
);
1733 sun4v_env_print_LEDs()
1735 char *fmt
= "%-34s %-18s %-8s\n";
1738 (void) picl_walk_tree_by_class(phyplatformh
, PICL_CLASS_LED
,
1739 (void *)PICL_PROP_STATE
, sun4v_env_print_indicator_callback
);
1740 if (!class_node_found
)
1742 log_printf("\nLEDs:\n");
1743 log_printf("-------------------------------------------------"
1744 "---------------\n");
1745 log_printf(fmt
, "Location", "LED", "State", 0);
1746 log_printf("-------------------------------------------------"
1747 "---------------\n");
1748 (void) picl_walk_tree_by_class(phyplatformh
, PICL_CLASS_LED
,
1749 (void *)PICL_PROP_STATE
, sun4v_env_print_indicator_callback
);
1754 sun4v_print_fru_status_callback(picl_nodehdl_t nodeh
, void *args
)
1756 char label
[PICL_PROPNAMELEN_MAX
];
1757 char status
[PICL_PROPNAMELEN_MAX
];
1759 picl_prophdl_t proph
;
1760 picl_nodehdl_t parenth
;
1761 char *names
[PARENT_NAMES
];
1765 if (!class_node_found
) {
1766 class_node_found
= 1;
1767 return (PICL_WALK_TERMINATE
);
1769 err
= picl_get_prop_by_name(nodeh
, PICL_PROP_IS_FRU
, &proph
);
1770 if (err
!= PICL_SUCCESS
)
1771 return (PICL_WALK_CONTINUE
);
1772 err
= picl_get_propval_by_name(nodeh
, PICL_PROP_LABEL
, label
,
1774 if (err
!= PICL_SUCCESS
)
1775 return (PICL_WALK_CONTINUE
);
1776 err
= picl_get_propval_by_name(nodeh
, PICL_PROP_OPERATIONAL_STATUS
,
1777 status
, sizeof (status
));
1778 if (err
!= PICL_SUCCESS
)
1779 return (PICL_WALK_CONTINUE
);
1780 if (syserrlog
== 0) {
1781 if (strcmp(status
, "disabled") == 0) {
1782 if (all_status_ok
) {
1784 return (PICL_WALK_TERMINATE
);
1787 return (PICL_WALK_CONTINUE
);
1789 if (all_status_ok
&& (strcmp(status
, "disabled") == 0)) {
1794 if (is_fru_absent(nodeh
))
1795 strcpy(status
, "Not present");
1797 err
= picl_get_propval_by_name(nodeh
, PICL_PROP_PARENT
, &parenth
,
1799 if (err
!= PICL_SUCCESS
) {
1801 return (PICL_WALK_CONTINUE
);
1803 if ((loc
= (char *)malloc(PICL_PROPNAMELEN_MAX
*PARENT_NAMES
)) == NULL
)
1804 return (PICL_WALK_TERMINATE
);
1805 for (i
= 0; i
< PARENT_NAMES
; i
++)
1806 if ((names
[i
] = (char *)malloc(PICL_PROPNAMELEN_MAX
)) == NULL
) {
1810 return (PICL_WALK_TERMINATE
);
1813 while (err
== PICL_SUCCESS
) {
1814 if (parenth
== phyplatformh
)
1816 err
= picl_get_propval_by_name(parenth
, PICL_PROP_NAME
,
1817 names
[i
++], PICL_PROPNAMELEN_MAX
);
1818 if (err
!= PICL_SUCCESS
) {
1822 if (i
== PARENT_NAMES
)
1824 err
= picl_get_propval_by_name(parenth
, PICL_PROP_PARENT
,
1825 &parenth
, sizeof (parenth
));
1829 (void) strlcat(loc
, names
[i
],
1830 PICL_PROPNAMELEN_MAX
* PARENT_NAMES
);
1833 (void) strlcat(loc
, "/", PICL_PROPNAMELEN_MAX
* PARENT_NAMES
);
1834 (void) strlcat(loc
, names
[i
],
1835 PICL_PROPNAMELEN_MAX
* PARENT_NAMES
);
1837 log_printf("%-35s", loc
);
1838 for (i
= 0; i
< PARENT_NAMES
; i
++)
1841 log_printf("%-10s", label
);
1842 log_printf("%-9s", status
);
1844 return (PICL_WALK_CONTINUE
);
1848 sun4v_print_fru_status()
1850 char *fmt
= "%-34s %-9s %-8s\n";
1852 (void) picl_walk_tree_by_class(phyplatformh
, NULL
, NULL
,
1853 sun4v_print_fru_status_callback
);
1854 if (!class_node_found
)
1858 log_printf("============================");
1859 log_printf(" FRU Status ");
1860 log_printf("============================");
1863 if (syserrlog
== 0) {
1864 (void) picl_walk_tree_by_class(phyplatformh
,
1866 sun4v_print_fru_status_callback
);
1867 if (all_status_ok
) {
1868 log_printf("All FRUs are enabled.\n");
1872 log_printf(fmt
, "Location", "Name", "Status", 0);
1873 log_printf("------------------------------------------------------\n");
1874 (void) picl_walk_tree_by_class(phyplatformh
, NULL
, NULL
,
1875 sun4v_print_fru_status_callback
);
1878 /* Check the children of the FRU node for a presence indicator */
1880 is_fru_absent(picl_nodehdl_t fruh
)
1882 char class [PICL_CLASSNAMELEN_MAX
];
1883 char condition
[PICL_PROPNAMELEN_MAX
];
1885 picl_nodehdl_t nodeh
;
1887 err
= picl_get_propval_by_name(fruh
, PICL_PROP_CHILD
, &nodeh
,
1888 sizeof (picl_nodehdl_t
));
1889 while (err
== PICL_SUCCESS
) {
1890 err
= picl_get_propval_by_name(nodeh
,
1891 PICL_PROP_CLASSNAME
, class, sizeof (class));
1892 if (err
== PICL_SUCCESS
&&
1893 strcmp(class, "presence-indicator") == 0) {
1894 err
= picl_get_propval_by_name(nodeh
,
1895 PICL_PROP_CONDITION
, condition
,
1896 sizeof (condition
));
1897 if (err
== PICL_SUCCESS
) {
1898 if (strcmp(condition
, "Absent") == 0) {
1905 err
= picl_get_propval_by_name(nodeh
, PICL_PROP_PEER
,
1906 &nodeh
, sizeof (picl_nodehdl_t
));
1913 sun4v_print_fw_rev_callback(picl_nodehdl_t nodeh
, void *args
)
1915 char rev
[PICL_PROPNAMELEN_MAX
];
1918 if (!class_node_found
) {
1919 class_node_found
= 1;
1920 return (PICL_WALK_TERMINATE
);
1923 err
= picl_get_propval_by_name(nodeh
, PICL_PROP_FW_REVISION
, rev
,
1925 if (err
!= PICL_SUCCESS
)
1926 return (PICL_WALK_CONTINUE
);
1927 if (strlen(rev
) == 0)
1928 return (PICL_WALK_CONTINUE
);
1929 log_printf("%s", rev
);
1931 return (PICL_WALK_CONTINUE
);
1935 sun4v_print_fw_rev()
1940 (void) picl_walk_tree_by_class(phyplatformh
, NULL
, NULL
,
1941 sun4v_print_fw_rev_callback
);
1942 if (!class_node_found
)
1946 log_printf("============================");
1947 log_printf(" FW Version ");
1948 log_printf("============================");
1950 log_printf("Version\n");
1951 log_printf("-------------------------------------------------"
1953 (void) picl_walk_tree_by_class(phyplatformh
, NULL
, NULL
,
1954 sun4v_print_fw_rev_callback
);
1958 sun4v_print_openprom_rev()
1963 (void) picl_walk_tree_by_class(rooth
, "openprom", NULL
,
1965 if (!class_node_found
)
1969 log_printf("======================");
1970 log_printf(" System PROM revisions ");
1971 log_printf("=======================");
1973 log_printf("Version\n");
1974 log_printf("-------------------------------------------------"
1976 (void) picl_walk_tree_by_class(rooth
, "openprom", NULL
,
1981 * display the OBP and POST prom revisions (if present)
1985 openprom_callback(picl_nodehdl_t openpromh
, void *arg
)
1987 picl_prophdl_t proph
;
1988 picl_prophdl_t tblh
;
1989 picl_prophdl_t rowproph
;
1990 picl_propinfo_t pinfo
;
1991 char *prom_version
= NULL
;
1992 char *obp_version
= NULL
;
1995 if (!class_node_found
) {
1996 class_node_found
= 1;
1997 return (PICL_WALK_TERMINATE
);
2000 err
= picl_get_propinfo_by_name(openpromh
, OBP_PROP_VERSION
,
2002 if (err
== PICL_PROPNOTFOUND
)
2003 return (PICL_WALK_TERMINATE
);
2004 else if (err
!= PICL_SUCCESS
)
2008 * If it's a table prop, the first element is OBP revision
2009 * The second one is POST revision.
2010 * If it's a charstring prop, the value will be only OBP revision
2012 if (pinfo
.type
== PICL_PTYPE_CHARSTRING
) {
2013 prom_version
= (char *)alloca(pinfo
.size
);
2014 if (prom_version
== NULL
)
2015 return (PICL_FAILURE
);
2016 err
= picl_get_propval(proph
, prom_version
, pinfo
.size
);
2017 if (err
!= PICL_SUCCESS
)
2019 log_printf("%s\n", prom_version
);
2022 if (pinfo
.type
!= PICL_PTYPE_TABLE
) /* not supported type */
2023 return (PICL_WALK_TERMINATE
);
2025 err
= picl_get_propval(proph
, &tblh
, pinfo
.size
);
2026 if (err
!= PICL_SUCCESS
)
2029 err
= picl_get_next_by_row(tblh
, &rowproph
);
2030 if (err
== PICL_SUCCESS
) {
2032 err
= picl_get_propinfo(rowproph
, &pinfo
);
2033 if (err
!= PICL_SUCCESS
)
2036 prom_version
= (char *)alloca(pinfo
.size
);
2037 if (prom_version
== NULL
)
2038 return (PICL_FAILURE
);
2040 err
= picl_get_propval(rowproph
, prom_version
, pinfo
.size
);
2041 if (err
!= PICL_SUCCESS
)
2043 log_printf("%s\n", prom_version
);
2045 /* get second row */
2046 err
= picl_get_next_by_col(rowproph
, &rowproph
);
2047 if (err
== PICL_SUCCESS
) {
2048 err
= picl_get_propinfo(rowproph
, &pinfo
);
2049 if (err
!= PICL_SUCCESS
)
2052 obp_version
= (char *)alloca(pinfo
.size
);
2053 if (obp_version
== NULL
)
2054 return (PICL_FAILURE
);
2055 err
= picl_get_propval(rowproph
, obp_version
,
2057 if (err
!= PICL_SUCCESS
)
2059 log_printf("%s\n", obp_version
);
2063 return (PICL_WALK_TERMINATE
);
2067 sun4v_print_chassis_serial_no()
2069 char val
[PICL_PROPNAMELEN_MAX
];
2071 if (syserrlog
== 0 || chassish
== 0)
2075 log_printf("Chassis Serial Number");
2077 log_printf("---------------------\n");
2078 err
= picl_get_propval_by_name(chassish
, PICL_PROP_SERIAL_NUMBER
,
2080 if (err
== PICL_SUCCESS
)
2081 log_printf("%s", val
);