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