xref: /onnv-gate/usr/src/lib/libprtdiag/common/display_sun4v.c (revision 5544:17ce2fc0f6d3)
11708Sstevel /*
21708Sstevel  * CDDL HEADER START
31708Sstevel  *
41708Sstevel  * The contents of this file are subject to the terms of the
53941Svenki  * Common Development and Distribution License (the "License").
63941Svenki  * You may not use this file except in compliance with the License.
71708Sstevel  *
81708Sstevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91708Sstevel  * or http://www.opensolaris.org/os/licensing.
101708Sstevel  * See the License for the specific language governing permissions
111708Sstevel  * and limitations under the License.
121708Sstevel  *
131708Sstevel  * When distributing Covered Code, include this CDDL HEADER in each
141708Sstevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151708Sstevel  * If applicable, add the following below this CDDL HEADER, with the
161708Sstevel  * fields enclosed by brackets "[]" replaced with your own identifying
171708Sstevel  * information: Portions Copyright [yyyy] [name of copyright owner]
181708Sstevel  *
191708Sstevel  * CDDL HEADER END
201708Sstevel  */
211708Sstevel /*
223941Svenki  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
231708Sstevel  * Use is subject to license terms.
241708Sstevel  */
251708Sstevel 
261708Sstevel #pragma ident	"%Z%%M%	%I%	%E% SMI"
271708Sstevel 
281708Sstevel #include <stdio.h>
291708Sstevel #include <stdlib.h>
305436Sfw157321 #include <alloca.h>
311708Sstevel #include <unistd.h>
321708Sstevel #include <ctype.h>
331708Sstevel #include <string.h>
341708Sstevel #include <kvm.h>
351708Sstevel #include <varargs.h>
361708Sstevel #include <time.h>
371708Sstevel #include <dirent.h>
381708Sstevel #include <fcntl.h>
391708Sstevel #include <sys/param.h>
401708Sstevel #include <sys/stat.h>
411708Sstevel #include <sys/types.h>
421708Sstevel #include <sys/utsname.h>
431708Sstevel #include <sys/openpromio.h>
441708Sstevel #include <libintl.h>
451708Sstevel #include <syslog.h>
461708Sstevel #include <sys/dkio.h>
473941Svenki #include <sys/systeminfo.h>
483941Svenki #include <picldefs.h>
494802Sfw157321 #include <math.h>
504802Sfw157321 #include <errno.h>
511708Sstevel #include "pdevinfo.h"
521708Sstevel #include "display.h"
531708Sstevel #include "display_sun4v.h"
541708Sstevel #include "libprtdiag.h"
551708Sstevel 
561708Sstevel #if !defined(TEXT_DOMAIN)
571708Sstevel #define	TEXT_DOMAIN	"SYS_TEST"
581708Sstevel #endif
591708Sstevel 
604669Sfw157321 #define	MOTHERBOARD			"MB"
613941Svenki #define	NETWORK				"network"
623941Svenki #define	PCIE_COMPATIBLE_STR		"pciex"
633941Svenki #define	PCIX_COMPATIBLE_STR		"pci"
643941Svenki #define	SUN4V_MACHINE			"sun4v"
653941Svenki #define	PARENT_NAMES			10
663941Svenki 
673941Svenki /*
683941Svenki  * Additional OBP properties
693941Svenki  */
703941Svenki #define	OBP_PROP_COMPATIBLE		"compatible"
713941Svenki #define	OBP_PROP_MODEL			"model"
723941Svenki #define	OBP_PROP_SLOT_NAMES		"slot-names"
735436Sfw157321 #define	OBP_PROP_VERSION		"version"
743941Svenki 
753941Svenki #define	PICL_NODE_PHYSICAL_PLATFORM	"physical-platform"
763941Svenki #define	PICL_NODE_CHASSIS		"chassis"
773941Svenki #define	MEMORY_SIZE_FIELD		11
783941Svenki #define	INVALID_THRESHOLD		1000000
793941Svenki 
803941Svenki /*
813941Svenki  * Additional picl classes
823941Svenki  */
833941Svenki #ifndef	PICL_CLASS_SUN4V
843941Svenki #define	PICL_CLASS_SUN4V		"sun4v"
853941Svenki #endif
863941Svenki 
873941Svenki #ifndef	PICL_PROP_NAC
883941Svenki #define	PICL_PROP_NAC			"nac"
893941Svenki #endif
903941Svenki 
913941Svenki extern int sys_clk;
923941Svenki extern picl_errno_t sun4v_get_node_by_name(picl_nodehdl_t, char *,
933941Svenki 	picl_nodehdl_t *);
943941Svenki 
953941Svenki static picl_nodehdl_t rooth = 0, phyplatformh = 0;
963941Svenki static picl_nodehdl_t chassish = 0;
973941Svenki static int class_node_found;
983941Svenki static int syserrlog;
993941Svenki static int all_status_ok;
1003941Svenki 
1013941Svenki /* local functions */
1023941Svenki static int sun4v_get_first_compatible_value(picl_nodehdl_t, char **);
1033941Svenki static void sun4v_display_memory_conf(picl_nodehdl_t);
1043941Svenki static void sun4v_disp_env_status();
1053941Svenki static void sun4v_env_print_fan_sensors();
1063941Svenki static void sun4v_env_print_fan_indicators();
1073941Svenki static void sun4v_env_print_temp_sensors();
1083941Svenki static void sun4v_env_print_temp_indicators();
1093941Svenki static void sun4v_env_print_current_sensors();
1103941Svenki static void sun4v_env_print_current_indicators();
1113941Svenki static void sun4v_env_print_voltage_sensors();
1123941Svenki static void sun4v_env_print_voltage_indicators();
1133941Svenki static void sun4v_env_print_LEDs();
1143941Svenki static void sun4v_print_fru_status();
1153941Svenki static void sun4v_print_fw_rev();
1163941Svenki static void sun4v_print_chassis_serial_no();
1175436Sfw157321 static int openprom_callback(picl_nodehdl_t openpromh, void *arg);
1185436Sfw157321 static void sun4v_print_openprom_rev();
1191708Sstevel 
1201708Sstevel int
1213941Svenki sun4v_display(Sys_tree *tree, Prom_node *root, int log,
1223941Svenki 	picl_nodehdl_t plafh)
1231708Sstevel {
1241708Sstevel 	void *value;		/* used for opaque PROM data */
1251708Sstevel 	struct mem_total memory_total;	/* Total memory in system */
1261708Sstevel 	struct grp_info grps;	/* Info on all groups in system */
1273941Svenki 	char machine[MAXSTRLEN];
1283941Svenki 
1293941Svenki 	if (sysinfo(SI_MACHINE, machine, sizeof (machine)) == -1)
1303941Svenki 		return (1);
1313941Svenki 	if (strncmp(machine, SUN4V_MACHINE, strlen(SUN4V_MACHINE)) != 0)
1323941Svenki 		return (1);
1331708Sstevel 
1341708Sstevel 	sys_clk = -1;  /* System clock freq. (in MHz) */
1351708Sstevel 
1361708Sstevel 	/*
1371708Sstevel 	 * Now display the machine's configuration. We do this if we
1381708Sstevel 	 * are not logging.
1391708Sstevel 	 */
1401708Sstevel 	if (!logging) {
1411708Sstevel 		struct utsname uts_buf;
1421708Sstevel 
1431708Sstevel 		/*
1441708Sstevel 		 * Display system banner
1451708Sstevel 		 */
1461708Sstevel 		(void) uname(&uts_buf);
1471708Sstevel 
1483941Svenki 		log_printf(dgettext(TEXT_DOMAIN, "System Configuration:  "
1494669Sfw157321 		    "Sun Microsystems  %s %s\n"), uts_buf.machine,
1504669Sfw157321 		    get_prop_val(find_prop(root, "banner-name")), 0);
1511708Sstevel 
1521708Sstevel 		/* display system clock frequency */
1531708Sstevel 		value = get_prop_val(find_prop(root, "clock-frequency"));
1541708Sstevel 		if (value != NULL) {
1551708Sstevel 			sys_clk = ((*((int *)value)) + 500000) / 1000000;
1561708Sstevel 			log_printf(dgettext(TEXT_DOMAIN, "System clock "
1574669Sfw157321 			    "frequency: %d MHz\n"), sys_clk, 0);
1581708Sstevel 		}
1591708Sstevel 
1601708Sstevel 		/* Display the Memory Size */
1611708Sstevel 		display_memorysize(tree, NULL, &grps, &memory_total);
1621708Sstevel 
1631708Sstevel 		/* Display the CPU devices */
1641708Sstevel 		sun4v_display_cpu_devices(plafh);
1651708Sstevel 
1661708Sstevel 		/* Display the Memory configuration */
1673941Svenki 		class_node_found = 0;
1683941Svenki 		sun4v_display_memory_conf(plafh);
1691708Sstevel 
1701708Sstevel 		/* Display all the IO cards. */
1711708Sstevel 		(void) sun4v_display_pci(plafh);
1723941Svenki 		sun4v_display_diaginfo((log || (logging)), root, plafh);
1731708Sstevel 
1743941Svenki 		if (picl_get_root(&rooth) != PICL_SUCCESS)
1753941Svenki 			return (1);
1763941Svenki 		if (sun4v_get_node_by_name(rooth, PICL_NODE_PHYSICAL_PLATFORM,
1774669Sfw157321 		    &phyplatformh) != PICL_SUCCESS)
1783941Svenki 			return (1);
1793941Svenki 
1803941Svenki 		if (picl_find_node(phyplatformh, PICL_PROP_CLASSNAME,
1814669Sfw157321 		    PICL_PTYPE_CHARSTRING, (void *)PICL_CLASS_CHASSIS,
1824669Sfw157321 		    strlen(PICL_CLASS_CHASSIS), &chassish) != PICL_SUCCESS)
1833941Svenki 			return (1);
1843941Svenki 
1853941Svenki 		syserrlog = log;
1863941Svenki 		sun4v_disp_env_status();
1873941Svenki 	}
1883941Svenki 	return (0);
1893941Svenki }
1903941Svenki 
1913941Svenki static void
1923941Svenki get_bus_type(picl_nodehdl_t nodeh, struct io_card *card)
1933941Svenki {
1943941Svenki 	char *compatible;
1953941Svenki 
1964003Svivek 	(void) strlcpy(card->bus_type, "PCIX", sizeof (card->bus_type));
1973941Svenki 	if (sun4v_get_first_compatible_value(nodeh, &compatible)
1984669Sfw157321 	    == PICL_SUCCESS) {
1993941Svenki 		if (strncmp(compatible, PCIE_COMPATIBLE_STR,
2004669Sfw157321 		    strlen(PCIE_COMPATIBLE_STR)) == 0)
2014003Svivek 			(void) strlcpy(card->bus_type, "PCIE",
2024669Sfw157321 			    sizeof (card->bus_type));
2033941Svenki 		free(compatible);
2043941Svenki 	}
2053941Svenki }
2063941Svenki 
2073941Svenki static picl_errno_t
2083941Svenki get_slot_label(picl_nodehdl_t nodeh, struct io_card *card)
2093941Svenki {
2103941Svenki 	char val[PICL_PROPNAMELEN_MAX];
2113941Svenki 	picl_errno_t err;
2125436Sfw157321 	picl_nodehdl_t pnodeh;
2133941Svenki 
2145436Sfw157321 	/*
2155436Sfw157321 	 * Look for a Label first in the node corresponding to the IO
2165436Sfw157321 	 * device.  If there's no Label then we might be on the downstream
2175436Sfw157321 	 * side of a bridge (i.e. the IO device/card has a bridge on it).
2185436Sfw157321 	 * So look at the parent and see if it has a Label.
2195436Sfw157321 	 */
2203941Svenki 	err = picl_get_propval_by_name(nodeh, PICL_PROP_LABEL, val,
2214669Sfw157321 	    sizeof (val));
2225436Sfw157321 	if (err == PICL_PROPNOTFOUND) {
2235436Sfw157321 		if (picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, &pnodeh,
2245436Sfw157321 		    sizeof (pnodeh)) == PICL_SUCCESS)
2255436Sfw157321 			err = picl_get_propval_by_name(pnodeh, PICL_PROP_LABEL,
2265436Sfw157321 			    val, sizeof (val));
2275436Sfw157321 	}
2283941Svenki 
2295436Sfw157321 	if (err == PICL_SUCCESS)
2305436Sfw157321 		(void) strlcpy(card->slot_str, val, sizeof (card->slot_str));
2315436Sfw157321 
2323941Svenki 	card->slot = -1;
2335436Sfw157321 	return (err);
2343941Svenki }
2353941Svenki 
2363941Svenki static void
2373941Svenki get_slot_number(picl_nodehdl_t nodeh, struct io_card *card)
2383941Svenki {
2393941Svenki 	picl_errno_t err;
2403941Svenki 	picl_prophdl_t proph;
2413941Svenki 	picl_propinfo_t pinfo;
2423941Svenki 	picl_nodehdl_t pnodeh;
2433941Svenki 	uint8_t *pval;
2443941Svenki 	uint32_t dev_mask;
2453941Svenki 	char uaddr[MAXSTRLEN];
2463941Svenki 	int i;
2473941Svenki 
2483941Svenki 	if (get_slot_label(nodeh, card) == PICL_SUCCESS)
2493941Svenki 		return;
2503941Svenki 	err = PICL_SUCCESS;
2513941Svenki 	while (err == PICL_SUCCESS) {
2523941Svenki 		if (picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, &pnodeh,
2534669Sfw157321 		    sizeof (pnodeh)) != PICL_SUCCESS) {
2544669Sfw157321 			(void) strlcpy(card->slot_str, MOTHERBOARD,
2554669Sfw157321 			    sizeof (card->slot_str));
2563941Svenki 			card->slot = -1;
2573941Svenki 			return;
2583941Svenki 		}
2593941Svenki 		if (picl_get_propinfo_by_name(pnodeh, OBP_PROP_SLOT_NAMES,
2604669Sfw157321 		    &pinfo, &proph) == PICL_SUCCESS) {
2613941Svenki 			break;
2623941Svenki 		}
2633941Svenki 		nodeh = pnodeh;
2643941Svenki 	}
2653941Svenki 	if (picl_get_propval_by_name(nodeh, PICL_PROP_UNIT_ADDRESS, uaddr,
2664669Sfw157321 	    sizeof (uaddr)) != PICL_SUCCESS) {
2674669Sfw157321 		(void) strlcpy(card->slot_str, MOTHERBOARD,
2684669Sfw157321 		    sizeof (card->slot_str));
2693941Svenki 		card->slot = -1;
2703941Svenki 		return;
2713941Svenki 	}
2723941Svenki 	pval = (uint8_t *)malloc(pinfo.size);
2733941Svenki 	if (!pval) {
2744669Sfw157321 		(void) strlcpy(card->slot_str, MOTHERBOARD,
2754669Sfw157321 		    sizeof (card->slot_str));
2763941Svenki 		card->slot = -1;
2773941Svenki 		return;
2783941Svenki 	}
2793941Svenki 	if (picl_get_propval(proph, pval, pinfo.size) != PICL_SUCCESS) {
2804669Sfw157321 		(void) strlcpy(card->slot_str, MOTHERBOARD,
2814669Sfw157321 		    sizeof (card->slot_str));
2823941Svenki 		card->slot = -1;
2833941Svenki 		free(pval);
2843941Svenki 		return;
2851708Sstevel 	}
2861708Sstevel 
2873941Svenki 	dev_mask = 0;
2883941Svenki 	for (i = 0; i < sizeof (dev_mask); i++)
2893941Svenki 		dev_mask |= (*(pval+i) << 8*(sizeof (dev_mask)-1-i));
2903941Svenki 	for (i = 0; i < sizeof (uaddr) && uaddr[i] != '\0'; i++) {
2913941Svenki 		if (uaddr[i] == ',') {
2923941Svenki 			uaddr[i] = '\0';
2933941Svenki 			break;
2943941Svenki 		}
2953941Svenki 	}
2963941Svenki 	card->slot = atol(uaddr);
2973941Svenki 	if (((1 << card->slot) & dev_mask) == 0) {
2984669Sfw157321 		(void) strlcpy(card->slot_str, MOTHERBOARD,
2994669Sfw157321 		    sizeof (card->slot_str));
3003941Svenki 		card->slot = -1;
3013941Svenki 	} else {
3023941Svenki 		char *p = (char *)(pval+sizeof (dev_mask));
3033941Svenki 		int shift = sizeof (uint32_t)*8-1-card->slot;
3043941Svenki 		uint32_t x = (dev_mask << shift) >> shift;
3053941Svenki 		int count = 0;	/* count # of 1's in x */
3063941Svenki 		int i = 0;
3073941Svenki 		while (x != 0) {
3083941Svenki 			count++;
3093941Svenki 			x &= x-1;
3103941Svenki 		}
3113941Svenki 		while (count > 1) {
3124669Sfw157321 			while (p[i++] != '\0')
3134669Sfw157321 				;
3143941Svenki 			count--;
3153941Svenki 		}
3164003Svivek 		(void) strlcpy(card->slot_str, (char *)(p+i),
3174669Sfw157321 		    sizeof (card->slot_str));
3183941Svenki 	}
3193941Svenki 	free(pval);
3203941Svenki }
3213941Svenki 
3223941Svenki /*
3233941Svenki  * add all io devices under pci in io list
3243941Svenki  */
3253941Svenki /* ARGSUSED */
3263941Svenki static int
3273941Svenki sun4v_pci_callback(picl_nodehdl_t pcih, void *args)
3283941Svenki {
3293941Svenki 	char path[PICL_PROPNAMELEN_MAX];
3303941Svenki 	char class[PICL_CLASSNAMELEN_MAX];
3313941Svenki 	char name[PICL_PROPNAMELEN_MAX];
3323941Svenki 	char model[PICL_PROPNAMELEN_MAX];
3333941Svenki 	char binding_name[PICL_PROPNAMELEN_MAX];
3343941Svenki 	char val[PICL_PROPNAMELEN_MAX];
3353941Svenki 	char *compatible;
3363941Svenki 	picl_errno_t err;
3373941Svenki 	picl_nodehdl_t nodeh;
3383941Svenki 	struct io_card pci_card;
3393941Svenki 
3403941Svenki 	/* Walk through the children */
3413941Svenki 
3423941Svenki 	err = picl_get_propval_by_name(pcih, PICL_PROP_CHILD, &nodeh,
3434669Sfw157321 	    sizeof (picl_nodehdl_t));
3443941Svenki 
3453941Svenki 	while (err == PICL_SUCCESS) {
3463941Svenki 		err = picl_get_propval_by_name(nodeh, PICL_PROP_CLASSNAME,
3474669Sfw157321 		    class, sizeof (class));
3483941Svenki 		if (err !=  PICL_SUCCESS)
3493941Svenki 			return (err);
3503941Svenki 
3513941Svenki 		if (args) {
3523941Svenki 			char *val = args;
3533941Svenki 			if (strcmp(class, val) == 0) {
3543941Svenki 				err = picl_get_propval_by_name(nodeh,
3554669Sfw157321 				    PICL_PROP_PEER, &nodeh,
3564669Sfw157321 				    sizeof (picl_nodehdl_t));
3573941Svenki 				continue;
3583941Svenki 			} else if (strcmp(val, PICL_CLASS_PCIEX) == 0 &&
3594669Sfw157321 			    strcmp(class, PICL_CLASS_PCI) == 0) {
3603941Svenki 				err = picl_get_propval_by_name(nodeh,
3614669Sfw157321 				    PICL_PROP_PEER, &nodeh,
3624669Sfw157321 				    sizeof (picl_nodehdl_t));
3633941Svenki 				continue;
3643941Svenki 			} else if (strcmp(val, PICL_CLASS_PCI) == 0 &&
3654669Sfw157321 			    strcmp(class, PICL_CLASS_PCIEX) == 0) {
3663941Svenki 				err = picl_get_propval_by_name(nodeh,
3674669Sfw157321 				    PICL_PROP_PEER, &nodeh,
3684669Sfw157321 				    sizeof (picl_nodehdl_t));
3693941Svenki 				continue;
3703941Svenki 			}
3713941Svenki 		}
3723941Svenki 
3733941Svenki 		err = picl_get_propval_by_name(nodeh, PICL_PROP_DEVFS_PATH,
3744669Sfw157321 		    path, sizeof (path));
3753941Svenki 		if (err != PICL_SUCCESS)
3763941Svenki 			return (err);
3773941Svenki 
3783941Svenki 		(void) strlcpy(pci_card.notes, path, sizeof (pci_card.notes));
3793941Svenki 
3803941Svenki 		get_bus_type(nodeh, &pci_card);
3813941Svenki 		get_slot_number(nodeh, &pci_card);
3823941Svenki 
3833941Svenki 		err = picl_get_propval_by_name(nodeh, PICL_PROP_NAME, name,
3844669Sfw157321 		    sizeof (name));
3853941Svenki 		if (err == PICL_PROPNOTFOUND)
3864003Svivek 			(void) strlcpy(name, "", sizeof (name));
3873941Svenki 		else if (err != PICL_SUCCESS)
3883941Svenki 			return (err);
3893941Svenki 
3903941Svenki 		err = picl_get_propval_by_name(nodeh, PICL_PROP_STATUS, val,
3914669Sfw157321 		    sizeof (val));
3923941Svenki 		if (err == PICL_PROPNOTFOUND)
3934003Svivek 			(void) strlcpy(val, "", sizeof (val));
3943941Svenki 		else if (err != PICL_SUCCESS)
3953941Svenki 			return (err);
3963941Svenki 
3975436Sfw157321 		(void) snprintf(pci_card.status, sizeof (pci_card.status),
3985436Sfw157321 		    "%s", pci_card.slot_str);
3993941Svenki 
4003941Svenki 		/*
4013941Svenki 		 * Get the name of this card. If binding_name is found,
4023941Svenki 		 * name will be <nodename>-<binding_name>.
4033941Svenki 		 */
4043941Svenki 		err = picl_get_propval_by_name(nodeh, PICL_PROP_BINDING_NAME,
4054669Sfw157321 		    binding_name, sizeof (binding_name));
4063941Svenki 		if (err == PICL_SUCCESS) {
4073941Svenki 			if (strcmp(name, binding_name) != 0) {
4083941Svenki 				(void) strlcat(name, "-", sizeof (name));
4093941Svenki 				(void) strlcat(name, binding_name,
4104669Sfw157321 				    sizeof (name));
4113941Svenki 			}
4123941Svenki 		} else if (err == PICL_PROPNOTFOUND) {
4133941Svenki 			/*
4143941Svenki 			 * if compatible prop is not found, name will be
4153941Svenki 			 * <nodename>-<compatible>
4163941Svenki 			 */
4173941Svenki 			err = sun4v_get_first_compatible_value(nodeh,
4184669Sfw157321 			    &compatible);
4193941Svenki 			if (err == PICL_SUCCESS) {
4203941Svenki 				(void) strlcat(name, "-", sizeof (name));
4214003Svivek 				(void) strlcat(name, compatible,
4224669Sfw157321 				    sizeof (name));
4233941Svenki 				free(compatible);
4243941Svenki 			}
4253941Svenki 		} else
4263941Svenki 			return (err);
4273941Svenki 
4283941Svenki 		(void) strlcpy(pci_card.name, name, sizeof (pci_card.name));
4293941Svenki 
4303941Svenki 		/* Get the model of this card */
4313941Svenki 
4323941Svenki 		err = picl_get_propval_by_name(nodeh, OBP_PROP_MODEL,
4334669Sfw157321 		    model, sizeof (model));
4343941Svenki 		if (err == PICL_PROPNOTFOUND)
4354003Svivek 			(void) strlcpy(model, "", sizeof (model));
4363941Svenki 		else if (err != PICL_SUCCESS)
4373941Svenki 			return (err);
4383941Svenki 		(void) strlcpy(pci_card.model, model, sizeof (pci_card.model));
4393941Svenki 
4403941Svenki 		/* Print NAC name */
4414802Sfw157321 		log_printf("%-18s", pci_card.status);
4423941Svenki 		/* Print IO Type */
4433941Svenki 		log_printf("%-6s", pci_card.bus_type);
4443941Svenki 		/* Printf Card Name */
445*5544Sfw157321 		log_printf("%-34s", pci_card.name);
4463941Svenki 		/* Print Card Model */
4473941Svenki 		log_printf("%-8s", pci_card.model);
4483941Svenki 		log_printf("\n");
4493941Svenki 		/* Print Status */
4504802Sfw157321 		log_printf("%-18s", val);
4513941Svenki 		/* Print IO Type */
4523941Svenki 		log_printf("%-6s", "");
4533941Svenki 		/* Print Parent Path */
4544802Sfw157321 		log_printf("%-44s", pci_card.notes);
4553941Svenki 		log_printf("\n");
4563941Svenki 
4573941Svenki 		err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, &nodeh,
4584669Sfw157321 		    sizeof (picl_nodehdl_t));
4593941Svenki 	}
4603941Svenki 	return (PICL_WALK_CONTINUE);
4611708Sstevel }
4621708Sstevel 
4631708Sstevel /*
4641708Sstevel  * display_pci
4651708Sstevel  * Display all the PCI IO cards on this board.
4661708Sstevel  */
4671708Sstevel void
4681708Sstevel sun4v_display_pci(picl_nodehdl_t plafh)
4691708Sstevel {
470*5544Sfw157321 	char *fmt = "%-17s %-5s %-33s %-8s";
4713941Svenki 	/* Have we printed the column headings? */
4723941Svenki 	static int banner = FALSE;
4733941Svenki 
4743941Svenki 	if (banner == FALSE) {
4753941Svenki 		log_printf("\n");
4764802Sfw157321 		log_printf("================================");
4773941Svenki 		log_printf(" IO Devices ");
4784802Sfw157321 		log_printf("================================");
4793941Svenki 		log_printf("\n");
4803941Svenki 		log_printf(fmt, "Slot +", "Bus", "Name +", "Model", 0);
4813941Svenki 		log_printf("\n");
4823941Svenki 		log_printf(fmt, "Status", "Type", "Path", "", 0);
4833941Svenki 		log_printf("\n");
4843941Svenki 		log_printf("---------------------------------"
4854802Sfw157321 		    "-------------------------------------------\n");
4863941Svenki 		banner = TRUE;
4873941Svenki 	}
4883941Svenki 
4893941Svenki 	(void) picl_walk_tree_by_class(plafh, PICL_CLASS_PCIEX,
4904669Sfw157321 	    PICL_CLASS_PCIEX, sun4v_pci_callback);
4913941Svenki 	(void) picl_walk_tree_by_class(plafh, PICL_CLASS_PCI,
4924669Sfw157321 	    PICL_CLASS_PCI, sun4v_pci_callback);
4933941Svenki 	(void) picl_walk_tree_by_class(plafh, PICL_CLASS_SUN4V,
4944669Sfw157321 	    PICL_CLASS_SUN4V, sun4v_pci_callback);
4953941Svenki }
4963941Svenki 
4973941Svenki /*
4983941Svenki  * return the first compatible value
4993941Svenki  */
5003941Svenki static int
5013941Svenki sun4v_get_first_compatible_value(picl_nodehdl_t nodeh, char **outbuf)
5023941Svenki {
5033941Svenki 	picl_errno_t err;
5043941Svenki 	picl_prophdl_t proph;
5053941Svenki 	picl_propinfo_t pinfo;
5063941Svenki 	picl_prophdl_t tblh;
5073941Svenki 	picl_prophdl_t rowproph;
5083941Svenki 	char *pval;
5093941Svenki 
5103941Svenki 	err = picl_get_propinfo_by_name(nodeh, OBP_PROP_COMPATIBLE,
5114669Sfw157321 	    &pinfo, &proph);
5123941Svenki 	if (err != PICL_SUCCESS)
5133941Svenki 		return (err);
5143941Svenki 
5153941Svenki 	if (pinfo.type == PICL_PTYPE_CHARSTRING) {
5163941Svenki 		pval = malloc(pinfo.size);
5173941Svenki 		if (pval == NULL)
5183941Svenki 			return (PICL_FAILURE);
5193941Svenki 		err = picl_get_propval(proph, pval, pinfo.size);
5203941Svenki 		if (err != PICL_SUCCESS) {
5213941Svenki 			free(pval);
5223941Svenki 			return (err);
5233941Svenki 		}
5243941Svenki 		*outbuf = pval;
5253941Svenki 		return (PICL_SUCCESS);
5263941Svenki 	}
5273941Svenki 
5283941Svenki 	if (pinfo.type != PICL_PTYPE_TABLE)
5293941Svenki 		return (PICL_FAILURE);
5303941Svenki 
5313941Svenki 	/* get first string from table */
5323941Svenki 	err = picl_get_propval(proph, &tblh, pinfo.size);
5333941Svenki 	if (err != PICL_SUCCESS)
5343941Svenki 		return (err);
5353941Svenki 
5363941Svenki 	err = picl_get_next_by_row(tblh, &rowproph);
5373941Svenki 	if (err != PICL_SUCCESS)
5383941Svenki 		return (err);
5393941Svenki 
5403941Svenki 	err = picl_get_propinfo(rowproph, &pinfo);
5413941Svenki 	if (err != PICL_SUCCESS)
5423941Svenki 		return (err);
5433941Svenki 
5443941Svenki 	pval = malloc(pinfo.size);
5453941Svenki 	if (pval == NULL)
5463941Svenki 		return (PICL_FAILURE);
5473941Svenki 
5483941Svenki 	err = picl_get_propval(rowproph, pval, pinfo.size);
5493941Svenki 	if (err != PICL_SUCCESS) {
5503941Svenki 		free(pval);
5513941Svenki 		return (err);
5523941Svenki 	}
5533941Svenki 
5543941Svenki 	*outbuf = pval;
5553941Svenki 	return (PICL_SUCCESS);
5561708Sstevel }
5571708Sstevel 
5583941Svenki /*
5593941Svenki  * print size of a memory segment
5603941Svenki  */
5613941Svenki static void
5623941Svenki print_memory_segment_size(uint64_t size)
5633941Svenki {
5643941Svenki 	uint64_t kbyte = 1024;
5653941Svenki 	uint64_t mbyte = kbyte * kbyte;
5663941Svenki 	uint64_t gbyte = kbyte * mbyte;
567*5544Sfw157321 	uint64_t tbyte = kbyte * gbyte;
5683941Svenki 	char buf[MEMORY_SIZE_FIELD];
5693941Svenki 
570*5544Sfw157321 	if (size >= tbyte) {
571*5544Sfw157321 		if (size % tbyte == 0)
572*5544Sfw157321 			(void) snprintf(buf, sizeof (buf), "%d TB",
573*5544Sfw157321 			    (int)(size / tbyte));
574*5544Sfw157321 		else
575*5544Sfw157321 			(void) snprintf(buf, sizeof (buf), "%.2f TB",
576*5544Sfw157321 			    (float)size / tbyte);
577*5544Sfw157321 	} else if (size >= gbyte) {
5783941Svenki 		if (size % gbyte == 0)
5793941Svenki 			(void) snprintf(buf, sizeof (buf), "%d GB",
5804669Sfw157321 			    (int)(size / gbyte));
5813941Svenki 		else
5823941Svenki 			(void) snprintf(buf, sizeof (buf), "%.2f GB",
5834669Sfw157321 			    (float)size / gbyte);
5843941Svenki 	} else if (size >= mbyte) {
5853941Svenki 		if (size % mbyte == 0)
5863941Svenki 			(void) snprintf(buf, sizeof (buf), "%d MB",
5874669Sfw157321 			    (int)(size / mbyte));
5883941Svenki 		else
5893941Svenki 			(void) snprintf(buf, sizeof (buf), "%.2f MB",
5904669Sfw157321 			    (float)size / mbyte);
5913941Svenki 	} else {
5923941Svenki 		if (size % kbyte == 0)
5933941Svenki 			(void) snprintf(buf, sizeof (buf), "%d KB",
5944669Sfw157321 			    (int)(size / kbyte));
5953941Svenki 		else
5963941Svenki 			(void) snprintf(buf, sizeof (buf), "%.2f KB",
5974669Sfw157321 			    (float)size / kbyte);
5983941Svenki 	}
599*5544Sfw157321 	log_printf("%-9s", buf);
6003941Svenki }
6013941Svenki 
6023941Svenki /*
6034669Sfw157321  * Enumerate banks and dimms within a memory segment.  We're handed
6044669Sfw157321  * the first bank within the segment - we assume there are dimms
6054669Sfw157321  * (memory-module) nodes underneath.
6063941Svenki  */
6073941Svenki static void
6084669Sfw157321 print_memory_segment_contain(picl_nodehdl_t bank_nodeh)
6091708Sstevel {
6103941Svenki 	char val[PICL_PROPNAMELEN_MAX];
6114669Sfw157321 	picl_nodehdl_t module_nodeh;
6124669Sfw157321 	int flag = 0;
613*5544Sfw157321 	uint64_t size;
6144669Sfw157321 
6154669Sfw157321 	do {
6164669Sfw157321 		if (picl_get_propval_by_name(bank_nodeh, PICL_PROP_CHILD,
6174669Sfw157321 		    &module_nodeh, sizeof (picl_nodehdl_t)) != PICL_SUCCESS)
6184669Sfw157321 			continue;
619*5544Sfw157321 		if (picl_get_propval_by_name(bank_nodeh, PICL_PROP_SIZE,
620*5544Sfw157321 		    &size, sizeof (size)) == PICL_SUCCESS) {
621*5544Sfw157321 			if (!flag) {
622*5544Sfw157321 				print_memory_segment_size(size);
623*5544Sfw157321 			} else {
624*5544Sfw157321 				log_printf("                "
625*5544Sfw157321 				    "                    ");
626*5544Sfw157321 				print_memory_segment_size(size);
627*5544Sfw157321 				flag = 0;
628*5544Sfw157321 			}
629*5544Sfw157321 		}
6304669Sfw157321 		do {
6314669Sfw157321 			if (picl_get_propval_by_name(module_nodeh,
6324669Sfw157321 			    PICL_PROP_NAC, val, sizeof (val)) !=
6334669Sfw157321 			    PICL_SUCCESS)
6344669Sfw157321 				continue;
6354669Sfw157321 			else {
6364669Sfw157321 				if (!flag) {
637*5544Sfw157321 					log_printf("%s\n", val);
6384669Sfw157321 					flag = 1;
639*5544Sfw157321 				} else {
640*5544Sfw157321 					log_printf("%s%s\n",
641*5544Sfw157321 					    "                       "
642*5544Sfw157321 					    "                      ",
643*5544Sfw157321 					    val);
644*5544Sfw157321 				}
6454669Sfw157321 			}
6464669Sfw157321 		} while (picl_get_propval_by_name(module_nodeh, PICL_PROP_PEER,
6474669Sfw157321 		    &module_nodeh, sizeof (picl_nodehdl_t)) ==
6484669Sfw157321 		    PICL_SUCCESS);
6494669Sfw157321 	} while (picl_get_propval_by_name(bank_nodeh, PICL_PROP_PEER,
6504669Sfw157321 	    &bank_nodeh, sizeof (picl_nodehdl_t)) == PICL_SUCCESS);
6513941Svenki }
6523941Svenki 
6533941Svenki /*
6543941Svenki  * Search node where _class=="memory-segment"
6553941Svenki  * print "Base Address", "Size", etc
6563941Svenki  */
6573941Svenki /*ARGSUSED*/
6583941Svenki static int
6593941Svenki sun4v_memory_conf_callback(picl_nodehdl_t nodeh, void *args)
6603941Svenki {
6613941Svenki 	uint64_t base;
6623941Svenki 	uint64_t size;
6633941Svenki 	uint64_t ifactor;
6643941Svenki 	picl_errno_t err = PICL_SUCCESS;
6653941Svenki 
6663941Svenki 	if (class_node_found == 0) {
6673941Svenki 		class_node_found = 1;
6683941Svenki 		return (PICL_WALK_TERMINATE);
6693941Svenki 	}
6703941Svenki 	while (err == PICL_SUCCESS) {
6713941Svenki 		err = picl_get_propval_by_name(nodeh, PICL_PROP_BASEADDRESS,
6724669Sfw157321 		    &base, sizeof (base));
6733941Svenki 		if (err !=  PICL_SUCCESS)
6743941Svenki 			break;
6753941Svenki 		err = picl_get_propval_by_name(nodeh, PICL_PROP_SIZE,
6764669Sfw157321 		    &size, sizeof (size));
6773941Svenki 		if (err !=  PICL_SUCCESS)
6783941Svenki 			break;
6793941Svenki 		err = picl_get_propval_by_name(nodeh,
6804669Sfw157321 		    PICL_PROP_INTERLEAVE_FACTOR, &ifactor,
6814669Sfw157321 		    sizeof (ifactor));
6823941Svenki 		if (err !=  PICL_SUCCESS)
6833941Svenki 			break;
684*5544Sfw157321 		log_printf("0x%-13llx", base);
6853941Svenki 		print_memory_segment_size(size);
686*5544Sfw157321 		log_printf("%-12lld", ifactor);
6874669Sfw157321 		err = picl_get_propval_by_name(nodeh, PICL_PROP_CHILD,
6884669Sfw157321 		    &nodeh, sizeof (nodeh));
6894669Sfw157321 		if (err ==  PICL_SUCCESS)
6904669Sfw157321 			print_memory_segment_contain(nodeh);
6913941Svenki 		log_printf("\n");
6923941Svenki 		err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, &nodeh,
6934669Sfw157321 		    sizeof (picl_nodehdl_t));
6943941Svenki 	}
6953941Svenki 
6963941Svenki 	return (PICL_WALK_CONTINUE);
6973941Svenki }
6983941Svenki 
6993941Svenki /*ARGSUSED*/
7003941Svenki void
7013941Svenki sun4v_display_memory_conf(picl_nodehdl_t plafh)
7023941Svenki {
703*5544Sfw157321 	char *fmt = "%-14s %-8s %-11s %-8s %-s";
7043941Svenki 	(void) picl_walk_tree_by_class(plafh, PICL_CLASS_MEMORY_SEGMENT,
7054669Sfw157321 	    NULL, sun4v_memory_conf_callback);
7063941Svenki 	if (class_node_found == 0)
7073941Svenki 		return;
7083941Svenki 	log_printf("\n");
709*5544Sfw157321 	log_printf("=======================");
710*5544Sfw157321 	log_printf(" Physical Memory Configuration ");
711*5544Sfw157321 	log_printf("========================");
7123941Svenki 	log_printf("\n");
7133941Svenki 	log_printf("Segment Table:\n");
7144669Sfw157321 	log_printf(
715*5544Sfw157321 	    "--------------------------------------------------------------\n");
716*5544Sfw157321 	log_printf(fmt, "Base", "Segment", "Interleave", "Bank", "Contains", 0);
717*5544Sfw157321 	log_printf("\n");
718*5544Sfw157321 	log_printf(fmt, "Address", "Size", "Factor", "Size", "Modules", 0);
7193941Svenki 	log_printf("\n");
7204669Sfw157321 	log_printf(
721*5544Sfw157321 	    "--------------------------------------------------------------\n");
7223941Svenki 	(void) picl_walk_tree_by_class(plafh, PICL_CLASS_MEMORY_SEGMENT,
7234669Sfw157321 	    NULL, sun4v_memory_conf_callback);
7241708Sstevel }
7251708Sstevel 
7261708Sstevel void
7271708Sstevel sun4v_display_cpu_devices(picl_nodehdl_t plafh)
7281708Sstevel {
729*5544Sfw157321 	char *fmt = "%-6s %-9s %-22s %-6s";
7301708Sstevel 
7311708Sstevel 	/*
7321708Sstevel 	 * Display the table header for CPUs . Then display the CPU
7331708Sstevel 	 * frequency, cache size, and processor revision of all cpus.
7341708Sstevel 	 */
7351708Sstevel 	log_printf(dgettext(TEXT_DOMAIN,
7364669Sfw157321 	    "\n"
737*5544Sfw157321 	    "================================"
738*5544Sfw157321 	    " Virtual CPUs "
739*5544Sfw157321 	    "================================"
7404669Sfw157321 	    "\n"
7414669Sfw157321 	    "\n"));
7421708Sstevel 	log_printf("\n");
743*5544Sfw157321 	log_printf(fmt, "CPU ID", "Frequency", "Implementation",
744*5544Sfw157321 	    "Status", 0);
7451708Sstevel 	log_printf("\n");
746*5544Sfw157321 	log_printf(fmt, "------", "---------",
747*5544Sfw157321 	    "----------------------", "-------", 0);
7481708Sstevel 	log_printf("\n");
7491708Sstevel 
750*5544Sfw157321 	(void) picl_walk_tree_by_class(plafh, PICL_CLASS_CPU, PICL_CLASS_CPU,
751*5544Sfw157321 	    sun4v_display_cpus);
7521708Sstevel }
7531708Sstevel 
7541708Sstevel /*
7551708Sstevel  * Display the CPUs present on this board.
7561708Sstevel  */
7571708Sstevel /*ARGSUSED*/
7581708Sstevel int
7591708Sstevel sun4v_display_cpus(picl_nodehdl_t cpuh, void* args)
7601708Sstevel {
7611708Sstevel 	int status;
7623941Svenki 	picl_prophdl_t proph;
7633941Svenki 	picl_prophdl_t tblh;
7643941Svenki 	picl_prophdl_t rowproph;
7651708Sstevel 	picl_propinfo_t propinfo;
7663941Svenki 	int *int_value;
7675028Sfw157321 	int cpuid;
7683941Svenki 	char *comp_value;
7693941Svenki 	char *no_prop_value = "   ";
7703941Svenki 	char freq_str[MAXSTRLEN];
7715028Sfw157321 	char state[MAXSTRLEN];
7721708Sstevel 
7731708Sstevel 	/*
7741708Sstevel 	 * Get cpuid property and print it and the NAC name
7751708Sstevel 	 */
776*5544Sfw157321 	status = picl_get_propinfo_by_name(cpuh, OBP_PROP_CPUID, &propinfo,
777*5544Sfw157321 	    &proph);
7781708Sstevel 	if (status == PICL_SUCCESS) {
7791708Sstevel 		status = picl_get_propval(proph, &cpuid, sizeof (cpuid));
7801708Sstevel 		if (status != PICL_SUCCESS) {
781*5544Sfw157321 			log_printf("%-7s", no_prop_value);
7821708Sstevel 		} else {
783*5544Sfw157321 			log_printf("%-7d", cpuid);
7841708Sstevel 		}
7851708Sstevel 	} else {
786*5544Sfw157321 		log_printf("%-7s", no_prop_value);
7871708Sstevel 	}
7881708Sstevel 
7891708Sstevel clock_freq:
7901708Sstevel 	status = picl_get_propinfo_by_name(cpuh, "clock-frequency", &propinfo,
7914669Sfw157321 	    &proph);
7921708Sstevel 	if (status == PICL_SUCCESS) {
7931708Sstevel 		int_value = malloc(propinfo.size);
7941708Sstevel 		if (int_value == NULL) {
795*5544Sfw157321 			log_printf("%-10s", no_prop_value);
7961708Sstevel 			goto compatible;
7971708Sstevel 		}
7981708Sstevel 		status = picl_get_propval(proph, int_value, propinfo.size);
7991708Sstevel 		if (status != PICL_SUCCESS) {
800*5544Sfw157321 			log_printf("%-10s", no_prop_value);
8011708Sstevel 		} else {
8021708Sstevel 			/* Running frequency */
8031708Sstevel 			(void) snprintf(freq_str, sizeof (freq_str), "%d MHz",
8041708Sstevel 			    CLK_FREQ_TO_MHZ(*int_value));
805*5544Sfw157321 			log_printf("%-10s", freq_str);
8061708Sstevel 		}
8071708Sstevel 		free(int_value);
8081708Sstevel 	} else
809*5544Sfw157321 		log_printf("%-10s", no_prop_value);
8101708Sstevel 
8111708Sstevel compatible:
8121708Sstevel 	status = picl_get_propinfo_by_name(cpuh, "compatible", &propinfo,
8134669Sfw157321 	    &proph);
8141708Sstevel 	if (status == PICL_SUCCESS) {
8151708Sstevel 		if (propinfo.type == PICL_PTYPE_CHARSTRING) {
8161708Sstevel 			/*
8171708Sstevel 			 * Compatible Property only has 1 value
8181708Sstevel 			 */
8191708Sstevel 			comp_value = malloc(propinfo.size);
8201708Sstevel 			if (comp_value == NULL) {
821*5544Sfw157321 				log_printf("%-23s", no_prop_value, 0);
8225028Sfw157321 				goto state;
8231708Sstevel 			}
8241708Sstevel 			status = picl_get_propval(proph, comp_value,
8254669Sfw157321 			    propinfo.size);
8263941Svenki 			if (status != PICL_SUCCESS)
827*5544Sfw157321 				log_printf("%-23s", no_prop_value, 0);
8283941Svenki 			else
829*5544Sfw157321 				log_printf("%-23s", comp_value, 0);
8303941Svenki 			free(comp_value);
8311708Sstevel 		} else if (propinfo.type == PICL_PTYPE_TABLE) {
8321708Sstevel 			/*
8331708Sstevel 			 * Compatible Property has multiple values
8341708Sstevel 			 */
8351708Sstevel 			status = picl_get_propval(proph, &tblh, propinfo.size);
8361708Sstevel 			if (status != PICL_SUCCESS) {
837*5544Sfw157321 				log_printf("%-23s", no_prop_value, 0);
8385028Sfw157321 				goto state;
8391708Sstevel 			}
8401708Sstevel 			status = picl_get_next_by_row(tblh, &rowproph);
8411708Sstevel 			if (status != PICL_SUCCESS) {
842*5544Sfw157321 				log_printf("%-23s", no_prop_value, 0);
8435028Sfw157321 				goto state;
8441708Sstevel 			}
8451708Sstevel 
8461708Sstevel 			status = picl_get_propinfo(rowproph, &propinfo);
8471708Sstevel 			if (status != PICL_SUCCESS) {
848*5544Sfw157321 				log_printf("%-23s", no_prop_value, 0);
8495028Sfw157321 				goto state;
8501708Sstevel 			}
8511708Sstevel 
8521708Sstevel 			comp_value = malloc(propinfo.size);
8531708Sstevel 			if (comp_value == NULL) {
854*5544Sfw157321 				log_printf("%-23s", no_prop_value, 0);
8555028Sfw157321 				goto state;
8561708Sstevel 			}
8571708Sstevel 			status = picl_get_propval(rowproph, comp_value,
8584669Sfw157321 			    propinfo.size);
8593941Svenki 			if (status != PICL_SUCCESS)
860*5544Sfw157321 				log_printf("%-23s", no_prop_value, 0);
8613941Svenki 			else
862*5544Sfw157321 				log_printf("%-23s", comp_value, 0);
8631708Sstevel 			free(comp_value);
8641708Sstevel 		}
8651708Sstevel 	} else
866*5544Sfw157321 		log_printf("%-23s", no_prop_value, 0);
8671708Sstevel 
8685028Sfw157321 state:
8695028Sfw157321 	status = picl_get_propinfo_by_name(cpuh, PICL_PROP_STATE,
8705028Sfw157321 	    &propinfo, &proph);
8711708Sstevel 	if (status == PICL_SUCCESS) {
8725028Sfw157321 		status = picl_get_propval(proph, state, sizeof (state));
8731708Sstevel 		if (status != PICL_SUCCESS) {
8743941Svenki 			log_printf("%-9s", no_prop_value);
8751708Sstevel 		} else {
8765028Sfw157321 			log_printf("%-9s", state);
8771708Sstevel 		}
8781708Sstevel 	} else
8793941Svenki 		log_printf("%-9s", no_prop_value);
8801708Sstevel 
8811708Sstevel done:
8821708Sstevel 	log_printf("\n");
8831708Sstevel 	return (PICL_WALK_CONTINUE);
8841708Sstevel }
8851708Sstevel 
8861708Sstevel void
8871708Sstevel sun4v_display_diaginfo(int flag, Prom_node *root, picl_nodehdl_t plafh)
8881708Sstevel {
8891708Sstevel #ifdef	lint
8901708Sstevel 	flag = flag;
8911708Sstevel 	root = root;
8921708Sstevel 	plafh = plafh;
8931708Sstevel #endif
8941708Sstevel 	/*
8951708Sstevel 	 * This function is intentionally empty
8961708Sstevel 	 */
8971708Sstevel }
8981708Sstevel 
8991708Sstevel void
9001708Sstevel display_boardnum(int num)
9011708Sstevel {
9021708Sstevel 	log_printf("%2d   ", num, 0);
9031708Sstevel }
9043941Svenki 
9053941Svenki static void
9063941Svenki sun4v_disp_env_status()
9073941Svenki {
9083941Svenki 	if (phyplatformh == 0)
9093941Svenki 		return;
9103941Svenki 	log_printf("\n");
9113941Svenki 	log_printf("============================");
9123941Svenki 	log_printf(" Environmental Status ");
9133941Svenki 	log_printf("============================");
9143941Svenki 	log_printf("\n");
9153941Svenki 
9163941Svenki 	class_node_found = 0;
9173941Svenki 	all_status_ok = 1;
9183941Svenki 	sun4v_env_print_fan_sensors();
9193941Svenki 
9203941Svenki 	class_node_found = 0;
9213941Svenki 	all_status_ok = 1;
9223941Svenki 	sun4v_env_print_fan_indicators();
9233941Svenki 
9243941Svenki 	class_node_found = 0;
9253941Svenki 	all_status_ok = 1;
9263941Svenki 	sun4v_env_print_temp_sensors();
9273941Svenki 
9283941Svenki 	class_node_found = 0;
9293941Svenki 	all_status_ok = 1;
9303941Svenki 	sun4v_env_print_temp_indicators();
9313941Svenki 
9323941Svenki 	class_node_found = 0;
9333941Svenki 	all_status_ok = 1;
9343941Svenki 	sun4v_env_print_current_sensors();
9353941Svenki 
9363941Svenki 	class_node_found = 0;
9373941Svenki 	all_status_ok = 1;
9383941Svenki 	sun4v_env_print_current_indicators();
9393941Svenki 
9403941Svenki 	class_node_found = 0;
9413941Svenki 	all_status_ok = 1;
9423941Svenki 	sun4v_env_print_voltage_sensors();
9433941Svenki 
9443941Svenki 	class_node_found = 0;
9453941Svenki 	all_status_ok = 1;
9463941Svenki 	sun4v_env_print_voltage_indicators();
9473941Svenki 
9483941Svenki 	class_node_found = 0;
9493941Svenki 	sun4v_env_print_LEDs();
9503941Svenki 
9513941Svenki 	class_node_found = 0;
9523941Svenki 	all_status_ok = 1;
9533941Svenki 	sun4v_print_fru_status();
9543941Svenki 
9553941Svenki 	class_node_found = 0;
9563941Svenki 	sun4v_print_fw_rev();
9573941Svenki 
9585436Sfw157321 	class_node_found = 0;
9595436Sfw157321 	sun4v_print_openprom_rev();
9605436Sfw157321 
9613941Svenki 	sun4v_print_chassis_serial_no();
9623941Svenki }
9633941Svenki 
9643941Svenki /*ARGSUSED*/
9653941Svenki static int
9663941Svenki sun4v_env_print_sensor_callback(picl_nodehdl_t nodeh, void *args)
9673941Svenki {
9683941Svenki 	char val[PICL_PROPNAMELEN_MAX];
9693941Svenki 	picl_nodehdl_t parenth;
9703941Svenki 	char *names[PARENT_NAMES];
9714802Sfw157321 	char *base_units[PICL_PROPNAMELEN_MAX];
9723941Svenki 	char *loc;
9733941Svenki 	int i;
9743941Svenki 	char *prop;
9753941Svenki 	picl_errno_t err;
9765436Sfw157321 	int32_t lo_warning, lo_shutdown, lo_poweroff;
9775436Sfw157321 	int32_t hi_warning, hi_shutdown, hi_poweroff;
9783941Svenki 	int32_t current_val;
9794802Sfw157321 	int32_t exponent;
9804802Sfw157321 	double display_val;
9814928Sfw157321 	typedef enum {SENSOR_OK, SENSOR_WARN, SENSOR_FAILED,
9824928Sfw157321 	    SENSOR_DISABLED, SENSOR_UNKNOWN} sensor_status_t;
9834928Sfw157321 	sensor_status_t sensor_status = SENSOR_OK;
9843941Svenki 
9853941Svenki 	if (class_node_found == 0) {
9863941Svenki 		class_node_found = 1;
9873941Svenki 		return (PICL_WALK_TERMINATE);
9883941Svenki 	}
9893941Svenki 
9904928Sfw157321 	prop = (char *)args;
9914928Sfw157321 	if (!prop) {
9924928Sfw157321 		sensor_status = SENSOR_UNKNOWN;
9934928Sfw157321 		all_status_ok = 0;
9944928Sfw157321 	} else {
9953941Svenki 		err = picl_get_propval_by_name(nodeh,
9964669Sfw157321 		    PICL_PROP_OPERATIONAL_STATUS, val,
9974669Sfw157321 		    sizeof (val));
9983941Svenki 		if (err == PICL_SUCCESS) {
9993941Svenki 			if (strcmp(val, "disabled") == 0) {
10004928Sfw157321 				sensor_status = SENSOR_DISABLED;
10014928Sfw157321 			}
10024928Sfw157321 		}
10034928Sfw157321 	}
10044928Sfw157321 
10054928Sfw157321 	if (sensor_status != SENSOR_DISABLED &&
10064928Sfw157321 	    sensor_status != SENSOR_UNKNOWN) {
10074928Sfw157321 		if (picl_get_propval_by_name(nodeh, prop, &current_val,
10084928Sfw157321 		    sizeof (current_val)) != PICL_SUCCESS) {
10094928Sfw157321 			sensor_status = SENSOR_UNKNOWN;
10105436Sfw157321 		} else {
10115436Sfw157321 			if (picl_get_propval_by_name(nodeh,
10125436Sfw157321 			    PICL_PROP_LOW_WARNING,
10135436Sfw157321 			    &lo_warning, sizeof (lo_warning)) != PICL_SUCCESS)
10145436Sfw157321 				lo_warning = INVALID_THRESHOLD;
10155436Sfw157321 			if (picl_get_propval_by_name(nodeh,
10165436Sfw157321 			    PICL_PROP_LOW_SHUTDOWN,
10175436Sfw157321 			    &lo_shutdown, sizeof (lo_shutdown)) != PICL_SUCCESS)
10185436Sfw157321 				lo_shutdown = INVALID_THRESHOLD;
10195436Sfw157321 			if (picl_get_propval_by_name(nodeh,
10205436Sfw157321 			    PICL_PROP_LOW_POWER_OFF,
10215436Sfw157321 			    &lo_poweroff, sizeof (lo_poweroff)) != PICL_SUCCESS)
10225436Sfw157321 				lo_poweroff = INVALID_THRESHOLD;
10235436Sfw157321 			if (picl_get_propval_by_name(nodeh,
10245436Sfw157321 			    PICL_PROP_HIGH_WARNING,
10255436Sfw157321 			    &hi_warning, sizeof (hi_warning)) != PICL_SUCCESS)
10265436Sfw157321 				hi_warning = INVALID_THRESHOLD;
10275436Sfw157321 			if (picl_get_propval_by_name(nodeh,
10285436Sfw157321 			    PICL_PROP_HIGH_SHUTDOWN,
10295436Sfw157321 			    &hi_shutdown, sizeof (hi_shutdown)) != PICL_SUCCESS)
10305436Sfw157321 				hi_shutdown = INVALID_THRESHOLD;
10315436Sfw157321 			if (picl_get_propval_by_name(nodeh,
10325436Sfw157321 			    PICL_PROP_HIGH_POWER_OFF,
10335436Sfw157321 			    &hi_poweroff, sizeof (hi_poweroff)) != PICL_SUCCESS)
10345436Sfw157321 				hi_poweroff = INVALID_THRESHOLD;
10354928Sfw157321 
10365436Sfw157321 			if ((lo_poweroff != INVALID_THRESHOLD &&
10375436Sfw157321 			    current_val <= lo_poweroff) ||
10385436Sfw157321 			    (hi_poweroff != INVALID_THRESHOLD &&
10395436Sfw157321 			    current_val >= hi_poweroff)) {
10405436Sfw157321 				sensor_status = SENSOR_FAILED;
10415436Sfw157321 			} else if ((lo_shutdown != INVALID_THRESHOLD &&
10425436Sfw157321 			    current_val <= lo_shutdown) ||
10435436Sfw157321 			    (hi_shutdown != INVALID_THRESHOLD &&
10445436Sfw157321 			    current_val >= hi_shutdown)) {
10455436Sfw157321 				sensor_status = SENSOR_FAILED;
10465436Sfw157321 			} else if ((lo_warning != INVALID_THRESHOLD &&
10475436Sfw157321 			    current_val <= lo_warning) ||
10485436Sfw157321 			    (hi_warning != INVALID_THRESHOLD &&
10495436Sfw157321 			    current_val >= hi_warning)) {
10505436Sfw157321 				sensor_status = SENSOR_WARN;
10515436Sfw157321 			} else {
10525436Sfw157321 				sensor_status = SENSOR_OK;
10535436Sfw157321 			}
10544928Sfw157321 		}
10554928Sfw157321 	}
10564928Sfw157321 
10574928Sfw157321 	if (syserrlog == 0) {
10584928Sfw157321 		if (sensor_status != SENSOR_OK && all_status_ok == 1) {
10593941Svenki 			all_status_ok = 0;
10603941Svenki 			return (PICL_WALK_TERMINATE);
10613941Svenki 		}
10624928Sfw157321 		if (sensor_status == SENSOR_OK) {
10634928Sfw157321 			return (PICL_WALK_CONTINUE);
10644928Sfw157321 		}
10653941Svenki 	}
10664928Sfw157321 
10674928Sfw157321 	/*
10684928Sfw157321 	 * If we're here then prtdiag was invoked with "-v" or we have
10694928Sfw157321 	 * a sensor that is beyond a threshold, so give them a book to
10704928Sfw157321 	 * read instead of the Cliff Notes.
10714928Sfw157321 	 */
10723941Svenki 	err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, &parenth,
10734669Sfw157321 	    sizeof (parenth));
10743941Svenki 	if (err != PICL_SUCCESS) {
10753941Svenki 		log_printf("\n");
10763941Svenki 		return (PICL_WALK_CONTINUE);
10773941Svenki 	}
10784003Svivek 
10794928Sfw157321 	/* gather up the path name for the sensor */
10804928Sfw157321 	if ((loc = (char *)malloc(PICL_PROPNAMELEN_MAX*PARENT_NAMES)) != NULL) {
10814928Sfw157321 		for (i = 0; i < PARENT_NAMES; i++) {
10824928Sfw157321 			if ((names[i] = (char *)malloc(PICL_PROPNAMELEN_MAX)) ==
10834928Sfw157321 			    NULL) {
10844928Sfw157321 				while (--i > -1)
10854928Sfw157321 					free(names[i]);
10864928Sfw157321 				free(loc);
10874928Sfw157321 				loc = NULL;
10884928Sfw157321 			}
10893941Svenki 		}
10904003Svivek 	}
10914928Sfw157321 	i = 0;
10924928Sfw157321 	if (loc != 0) {
10934928Sfw157321 		while (err == PICL_SUCCESS) {
10944928Sfw157321 			if (parenth == phyplatformh)
10954928Sfw157321 				break;
10964928Sfw157321 			err = picl_get_propval_by_name(parenth, PICL_PROP_NAME,
10974928Sfw157321 			    names[i++], PICL_PROPNAMELEN_MAX);
10984928Sfw157321 			if (err != PICL_SUCCESS) {
10994928Sfw157321 				i--;
11004928Sfw157321 				break;
11014928Sfw157321 			}
11024928Sfw157321 			if (i == PARENT_NAMES)
11034928Sfw157321 				break;
11044928Sfw157321 			err = picl_get_propval_by_name(parenth,
11054928Sfw157321 			    PICL_PROP_PARENT, &parenth, sizeof (parenth));
11064928Sfw157321 		}
11074928Sfw157321 		loc[0] = '\0';
11084928Sfw157321 		if (--i > -1) {
11094928Sfw157321 			(void) strlcat(loc, names[i],
11104928Sfw157321 			    PICL_PROPNAMELEN_MAX * PARENT_NAMES);
11114928Sfw157321 		}
11124928Sfw157321 		while (--i > -1) {
11134928Sfw157321 			(void) strlcat(loc, "/", PICL_PROPNAMELEN_MAX *
11144928Sfw157321 			    PARENT_NAMES);
11154928Sfw157321 			(void) strlcat(loc, names[i],
11164928Sfw157321 			    PICL_PROPNAMELEN_MAX * PARENT_NAMES);
11174928Sfw157321 		}
11185028Sfw157321 		log_printf("%-35s", loc);
11194928Sfw157321 		for (i = 0; i < PARENT_NAMES; i++)
11204928Sfw157321 			free(names[i]);
11214928Sfw157321 		free(loc);
11224928Sfw157321 	} else {
11235028Sfw157321 		log_printf("%-35s", " ");
11243941Svenki 	}
11253941Svenki 	err = picl_get_propval_by_name(nodeh, PICL_PROP_LABEL, val,
11264669Sfw157321 	    sizeof (val));
11273941Svenki 	if (err == PICL_SUCCESS)
11283941Svenki 		log_printf("%-15s", val);
11293941Svenki 
11304928Sfw157321 	/*
11314928Sfw157321 	 * Get the exponent if present, and do a little math so that
11324928Sfw157321 	 * if we need to we can print a normalized value for the
11334928Sfw157321 	 * sensor reading.
11344928Sfw157321 	 */
11354802Sfw157321 	if (picl_get_propval_by_name(nodeh, PICL_PROP_EXPONENT,
11364802Sfw157321 	    &exponent, sizeof (exponent)) != PICL_SUCCESS)
11374802Sfw157321 		exponent = 0;
11384802Sfw157321 	if (exponent == 0)
11394802Sfw157321 		display_val = (double)current_val;
11405436Sfw157321 	else {
11414802Sfw157321 		display_val = (double)current_val *
11424802Sfw157321 		    pow((double)10, (double)exponent);
11435436Sfw157321 
11445436Sfw157321 		/*
11455436Sfw157321 		 * Sometimes ILOM will scale a sensor reading but
11465436Sfw157321 		 * there will be nothing to the right of the decimal
11475436Sfw157321 		 * once that value is normalized.  Setting the
11485436Sfw157321 		 * exponent to zero will prevent the printf below
11495436Sfw157321 		 * from printing extraneous zeros.  Otherwise a
11505436Sfw157321 		 * negative exponent is used to set the precision
11515436Sfw157321 		 * for the printf.
11525436Sfw157321 		 */
11535436Sfw157321 		if ((int)display_val == display_val || exponent > 0)
11545436Sfw157321 			exponent = 0;
11555436Sfw157321 	}
11565436Sfw157321 
11574928Sfw157321 	err = picl_get_propval_by_name(nodeh, PICL_PROP_BASE_UNITS,
11584928Sfw157321 	    base_units, sizeof (base_units));
11594802Sfw157321 	if (err != PICL_SUCCESS)
11604802Sfw157321 		base_units[0] = '\0';
11613941Svenki 
11624928Sfw157321 	switch (sensor_status) {
11634928Sfw157321 	case SENSOR_FAILED:
11643941Svenki 		log_printf("%-s", "failed (");
11654802Sfw157321 		log_printf("%-.*f", abs(exponent), display_val);
11664802Sfw157321 		log_printf("%-s %s", base_units, ")");
11674928Sfw157321 		break;
11684928Sfw157321 	case SENSOR_WARN:
11693941Svenki 		log_printf("%-s", "warning (");
11704802Sfw157321 		log_printf("%-.*f", abs(exponent), display_val);
11714802Sfw157321 		log_printf("%-s %s", base_units, ")");
11724928Sfw157321 		break;
11734928Sfw157321 	case SENSOR_DISABLED:
11744928Sfw157321 		log_printf("%-s", "disabled");
11754928Sfw157321 		break;
11764928Sfw157321 	case SENSOR_OK:
11773941Svenki 		log_printf("%-s", "ok");
11784928Sfw157321 		break;
11794928Sfw157321 	default:
11804928Sfw157321 		log_printf("%-s", "unknown");
11814928Sfw157321 		break;
11824928Sfw157321 	}
11833941Svenki 
11843941Svenki 	log_printf("\n");
11853941Svenki 	return (PICL_WALK_CONTINUE);
11863941Svenki }
11873941Svenki 
11883941Svenki /*ARGSUSED*/
11893941Svenki static int
11903941Svenki sun4v_env_print_indicator_callback(picl_nodehdl_t nodeh, void *args)
11913941Svenki {
11924928Sfw157321 	char current_val[PICL_PROPNAMELEN_MAX];
11934928Sfw157321 	char expected_val[PICL_PROPNAMELEN_MAX];
11944928Sfw157321 	char label[PICL_PROPNAMELEN_MAX];
11953941Svenki 	picl_nodehdl_t parenth;
11963941Svenki 	char *names[PARENT_NAMES];
11973941Svenki 	char *loc;
11983941Svenki 	int i = 0;
11993941Svenki 	char *prop = (char *)args;
12003941Svenki 	picl_errno_t err = PICL_SUCCESS;
12014928Sfw157321 	typedef enum {SENSOR_OK, SENSOR_WARN, SENSOR_FAILED,
12024928Sfw157321 	    SENSOR_DISABLED, SENSOR_UNKNOWN} sensor_status_t;
12034928Sfw157321 	sensor_status_t sensor_status = SENSOR_OK;
12043941Svenki 
12053941Svenki 	if (class_node_found == 0) {
12063941Svenki 		class_node_found = 1;
12073941Svenki 		return (PICL_WALK_TERMINATE);
12083941Svenki 	}
12094928Sfw157321 
12104928Sfw157321 	prop = (char *)args;
12114928Sfw157321 	if (!prop) {
12124928Sfw157321 		sensor_status = SENSOR_UNKNOWN;
12134928Sfw157321 		all_status_ok = 0;
12144928Sfw157321 	} else {
12153941Svenki 		err = picl_get_propval_by_name(nodeh,
12164928Sfw157321 		    PICL_PROP_OPERATIONAL_STATUS, current_val,
12174928Sfw157321 		    sizeof (current_val));
12183941Svenki 		if (err == PICL_SUCCESS) {
12194928Sfw157321 			if (strcmp(current_val, "disabled") == 0) {
12204928Sfw157321 				sensor_status = SENSOR_DISABLED;
12214928Sfw157321 			}
12224928Sfw157321 		}
12234928Sfw157321 	}
12244928Sfw157321 
12254928Sfw157321 	if (sensor_status != SENSOR_DISABLED &&
12264928Sfw157321 	    sensor_status != SENSOR_UNKNOWN) {
12274928Sfw157321 		if (picl_get_propval_by_name(nodeh, prop, &current_val,
12284928Sfw157321 		    sizeof (current_val)) != PICL_SUCCESS) {
12294928Sfw157321 			(void) strlcpy(current_val, "unknown",
12304928Sfw157321 			    sizeof (current_val));
12314928Sfw157321 			sensor_status = SENSOR_UNKNOWN;
12324928Sfw157321 		} else {
12334928Sfw157321 			if (picl_get_propval_by_name(nodeh, PICL_PROP_EXPECTED,
12344928Sfw157321 			    &expected_val, sizeof (expected_val)) !=
12354928Sfw157321 			    PICL_SUCCESS) {
12364928Sfw157321 				sensor_status = SENSOR_UNKNOWN;
12374928Sfw157321 			} else {
12384928Sfw157321 				if (strncmp(current_val, expected_val,
12394928Sfw157321 				    sizeof (current_val)) == 0) {
12404928Sfw157321 					sensor_status = SENSOR_OK;
12414928Sfw157321 				} else {
12424928Sfw157321 					sensor_status = SENSOR_FAILED;
12433941Svenki 				}
12444928Sfw157321 			}
12454928Sfw157321 		}
12464928Sfw157321 	}
12474928Sfw157321 
12484928Sfw157321 	if (syserrlog == 0) {
12494928Sfw157321 		if (sensor_status != SENSOR_OK && all_status_ok == 1) {
12503941Svenki 			all_status_ok = 0;
12513941Svenki 			return (PICL_WALK_TERMINATE);
12523941Svenki 		}
12534928Sfw157321 		if (sensor_status == SENSOR_OK) {
12544928Sfw157321 			return (PICL_WALK_CONTINUE);
12554928Sfw157321 		}
12563941Svenki 	}
12574928Sfw157321 
12584928Sfw157321 	/*
12594928Sfw157321 	 * If we're here then prtdiag was invoked with "-v" or we have
12604928Sfw157321 	 * a sensor that is beyond a threshold, so give them a book to
12614928Sfw157321 	 * read instead of the Cliff Notes.
12624928Sfw157321 	 */
12633941Svenki 	err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, &parenth,
12644669Sfw157321 	    sizeof (parenth));
12653941Svenki 	if (err != PICL_SUCCESS) {
12663941Svenki 		log_printf("\n");
12673941Svenki 		return (PICL_WALK_CONTINUE);
12683941Svenki 	}
12694928Sfw157321 	if ((loc = (char *)malloc(PICL_PROPNAMELEN_MAX*PARENT_NAMES)) != NULL) {
12704928Sfw157321 		for (i = 0; i < PARENT_NAMES; i++) {
12714928Sfw157321 			if ((names[i] = (char *)malloc(PICL_PROPNAMELEN_MAX)) ==
12724928Sfw157321 			    NULL) {
12734928Sfw157321 				while (--i > -1)
12744928Sfw157321 					free(names[i]);
12754928Sfw157321 				free(loc);
12764928Sfw157321 				loc = NULL;
12774928Sfw157321 			}
12783941Svenki 		}
12793941Svenki 	}
12804928Sfw157321 	i = 0;
12814928Sfw157321 	if (loc) {
12824928Sfw157321 		while (err == PICL_SUCCESS) {
12834928Sfw157321 			if (parenth == phyplatformh)
12844928Sfw157321 				break;
12854928Sfw157321 			err = picl_get_propval_by_name(parenth, PICL_PROP_NAME,
12864928Sfw157321 			    names[i++], PICL_PROPNAMELEN_MAX);
12874928Sfw157321 			if (err != PICL_SUCCESS) {
12884928Sfw157321 				i--;
12894928Sfw157321 				break;
12904928Sfw157321 			}
12914928Sfw157321 			if (i == PARENT_NAMES)
12924928Sfw157321 				break;
12934928Sfw157321 			err = picl_get_propval_by_name(parenth,
12944928Sfw157321 			    PICL_PROP_PARENT, &parenth, sizeof (parenth));
12954928Sfw157321 		}
12964928Sfw157321 		loc[0] = '\0';
12974928Sfw157321 		if (--i > -1) {
12984928Sfw157321 			(void) strlcat(loc, names[i],
12994928Sfw157321 			    PICL_PROPNAMELEN_MAX * PARENT_NAMES);
13004928Sfw157321 		}
13014928Sfw157321 		while (--i > -1) {
13024928Sfw157321 			(void) strlcat(loc, "/", PICL_PROPNAMELEN_MAX *
13034928Sfw157321 			    PARENT_NAMES);
13044928Sfw157321 			(void) strlcat(loc, names[i],
13054928Sfw157321 			    PICL_PROPNAMELEN_MAX * PARENT_NAMES);
13064928Sfw157321 		}
13075028Sfw157321 		log_printf("%-35s", loc);
13084928Sfw157321 		for (i = 0; i < PARENT_NAMES; i++)
13094928Sfw157321 			free(names[i]);
13104928Sfw157321 		free(loc);
13114928Sfw157321 	} else {
13125028Sfw157321 		log_printf("%-35s", "");
13133941Svenki 	}
13144928Sfw157321 
13154928Sfw157321 	err = picl_get_propval_by_name(nodeh, PICL_PROP_LABEL, label,
13164928Sfw157321 	    sizeof (label));
13174928Sfw157321 	if (err != PICL_SUCCESS)
13184928Sfw157321 		(void) strlcpy(label, "", sizeof (label));
13194928Sfw157321 	log_printf("%-15s", label);
13204928Sfw157321 
13214928Sfw157321 	log_printf("%-8s", current_val);
13224928Sfw157321 
13233941Svenki 	log_printf("\n");
13243941Svenki 	return (PICL_WALK_CONTINUE);
13253941Svenki }
13263941Svenki 
13273941Svenki static void
13283941Svenki sun4v_env_print_fan_sensors()
13293941Svenki {
13305028Sfw157321 	char *fmt = "%-34s %-14s %-10s\n";
13313941Svenki 	/*
13323941Svenki 	 * If there isn't any fan sensor node, return now.
13333941Svenki 	 */
13343941Svenki 	(void) picl_walk_tree_by_class(phyplatformh,
13354928Sfw157321 	    PICL_CLASS_RPM_SENSOR, (void *)PICL_PROP_SPEED,
13364669Sfw157321 	    sun4v_env_print_sensor_callback);
13373941Svenki 	if (!class_node_found)
13383941Svenki 		return;
13393941Svenki 	log_printf("Fan sensors:\n");
13403941Svenki 	if (syserrlog == 0) {
13413941Svenki 		(void) picl_walk_tree_by_class(phyplatformh,
13424669Sfw157321 		    PICL_CLASS_RPM_SENSOR,
13434928Sfw157321 		    PICL_PROP_SPEED, sun4v_env_print_sensor_callback);
13443941Svenki 		if (all_status_ok) {
13453941Svenki 			log_printf("All fan sensors are OK.\n");
13463941Svenki 			return;
13473941Svenki 		}
13483941Svenki 	}
13495028Sfw157321 	log_printf("-------------------------------------------------"
13505028Sfw157321 	    "-----------\n");
13513941Svenki 	log_printf(fmt, "Location", "Sensor", "Status", 0);
13525028Sfw157321 	log_printf("-------------------------------------------------"
13535028Sfw157321 	    "-----------\n");
13543941Svenki 	(void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_RPM_SENSOR,
13554669Sfw157321 	    PICL_PROP_SPEED, sun4v_env_print_sensor_callback);
13563941Svenki }
13573941Svenki 
13583941Svenki static void
13593941Svenki sun4v_env_print_fan_indicators()
13603941Svenki {
13615028Sfw157321 	char *fmt = "%-34s %-14s %-10s\n";
13623941Svenki 	(void) picl_walk_tree_by_class(phyplatformh,
13634928Sfw157321 	    PICL_CLASS_RPM_INDICATOR, (void *)PICL_PROP_CONDITION,
13644669Sfw157321 	    sun4v_env_print_indicator_callback);
13653941Svenki 	if (!class_node_found)
13663941Svenki 		return;
13673941Svenki 	log_printf("\nFan indicators:\n");
13683941Svenki 	if (syserrlog == 0) {
13693941Svenki 		(void) picl_walk_tree_by_class(phyplatformh,
13704669Sfw157321 		    PICL_CLASS_RPM_INDICATOR,
13714928Sfw157321 		    (void *)PICL_PROP_CONDITION,
13724928Sfw157321 		    sun4v_env_print_indicator_callback);
13733941Svenki 		if (all_status_ok) {
13743941Svenki 			log_printf("All fan indicators are OK.\n");
13753941Svenki 			return;
13763941Svenki 		}
13773941Svenki 	}
13785028Sfw157321 	log_printf("-------------------------------------------------"
13795028Sfw157321 	    "-----------\n");
13803941Svenki 	log_printf(fmt, "Location", "Sensor", "Condition", 0);
13815028Sfw157321 	log_printf("-------------------------------------------------"
13825028Sfw157321 	    "-----------\n");
13833941Svenki 	(void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_RPM_INDICATOR,
13844802Sfw157321 	    (void *)PICL_PROP_CONDITION, sun4v_env_print_indicator_callback);
13853941Svenki }
13863941Svenki 
13873941Svenki static void
13883941Svenki sun4v_env_print_temp_sensors()
13893941Svenki {
13905028Sfw157321 	char *fmt = "%-34s %-14s %-10s\n";
13913941Svenki 	(void) picl_walk_tree_by_class(phyplatformh,
13924669Sfw157321 	    PICL_CLASS_TEMPERATURE_SENSOR,
13934669Sfw157321 	    (void *)PICL_PROP_TEMPERATURE,
13944669Sfw157321 	    sun4v_env_print_sensor_callback);
13953941Svenki 	if (!class_node_found)
13963941Svenki 		return;
13973941Svenki 
13983941Svenki 	log_printf("\nTemperature sensors:\n");
13993941Svenki 	if (syserrlog == 0) {
14003941Svenki 		(void) picl_walk_tree_by_class(phyplatformh,
14014669Sfw157321 		    PICL_CLASS_TEMPERATURE_SENSOR,
14024928Sfw157321 		    PICL_PROP_TEMPERATURE, sun4v_env_print_sensor_callback);
14033941Svenki 		if (all_status_ok) {
14043941Svenki 			log_printf("All temperature sensors are OK.\n");
14053941Svenki 			return;
14063941Svenki 		}
14073941Svenki 	}
14085028Sfw157321 	log_printf("-------------------------------------------------"
14095028Sfw157321 	    "-----------\n");
14103941Svenki 	log_printf(fmt, "Location", "Sensor", "Status", 0);
14115028Sfw157321 	log_printf("-------------------------------------------------"
14125028Sfw157321 	    "-----------\n");
14133941Svenki 	(void) picl_walk_tree_by_class(phyplatformh,
14144669Sfw157321 	    PICL_CLASS_TEMPERATURE_SENSOR,
14154669Sfw157321 	    (void *)PICL_PROP_TEMPERATURE, sun4v_env_print_sensor_callback);
14163941Svenki }
14173941Svenki 
14183941Svenki static void
14193941Svenki sun4v_env_print_temp_indicators()
14203941Svenki {
14215028Sfw157321 	char *fmt = "%-34s %-14s %-8s\n";
14223941Svenki 	(void) picl_walk_tree_by_class(phyplatformh,
14234669Sfw157321 	    PICL_CLASS_TEMPERATURE_INDICATOR, (void *)PICL_PROP_CONDITION,
14244669Sfw157321 	    sun4v_env_print_indicator_callback);
14253941Svenki 	if (!class_node_found)
14263941Svenki 		return;
14273941Svenki 	log_printf("\nTemperature indicators:\n");
14283941Svenki 	if (syserrlog == 0) {
14293941Svenki 		(void) picl_walk_tree_by_class(phyplatformh,
14304928Sfw157321 		    PICL_CLASS_TEMPERATURE_INDICATOR,
14314928Sfw157321 		    (void *)PICL_PROP_CONDITION,
14324669Sfw157321 		    sun4v_env_print_indicator_callback);
14333941Svenki 		if (all_status_ok) {
14343941Svenki 			log_printf("All temperature indicators are OK.\n");
14353941Svenki 			return;
14363941Svenki 		}
14373941Svenki 	}
14385028Sfw157321 	log_printf("-------------------------------------------------"
14395028Sfw157321 	    "-----------\n");
14403941Svenki 	log_printf(fmt, "Location", "Indicator", "Condition", 0);
14415028Sfw157321 	log_printf("-------------------------------------------------"
14425028Sfw157321 	    "-----------\n");
14433941Svenki 	(void) picl_walk_tree_by_class(phyplatformh,
14444669Sfw157321 	    PICL_CLASS_TEMPERATURE_INDICATOR,
14454669Sfw157321 	    (void *)PICL_PROP_CONDITION,
14464669Sfw157321 	    sun4v_env_print_indicator_callback);
14473941Svenki }
14483941Svenki 
14493941Svenki static void
14503941Svenki sun4v_env_print_current_sensors()
14513941Svenki {
14525028Sfw157321 	char *fmt = "%-34s %-14s %-10s\n";
14533941Svenki 	(void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_CURRENT_SENSOR,
14544669Sfw157321 	    (void *)PICL_PROP_CURRENT, sun4v_env_print_sensor_callback);
14553941Svenki 	if (!class_node_found)
14563941Svenki 		return;
14573941Svenki 	log_printf("\nCurrent sensors:\n");
14583941Svenki 	if (syserrlog == 0) {
14593941Svenki 		(void) picl_walk_tree_by_class(phyplatformh,
14604669Sfw157321 		    PICL_CLASS_CURRENT_SENSOR,
14614928Sfw157321 		    PICL_PROP_CURRENT, sun4v_env_print_sensor_callback);
14623941Svenki 		if (all_status_ok) {
14633941Svenki 			log_printf("All current sensors are OK.\n");
14643941Svenki 			return;
14653941Svenki 		}
14663941Svenki 	}
14675028Sfw157321 	log_printf("-------------------------------------------------"
14685028Sfw157321 	    "-----------\n");
14693941Svenki 	log_printf(fmt, "Location", "Sensor", "Status", 0);
14705028Sfw157321 	log_printf("-------------------------------------------------"
14715028Sfw157321 	    "-----------\n");
14723941Svenki 	(void) picl_walk_tree_by_class(phyplatformh,
14734669Sfw157321 	    PICL_CLASS_CURRENT_SENSOR, (void *)PICL_PROP_CURRENT,
14744669Sfw157321 	    sun4v_env_print_sensor_callback);
14753941Svenki }
14763941Svenki 
14773941Svenki static void
14783941Svenki sun4v_env_print_current_indicators()
14793941Svenki {
14805028Sfw157321 	char *fmt = "%-34s %-14s %-8s\n";
14813941Svenki 	(void) picl_walk_tree_by_class(phyplatformh,
14824669Sfw157321 	    PICL_CLASS_CURRENT_INDICATOR,
14834669Sfw157321 	    (void *)PICL_PROP_CONDITION,
14844669Sfw157321 	    sun4v_env_print_indicator_callback);
14853941Svenki 	if (!class_node_found)
14863941Svenki 		return;
14873941Svenki 	log_printf("\nCurrent indicators:\n");
14883941Svenki 	if (syserrlog == 0) {
14893941Svenki 		(void) picl_walk_tree_by_class(phyplatformh,
14904928Sfw157321 		    PICL_CLASS_CURRENT_INDICATOR, (void *)PICL_PROP_CONDITION,
14914669Sfw157321 		    sun4v_env_print_indicator_callback);
14923941Svenki 		if (all_status_ok) {
14933941Svenki 			log_printf("All current indicators are OK.\n");
14943941Svenki 			return;
14953941Svenki 		}
14963941Svenki 	}
14975028Sfw157321 	log_printf("-------------------------------------------------"
14985028Sfw157321 	    "-----------\n");
14993941Svenki 	log_printf(fmt, "Location", "Indicator", "Condition", 0);
15005028Sfw157321 	log_printf("-------------------------------------------------"
15015028Sfw157321 	    "-----------\n");
15023941Svenki 	(void) picl_walk_tree_by_class(phyplatformh,
15034669Sfw157321 	    PICL_CLASS_CURRENT_INDICATOR,
15044669Sfw157321 	    (void *)PICL_PROP_CONDITION,
15054669Sfw157321 	    sun4v_env_print_indicator_callback);
15063941Svenki }
15073941Svenki 
15083941Svenki static void
15093941Svenki sun4v_env_print_voltage_sensors()
15103941Svenki {
15115028Sfw157321 	char *fmt = "%-34s %-14s %-10s\n";
15123941Svenki 	(void) picl_walk_tree_by_class(phyplatformh,
15134669Sfw157321 	    PICL_CLASS_VOLTAGE_SENSOR,
15144669Sfw157321 	    PICL_PROP_VOLTAGE,
15154669Sfw157321 	    sun4v_env_print_sensor_callback);
15163941Svenki 	if (!class_node_found)
15173941Svenki 		return;
15183941Svenki 	log_printf("\nVoltage sensors:\n");
15193941Svenki 	if (syserrlog == 0) {
15203941Svenki 		(void) picl_walk_tree_by_class(phyplatformh,
15214669Sfw157321 		    PICL_CLASS_VOLTAGE_SENSOR,
15224928Sfw157321 		    PICL_PROP_VOLTAGE, sun4v_env_print_sensor_callback);
15233941Svenki 		if (all_status_ok) {
15243941Svenki 			log_printf("All voltage sensors are OK.\n");
15253941Svenki 			return;
15263941Svenki 		}
15273941Svenki 	}
15285028Sfw157321 	log_printf("-------------------------------------------------"
15295028Sfw157321 	    "-----------\n");
15303941Svenki 	log_printf(fmt, "Location", "Sensor", "Status", 0);
15315028Sfw157321 	log_printf("-------------------------------------------------"
15325028Sfw157321 	    "-----------\n");
15333941Svenki 	(void) picl_walk_tree_by_class(phyplatformh,
15344669Sfw157321 	    PICL_CLASS_VOLTAGE_SENSOR,
15354669Sfw157321 	    (void *)PICL_PROP_VOLTAGE,
15364669Sfw157321 	    sun4v_env_print_sensor_callback);
15373941Svenki }
15383941Svenki 
15393941Svenki static void
15403941Svenki sun4v_env_print_voltage_indicators()
15413941Svenki {
15425028Sfw157321 	char *fmt = "%-34s %-14s %-8s\n";
15433941Svenki 	(void) picl_walk_tree_by_class(phyplatformh,
15444669Sfw157321 	    PICL_CLASS_VOLTAGE_INDICATOR,
15454669Sfw157321 	    (void *)PICL_PROP_CONDITION,
15464669Sfw157321 	    sun4v_env_print_indicator_callback);
15473941Svenki 	if (!class_node_found)
15483941Svenki 		return;
15493941Svenki 	log_printf("\nVoltage indicators:\n");
15503941Svenki 	if (syserrlog == 0) {
15513941Svenki 		(void) picl_walk_tree_by_class(phyplatformh,
15524928Sfw157321 		    PICL_CLASS_VOLTAGE_INDICATOR, (void *)PICL_PROP_CONDITION,
15534669Sfw157321 		    sun4v_env_print_indicator_callback);
15543941Svenki 		if (all_status_ok) {
15553941Svenki 			log_printf("All voltage indicators are OK.\n");
15563941Svenki 			return;
15573941Svenki 		}
15583941Svenki 	}
15595028Sfw157321 	log_printf("-------------------------------------------------"
15605028Sfw157321 	    "-----------\n");
15613941Svenki 	log_printf(fmt, "Location", "Indicator", "Condition", 0);
15625028Sfw157321 	log_printf("-------------------------------------------------"
15635028Sfw157321 	    "-----------\n");
15643941Svenki 	(void) picl_walk_tree_by_class(phyplatformh,
15654669Sfw157321 	    PICL_CLASS_VOLTAGE_INDICATOR,
15664669Sfw157321 	    (void *)PICL_PROP_CONDITION,
15674669Sfw157321 	    sun4v_env_print_indicator_callback);
15683941Svenki }
15693941Svenki 
15703941Svenki static void
15713941Svenki sun4v_env_print_LEDs()
15723941Svenki {
15735028Sfw157321 	char *fmt = "%-34s %-14s %-8s\n";
15743941Svenki 	if (syserrlog == 0)
15753941Svenki 		return;
15763941Svenki 	(void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_LED,
15774669Sfw157321 	    (void *)PICL_PROP_STATE, sun4v_env_print_indicator_callback);
15783941Svenki 	if (!class_node_found)
15793941Svenki 		return;
15803941Svenki 	log_printf("\nLEDs:\n");
15815028Sfw157321 	log_printf("-------------------------------------------------"
15825028Sfw157321 	    "-----------\n");
15833941Svenki 	log_printf(fmt, "Location", "LED", "State", 0);
15845028Sfw157321 	log_printf("-------------------------------------------------"
15855028Sfw157321 	    "-----------\n");
15863941Svenki 	(void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_LED,
15874669Sfw157321 	    (void *)PICL_PROP_STATE, sun4v_env_print_indicator_callback);
15883941Svenki }
15893941Svenki 
15903941Svenki /*ARGSUSED*/
15913941Svenki static int
15923941Svenki sun4v_print_fru_status_callback(picl_nodehdl_t nodeh, void *args)
15933941Svenki {
15943941Svenki 	char label[PICL_PROPNAMELEN_MAX];
15953941Svenki 	char status[PICL_PROPNAMELEN_MAX];
15963941Svenki 	picl_errno_t err;
15973941Svenki 	picl_prophdl_t proph;
15983941Svenki 	picl_nodehdl_t parenth;
15993941Svenki 	char *names[PARENT_NAMES];
16003941Svenki 	char *loc;
16013941Svenki 	int i;
16023941Svenki 
16033941Svenki 	if (!class_node_found) {
16043941Svenki 		class_node_found = 1;
16053941Svenki 		return (PICL_WALK_TERMINATE);
16063941Svenki 	}
16073941Svenki 	err = picl_get_prop_by_name(nodeh, PICL_PROP_IS_FRU, &proph);
16083941Svenki 	if (err != PICL_SUCCESS)
16093941Svenki 		return (PICL_WALK_CONTINUE);
16103941Svenki 	err = picl_get_propval_by_name(nodeh, PICL_PROP_LABEL, label,
16114669Sfw157321 	    sizeof (label));
16123941Svenki 	if (err != PICL_SUCCESS)
16133941Svenki 		return (PICL_WALK_CONTINUE);
16143941Svenki 	err = picl_get_propval_by_name(nodeh, PICL_PROP_OPERATIONAL_STATUS,
16154669Sfw157321 	    status, sizeof (status));
16163941Svenki 	if (err != PICL_SUCCESS)
16173941Svenki 		return (PICL_WALK_CONTINUE);
16183941Svenki 	if (syserrlog == 0) {
16193941Svenki 		if (strcmp(status, "disabled") == 0) {
16203941Svenki 			if (all_status_ok) {
16213941Svenki 				all_status_ok = 0;
16223941Svenki 				return (PICL_WALK_TERMINATE);
16233941Svenki 			}
16243941Svenki 		} else
16253941Svenki 			return (PICL_WALK_CONTINUE);
16263941Svenki 	}
16273941Svenki 	err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, &parenth,
16284669Sfw157321 	    sizeof (parenth));
16293941Svenki 	if (err != PICL_SUCCESS) {
16303941Svenki 		log_printf("\n");
16313941Svenki 		return (PICL_WALK_CONTINUE);
16323941Svenki 	}
16333941Svenki 	if ((loc = (char *)malloc(PICL_PROPNAMELEN_MAX*PARENT_NAMES)) == NULL)
16343941Svenki 		return (PICL_WALK_TERMINATE);
16353941Svenki 	for (i = 0; i < PARENT_NAMES; i++)
16363941Svenki 		if ((names[i] = (char *)malloc(PICL_PROPNAMELEN_MAX)) == NULL) {
16373941Svenki 			while (--i > -1)
16383941Svenki 				free(names[i]);
16393941Svenki 			free(loc);
16403941Svenki 			return (PICL_WALK_TERMINATE);
16413941Svenki 		}
16423941Svenki 	i = 0;
16433941Svenki 	while (err == PICL_SUCCESS) {
16444802Sfw157321 		if (parenth == phyplatformh)
16453941Svenki 			break;
16463941Svenki 		err = picl_get_propval_by_name(parenth, PICL_PROP_NAME,
16474669Sfw157321 		    names[i++], PICL_PROPNAMELEN_MAX);
16483941Svenki 		if (err != PICL_SUCCESS) {
16493941Svenki 			i--;
16503941Svenki 			break;
16513941Svenki 		}
16523941Svenki 		if (i == PARENT_NAMES)
16533941Svenki 			break;
16543941Svenki 		err = picl_get_propval_by_name(parenth, PICL_PROP_PARENT,
16554669Sfw157321 		    &parenth, sizeof (parenth));
16563941Svenki 	}
16573941Svenki 	loc[0] = '\0';
16584003Svivek 	if (--i > -1) {
16594003Svivek 		(void) strlcat(loc, names[i],
16604669Sfw157321 		    PICL_PROPNAMELEN_MAX * PARENT_NAMES);
16614003Svivek 	}
16623941Svenki 	while (--i > -1) {
16634003Svivek 		(void) strlcat(loc, "/", PICL_PROPNAMELEN_MAX * PARENT_NAMES);
16644003Svivek 		(void) strlcat(loc, names[i],
16654669Sfw157321 		    PICL_PROPNAMELEN_MAX * PARENT_NAMES);
16663941Svenki 	}
16675028Sfw157321 	log_printf("%-35s", loc);
16683941Svenki 	for (i = 0; i < PARENT_NAMES; i++)
16693941Svenki 		free(names[i]);
16703941Svenki 	free(loc);
16713941Svenki 	log_printf("%-10s", label);
16723941Svenki 	log_printf("%-9s", status);
16733941Svenki 	log_printf("\n");
16743941Svenki 	return (PICL_WALK_CONTINUE);
16753941Svenki }
16763941Svenki 
16773941Svenki static void
16783941Svenki sun4v_print_fru_status()
16793941Svenki {
16805028Sfw157321 	char *fmt = "%-34s %-9s %-8s\n";
16815436Sfw157321 
16823941Svenki 	(void) picl_walk_tree_by_class(phyplatformh, NULL, NULL,
16834669Sfw157321 	    sun4v_print_fru_status_callback);
16843941Svenki 	if (!class_node_found)
16853941Svenki 		return;
16865436Sfw157321 
16873941Svenki 	log_printf("\n");
16883941Svenki 	log_printf("============================");
16893941Svenki 	log_printf(" FRU Status ");
16903941Svenki 	log_printf("============================");
16913941Svenki 	log_printf("\n");
16923941Svenki 
16933941Svenki 	if (syserrlog == 0) {
16943941Svenki 		(void) picl_walk_tree_by_class(phyplatformh,
16954802Sfw157321 		    NULL, NULL,
16964669Sfw157321 		    sun4v_print_fru_status_callback);
16973941Svenki 		if (all_status_ok) {
16983941Svenki 			log_printf("All FRUs are enabled.\n");
16993941Svenki 			return;
17003941Svenki 		}
17013941Svenki 	}
17023941Svenki 	log_printf(fmt, "Location", "Name", "Status", 0);
17035028Sfw157321 	log_printf("------------------------------------------------------\n");
17044802Sfw157321 	(void) picl_walk_tree_by_class(phyplatformh, NULL, NULL,
17054669Sfw157321 	    sun4v_print_fru_status_callback);
17063941Svenki }
17073941Svenki 
17083941Svenki /*ARGSUSED*/
17093941Svenki static int
17103941Svenki sun4v_print_fw_rev_callback(picl_nodehdl_t nodeh, void *args)
17113941Svenki {
17123941Svenki 	char rev[PICL_PROPNAMELEN_MAX];
17133941Svenki 	picl_errno_t err;
17143941Svenki 
17153941Svenki 	if (!class_node_found) {
17163941Svenki 		class_node_found = 1;
17173941Svenki 		return (PICL_WALK_TERMINATE);
17183941Svenki 	}
17195436Sfw157321 
17203941Svenki 	err = picl_get_propval_by_name(nodeh, PICL_PROP_FW_REVISION, rev,
17214669Sfw157321 	    sizeof (rev));
17223941Svenki 	if (err != PICL_SUCCESS)
17233941Svenki 		return (PICL_WALK_CONTINUE);
17243941Svenki 	if (strlen(rev) == 0)
17253941Svenki 		return (PICL_WALK_CONTINUE);
17265436Sfw157321 	log_printf("%s", rev);
17273941Svenki 	log_printf("\n");
17283941Svenki 	return (PICL_WALK_CONTINUE);
17293941Svenki }
17303941Svenki 
17313941Svenki static void
17323941Svenki sun4v_print_fw_rev()
17333941Svenki {
17343941Svenki 	if (syserrlog == 0)
17353941Svenki 		return;
17365436Sfw157321 
17373941Svenki 	(void) picl_walk_tree_by_class(phyplatformh, NULL, NULL,
17384669Sfw157321 	    sun4v_print_fw_rev_callback);
17393941Svenki 	if (!class_node_found)
17403941Svenki 		return;
17415436Sfw157321 
17423941Svenki 	log_printf("\n");
17433941Svenki 	log_printf("============================");
17443941Svenki 	log_printf(" FW Version ");
17453941Svenki 	log_printf("============================");
17463941Svenki 	log_printf("\n");
17475436Sfw157321 	log_printf("Version\n");
17485028Sfw157321 	log_printf("-------------------------------------------------"
17495028Sfw157321 	    "-----------\n");
17503941Svenki 	(void) picl_walk_tree_by_class(phyplatformh, NULL, NULL,
17514669Sfw157321 	    sun4v_print_fw_rev_callback);
17523941Svenki }
17533941Svenki 
17543941Svenki static void
17555436Sfw157321 sun4v_print_openprom_rev()
17565436Sfw157321 {
17575436Sfw157321 	if (syserrlog == 0)
17585436Sfw157321 		return;
17595436Sfw157321 
17605436Sfw157321 	(void) picl_walk_tree_by_class(rooth, "openprom", NULL,
17615436Sfw157321 	    openprom_callback);
17625436Sfw157321 	if (!class_node_found)
17635436Sfw157321 		return;
17645436Sfw157321 
17655436Sfw157321 	log_printf("\n");
17665436Sfw157321 	log_printf("======================");
17675436Sfw157321 	log_printf(" System PROM revisions ");
17685436Sfw157321 	log_printf("=======================");
17695436Sfw157321 	log_printf("\n");
17705436Sfw157321 	log_printf("Version\n");
17715436Sfw157321 	log_printf("-------------------------------------------------"
17725436Sfw157321 	    "-----------\n");
17735436Sfw157321 	(void) picl_walk_tree_by_class(rooth, "openprom", NULL,
17745436Sfw157321 	    openprom_callback);
17755436Sfw157321 }
17765436Sfw157321 
17775436Sfw157321 /*
17785436Sfw157321  * display the OBP and POST prom revisions (if present)
17795436Sfw157321  */
17805436Sfw157321 /* ARGSUSED */
17815436Sfw157321 static int
17825436Sfw157321 openprom_callback(picl_nodehdl_t openpromh, void *arg)
17835436Sfw157321 {
17845436Sfw157321 	picl_prophdl_t	proph;
17855436Sfw157321 	picl_prophdl_t	tblh;
17865436Sfw157321 	picl_prophdl_t	rowproph;
17875436Sfw157321 	picl_propinfo_t	pinfo;
17885436Sfw157321 	char		*prom_version = NULL;
17895436Sfw157321 	char		*obp_version = NULL;
17905436Sfw157321 	int		err;
17915436Sfw157321 
17925436Sfw157321 	if (!class_node_found) {
17935436Sfw157321 		class_node_found = 1;
17945436Sfw157321 		return (PICL_WALK_TERMINATE);
17955436Sfw157321 	}
17965436Sfw157321 
17975436Sfw157321 	err = picl_get_propinfo_by_name(openpromh, OBP_PROP_VERSION,
17985436Sfw157321 	    &pinfo, &proph);
17995436Sfw157321 	if (err == PICL_PROPNOTFOUND)
18005436Sfw157321 		return (PICL_WALK_TERMINATE);
18015436Sfw157321 	else if (err != PICL_SUCCESS)
18025436Sfw157321 		return (err);
18035436Sfw157321 
18045436Sfw157321 	/*
18055436Sfw157321 	 * If it's a table prop, the first element is OBP revision
18065436Sfw157321 	 * The second one is POST revision.
18075436Sfw157321 	 * If it's a charstring prop, the value will be only OBP revision
18085436Sfw157321 	 */
18095436Sfw157321 	if (pinfo.type == PICL_PTYPE_CHARSTRING) {
18105436Sfw157321 		prom_version = (char *)alloca(pinfo.size);
18115436Sfw157321 		if (prom_version == NULL)
18125436Sfw157321 			return (PICL_FAILURE);
18135436Sfw157321 		err = picl_get_propval(proph, prom_version, pinfo.size);
18145436Sfw157321 		if (err != PICL_SUCCESS)
18155436Sfw157321 			return (err);
18165436Sfw157321 		log_printf("%s\n", prom_version);
18175436Sfw157321 	}
18185436Sfw157321 
18195436Sfw157321 	if (pinfo.type != PICL_PTYPE_TABLE)	/* not supported type */
18205436Sfw157321 		return (PICL_WALK_TERMINATE);
18215436Sfw157321 
18225436Sfw157321 	err = picl_get_propval(proph, &tblh, pinfo.size);
18235436Sfw157321 	if (err != PICL_SUCCESS)
18245436Sfw157321 		return (err);
18255436Sfw157321 
18265436Sfw157321 	err = picl_get_next_by_row(tblh, &rowproph);
18275436Sfw157321 	if (err == PICL_SUCCESS) {
18285436Sfw157321 		/* get first row */
18295436Sfw157321 		err = picl_get_propinfo(rowproph, &pinfo);
18305436Sfw157321 		if (err != PICL_SUCCESS)
18315436Sfw157321 			return (err);
18325436Sfw157321 
18335436Sfw157321 		prom_version = (char *)alloca(pinfo.size);
18345436Sfw157321 		if (prom_version == NULL)
18355436Sfw157321 			return (PICL_FAILURE);
18365436Sfw157321 
18375436Sfw157321 		err = picl_get_propval(rowproph, prom_version, pinfo.size);
18385436Sfw157321 		if (err != PICL_SUCCESS)
18395436Sfw157321 			return (err);
18405436Sfw157321 		log_printf("%s\n", prom_version);
18415436Sfw157321 
18425436Sfw157321 		/* get second row */
18435436Sfw157321 		err = picl_get_next_by_col(rowproph, &rowproph);
18445436Sfw157321 		if (err == PICL_SUCCESS) {
18455436Sfw157321 			err = picl_get_propinfo(rowproph, &pinfo);
18465436Sfw157321 			if (err != PICL_SUCCESS)
18475436Sfw157321 				return (err);
18485436Sfw157321 
18495436Sfw157321 			obp_version = (char *)alloca(pinfo.size);
18505436Sfw157321 			if (obp_version == NULL)
18515436Sfw157321 				return (PICL_FAILURE);
18525436Sfw157321 			err = picl_get_propval(rowproph, obp_version,
18535436Sfw157321 			    pinfo.size);
18545436Sfw157321 			if (err != PICL_SUCCESS)
18555436Sfw157321 				return (err);
18565436Sfw157321 			log_printf("%s\n", obp_version);
18575436Sfw157321 		}
18585436Sfw157321 	}
18595436Sfw157321 
18605436Sfw157321 	return (PICL_WALK_TERMINATE);
18615436Sfw157321 }
18625436Sfw157321 
18635436Sfw157321 static void
18643941Svenki sun4v_print_chassis_serial_no()
18653941Svenki {
18663941Svenki 	char val[PICL_PROPNAMELEN_MAX];
18673941Svenki 	picl_errno_t err;
18683941Svenki 	if (syserrlog == 0 || chassish == 0)
18693941Svenki 		return;
18703941Svenki 
18713941Svenki 	log_printf("\n");
18723941Svenki 	log_printf("Chassis Serial Number");
18733941Svenki 	log_printf("\n");
18743941Svenki 	log_printf("---------------------\n");
18753941Svenki 	err = picl_get_propval_by_name(chassish, PICL_PROP_SERIAL_NUMBER,
18764669Sfw157321 	    val, sizeof (val));
18773941Svenki 	if (err == PICL_SUCCESS)
18783941Svenki 		log_printf("%s", val);
18793941Svenki 	log_printf("\n");
18803941Svenki }
1881