xref: /onnv-gate/usr/src/lib/libprtdiag/common/display_funcs.c (revision 1708:ea74d8598a3a)
1*1708Sstevel /*
2*1708Sstevel  * CDDL HEADER START
3*1708Sstevel  *
4*1708Sstevel  * The contents of this file are subject to the terms of the
5*1708Sstevel  * Common Development and Distribution License, Version 1.0 only
6*1708Sstevel  * (the "License").  You may not use this file except in compliance
7*1708Sstevel  * with the License.
8*1708Sstevel  *
9*1708Sstevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*1708Sstevel  * or http://www.opensolaris.org/os/licensing.
11*1708Sstevel  * See the License for the specific language governing permissions
12*1708Sstevel  * and limitations under the License.
13*1708Sstevel  *
14*1708Sstevel  * When distributing Covered Code, include this CDDL HEADER in each
15*1708Sstevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*1708Sstevel  * If applicable, add the following below this CDDL HEADER, with the
17*1708Sstevel  * fields enclosed by brackets "[]" replaced with your own identifying
18*1708Sstevel  * information: Portions Copyright [yyyy] [name of copyright owner]
19*1708Sstevel  *
20*1708Sstevel  * CDDL HEADER END
21*1708Sstevel  */
22*1708Sstevel /*
23*1708Sstevel  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*1708Sstevel  * Use is subject to license terms.
25*1708Sstevel  */
26*1708Sstevel 
27*1708Sstevel #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*1708Sstevel 
29*1708Sstevel #include <stdio.h>
30*1708Sstevel #include <stdlib.h>
31*1708Sstevel #include <ctype.h>
32*1708Sstevel #include <string.h>
33*1708Sstevel #include <sys/param.h>
34*1708Sstevel #include <sys/types.h>
35*1708Sstevel #include <sys/utsname.h>
36*1708Sstevel #include <stdarg.h>
37*1708Sstevel #include <syslog.h>
38*1708Sstevel #include <sys/openpromio.h>
39*1708Sstevel #include <libintl.h>
40*1708Sstevel #include "pdevinfo.h"
41*1708Sstevel #include "display.h"
42*1708Sstevel 
43*1708Sstevel #if !defined(TEXT_DOMAIN)
44*1708Sstevel #define	TEXT_DOMAIN	"SYS_TEST"
45*1708Sstevel #endif
46*1708Sstevel 
47*1708Sstevel /*
48*1708Sstevel  * external data
49*1708Sstevel  */
50*1708Sstevel extern int	print_flag;
51*1708Sstevel extern int	logging;
52*1708Sstevel 
53*1708Sstevel /*
54*1708Sstevel  * The following macros for dealing with raw output from the Mostek 48T02
55*1708Sstevel  * were borrowed from the kernel. Openboot passes the raw Mostek data
56*1708Sstevel  * thru the device tree, and there are no library routines to deal with
57*1708Sstevel  * this data.
58*1708Sstevel  */
59*1708Sstevel 
60*1708Sstevel /*
61*1708Sstevel  * Tables to convert a single byte from binary-coded decimal (BCD).
62*1708Sstevel  */
63*1708Sstevel static uchar_t bcd_to_byte[256] = {		/* CSTYLED */
64*1708Sstevel 	 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  0,  0,  0,  0,  0,  0,
65*1708Sstevel 	10, 11, 12, 13, 14, 15, 16, 17, 18, 19,  0,  0,  0,  0,  0,  0,
66*1708Sstevel 	20, 21, 22, 23, 24, 25, 26, 27, 28, 29,  0,  0,  0,  0,  0,  0,
67*1708Sstevel 	30, 31, 32, 33, 34, 35, 36, 37, 38, 39,  0,  0,  0,  0,  0,  0,
68*1708Sstevel 	40, 41, 42, 43, 44, 45, 46, 47, 48, 49,  0,  0,  0,  0,  0,  0,
69*1708Sstevel 	50, 51, 52, 53, 54, 55, 56, 57, 58, 59,  0,  0,  0,  0,  0,  0,
70*1708Sstevel 	60, 61, 62, 63, 64, 65, 66, 67, 68, 69,  0,  0,  0,  0,  0,  0,
71*1708Sstevel 	70, 71, 72, 73, 74, 75, 76, 77, 78, 79,  0,  0,  0,  0,  0,  0,
72*1708Sstevel 	80, 81, 82, 83, 84, 85, 86, 87, 88, 89,  0,  0,  0,  0,  0,  0,
73*1708Sstevel 	90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
74*1708Sstevel };
75*1708Sstevel 
76*1708Sstevel #define	BCD_TO_BYTE(x)	bcd_to_byte[(x) & 0xff]
77*1708Sstevel #define	YRBASE	68
78*1708Sstevel 
79*1708Sstevel static int days_thru_month[64] = {
80*1708Sstevel 	0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366, 0, 0,
81*1708Sstevel 	0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, 0, 0,
82*1708Sstevel 	0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, 0, 0,
83*1708Sstevel 	0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, 0, 0,
84*1708Sstevel };
85*1708Sstevel 
86*1708Sstevel /*
87*1708Sstevel  * This function takes the raw Mostek data from the device tree translates
88*1708Sstevel  * it into UNIXC time (secs since Jan 1, 1970) and returns a string from
89*1708Sstevel  * ctime(3c).
90*1708Sstevel  */
91*1708Sstevel char *
get_time(uchar_t * mostek)92*1708Sstevel get_time(uchar_t *mostek)
93*1708Sstevel {
94*1708Sstevel 	time_t utc;
95*1708Sstevel 	int sec, min, hour, day, month, year;
96*1708Sstevel 
97*1708Sstevel 	year	= BCD_TO_BYTE(mostek[6]) + YRBASE;
98*1708Sstevel 	month	= BCD_TO_BYTE(mostek[5] & 0x1f) + ((year & 3) << 4);
99*1708Sstevel 	day	= BCD_TO_BYTE(mostek[4] & 0x3f);
100*1708Sstevel 	hour	= BCD_TO_BYTE(mostek[2] & 0x3f);
101*1708Sstevel 	min	= BCD_TO_BYTE(mostek[1] & 0x7f);
102*1708Sstevel 	sec	= BCD_TO_BYTE(mostek[0] & 0x7f);
103*1708Sstevel 
104*1708Sstevel 	utc = (year - 70);		/* next 3 lines: utc = 365y + y/4 */
105*1708Sstevel 	utc += (utc << 3) + (utc << 6);
106*1708Sstevel 	utc += (utc << 2) + ((year - 69) >> 2);
107*1708Sstevel 	utc += days_thru_month[month] + day - 1;
108*1708Sstevel 	utc = (utc << 3) + (utc << 4) + hour;	/* 24 * day + hour */
109*1708Sstevel 	utc = (utc << 6) - (utc << 2) + min;	/* 60 * hour + min */
110*1708Sstevel 	utc = (utc << 6) - (utc << 2) + sec;	/* 60 * min + sec */
111*1708Sstevel 
112*1708Sstevel 	return (ctime((time_t *)&utc));
113*1708Sstevel }
114*1708Sstevel 
115*1708Sstevel void
disp_powerfail(Prom_node * root)116*1708Sstevel disp_powerfail(Prom_node *root)
117*1708Sstevel {
118*1708Sstevel 	Prom_node *pnode;
119*1708Sstevel 	char *option_str = "options";
120*1708Sstevel 	char *pf_str = "powerfail-time";
121*1708Sstevel 	char *value_str;
122*1708Sstevel 	time_t value;
123*1708Sstevel 
124*1708Sstevel 	pnode = dev_find_node(root, option_str);
125*1708Sstevel 	if (pnode == NULL) {
126*1708Sstevel 		return;
127*1708Sstevel 	}
128*1708Sstevel 
129*1708Sstevel 	value_str = get_prop_val(find_prop(pnode, pf_str));
130*1708Sstevel 	if (value_str == NULL) {
131*1708Sstevel 		return;
132*1708Sstevel 	}
133*1708Sstevel 
134*1708Sstevel 	value = (time_t)atoi(value_str);
135*1708Sstevel 	if (value == 0)
136*1708Sstevel 		return;
137*1708Sstevel 
138*1708Sstevel 	(void) log_printf(
139*1708Sstevel 		dgettext(TEXT_DOMAIN,
140*1708Sstevel 			"Most recent AC Power Failure:\n"));
141*1708Sstevel 	(void) log_printf("=============================\n");
142*1708Sstevel 	(void) log_printf("%s", ctime(&value));
143*1708Sstevel 	(void) log_printf("\n");
144*1708Sstevel }
145*1708Sstevel 
146*1708Sstevel 
147*1708Sstevel /*VARARGS1*/
148*1708Sstevel void
log_printf(char * fmt,...)149*1708Sstevel log_printf(char *fmt, ...)
150*1708Sstevel {
151*1708Sstevel 	va_list ap;
152*1708Sstevel 	int len;
153*1708Sstevel 	static char bigbuf[4096];
154*1708Sstevel 	char buffer[1024];
155*1708Sstevel 
156*1708Sstevel 	if (print_flag == 0) {
157*1708Sstevel 		return;
158*1708Sstevel 	}
159*1708Sstevel 
160*1708Sstevel 	va_start(ap, fmt);
161*1708Sstevel 	if (logging != 0) {
162*1708Sstevel 		len = vsprintf(buffer, fmt, ap);
163*1708Sstevel 		(void) strcat(bigbuf, buffer);
164*1708Sstevel 
165*1708Sstevel 		/* we only call to syslog when we get the entire line. */
166*1708Sstevel 		if (buffer[len-1] == '\n') {
167*1708Sstevel 			syslog(LOG_DAEMON|LOG_NOTICE, bigbuf);
168*1708Sstevel 			bigbuf[0] = 0;
169*1708Sstevel 		}
170*1708Sstevel 
171*1708Sstevel 	} else {
172*1708Sstevel 		(void) vprintf(fmt, ap);
173*1708Sstevel 	}
174*1708Sstevel 	va_end(ap);
175*1708Sstevel }
176*1708Sstevel 
177*1708Sstevel void
print_header(int board)178*1708Sstevel print_header(int board)
179*1708Sstevel {
180*1708Sstevel 	log_printf("\n");
181*1708Sstevel 	log_printf(dgettext(TEXT_DOMAIN,
182*1708Sstevel 		"Analysis for Board %d\n"), board, 0);
183*1708Sstevel 	log_printf("--------------------\n", 0);
184*1708Sstevel }
185