#ident "$Header: engine.c 1.5 89/02/24 $"

/*
 * $Copyright:	$
 * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989, 1990 
 * Sequent Computer Systems, Inc.   All rights reserved.
 *  
 * This software is furnished under a license and may be used
 * only in accordance with the terms of that license and with the
 * inclusion of the above copyright notice.   This software may not
 * be provided or otherwise made available to, or used by, any
 * other person.  No title to or ownership of the software is
 * hereby transferred.
 */

#ifndef lint
static char rcsid[] = "$Header: engine.c 1.5 89/02/24 $";
#endif

#include "crash.h"

#include <sys/types.h>
#include <sys/param.h>
#include <sys/mutex.h>
#include <sys/systm.h>
#include <sys/map.h>
#include <sys/dir.h>
#include <sys/resource.h>
#include <signal.h>
#include <sys/user.h>
#include <sys/timer.h>
#include <sys/proc.h>

#include <sys/engine.h>

struct engine *l_engine;	/* local copy of engine table */
struct engine *v_engine;	/* kernel virtual address of engine table */
unsigned Nengine;		/* number of engines */
unsigned nonline;		/* number of online engines */

bool_t dblpanic;		/* double panic? */
struct panic_data panic_data;	/* panic data stuffed here */

eng_init()
{
	if (search("panic_data") == NULL)
		printf("Warning:  no kernel data structure 'panic_data', probably an old kernel.\n");
	readv(search("Nengine"), &Nengine, sizeof Nengine);
	readv(search("nonline"), &nonline, sizeof nonline);
	readv(search("panic_data"), &panic_data, sizeof panic_data);
	readv(search("dblpanic"), &dblpanic, sizeof dblpanic);
	if (dblpanic)
		printf("Warning: double panic occured\n");
	if (Nengine > MAXNUMCPU)
		printf("%u for Nengine?, memory probably hosed.\n", Nengine);
	else  if (nonline > MAXNUMCPU || nonline > Nengine)
		printf("%u online, %d Nengine?, memory probably hosed.\n",
		    nonline, Nengine);
	else  if (Nengine != nonline)
		printf("Engine table: %d of %d engines online\n", nonline, Nengine);
	readv(search("engine"), &v_engine, sizeof v_engine);
	l_engine = (struct engine *)malloc(Nengine * sizeof (struct engine));
	readv(v_engine, l_engine, Nengine * sizeof (struct engine));
}

Eng()
{
	register int i;
	register char *arg;

	printf("ENG    HEAD    TAIL SLIC   DIAG    FLAG  STATE PRI NPRI CNT  ELOCAL\n");
	if ((arg = token()) == NULL) {
		for(i = 0; i < Nengine; i++)
			preng(i);
	} else
		 do {
			preng(atoi(arg));
		} while ((arg = token()));
}

Every()
{
	register char *arg;
	extern	int	Eve;
	char	buf[512];
	extern 	char	pline[512];

	if (!live) {
		printf("option only valid on live systems\n");
		return;
	}
	strcpy(buf,pline);
	if ((arg = token()) == NULL) {
		Eve = 0;
	} else
		Eve = atoi(arg);
	strcpy(pline,buf);
	printf("%d seconds\n",Eve);
}

preng(i)
{
	register struct engine *e, *v;
	register char *p;
	char lbuf[128];

	if ( i > Nengine) {
		printf("eng %d?, silly boy..\n", i);
		return;
	}
	e = &l_engine[i];
	v = &v_engine[i];
	if (live) readv(v, e, sizeof (struct engine));
	printf("%3d %#06x %#06x %4d ", i, e->e_head, e->e_tail, e->e_slicaddr);
	switch (e->e_diag_flag) {
		case 0:		p = "      "; break;
		default:	sprintf(lbuf, "%#06x", e->e_diag_flag); p = lbuf; break;
	}
	printf("%s ", p);
	switch (e->e_flags) {
		default: 	sprintf(lbuf, "%#07x", e->e_flags); p = lbuf; break;
		case 0:		p = "       "; break;
		case E_OFFLINE: p = "OFFLINE"; break;
		case E_BAD:	p = "    BAD"; break;
		case E_SHUTDOWN:p = "SHUTDWN"; break;
		case E_DRIVER:	p = " DRIVER"; break;
		case E_PAUSED:	p = " PAUSED"; break;
	}
	printf("%s ", p);
	switch (e->e_state) {
		default:	sprintf(lbuf, "%#06x", e->e_state); p = lbuf; break;
		case E_GLOBAL:	p = "GLOBAL"; break;
		case E_BOUND:	p = "BOUND"; break;
	}
	printf("%s %3d  %3d  %2d %#06x", p, (unchar) e->e_pri, (unchar) e->e_npri, e->e_count, e->e_local);
	if (v == panic_data.pd_engine) {
		if (panic_data.pd_proc)
			printf(" [proc=%d]", panic_data.pd_proc - proc);
		else
			printf(" [idle]");
	}
	printf("\n");
}
