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