11708Sstevel /*
21708Sstevel  * CDDL HEADER START
31708Sstevel  *
41708Sstevel  * The contents of this file are subject to the terms of the
5*13019SMichael.Bergknoff@Oracle.COM  * Common Development and Distribution License (the "License").
6*13019SMichael.Bergknoff@Oracle.COM  * 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 /*
22*13019SMichael.Bergknoff@Oracle.COM  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
231708Sstevel  */
241708Sstevel 
251708Sstevel 
261708Sstevel /*
271708Sstevel  * This program prints the diagnostics of Sanibel system. It
281708Sstevel  * also prints other miscellaneous information about watchdog, temperature
291708Sstevel  * of CPU sensor, firmware versions of SMC and, micro controller role
301708Sstevel  * etc. The basic sources of output is PICL, and  SMC.
311708Sstevel  */
321708Sstevel 
331708Sstevel /* includes */
341708Sstevel 
351708Sstevel #include <stdio.h>
361708Sstevel #include <strings.h>
371708Sstevel #include <ctype.h>
381708Sstevel #include <string.h>
391708Sstevel #include <time.h>
401708Sstevel #include <dirent.h>
411708Sstevel #include <sys/param.h>
421708Sstevel #include <picl.h>
431708Sstevel #include <libintl.h>
441708Sstevel #include <sys/types.h>
451708Sstevel #include <sys/stat.h>
461708Sstevel #include <sys/systeminfo.h>
471708Sstevel #include <sys/openpromio.h>
481708Sstevel #include <fcntl.h>
491708Sstevel #include <smc_if.h>
501708Sstevel #include <stropts.h>
511708Sstevel #include <alloca.h>
521708Sstevel #include <errno.h>
531708Sstevel #include <poll.h>
541708Sstevel #include <stdlib.h>
551708Sstevel #include <unistd.h>
561708Sstevel #include <kstat.h>
571708Sstevel #include <sys/utsname.h>
581708Sstevel #include <stddef.h>
591708Sstevel #include <pdevinfo.h>
601708Sstevel #include <display_sun4u.h>
611708Sstevel #include <libprtdiag.h>
621708Sstevel #include <smclib.h>
631708Sstevel #include <smc_commands.h>
641708Sstevel #include <picldefs.h>
651708Sstevel 
661708Sstevel /* #defines for the PICL library API usage and local static variables */
671708Sstevel #define	PD_CPCI_SLOT_TYPE	"cpci"
681708Sstevel #define	PD_PCI_SLOT_TYPE	"pci"
691708Sstevel #define	PD_PRESENT		1
701708Sstevel #define	PD_BLANK		" "
711708Sstevel #define	PD_ENABLED		1
721708Sstevel #define	PD_DISABLED		0
731708Sstevel #define	SNOWBIRD		"SUNW,Netra-CP2300"
741708Sstevel #define	CHASSIS_NODE_NAME	"chassis"
751708Sstevel 
761708Sstevel /* #defines for the SMC and IPMI commands */
771708Sstevel #define	POLL_TIMEOUT				10000
781708Sstevel #define	DEFAULT_SEQN				0xff
791708Sstevel 
801708Sstevel /* SMC driver */
811708Sstevel #define	PD_SMC_DRV_PATH			"/dev/ctsmc"
821708Sstevel 
831708Sstevel /* Constants */
841708Sstevel #define	OBP_PROP_BANNER_NAME		"banner-name"
851708Sstevel #define	OBP_PROP_CLOCK_FREQ		"clock-frequency"
861708Sstevel 
871708Sstevel 
881708Sstevel 
891708Sstevel /* #defines for local usage */
901708Sstevel #define	PD_SUCCESS	0
911708Sstevel #define	PD_FAILURE	1
921708Sstevel #define	PD_INTERNAL_FAILURE	2
931708Sstevel #define	PD_ERROR	-1
941708Sstevel 
951708Sstevel /*	static global variables	*/
961708Sstevel static int pd_print_option;
971708Sstevel static uint8_t pd_smc_glbl_enabl_rsp[2];
981708Sstevel static boolean_t pd_hdr_prt		= B_TRUE;
991708Sstevel static int pd_smc_fd			= 0;
1001708Sstevel 
1011708Sstevel 
1021708Sstevel /* function declarations used in this program */
1031708Sstevel static uint32_t pd_check_for_snowbird();
1041708Sstevel static uint32_t pd_prt_snowbird_diag();
1051708Sstevel static uint32_t pd_check_cpu_health();
1061708Sstevel static uint32_t pd_check_tty_debug_mode();
1071708Sstevel static uint32_t pd_query_SMC_firmware_version();
1081708Sstevel static uint32_t pd_check_slots();
1091708Sstevel int32_t pd_prt_slot_info(picl_nodehdl_t, void *);
1101708Sstevel int do_prominfo(int syserrlog, char *pname, int log_flag, int prt_flag);
1111708Sstevel static uint32_t pd_query_watchdog_state();
1121708Sstevel int pd_check_wd_state(picl_nodehdl_t, void *);
1131708Sstevel static uint32_t pd_print_fruinfo_hdr();
1141708Sstevel static uint32_t pd_print_device_info(int);
1151708Sstevel static uint32_t pd_get_role_information();
1161708Sstevel static uint32_t pd_get_message_flags();
1171708Sstevel static uint32_t pd_get_reset_mode();
1181708Sstevel static uint32_t pd_get_sensor_reading();
1191708Sstevel static uint32_t pd_get_sensor_threshold();
1201708Sstevel static uint32_t pd_prt_cpci_condition(picl_nodehdl_t nodeh);
1211708Sstevel static uint32_t pd_check_location_parent(picl_nodehdl_t nodeh);
1221708Sstevel static uint64_t
1231708Sstevel picldiag_get_uint_propval(picl_nodehdl_t modh, char *prop_name, int *ret);
1241708Sstevel static int picldiag_get_clock_freq(picl_nodehdl_t modh, uint32_t *freq);
1251708Sstevel static int display_system_clock(picl_nodehdl_t plafh);
1261708Sstevel 
1271708Sstevel /*
1281708Sstevel  * return the value of the uint prop
1291708Sstevel  */
1301708Sstevel static uint64_t
picldiag_get_uint_propval(picl_nodehdl_t modh,char * prop_name,int * ret)1311708Sstevel picldiag_get_uint_propval(picl_nodehdl_t modh, char *prop_name, int *ret)
1321708Sstevel {
1331708Sstevel 	int		err;
1341708Sstevel 	picl_prophdl_t	proph;
1351708Sstevel 	picl_propinfo_t	pinfo;
1361708Sstevel 	uint8_t		uint8v;
1371708Sstevel 	uint16_t	uint16v;
1381708Sstevel 	uint32_t	uint32v;
1391708Sstevel 	uint64_t	uint64v;
1401708Sstevel 
1411708Sstevel 	err = picl_get_propinfo_by_name(modh, prop_name, &pinfo, &proph);
1421708Sstevel 	if (err != PICL_SUCCESS) {
1431708Sstevel 		*ret = err;
1441708Sstevel 		return (0);
1451708Sstevel 	}
1461708Sstevel 
1471708Sstevel 	/*
1481708Sstevel 	 * If it is not an int or uint prop, return failure
1491708Sstevel 	 */
1501708Sstevel 	if ((pinfo.type != PICL_PTYPE_INT) &&
151*13019SMichael.Bergknoff@Oracle.COM 	    (pinfo.type != PICL_PTYPE_UNSIGNED_INT)) {
1521708Sstevel 		*ret = PICL_FAILURE;
1531708Sstevel 		return (0);
1541708Sstevel 	}
1551708Sstevel 
1561708Sstevel 	/* uint prop */
1571708Sstevel 
1581708Sstevel 	switch (pinfo.size) {
1591708Sstevel 	case sizeof (uint8_t):
1601708Sstevel 		err = picl_get_propval(proph, &uint8v, sizeof (uint8v));
1611708Sstevel 		*ret = err;
1621708Sstevel 		return (uint8v);
1631708Sstevel 	case sizeof (uint16_t):
1641708Sstevel 		err = picl_get_propval(proph, &uint16v, sizeof (uint16v));
1651708Sstevel 		*ret = err;
1661708Sstevel 		return (uint16v);
1671708Sstevel 	case sizeof (uint32_t):
1681708Sstevel 		err = picl_get_propval(proph, &uint32v, sizeof (uint32v));
1691708Sstevel 		*ret = err;
1701708Sstevel 		return (uint32v);
1711708Sstevel 	case sizeof (uint64_t):
1721708Sstevel 		err = picl_get_propval(proph, &uint64v, sizeof (uint64v));
1731708Sstevel 		*ret = err;
1741708Sstevel 		return (uint64v);
1751708Sstevel 	default:	/* not supported size */
1761708Sstevel 		*ret = PICL_FAILURE;
1771708Sstevel 		return (0);
1781708Sstevel 	}
1791708Sstevel }
1801708Sstevel 
1811708Sstevel 
1821708Sstevel 
1831708Sstevel /*
1841708Sstevel  * get the clock frequency
1851708Sstevel  */
1861708Sstevel static int
picldiag_get_clock_freq(picl_nodehdl_t modh,uint32_t * freq)1871708Sstevel picldiag_get_clock_freq(picl_nodehdl_t modh, uint32_t *freq)
1881708Sstevel {
1891708Sstevel #define	ROUND_TO_MHZ(x)	(((x) + 500000)/ 1000000)
1901708Sstevel 
1911708Sstevel 	int		err;
1921708Sstevel 	uint64_t	clk_freq;
1931708Sstevel 
1941708Sstevel 	clk_freq = picldiag_get_uint_propval(modh, OBP_PROP_CLOCK_FREQ, &err);
1951708Sstevel 	if (err != PICL_SUCCESS)
1961708Sstevel 		return (err);
1971708Sstevel 
1981708Sstevel 	*freq = ROUND_TO_MHZ(clk_freq);
1991708Sstevel 
2001708Sstevel 	return (PICL_SUCCESS);
2011708Sstevel }
2021708Sstevel 
2031708Sstevel 
2041708Sstevel /*
2051708Sstevel  * display the clock frequency
2061708Sstevel  */
2071708Sstevel static int
display_system_clock(picl_nodehdl_t plafh)2081708Sstevel display_system_clock(picl_nodehdl_t plafh)
2091708Sstevel {
2101708Sstevel 	uint32_t	system_clk;
2111708Sstevel 	int		err;
2121708Sstevel 
2131708Sstevel 	err = picldiag_get_clock_freq(plafh, &system_clk);
2141708Sstevel 	if (err != PICL_SUCCESS)
2151708Sstevel 		return (err);
2161708Sstevel 
2171708Sstevel 	log_printf(dgettext(TEXT_DOMAIN,
218*13019SMichael.Bergknoff@Oracle.COM 	    "System clock frequency: %d MHZ\n"), system_clk);
2191708Sstevel 
2201708Sstevel 	return (PICL_SUCCESS);
2211708Sstevel }
2221708Sstevel 
2231708Sstevel 
2241708Sstevel /*
2251708Sstevel  * get the value by the property name of the string prop
2261708Sstevel  * Caller must free the outbuf
2271708Sstevel  */
2281708Sstevel static int
picldiag_get_string_propval(picl_nodehdl_t modh,char * prop_name,char ** outbuf)2291708Sstevel picldiag_get_string_propval(picl_nodehdl_t modh, char *prop_name, char **outbuf)
2301708Sstevel {
2311708Sstevel 	int		err;
2321708Sstevel 	picl_prophdl_t	proph;
2331708Sstevel 	picl_propinfo_t	pinfo;
2341708Sstevel 	char		*prop_value;
2351708Sstevel 
2361708Sstevel 	err = picl_get_propinfo_by_name(modh, prop_name, &pinfo, &proph);
2371708Sstevel 	if (err != PICL_SUCCESS)
2381708Sstevel 		return (err);
2391708Sstevel 
2401708Sstevel 	/*
2411708Sstevel 	 * If it is not a string prop, return NULL
2421708Sstevel 	 */
2431708Sstevel 	if (pinfo.type != PICL_PTYPE_CHARSTRING)
244*13019SMichael.Bergknoff@Oracle.COM 		return (PICL_FAILURE);
2451708Sstevel 
2461708Sstevel 	prop_value = malloc(pinfo.size);
2471708Sstevel 	if (prop_value == NULL)
2481708Sstevel 		return (PICL_FAILURE);
2491708Sstevel 
2501708Sstevel 	err = picl_get_propval(proph, prop_value, pinfo.size);
2511708Sstevel 	if (err != PICL_SUCCESS) {
2521708Sstevel 		free(prop_value);
2531708Sstevel 		return (err);
2541708Sstevel 	}
2551708Sstevel 
2561708Sstevel 	*outbuf = prop_value;
2571708Sstevel 	return (PICL_SUCCESS);
2581708Sstevel }
2591708Sstevel 
2601708Sstevel 
2611708Sstevel 
2621708Sstevel /*
2631708Sstevel  * display platform banner
2641708Sstevel  */
2651708Sstevel static int
display_platform_banner(picl_nodehdl_t plafh)2661708Sstevel display_platform_banner(picl_nodehdl_t plafh)
2671708Sstevel {
2681708Sstevel 	char	*platform;
2691708Sstevel 	char	*banner_name;
2701708Sstevel 	int	err;
2711708Sstevel 
2721708Sstevel 	/*
2731708Sstevel 	 * get PICL_PROP_MACHINE and PICL_PROP_BANNER_NAME
2741708Sstevel 	 */
2751708Sstevel 	log_printf(dgettext(TEXT_DOMAIN,
276*13019SMichael.Bergknoff@Oracle.COM 	    "System Configuration: Oracle Corporation "), 0);
2771708Sstevel 	err = picldiag_get_string_propval(plafh, PICL_PROP_MACHINE,
2781708Sstevel 	    &platform);
2791708Sstevel 	if (err != PICL_SUCCESS)
2801708Sstevel 		return (err);
2811708Sstevel 	log_printf(" %s", platform, 0);
2821708Sstevel 	free(platform);
2831708Sstevel 
2841708Sstevel 	err = picldiag_get_string_propval(plafh, OBP_PROP_BANNER_NAME,
2851708Sstevel 	    &banner_name);
2861708Sstevel 	if (err != PICL_SUCCESS)
2871708Sstevel 		return (err);
2881708Sstevel 	log_printf(" %s", banner_name, 0);
2891708Sstevel 	free(banner_name);
2901708Sstevel 
2911708Sstevel 	log_printf("\n", 0);
2921708Sstevel 	return (PICL_SUCCESS);
2931708Sstevel }
2941708Sstevel 
2951708Sstevel /*
2961708Sstevel  * search children to get the node by the nodename
2971708Sstevel  */
2981708Sstevel static int
picldiag_get_node_by_name(picl_nodehdl_t rooth,char * name,picl_nodehdl_t * nodeh)2991708Sstevel picldiag_get_node_by_name(picl_nodehdl_t rooth, char *name,
3001708Sstevel     picl_nodehdl_t *nodeh)
3011708Sstevel {
3021708Sstevel 	picl_nodehdl_t	childh;
3031708Sstevel 	int		err;
3041708Sstevel 	char		*nodename;
3051708Sstevel 
3061708Sstevel 	nodename = alloca(strlen(name) + 1);
3071708Sstevel 	if (nodename == NULL)
3081708Sstevel 		return (PICL_FAILURE);
3091708Sstevel 
3101708Sstevel 	err = picl_get_propval_by_name(rooth, PICL_PROP_CHILD, &childh,
3111708Sstevel 	    sizeof (picl_nodehdl_t));
3121708Sstevel 
3131708Sstevel 	while (err == PICL_SUCCESS) {
3141708Sstevel 		err = picl_get_propval_by_name(childh, PICL_PROP_NAME,
3151708Sstevel 		    nodename, (strlen(name) + 1));
3161708Sstevel 		if (err != PICL_SUCCESS) {
3171708Sstevel 			err = picl_get_propval_by_name(childh, PICL_PROP_PEER,
318*13019SMichael.Bergknoff@Oracle.COM 			    &childh, sizeof (picl_nodehdl_t));
3191708Sstevel 			continue;
3201708Sstevel 		}
3211708Sstevel 
3221708Sstevel 		if (strcmp(nodename, name) == 0) {
3231708Sstevel 			*nodeh = childh;
3241708Sstevel 			return (PICL_SUCCESS);
3251708Sstevel 		}
3261708Sstevel 
3271708Sstevel 		err = picl_get_propval_by_name(childh, PICL_PROP_PEER,
3281708Sstevel 		    &childh, sizeof (picl_nodehdl_t));
3291708Sstevel 	}
3301708Sstevel 
3311708Sstevel 	return (err);
3321708Sstevel }
3331708Sstevel 
3341708Sstevel 
3351708Sstevel /*
3361708Sstevel  * This routine is invoked when prtdiag starts execution. It prints
3371708Sstevel  * system configuration, memory size, initializes PICL and acts as
3381708Sstevel  * a driver routine for prtdiag output for Snowbird.
3391708Sstevel  */
3401708Sstevel /* ARGSUSED */
3411708Sstevel int
do_prominfo(int syserrlog,char * pname,int log_flag,int prt_flag)3421708Sstevel do_prominfo(int syserrlog, char *pname, int log_flag, int prt_flag)
3431708Sstevel {
3441708Sstevel 
3451708Sstevel 	struct mem_total memory_total;	/*	total memory in system	*/
3461708Sstevel 	struct grp_info grps;
3471708Sstevel 	uint8_t status = PD_SUCCESS;
3481708Sstevel 	picl_nodehdl_t rooth;
3491708Sstevel 	picl_nodehdl_t plafh;
3501708Sstevel 	struct system_kstat_data *kstats = NULL;
3511708Sstevel 	Sys_tree *tree = NULL;
3521708Sstevel 
3531708Sstevel 	sys_clk = -1;
3541708Sstevel 	pd_print_option = syserrlog;
3551708Sstevel 
3561708Sstevel 	if ((status = picl_initialize()) != PICL_SUCCESS) {
3571708Sstevel 		log_printf("prtdiag: failed to initialize the PICL\n", 0);
3581708Sstevel 		exit(1);
3591708Sstevel 	}
3601708Sstevel 
3611708Sstevel 	if ((status = picl_get_root(&rooth)) != PICL_SUCCESS) {
3621708Sstevel 		log_printf("prtdiag: failed\n", 0);
3631708Sstevel 		exit(1);
3641708Sstevel 	}
3651708Sstevel 
3661708Sstevel 	status = picldiag_get_node_by_name(rooth, PICL_NODE_PLATFORM, &plafh);
3671708Sstevel 	if (status != PICL_SUCCESS)
3681708Sstevel 		return (status);
3691708Sstevel 
3701708Sstevel 	if (!log_flag) {
3711708Sstevel 
3721708Sstevel 		status = display_platform_banner(plafh);
3731708Sstevel 		if (status != PICL_SUCCESS)
3741708Sstevel 			return (status);
3751708Sstevel 
3761708Sstevel 		status = display_system_clock(plafh);
3771708Sstevel 		if (status != PICL_SUCCESS)
3781708Sstevel 			return (status);
3791708Sstevel 
3801708Sstevel 		/* display the memory Size */
3811708Sstevel 		display_memorysize(tree, kstats, &grps, &memory_total);
3821708Sstevel 	}
3831708Sstevel 
3841708Sstevel 	if ((pd_smc_fd = open(PD_SMC_DRV_PATH, O_RDWR)) == -1)
3851708Sstevel 		return (PD_FAILURE);
3861708Sstevel 
3871708Sstevel 	if ((status = pd_check_for_snowbird()) != PD_SUCCESS)
3881708Sstevel 		return (status);
3891708Sstevel 
3901708Sstevel 	if ((status = pd_prt_snowbird_diag()) != PD_SUCCESS)
3911708Sstevel 		return (status);
3921708Sstevel 
3931708Sstevel 	(void) close(pd_smc_fd);
3941708Sstevel 
3951708Sstevel 	if (picl_shutdown() != PICL_SUCCESS)
3961708Sstevel 		return (PD_INTERNAL_FAILURE);
3971708Sstevel 
3981708Sstevel 	return (PD_SUCCESS);
3991708Sstevel 
4001708Sstevel }
4011708Sstevel 
4021708Sstevel /*
4031708Sstevel  * This routine prints out the platform name.
4041708Sstevel  */
4051708Sstevel 
4061708Sstevel static uint32_t
pd_check_for_snowbird()4071708Sstevel pd_check_for_snowbird()
4081708Sstevel {
4091708Sstevel 
4101708Sstevel 	char si_platform[30];
4111708Sstevel 
4121708Sstevel 	if (sysinfo(SI_PLATFORM, si_platform, sizeof (si_platform)) == -1) {
4131708Sstevel 		return (PD_FAILURE);
4141708Sstevel 	}
4151708Sstevel 	/* is it a Snowbird? */
4161708Sstevel 	if (strcmp(si_platform, SNOWBIRD) != 0)
4171708Sstevel 		return (PD_FAILURE);
4181708Sstevel 
4191708Sstevel 	log_printf("platform Type : %s\n", si_platform, 0);
4201708Sstevel 	return (PD_SUCCESS);
4211708Sstevel 
4221708Sstevel }
4231708Sstevel 
4241708Sstevel 
4251708Sstevel /*
4261708Sstevel  * Driver routine for satellite specific output. This is also used by
4271708Sstevel  * host driver routine as all satellite information is printed by host.
4281708Sstevel  * It also prints some host specific information for formatting purposes
4291708Sstevel  */
4301708Sstevel 
4311708Sstevel static uint32_t
pd_prt_snowbird_diag()4321708Sstevel pd_prt_snowbird_diag()
4331708Sstevel {
4341708Sstevel 	uint8_t status = PD_SUCCESS;
4351708Sstevel 	if ((status = pd_check_cpu_health()) != PD_SUCCESS) {
4361708Sstevel 		return (status);
4371708Sstevel 	}
4381708Sstevel 	if (pd_print_option) {
4391708Sstevel 
4401708Sstevel 		log_printf(
441*13019SMichael.Bergknoff@Oracle.COM 		    "\n %11s Other Miscellaneous Information \n",
442*13019SMichael.Bergknoff@Oracle.COM 		    PD_BLANK, 0);
4431708Sstevel 		log_printf(
444*13019SMichael.Bergknoff@Oracle.COM 		    "%12s ------------------------------- \n",
445*13019SMichael.Bergknoff@Oracle.COM 		    PD_BLANK, 0);
4461708Sstevel 
4471708Sstevel 		if ((status = pd_get_role_information()) != PD_SUCCESS) {
4481708Sstevel 			return (status);
4491708Sstevel 		}
4501708Sstevel 
4511708Sstevel 		if (pd_smc_glbl_enabl_rsp[1] & 0x10) {
4521708Sstevel 			log_printf(
453*13019SMichael.Bergknoff@Oracle.COM 			    "IPMI Response Notification\t\tEnabled\n", 0);
4541708Sstevel 		} else {
4551708Sstevel 			log_printf(
456*13019SMichael.Bergknoff@Oracle.COM 			    "IPMI Response Notification\t\tDisabled\n", 0);
4571708Sstevel 		}
4581708Sstevel 		if ((status = pd_query_SMC_firmware_version()) != PD_SUCCESS) {
4591708Sstevel 			return (status);
4601708Sstevel 		}
4611708Sstevel 
4621708Sstevel 		if ((status = pd_check_tty_debug_mode()) != PD_SUCCESS) {
4631708Sstevel 			return (status);
4641708Sstevel 		}
4651708Sstevel 
4661708Sstevel 		if ((status = pd_get_reset_mode()) != PD_SUCCESS) {
4671708Sstevel 			return (status);
4681708Sstevel 		}
4691708Sstevel 
4701708Sstevel 		if ((status = pd_get_message_flags()) != PD_SUCCESS) {
4711708Sstevel 			return (status);
4721708Sstevel 		}
4731708Sstevel 
4741708Sstevel 		if ((status = pd_query_watchdog_state()) != PD_SUCCESS) {
4751708Sstevel 			return (status);
4761708Sstevel 		}
4771708Sstevel 
4781708Sstevel 		if ((status = pd_get_sensor_reading()) != PD_SUCCESS) {
4791708Sstevel 			return (status);
4801708Sstevel 		}
4811708Sstevel 
4821708Sstevel 		if ((status = pd_get_sensor_threshold()) != PD_SUCCESS) {
4831708Sstevel 			return (status);
4841708Sstevel 		}
4851708Sstevel 
4861708Sstevel 	}
4871708Sstevel 	return (status);
4881708Sstevel 
4891708Sstevel }
4901708Sstevel 
4911708Sstevel /*
4921708Sstevel  * This routine prints the mode in which SMC is running. It uses the
4931708Sstevel  * response from SMC global enables to determine the mode
4941708Sstevel  */
4951708Sstevel static uint32_t
pd_check_tty_debug_mode()4961708Sstevel pd_check_tty_debug_mode()
4971708Sstevel {
4981708Sstevel 
4991708Sstevel 	if (pd_smc_glbl_enabl_rsp[1] & 0x20) {
5001708Sstevel 		log_printf("SMC verbose mode\t\t\tON\n", 0);
5011708Sstevel 	} else {
5021708Sstevel 		log_printf("SMC verbose mode\t\t\tOFF\n", 0);
5031708Sstevel 	}
5041708Sstevel 
5051708Sstevel 	return (PD_SUCCESS);
5061708Sstevel }
5071708Sstevel 
5081708Sstevel /* This routine prints SMC f/w version */
5091708Sstevel static uint32_t
pd_query_SMC_firmware_version()5101708Sstevel pd_query_SMC_firmware_version()
5111708Sstevel {
5121708Sstevel 
5131708Sstevel 	sc_reqmsg_t req_pkt;
5141708Sstevel 	sc_rspmsg_t rsp_pkt;
5151708Sstevel 	uint8_t ver, rev, bldrev;
5161708Sstevel 
5171708Sstevel 
5181708Sstevel 	smc_init_smc_msg(&req_pkt, SMC_QUERY_FIRMWARE_VERSION,
519*13019SMichael.Bergknoff@Oracle.COM 	    DEFAULT_SEQN, 0);
5201708Sstevel 	smc_send_msg(-1, &req_pkt, &rsp_pkt, POLL_TIMEOUT);
5211708Sstevel 	ver = (rsp_pkt.data[0] & 0xf0) >> 4;
5221708Sstevel 	rev = rsp_pkt.data[0] & 0x0f;
5231708Sstevel 	bldrev = rsp_pkt.data[2] & 0x3f;
5241708Sstevel 
5251708Sstevel 	log_printf("SMC f/w version is\t\t\t%d.%d.%d\n", ver, rev, bldrev, 0);
5261708Sstevel 
5271708Sstevel 	return (PD_SUCCESS);
5281708Sstevel 
5291708Sstevel }
5301708Sstevel 
5311708Sstevel /*
5321708Sstevel  * This routine checks CPU's health by using SMC self test results command
5331708Sstevel  * It acts as driver routine for printing cPCI slot information
5341708Sstevel  */
5351708Sstevel static uint32_t
pd_check_cpu_health()5361708Sstevel pd_check_cpu_health()
5371708Sstevel {
5381708Sstevel 
5391708Sstevel 	sc_reqmsg_t req_pkt;
5401708Sstevel 	sc_rspmsg_t rsp_pkt;
5411708Sstevel 	uint8_t	dev_id = 0x1f;
5421708Sstevel #ifdef DEBUG
5431708Sstevel 	uint8_t i2c_chk = 0x40;
5441708Sstevel #endif
5451708Sstevel 	uint8_t mem_test = 0x20;
5461708Sstevel 
5471708Sstevel 	smc_init_smc_msg(&req_pkt, SMC_GET_SMC_SELF_TEST_RESULT,
548*13019SMichael.Bergknoff@Oracle.COM 	    DEFAULT_SEQN, 0);
5491708Sstevel 	smc_send_msg(-1, &req_pkt, &rsp_pkt, POLL_TIMEOUT);
5501708Sstevel 
5511708Sstevel 	dev_id = rsp_pkt.data[0] & dev_id;
5521708Sstevel 
5531708Sstevel #ifdef DEBUG
5541708Sstevel 	if (rsp_pkt.data[0] & i2c_chk) {
5551708Sstevel 		pd_print_device_info(dev_id);
5561708Sstevel 	}
5571708Sstevel #endif
5581708Sstevel 	if (rsp_pkt.data[0] & mem_test) {
5591708Sstevel 		pd_print_device_info(dev_id);
5601708Sstevel 	}
5611708Sstevel 	return (pd_check_slots());
5621708Sstevel 
5631708Sstevel }
5641708Sstevel 
5651708Sstevel /*
5661708Sstevel  * This routine decodes error message for CPU failures and prints details
5671708Sstevel  * of the failure
5681708Sstevel  */
5691708Sstevel static uint32_t
pd_print_device_info(int dev_id)5701708Sstevel pd_print_device_info(int dev_id)
5711708Sstevel {
5721708Sstevel 
5731708Sstevel 	switch (dev_id) {
5741708Sstevel 		case 1:
5751708Sstevel 			log_printf("Mux Philip 9540\n", 0);
5761708Sstevel 			break;
5771708Sstevel 		case 2:
5781708Sstevel 			log_printf("cpu temp max1617\n", 0);
5791708Sstevel 			break;
5801708Sstevel 		case 3:
5811708Sstevel 			log_printf("pmc temp max 1617\n", 0);
5821708Sstevel 			break;
5831708Sstevel 		case 4:
5841708Sstevel 			log_printf("MB HS temp max 1617\n", 0);
5851708Sstevel 			break;
5861708Sstevel 		case 5:
5871708Sstevel 			log_printf("MB mem temp max1617\n", 0);
5881708Sstevel 			break;
5891708Sstevel 		case 6:
5901708Sstevel 			log_printf("MB gpio Philip8574\n", 0);
5911708Sstevel 			break;
5921708Sstevel 		case 7:
5931708Sstevel 			log_printf("MB Fru ID ID i2c eep\n", 0);
5941708Sstevel 			break;
5951708Sstevel 		case 8:
5961708Sstevel 			log_printf("MB enet ID ID i2d eep\n", 0);
5971708Sstevel 			break;
5981708Sstevel 		case 9:
5991708Sstevel 			log_printf("MB gpio Philip8574A\n", 0);
6001708Sstevel 			break;
6011708Sstevel 		case 10:
6021708Sstevel 			log_printf("SDRAM mod1 temp max1617\n", 0);
6031708Sstevel 			break;
6041708Sstevel 		case 11:
6051708Sstevel 			log_printf("SDRAM mod ID  ID i2c eep\n", 0);
6061708Sstevel 			break;
6071708Sstevel 		case 12:
6081708Sstevel 			log_printf("SDRAM mod2 temp max1617\n", 0);
6091708Sstevel 			break;
6101708Sstevel 		case 13:
6111708Sstevel 			log_printf("SDRAM mod ID  ID i2c eep\n", 0);
6121708Sstevel 			break;
6131708Sstevel 		case 14:
6141708Sstevel 			log_printf("Power mod temp ds1721\n", 0);
6151708Sstevel 			break;
6161708Sstevel 		case 15:
6171708Sstevel 			log_printf("Power mod gpio Philip 8574\n", 0);
6181708Sstevel 			break;
6191708Sstevel 		case 16:
6201708Sstevel 			log_printf("Power mod ID eep ST M24C01\n", 0);
6211708Sstevel 			break;
6221708Sstevel 		case 17:
6231708Sstevel 			log_printf("SMC ID i2c eep\n", 0);
6241708Sstevel 			break;
6251708Sstevel 
6261708Sstevel 		default:
6271708Sstevel 			log_printf("device id unknown\n", 0);
6281708Sstevel 			break;
6291708Sstevel 
6301708Sstevel 	}
6311708Sstevel 
6321708Sstevel 	return (PD_SUCCESS);
6331708Sstevel 
6341708Sstevel }
6351708Sstevel 
6361708Sstevel /*
6371708Sstevel  * This routine walks PICL tree by "Location" class and calls prt_slot_info
6381708Sstevel  * routine to print the slot information
6391708Sstevel  */
6401708Sstevel 
6411708Sstevel /*ARGSUSED*/
6421708Sstevel static uint32_t
pd_check_slots()6431708Sstevel pd_check_slots()
6441708Sstevel {
6451708Sstevel 
6461708Sstevel 	picl_nodehdl_t nodeh;
6471708Sstevel 	char *c_args = NULL;
6481708Sstevel 
6491708Sstevel 	if (picl_get_root(&nodeh) != PICL_SUCCESS)
6501708Sstevel 		return (PD_INTERNAL_FAILURE);
6511708Sstevel 
6521708Sstevel 
6531708Sstevel 	if (picl_walk_tree_by_class(nodeh, PICL_CLASS_LOCATION,
654*13019SMichael.Bergknoff@Oracle.COM 	    (void *)c_args, pd_prt_slot_info) != PICL_SUCCESS) {
6551708Sstevel 		return (PD_INTERNAL_FAILURE);
6561708Sstevel 	}
6571708Sstevel 
6581708Sstevel 	return (PD_SUCCESS);
6591708Sstevel 
6601708Sstevel }
6611708Sstevel 
6621708Sstevel 
6631708Sstevel /*ARGSUSED*/
6641708Sstevel int32_t
6651708Sstevel 
pd_prt_slot_info(picl_nodehdl_t nodeh,void * c_args)6661708Sstevel pd_prt_slot_info(picl_nodehdl_t nodeh, void *c_args)
6671708Sstevel {
6681708Sstevel 
6691708Sstevel 	char *valbuf;
6701708Sstevel 	char label_txt[30];
6711708Sstevel 	int unit_no = -1, ctr = 0;
6721708Sstevel 	picl_nodehdl_t childh;
6731708Sstevel 	picl_propinfo_t propinfo;
6741708Sstevel 	picl_prophdl_t proph;
6751708Sstevel 
6761708Sstevel 	/* if not immediate child of "chassis" node, ignore it */
6771708Sstevel 	if (pd_check_location_parent(nodeh) != PD_SUCCESS)
6781708Sstevel 		return (PD_INTERNAL_FAILURE);
6791708Sstevel 
6801708Sstevel 
6811708Sstevel 	/* get the label on the location */
6821708Sstevel 	if (picl_get_prop_by_name(nodeh, PICL_PROP_LABEL,
683*13019SMichael.Bergknoff@Oracle.COM 	    &proph) != PICL_SUCCESS)
6841708Sstevel 		return (PD_INTERNAL_FAILURE);
6851708Sstevel 
6861708Sstevel 	if (picl_get_propinfo(proph, &propinfo) != PICL_SUCCESS)
6871708Sstevel 		return (PD_INTERNAL_FAILURE);
6881708Sstevel 
6891708Sstevel 	valbuf = (char *) malloc(sizeof (char) * (propinfo.size));
6901708Sstevel 	if (valbuf == NULL)
6911708Sstevel 		return (PD_INTERNAL_FAILURE);
6921708Sstevel 
6931708Sstevel 	if (picl_get_propval(proph, (void *)valbuf, propinfo.size)
694*13019SMichael.Bergknoff@Oracle.COM 	    != PICL_SUCCESS) {
6951708Sstevel 		free(valbuf);
6961708Sstevel 		return (PD_INTERNAL_FAILURE);
6971708Sstevel 	}
6981708Sstevel 
6991708Sstevel 	while (valbuf[ctr] != ' ' && valbuf[ctr] != NULL) {
7001708Sstevel 		label_txt[ctr] = valbuf[ctr];
7011708Sstevel 		++ctr;
7021708Sstevel 	}
7031708Sstevel 
7041708Sstevel 	label_txt[ctr++] = '\0';
7051708Sstevel 
7061708Sstevel 	if (valbuf[ctr] != NULL) {
7071708Sstevel 		unit_no = atoi(valbuf+ctr);
7081708Sstevel 	}
7091708Sstevel 
7101708Sstevel 	free(valbuf);
7111708Sstevel 
7121708Sstevel 	/* get the slot type for the location */
7131708Sstevel 	if (picl_get_prop_by_name(nodeh, PICL_PROP_SLOT_TYPE,
714*13019SMichael.Bergknoff@Oracle.COM 	    &proph) != PICL_SUCCESS)
7151708Sstevel 		return (PD_INTERNAL_FAILURE);
7161708Sstevel 
7171708Sstevel 	if (picl_get_propinfo(proph, & propinfo) != PICL_SUCCESS)
7181708Sstevel 		return (PD_INTERNAL_FAILURE);
7191708Sstevel 
7201708Sstevel 	valbuf = (char *) malloc(sizeof (char) * (propinfo.size));
7211708Sstevel 	if (valbuf == NULL)
7221708Sstevel 		return (PD_INTERNAL_FAILURE);
7231708Sstevel 
7241708Sstevel 	if (picl_get_propval(proph, (void *)valbuf,
725*13019SMichael.Bergknoff@Oracle.COM 	    propinfo.size) != PICL_SUCCESS) {
7261708Sstevel 		free(valbuf);
7271708Sstevel 		return (PD_INTERNAL_FAILURE);
7281708Sstevel 	}
7291708Sstevel 
7301708Sstevel 	if ((strcmp(valbuf, PD_CPCI_SLOT_TYPE) == 0) ||
7311708Sstevel 	    (strcmp(valbuf, PD_PCI_SLOT_TYPE) == 0)) {
7321708Sstevel 		(void) pd_print_fruinfo_hdr();
7331708Sstevel 		log_printf("\n%s         ", label_txt, 0);
7341708Sstevel 
7351708Sstevel 	/* For Snowbird no unit number is present on the label */
7361708Sstevel 		unit_no = 1;
7371708Sstevel 		log_printf(" %d       Yes      cPSB IO Slot\n", unit_no, 0);
7381708Sstevel 
7391708Sstevel 		if (picl_get_propval_by_name(nodeh, PICL_PROP_CHILD,
740*13019SMichael.Bergknoff@Oracle.COM 		    &childh, sizeof (childh)) == PICL_SUCCESS) {
7411708Sstevel 			pd_prt_cpci_condition(childh);
7421708Sstevel 		}
7431708Sstevel 		/* For Snowbird auto configuration is always enabled */
7441708Sstevel 		log_printf("%29s Properties:\n", PD_BLANK, 0);
7451708Sstevel 		log_printf("%31s auto-config = enabled\n", PD_BLANK, 0);
7461708Sstevel 	}
7471708Sstevel 
7481708Sstevel 
7491708Sstevel 	free(valbuf);
7501708Sstevel 	return (PD_SUCCESS);
7511708Sstevel 
7521708Sstevel }
7531708Sstevel 
7541708Sstevel 
7551708Sstevel 
7561708Sstevel static uint32_t
pd_print_fruinfo_hdr()7571708Sstevel pd_print_fruinfo_hdr()
7581708Sstevel {
7591708Sstevel 
7601708Sstevel 	log_printf(
761*13019SMichael.Bergknoff@Oracle.COM 	    "\n %19s FRU Information \n",
762*13019SMichael.Bergknoff@Oracle.COM 	    PD_BLANK, 0);
7631708Sstevel 	log_printf(
764*13019SMichael.Bergknoff@Oracle.COM 	    "%11s ------------------------------------------------\n",
765*13019SMichael.Bergknoff@Oracle.COM 	    PD_BLANK, 0);
7661708Sstevel 
7671708Sstevel 	log_printf(dgettext(TEXT_DOMAIN,
768*13019SMichael.Bergknoff@Oracle.COM 	    "FRU         FRU    FRU      Miscellaneous\n"), 0);
7691708Sstevel 	log_printf(dgettext(TEXT_DOMAIN,
770*13019SMichael.Bergknoff@Oracle.COM 	    "Type        Unit#  Present  Information\n"), 0);
7711708Sstevel 	log_printf("----        -----  -------", 0);
7721708Sstevel 	log_printf("  --------------------------------\n", 0);
7731708Sstevel 	return (PD_SUCCESS);
7741708Sstevel 
7751708Sstevel }
7761708Sstevel 
7771708Sstevel static uint32_t
pd_check_location_parent(picl_nodehdl_t nodeh)7781708Sstevel pd_check_location_parent(picl_nodehdl_t nodeh)
7791708Sstevel {
7801708Sstevel 
7811708Sstevel 	picl_nodehdl_t parenth;
7821708Sstevel 	char *prop_name;
7831708Sstevel 
7841708Sstevel 	if (picl_get_propval_by_name(nodeh, PICL_PROP_PARENT,
785*13019SMichael.Bergknoff@Oracle.COM 	    &parenth, sizeof (parenth)) != PICL_SUCCESS) {
7861708Sstevel 		return (PD_FAILURE);
7871708Sstevel 	}
7881708Sstevel 
7891708Sstevel 	prop_name = (char *) malloc(sizeof (char) * PICL_PROPNAMELEN_MAX);
7901708Sstevel 	if (prop_name == NULL) {
7911708Sstevel 		return (PD_FAILURE);
7921708Sstevel 	}
7931708Sstevel 
7941708Sstevel 	if (picl_get_propval_by_name(parenth, PICL_PROP_NAME, (void *)prop_name,
795*13019SMichael.Bergknoff@Oracle.COM 	    PICL_PROPNAMELEN_MAX) != PICL_SUCCESS) {
7961708Sstevel 		free(prop_name);
7971708Sstevel 		return (PD_FAILURE);
7981708Sstevel 	}
7991708Sstevel 
8001708Sstevel 	if (strcmp(prop_name, CHASSIS_NODE_NAME) == 0) {
8011708Sstevel 		free(prop_name);
8021708Sstevel 		return (PD_SUCCESS);
8031708Sstevel 	} else {
8041708Sstevel 		free(prop_name);
8051708Sstevel 		return (PD_FAILURE);
8061708Sstevel 	}
8071708Sstevel 
8081708Sstevel }
8091708Sstevel 
8101708Sstevel 
8111708Sstevel /*ARGSUSED*/
8121708Sstevel static uint32_t
pd_query_watchdog_state()8131708Sstevel pd_query_watchdog_state()
8141708Sstevel {
8151708Sstevel 
8161708Sstevel 	picl_nodehdl_t nodehandle;
8171708Sstevel 	char *c_args = NULL;
8181708Sstevel 
8191708Sstevel 	if (picl_get_root(&nodehandle) != PICL_SUCCESS) {
8201708Sstevel 		return (PD_INTERNAL_FAILURE);
8211708Sstevel 	}
8221708Sstevel 
8231708Sstevel 	if (picl_walk_tree_by_class(nodehandle, PICL_CLASS_WATCHDOG_TIMER,
824*13019SMichael.Bergknoff@Oracle.COM 	    (void *)c_args, pd_check_wd_state) != PICL_SUCCESS)
8251708Sstevel 		return (PD_INTERNAL_FAILURE);
8261708Sstevel 
8271708Sstevel 	return (PD_SUCCESS);
8281708Sstevel 
8291708Sstevel }
8301708Sstevel 
8311708Sstevel /*ARGSUSED*/
8321708Sstevel int
pd_check_wd_state(picl_nodehdl_t nodeh,void * c_args)8331708Sstevel pd_check_wd_state(picl_nodehdl_t nodeh, void *c_args)
8341708Sstevel {
8351708Sstevel 
8361708Sstevel 	char *prop_name, *valbuf;
8371708Sstevel 	picl_propinfo_t propinfo;
8381708Sstevel 	picl_prophdl_t proph;
8391708Sstevel 
8401708Sstevel 	prop_name = (char *) malloc(sizeof (char) * PICL_PROPNAMELEN_MAX);
8411708Sstevel 	if (prop_name == NULL) {
8421708Sstevel 		return (PICL_WALK_TERMINATE);
8431708Sstevel 	}
8441708Sstevel 
8451708Sstevel 	if (picl_get_propval_by_name(nodeh, PICL_PROP_NAME,
846*13019SMichael.Bergknoff@Oracle.COM 	    (void *)prop_name, PICL_PROPNAMELEN_MAX) != PICL_SUCCESS) {
8471708Sstevel 		free(prop_name);
8481708Sstevel 		return (PICL_WALK_TERMINATE);
8491708Sstevel 	}
8501708Sstevel 
8511708Sstevel 	if ((picl_get_prop_by_name(nodeh, PICL_PROP_STATE,
852*13019SMichael.Bergknoff@Oracle.COM 	    &proph)) != PICL_SUCCESS) {
8531708Sstevel 		free(prop_name);
8541708Sstevel 		return (PICL_WALK_TERMINATE);
8551708Sstevel 	}
8561708Sstevel 
8571708Sstevel 	if ((picl_get_propinfo(proph, &propinfo)) != PICL_SUCCESS) {
8581708Sstevel 		free(prop_name);
8591708Sstevel 		return (PICL_WALK_TERMINATE);
8601708Sstevel 	}
8611708Sstevel 
8621708Sstevel 	valbuf = (char *) malloc(sizeof (char) * (propinfo.size));
8631708Sstevel 	if (valbuf == NULL) {
8641708Sstevel 		free(prop_name);
8651708Sstevel 		return (PICL_WALK_TERMINATE);
8661708Sstevel 	}
8671708Sstevel 
8681708Sstevel 	if ((picl_get_propval(proph, (void *)valbuf,
869*13019SMichael.Bergknoff@Oracle.COM 	    propinfo.size)) != PICL_SUCCESS) {
8701708Sstevel 		free(valbuf);
8711708Sstevel 		free(prop_name);
8721708Sstevel 		return (PICL_WALK_TERMINATE);
8731708Sstevel 	}
8741708Sstevel 
8751708Sstevel 	if (pd_hdr_prt) {
8761708Sstevel 		log_printf("\n       Watch Dog Status \n", 0);
8771708Sstevel 		log_printf("       ---------------- \n", 0);
8781708Sstevel 		log_printf("Node                      Status\n", 0);
8791708Sstevel 		log_printf("----                      ------\n", 0);
8801708Sstevel 		pd_hdr_prt = B_FALSE;
8811708Sstevel 	}
8821708Sstevel 
8831708Sstevel 	log_printf("%s           ", prop_name, 0);
8841708Sstevel 	log_printf("%s\n", valbuf, 0);
8851708Sstevel 
8861708Sstevel 	free(prop_name);
8871708Sstevel 	free(valbuf);
8881708Sstevel 	return (PICL_WALK_CONTINUE);
8891708Sstevel 
8901708Sstevel }
8911708Sstevel 
8921708Sstevel 
8931708Sstevel static uint32_t
pd_get_role_information()8941708Sstevel pd_get_role_information()
8951708Sstevel {
8961708Sstevel 
8971708Sstevel 	sc_reqmsg_t req_pkt;
8981708Sstevel 	sc_rspmsg_t rsp_pkt;
8991708Sstevel 	uint8_t usparc_role;
9001708Sstevel 
9011708Sstevel 	smc_init_smc_msg(&req_pkt, SMC_GET_ROLE_INFO,
902*13019SMichael.Bergknoff@Oracle.COM 	    DEFAULT_SEQN, 0);
9031708Sstevel 	smc_send_msg(-1, &req_pkt, &rsp_pkt, POLL_TIMEOUT);
9041708Sstevel 	usparc_role = rsp_pkt.data[1];
9051708Sstevel 
9061708Sstevel 	log_printf(dgettext(TEXT_DOMAIN,
907*13019SMichael.Bergknoff@Oracle.COM 	    "UltraSPARC Host Role\t\t\t"), 0);
9081708Sstevel 	if (usparc_role & 0x80) {
9091708Sstevel 		log_printf(
910*13019SMichael.Bergknoff@Oracle.COM 		    dgettext(TEXT_DOMAIN,
911*13019SMichael.Bergknoff@Oracle.COM 		    "System Board Computer (SBC)\n"), 0);
9121708Sstevel 	}
9131708Sstevel 	if (usparc_role & 0x40) {
9141708Sstevel 		log_printf(dgettext(TEXT_DOMAIN,
915*13019SMichael.Bergknoff@Oracle.COM 		    "Standby System Board Computer (Standby SBC)\n"), 0);
9161708Sstevel 	}
9171708Sstevel 	if (usparc_role & 0x20) {
9181708Sstevel 		log_printf(dgettext(TEXT_DOMAIN,
9191708Sstevel 		"Alternate System Board Computer (Alternate SBC)\n"), 0);
9201708Sstevel 	}
9211708Sstevel 	if (usparc_role & 0x10) {
9221708Sstevel 		log_printf(dgettext(TEXT_DOMAIN,
923*13019SMichael.Bergknoff@Oracle.COM 		    "Satellite Board Computer (SAT)\n"), 0);
9241708Sstevel 	}
9251708Sstevel 	return (PD_SUCCESS);
9261708Sstevel 
9271708Sstevel }
9281708Sstevel 
9291708Sstevel 
9301708Sstevel static uint32_t
pd_get_message_flags()9311708Sstevel pd_get_message_flags()
9321708Sstevel {
9331708Sstevel 
9341708Sstevel 	sc_reqmsg_t req_pkt;
9351708Sstevel 	sc_rspmsg_t rsp_pkt;
9361708Sstevel 
9371708Sstevel 	smc_init_smc_msg(&req_pkt, SMC_GET_MESSAGE_FLAGS,
938*13019SMichael.Bergknoff@Oracle.COM 	    DEFAULT_SEQN, 0);
9391708Sstevel 	smc_send_msg(-1, &req_pkt, &rsp_pkt, POLL_TIMEOUT);
9401708Sstevel 
9411708Sstevel 	if (rsp_pkt.data[0] & 0x01) {
9421708Sstevel 		log_printf("Messages Available in queue Recieving\n", 0);
9431708Sstevel 	} else {
9441708Sstevel 		log_printf("No messages in queue for Recieving\n", 0);
9451708Sstevel 	}
9461708Sstevel 
9471708Sstevel 	return (PD_SUCCESS);
9481708Sstevel 
9491708Sstevel 
9501708Sstevel }
9511708Sstevel 
9521708Sstevel 
9531708Sstevel 
9541708Sstevel static uint32_t
pd_get_reset_mode()9551708Sstevel pd_get_reset_mode()
9561708Sstevel {
9571708Sstevel 
9581708Sstevel 	sc_reqmsg_t req_pkt;
9591708Sstevel 	sc_rspmsg_t rsp_pkt;
9601708Sstevel 
9611708Sstevel 
9621708Sstevel 	smc_init_smc_msg(&req_pkt, SMC_GET_CONFIG_BLOCK,
963*13019SMichael.Bergknoff@Oracle.COM 	    DEFAULT_SEQN,  0);
9641708Sstevel 	smc_send_msg(-1, &req_pkt, &rsp_pkt, POLL_TIMEOUT);
9651708Sstevel 
9661708Sstevel 	log_printf("Reset Mode\t\t\t\t%x \n", rsp_pkt.data[2], 0);
9671708Sstevel 
9681708Sstevel 	return (PD_SUCCESS);
9691708Sstevel 
9701708Sstevel }
9711708Sstevel 
9721708Sstevel 
9731708Sstevel static uint32_t
pd_get_sensor_reading()9741708Sstevel pd_get_sensor_reading()
9751708Sstevel {
9761708Sstevel 
9771708Sstevel 
9781708Sstevel 	sc_reqmsg_t req_pkt;
9791708Sstevel 	sc_rspmsg_t rsp_pkt;
9801708Sstevel 
9811708Sstevel 	req_pkt.data[0] = 0x0e;
9821708Sstevel 
9831708Sstevel 	smc_init_smc_msg(&req_pkt, SMC_SENSOR_READING_GET,
984*13019SMichael.Bergknoff@Oracle.COM 	    DEFAULT_SEQN, 1);
9851708Sstevel 	smc_send_msg(-1, &req_pkt, &rsp_pkt, POLL_TIMEOUT);
9861708Sstevel 	log_printf("\nCPU Node Temperature Information\n", PD_BLANK, 0);
9871708Sstevel 	log_printf("--------------------------------\n", PD_BLANK, 0);
9881708Sstevel 	log_printf("Temperature Reading: %d\n\n", rsp_pkt.data[0], 0);
9891708Sstevel 
9901708Sstevel 	return (PD_SUCCESS);
9911708Sstevel 
9921708Sstevel }
9931708Sstevel 
9941708Sstevel 
9951708Sstevel static uint32_t
pd_get_sensor_threshold()9961708Sstevel pd_get_sensor_threshold()
9971708Sstevel {
9981708Sstevel 
9991708Sstevel 
10001708Sstevel 	sc_reqmsg_t req_pkt;
10011708Sstevel 	sc_rspmsg_t rsp_pkt;
10021708Sstevel 	uint8_t thres_mask;
10031708Sstevel 	req_pkt.data[0] = 0x0e;
10041708Sstevel 
10051708Sstevel 	smc_init_smc_msg(&req_pkt, SMC_SENSOR_THRESHOLD_GET,
1006*13019SMichael.Bergknoff@Oracle.COM 	    DEFAULT_SEQN,  1);
10071708Sstevel 	smc_send_msg(-1, &req_pkt, &rsp_pkt, POLL_TIMEOUT);
10081708Sstevel 	log_printf("Critical Threshold Information\n", 0);
10091708Sstevel 	log_printf("------------------------------\n", 0);
10101708Sstevel 
10111708Sstevel 	thres_mask = rsp_pkt.data[0];
10121708Sstevel 
10131708Sstevel 	if (thres_mask & 0x20) {
10141708Sstevel 		log_printf("High Power-Off Threshold %9s", PD_BLANK, 0);
10151708Sstevel 		if (rsp_pkt.data[6] & 0x80) {
10161708Sstevel 			log_printf("-%d\n",
1017*13019SMichael.Bergknoff@Oracle.COM 			    (int)((uint8_t)~rsp_pkt.data[6] + 1), 0);
10181708Sstevel 		} else {
10191708Sstevel 			log_printf(" %d\n", rsp_pkt.data[6], 0);
10201708Sstevel 		}
10211708Sstevel 	}
10221708Sstevel 
10231708Sstevel 	if (thres_mask & 0x10) {
10241708Sstevel 		log_printf("High Shutdown Threshold %10s", PD_BLANK, 0);
10251708Sstevel 		if (rsp_pkt.data[5] & 0x80) {
10261708Sstevel 			log_printf("-%d\n",
1027*13019SMichael.Bergknoff@Oracle.COM 			    (int)((uint8_t)~rsp_pkt.data[5] + 1), 0);
10281708Sstevel 		} else {
10291708Sstevel 			log_printf(" %d\n", rsp_pkt.data[5], 0);
10301708Sstevel 		}
10311708Sstevel 	}
10321708Sstevel 
10331708Sstevel 
10341708Sstevel 	if (thres_mask & 0x08) {
10351708Sstevel 		log_printf("High Warning Threshold %11s", PD_BLANK, 0);
10361708Sstevel 		if (rsp_pkt.data[4] & 0x80) {
10371708Sstevel 			log_printf("-%d\n",
1038*13019SMichael.Bergknoff@Oracle.COM 			    (int)((uint8_t)~rsp_pkt.data[4] + 1), 0);
10391708Sstevel 		} else {
10401708Sstevel 			log_printf(" %d\n", rsp_pkt.data[4], 0);
10411708Sstevel 		}
10421708Sstevel 	}
10431708Sstevel 
10441708Sstevel 	if (thres_mask & 0x04) {
10451708Sstevel 		log_printf("Low Power Off Threshold %10s", PD_BLANK, 0);
10461708Sstevel 		if (rsp_pkt.data[3] & 0x80) {
10471708Sstevel 			log_printf("-%d\n",
1048*13019SMichael.Bergknoff@Oracle.COM 			    (int)((uint8_t)~rsp_pkt.data[3] + 1), 0);
10491708Sstevel 		} else {
10501708Sstevel 			log_printf(" %d\n", rsp_pkt.data[3], 0);
10511708Sstevel 		}
10521708Sstevel 	}
10531708Sstevel 
10541708Sstevel 	if (thres_mask & 0x02) {
10551708Sstevel 		log_printf("Low Shutdown Threshold %11s", PD_BLANK, 0);
10561708Sstevel 		if (rsp_pkt.data[2] & 0x80) {
10571708Sstevel 			log_printf("-%d\n",
1058*13019SMichael.Bergknoff@Oracle.COM 			    (int)((uint8_t)~rsp_pkt.data[2] + 1), 0);
10591708Sstevel 		} else {
10601708Sstevel 			log_printf(" %d\n", rsp_pkt.data[2], 0);
10611708Sstevel 		}
10621708Sstevel 	}
10631708Sstevel 
10641708Sstevel 	if (thres_mask & 0x01) {
10651708Sstevel 		log_printf("Low Warning Threshold %12s", PD_BLANK, 0);
10661708Sstevel 		if (rsp_pkt.data[1] & 0x80) {
10671708Sstevel 			log_printf("-%d\n",
1068*13019SMichael.Bergknoff@Oracle.COM 			    (int)((uint8_t)~rsp_pkt.data[1] + 1), 0);
10691708Sstevel 		} else {
10701708Sstevel 			log_printf(" %d\n", rsp_pkt.data[1], 0);
10711708Sstevel 		}
10721708Sstevel 	}
10731708Sstevel 
10741708Sstevel 	return (PD_SUCCESS);
10751708Sstevel 
10761708Sstevel }
10771708Sstevel 
10781708Sstevel 
10791708Sstevel 
10801708Sstevel static uint32_t
pd_prt_cpci_condition(picl_nodehdl_t nodeh)10811708Sstevel pd_prt_cpci_condition(picl_nodehdl_t nodeh)
10821708Sstevel {
10831708Sstevel 
10841708Sstevel 	picl_propinfo_t propinfo;
10851708Sstevel 	picl_prophdl_t proph;
10861708Sstevel 	char *valbuf;
10871708Sstevel 
10881708Sstevel 
10891708Sstevel 	if (picl_get_prop_by_name(nodeh, PICL_PROP_CONDITION,
1090*13019SMichael.Bergknoff@Oracle.COM 	    &proph) != PICL_SUCCESS) {
10911708Sstevel 		return (PD_FAILURE);
10921708Sstevel 	}
10931708Sstevel 
10941708Sstevel 	if (picl_get_propinfo(proph, &propinfo) != PICL_SUCCESS) {
10951708Sstevel 		return (PD_FAILURE);
10961708Sstevel 	}
10971708Sstevel 
10981708Sstevel 	valbuf = (char *) malloc(sizeof (char) * (propinfo.size));
10991708Sstevel 	if (valbuf == NULL) {
11001708Sstevel 		return (PD_FAILURE);
11011708Sstevel 	}
11021708Sstevel 
11031708Sstevel 	if (picl_get_propval(proph, (void *)valbuf,
1104*13019SMichael.Bergknoff@Oracle.COM 	    propinfo.size) != PICL_SUCCESS) {
11051708Sstevel 		free(valbuf);
11061708Sstevel 		return (PD_FAILURE);
11071708Sstevel 	}
11081708Sstevel 
11091708Sstevel 
11101708Sstevel 	log_printf("%29s Condition : %s\n", PD_BLANK, valbuf, 0);
11111708Sstevel 
11121708Sstevel 	free(valbuf);
11131708Sstevel 	return (PD_SUCCESS);
11141708Sstevel 
11151708Sstevel 
11161708Sstevel }
1117