379 lines
8.9 KiB
C
379 lines
8.9 KiB
C
/**************************************************************************
|
|
* *
|
|
* Copyright (C) 1988, Silicon Graphics, Inc. *
|
|
* *
|
|
* These coded instructions, statements, and computer programs contain *
|
|
* unpublished proprietary information of Silicon Graphics, Inc., and *
|
|
* are protected by Federal copyright law. They may not be disclosed *
|
|
* to third parties or copied or duplicated in any form, in whole or *
|
|
* in part, without the prior written consent of Silicon Graphics, Inc. *
|
|
* *
|
|
**************************************************************************/
|
|
|
|
#ident "$Revision: 1.4 $"
|
|
|
|
#include <stdarg.h>
|
|
#include <saioctl.h>
|
|
#include <libsc.h>
|
|
#include <libsk.h>
|
|
#include <uif.h>
|
|
#include <ide_msg.h>
|
|
|
|
#define PUTBUFSIZE 0xc00
|
|
#define MAXMSGLENGTH 160
|
|
|
|
#ifdef PROM
|
|
static __psint_t spReportlevel;
|
|
__psint_t *Reportlevel=&spReportlevel;
|
|
#endif
|
|
|
|
short msg_where; /* indicates destination of output */
|
|
static char putbuf[PUTBUFSIZE]; /* storage for msg_printf() output */
|
|
unsigned int putbufndx; /* index to next character in putbuf */
|
|
|
|
unsigned int putbufndx; /* index to next character in putbuf */
|
|
short msg_where; /* indicates destination of output */
|
|
int failflag;
|
|
|
|
#ifndef PROM
|
|
/*********** MESSAGE LOGGING FOR SERVER SYSTEMS ***************/
|
|
static char *msglog = NULL; /* malloc'ed storage for msg log */
|
|
#define DEFAULT_MSG_LOG_SIZE (50 * 1024)
|
|
int msglogsize = 0;
|
|
/* used by pager() when we print the msg log */
|
|
extern pagesize;
|
|
unsigned int msglogndx;
|
|
extern int pager(char *, int , int *);
|
|
/*********** MESSAGE LOGGING FOR SERVER SYSTEMS ***************/
|
|
#endif
|
|
|
|
|
|
/*
|
|
* msg_printf - message printf
|
|
*
|
|
* This function is intended to be the formatted print tool common to
|
|
* all diagnostic tests. It is patterned after printf() but requires
|
|
* that a "message level" be provided with each call. Actual output
|
|
* only occurs when this message level is less than or equal to the
|
|
* symbol value pointed to by the globally defined "Reportlevel".
|
|
* Also provided is the ability to temporarily buffer messages when
|
|
* buffering mode is turned on via the externally defined variable
|
|
* "msg_where".
|
|
*
|
|
* WARNING: For message buffering to work messages must not be longer
|
|
* than MAXMSGLENGTH.
|
|
*/
|
|
/*VARARGS2*/
|
|
void
|
|
msg_printf(int msglevel, char *fmt, ...)
|
|
{
|
|
extern short msg_where; /* indicates destination of output */
|
|
static char errmsg[] = "\r\t\t\t\t\t\t\t\t- ERROR -\n";
|
|
va_list ap;
|
|
|
|
if (msglevel == ERR)
|
|
{
|
|
#if IP22 || IP26
|
|
ip22_set_cpuled(3); /* red */
|
|
#endif
|
|
#if IP20
|
|
ip20_set_sickled(1);
|
|
#endif
|
|
/*
|
|
* We use a failure flag to tell us whether the failure LED should
|
|
* be on or off at any given time. This way we can do things like
|
|
* blink the LED during long tests and leave it in its proper state
|
|
* at the end of the test.
|
|
*/
|
|
failflag = 1;
|
|
}
|
|
|
|
if ( !(msg_where & PRW_BUF) && putbufndx )
|
|
{
|
|
/* We're NOT in "buffering" mode and there's something in the
|
|
* buffer, so print it out.
|
|
*/
|
|
printf("%s", putbuf);
|
|
putbufndx = 0;
|
|
}
|
|
|
|
if (msglevel <= *Reportlevel)
|
|
{
|
|
va_start(ap,fmt);
|
|
if (msg_where & PRW_BUF)
|
|
{
|
|
/*
|
|
* We`re in "buffering" mode (we must be waiting for the
|
|
* graphics console to be initialized).
|
|
*/
|
|
if ((putbufndx + sizeof(errmsg)) < (PUTBUFSIZE - MAXMSGLENGTH))
|
|
{
|
|
if (msglevel == ERR)
|
|
{
|
|
sprintf(&putbuf[putbufndx], "%s", errmsg);
|
|
/*
|
|
* Move the buffer pointer to end of newly added string.
|
|
*/
|
|
putbufndx += sizeof(errmsg) - 1;
|
|
}
|
|
vsprintf(&putbuf[putbufndx], fmt, ap);
|
|
/*
|
|
* Move the buffer pointer to end of newly added string.
|
|
* NOTE: The pointer is left pointing at the terminating
|
|
* NULL char so that it will be overwritten and the
|
|
* buffer will end up containing one big string.
|
|
*/
|
|
while ( (putbuf[putbufndx] != '\0') &&
|
|
(putbufndx < (PUTBUFSIZE-1)) )
|
|
putbufndx++;
|
|
}
|
|
}
|
|
|
|
#ifndef PROM
|
|
/********** BEGIN SERVER MESSAGE LOGGING *************/
|
|
if (msg_where & MSG_LOG)
|
|
{
|
|
/* log and print output messages */
|
|
if ((msglogndx + sizeof(errmsg)) < (msglogsize - MAXMSGLENGTH))
|
|
{
|
|
if (msglevel == ERR)
|
|
{
|
|
/* log the message */
|
|
sprintf(msglog+msglogndx, "%s", errmsg);
|
|
msglogndx += sizeof(errmsg) - 1;
|
|
}
|
|
|
|
/* log the message */
|
|
vsprintf(msglog+msglogndx, fmt, ap);
|
|
while ( (*(msglog+msglogndx) != '\0') &&
|
|
(msglogndx < (msglogsize-1)) ) {
|
|
msglogndx++;
|
|
}
|
|
|
|
} else {
|
|
/* Ouch! message buffer overflow */
|
|
msg_where |= MSG_LOG_OVERFLOW;
|
|
}
|
|
|
|
/* just print the message out */
|
|
if (msglevel == ERR)
|
|
{
|
|
printf("%s", errmsg);
|
|
}
|
|
vprintf(fmt, ap);
|
|
}
|
|
/********** END SERVER MESSSAGE LOGGING **********/
|
|
#endif
|
|
else
|
|
{
|
|
if (msglevel == ERR)
|
|
{
|
|
printf("%s", errmsg);
|
|
}
|
|
vprintf(fmt, ap);
|
|
}
|
|
va_end(ap);
|
|
}
|
|
}
|
|
|
|
extern int gfx_testing;
|
|
|
|
/*
|
|
* buffon - msg_printf buffering ON
|
|
*
|
|
* If using the graphics console, turn on buffering within msg_printf().
|
|
*/
|
|
void
|
|
buffon(void)
|
|
{
|
|
if (console_is_gfx()) {
|
|
gfx_testing = 1;
|
|
msg_where |= PRW_BUF; /* buffering is ON */
|
|
msg_where &= ~PRW_CONS;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* buffoff - msg_printf buffering OFF
|
|
*/
|
|
void
|
|
buffoff(void)
|
|
{
|
|
gfx_testing = 0;
|
|
msg_where |= PRW_CONS; /* buffering is OFF */
|
|
msg_where &= ~PRW_BUF;
|
|
msg_printf(VRB, ""); /* dummy msg_printf call to flush buffer */
|
|
|
|
}
|
|
|
|
#if !defined(PROM)
|
|
|
|
/*********************************
|
|
* SERVER message logging code *
|
|
*********************************/
|
|
|
|
/*
|
|
* msglog_start
|
|
* Allocate a large buffer and start logging IDE
|
|
* msg_printfs
|
|
*
|
|
* arguments:
|
|
* -b xxx Buffer size in bytes. Defaults to 100Kb
|
|
* -r Restart msg logging. Don't allocate new buffer
|
|
*
|
|
*/
|
|
msglog_start(int argc, char *argv[])
|
|
{
|
|
int i;
|
|
|
|
msg_where &= ~MSG_LOG;
|
|
|
|
/* parse arguments */
|
|
if (argc < 2) {
|
|
if (msglog != NULL) {
|
|
/* just restart */
|
|
bzero(msglog, msglogsize);
|
|
} else {
|
|
/* no size specified; default is 100k */
|
|
msglogsize = DEFAULT_MSG_LOG_SIZE;
|
|
if ( (msglog = (char *)malloc(msglogsize)) == NULL) {
|
|
msg_printf(JUST_DOIT,
|
|
"\nERR: Unable to allocate %d byte message log buffer\n",
|
|
msglogsize);
|
|
msg_printf(JUST_DOIT,
|
|
"\nERR: Message log not started\n");
|
|
return 1;
|
|
}
|
|
}
|
|
msglogndx = 0;
|
|
msg_where |= MSG_LOG;
|
|
|
|
} else {
|
|
for (i=1; i < argc; i++) {
|
|
if (argv[i][0] != '-')
|
|
goto msglog_start_usage;
|
|
else
|
|
switch (argv[i][1]) {
|
|
case 'b':
|
|
i++;
|
|
/* verify the buffer size argument was passed */
|
|
if (i >= argc) {
|
|
goto msglog_start_usage;
|
|
}
|
|
|
|
(void)atob(argv[i], &msglogsize);
|
|
|
|
if (msglog != NULL) {
|
|
free(msglog);
|
|
}
|
|
|
|
if ( (msglog = (char *)malloc(msglogsize)) == NULL) {
|
|
msg_printf(JUST_DOIT,
|
|
"\nERR: Unable to alloc %d byte message log buffer\n",
|
|
msglogsize);
|
|
msg_printf(JUST_DOIT,
|
|
"\nERR: Message log not started\n");
|
|
return 1;
|
|
}
|
|
msglogndx = 0;
|
|
msg_where |= MSG_LOG;
|
|
|
|
break;
|
|
|
|
default:
|
|
goto msglog_start_usage;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
|
|
msglog_start_usage:
|
|
printf("usage: msglog_start [-b SIZE]\n");
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
* msglog_stop
|
|
* Disable IDE msg_printf logging
|
|
*
|
|
*/
|
|
msglog_stop(int argc, char *argv[])
|
|
{
|
|
msg_where &= ~MSG_LOG;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* msglog_info:
|
|
* print information about the msg log such as total
|
|
* size and size in use.
|
|
*/
|
|
msglog_info()
|
|
{
|
|
|
|
printf("MsgLog Bufsize = %d[0x%x] bytes\n", msglogsize, msglogsize);
|
|
printf("In Use = %d[0x%x] bytes\n", msglogndx, msglogndx);
|
|
|
|
/* print log status */
|
|
printf("Status = ");
|
|
if (msg_where & MSG_LOG) {
|
|
printf("Logging Messages");
|
|
} else {
|
|
printf("Not Logging Messages");
|
|
}
|
|
|
|
if (msg_where & MSG_LOG_OVERFLOW) {
|
|
printf(", Log Overflow");
|
|
}
|
|
printf("\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
* msglog_print
|
|
* Print out the message log. Printing the log
|
|
* momentarily turns off message logging.
|
|
*
|
|
*/
|
|
msglog_print()
|
|
{
|
|
char linebuf[80];
|
|
int line = 0;
|
|
char reenable = 0;
|
|
|
|
if (msglog == NULL) {
|
|
msg_printf(JUST_DOIT, "No message log\n");
|
|
return 0;
|
|
}
|
|
|
|
if (msg_where & MSG_LOG) {
|
|
msg_where &= ~MSG_LOG;
|
|
reenable++;
|
|
}
|
|
if (msg_where & MSG_LOG_OVERFLOW) {
|
|
pager("\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", pagesize, &line);
|
|
pager("!!!!!!!!!!! WARNING !!!!!!!!!!!!!", pagesize, &line);
|
|
pager("!!!!!! MESSAGE LOG OVERFLOW !!!!!", pagesize, &line);
|
|
pager("!!!!!! DATA HAS BEEN LOST !!!!!!!", pagesize, &line);
|
|
pager("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", pagesize, &line);
|
|
msg_printf(JUST_DOIT,
|
|
"\n - Press <ENTER> to continue - ");
|
|
gets(linebuf);
|
|
}
|
|
|
|
pager("\n*********** START OF MESSAGE LOG ***********", pagesize, &line);
|
|
pager(msglog, pagesize, &line);
|
|
pager("************ END OF MESSAGE LOG ************", pagesize, &line);
|
|
|
|
if (reenable)
|
|
msg_where |= MSG_LOG;
|
|
|
|
return 0;
|
|
}
|
|
|
|
#endif /*** MESSAGE LOGGING ******/
|