/*
 * This file is part of the UCB release of Plan 9. It is subject to the license
 * terms in the LICENSE file found in the top-level directory of this
 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
 * part of the UCB release of Plan 9, including this file, may be copied,
 * modified, propagated, or distributed except according to the terms contained
 * in the LICENSE file.
 */

#include <arch/arch.h>
#include <ros/fs.h>
#include <ns.h>
#include <kmalloc.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <atomic.h>
#include <smp.h>
#include <error.h>
#include <sys/queue.h>
#include <event.h>
#include <ros/procinfo.h>

#if 0
void (*consdebug) (void) = NULL;
#endif
void (*screenputs) (const char *, int) = cputbuf;

struct queue *kbdq;				/* unprocessed console input */
struct queue *lineq;			/* processed console input */
struct queue *serialoq;			/* serial console output */
struct queue *kprintoq;			/* console output, for /dev/kprint */
atomic_t kprintinuse = 0;		/* test and set whether /dev/kprint is open */
int iprintscreenputs = 1;
int keepbroken = 1;

static uint8_t logbuffer[1 << 20];
static int index = 0;
static struct queue *logqueue = NULL;
static int reading_kmesg = 0;

typedef unsigned char uint8_t;

void logbuf(int c)
{
	if (reading_kmesg)
		return;
	if (index > 1 << 20)
		return;
	logbuffer[index++] = c;
}

/*
 *  return true if current user is eve
 */
int iseve(void)
{
#if 0
	return strcmp(eve, o->user) == 0;
#endif
	return 1;
}

char *eve = "eve";
char hostdomain[256] = "akaros.org";

static struct {
	qlock_t qlock;

	int raw;					/* true if we shouldn't process input */
	struct kref ctl;			/* number of opens to the control file */
	int x;						/* index into line */
	char line[1024];			/* current input line */

	int count;
	int ctlpoff;

	/* a place to save up characters at interrupt time before dumping them in the queue */
	spinlock_t lockputc;
	char istage[1024];
	char *iw;
	char *ir;
	char *ie;
} kbd = {
.iw = kbd.istage,.ir = kbd.istage,.ie = kbd.istage + sizeof(kbd.istage),};

char *sysname;
int64_t fasthz;

static int readtime(uint32_t, char *, int);
static int readbintime(char *, int);
static int writetime(char *, int);
static int writebintime(char *, int);
static void killkid(void);

enum {
	CMbroken,
	CMconsole,
	CMhalt,
	CMnobroken,
	CMpanic,
	CMreboot,
};


struct cmdtab rebootmsg[] = {
	{CMbroken, "broken", 0},
	{CMconsole, "console", 1},
	{CMhalt, "halt", 1},
	{CMnobroken, "nobroken", 0},
	{CMpanic, "panic", 0},
	{CMreboot, "reboot", 0},
};

void printinit(void)
{
	lineq = qopen(2 * 1024, 0, NULL, NULL);
	if (lineq == NULL)
		panic("printinit");
	qdropoverflow(lineq, 1);
}

int consactive(void)
{
	if (serialoq)
		return qlen(serialoq) > 0;
	return 0;
}

void prflush(void)
{
	long times = 0;

	while (consactive())
		if (times++ > 1000)
			break;
}

/*
 * Log console output so it can be retrieved via /dev/kmesg.
 * This is good for catching boot-time messages after the fact.
 */
struct {
	spinlock_t lk;
	char buf[1 << 20];
	unsigned int n;
} kmesg;

static void kmesgputs(char *str, int n)
{
	unsigned int nn, d;

	spin_lock_irqsave(&kmesg.lk);
	/* take the tail of huge writes */
	if (n > sizeof kmesg.buf) {
		d = n - sizeof kmesg.buf;
		str += d;
		n -= d;
	}

	/* slide the buffer down to make room */
	nn = kmesg.n;
	if (nn + n >= sizeof kmesg.buf) {
		d = nn + n - sizeof kmesg.buf;
		if (d)
			memmove(kmesg.buf, kmesg.buf + d, sizeof kmesg.buf - d);
		nn -= d;
	}

	/* copy the data in */
	memmove(kmesg.buf + nn, str, n);
	nn += n;
	kmesg.n = nn;
	spin_unlock_irqsave(&kmesg.lk);
}

/*
 *   Print a string on the console.  Convert \n to \r\n for serial
 *   line consoles.  Locking of the queues is left up to the screen
 *   or uart code.  Multi-line messages to serial consoles may get
 *   interspersed with other messages.
 */
static void putstrn0(char *str, int n, int usewrite)
{
	int m;
	char *t;

#if 0
	if (!islo())
		usewrite = 0;
#endif

	/*
	 *  how many different output devices do we need?
	 */
	kmesgputs(str, n);

	/*
	 *  if someone is reading /dev/kprint
	 *  put the message there.
	 *  if not and there's an attached bit mapped display,
	 *  put the message there.
	 *
	 *  if there's a serial line being used as a console,
	 *  put the message there.
	 */
	if (kprintoq != NULL && !qisclosed(kprintoq)) {
		if (usewrite)
			qwrite(kprintoq, str, n);
		else
			qiwrite(kprintoq, str, n);
	} else if (screenputs != NULL)
		screenputs(str, n);

	if (serialoq == NULL) {
#if 0
		uartputs(str, n);
#endif
		return;
	}

	while (n > 0) {
		t = memchr(str, '\n', n);
		if (t && !kbd.raw) {
			m = t - str;
			if (usewrite) {
				qwrite(serialoq, str, m);
				qwrite(serialoq, "\r\n", 2);
			} else {
				qiwrite(serialoq, str, m);
				qiwrite(serialoq, "\r\n", 2);
			}
			n -= m + 1;
			str = t + 1;
		} else {
			if (usewrite)
				qwrite(serialoq, str, n);
			else
				qiwrite(serialoq, str, n);
			break;
		}
	}
}

void putstrn(char *str, int n)
{
	putstrn0(str, n, 0);
}

int noprint;

int print(char *fmt, ...)
{
	int n;
	va_list arg;
	char buf[PRINTSIZE];

	if (noprint)
		return -1;

	va_start(arg, fmt);
	n = vsnprintf(buf, sizeof(buf), fmt, arg);
	va_end(arg);
	putstrn(buf, n);

	return n;
}

/*
 * Want to interlock iprints to avoid interlaced output on
 * multiprocessor, but don't want to deadlock if one processor
 * dies during print and another has something important to say.
 * Make a good faith effort.
 */
static spinlock_t iprintlock;
static int iprintcanlock(spinlock_t * l)
{
	int i;

	for (i = 0; i < 1000; i++) {
		if (spin_trylock(l))
			return 1;
	}
	return 0;
}

int iprint(char *fmt, ...)
{
	int8_t s = 0;
	int n, locked;
	va_list arg;
	char buf[PRINTSIZE];

	disable_irqsave(&s);
	va_start(arg, fmt);
	n = vsnprintf(buf, sizeof(buf), fmt, arg);
	va_end(arg);
	locked = iprintcanlock(&iprintlock);
	if (screenputs != NULL && iprintscreenputs)
		screenputs(buf, n);
#if 0
	uartputs(buf, n);
#endif
	if (locked)
		spin_unlock(&iprintlock);
	enable_irqsave(&s);

	return n;
}

/* libmp at least contains a few calls to sysfatal; simulate with panic */
void sysfatal(char *fmt, ...)
{
	char err[256];
	va_list arg;

	va_start(arg, fmt);
	vsnprintf(err, sizeof err, fmt, arg);
	va_end(arg);
	panic("sysfatal: %s", err);
}

void _assert(char *fmt)
{
	panic("assert failed at %#p: %s", getcallerpc(&fmt), fmt);
}

#if 0
int pprint(char *fmt, ...)
{
	ERRSTACK(2);
	int n;
	struct chan *c;
	va_list arg;
	char buf[2 * PRINTSIZE];

	if (up == NULL || current->fgrp == NULL)
		return 0;

	c = current->fgrp->fd[2];
	if (c == 0 || (c->mode != O_WRITE && c->mode != O_RDWR))
		return 0;
	n = snprintf(buf, sizeof buf, "%s %lud: ", current->text, current->pid);
	va_start(arg, fmt);
	n = vsnprintf(buf + n, sizeof(buf), fmt, arg);
	va_end(arg);

	if (waserror())
		return 0;
	devtab[c->type]->write(c, buf, n, c->offset);
	poperror();

	spin_lock(&c->lock);
	c->offset += n;
	spin_unlock(&c->lock);

	return n;
}
#endif

static void echoscreen(char *buf, int n)
{
	char *e, *p;
	char ebuf[128];
	int x;

	p = ebuf;
	e = ebuf + sizeof(ebuf) - 4;
	while (n-- > 0) {
		if (p >= e) {
			screenputs(ebuf, p - ebuf);
			p = ebuf;
		}
		x = *buf++;
		if (x == 0x15) {
			*p++ = '^';
			*p++ = 'U';
			*p++ = '\n';
		} else
			*p++ = x;
	}
	if (p != ebuf)
		screenputs(ebuf, p - ebuf);
}

static void echoserialoq(char *buf, int n)
{
	char *e, *p;
	char ebuf[128];
	int x;

	p = ebuf;
	e = ebuf + sizeof(ebuf) - 4;
	while (n-- > 0) {
		if (p >= e) {
			qiwrite(serialoq, ebuf, p - ebuf);
			p = ebuf;
		}
		x = *buf++;
		if (x == '\n') {
			*p++ = '\r';
			*p++ = '\n';
		} else if (x == 0x15) {
			*p++ = '^';
			*p++ = 'U';
			*p++ = '\n';
		} else
			*p++ = x;
	}
	if (p != ebuf)
		qiwrite(serialoq, ebuf, p - ebuf);
}

static void echo(char *buf, int n)
{
	static int ctrlt, pid;
	char *e, *p;

	if (n == 0)
		return;

	e = buf + n;
	for (p = buf; p < e; p++) {
		switch (*p) {
#if 0
			case 0x10:	/* ^P */
				if (cpuserver && !kbd.ctlpoff) {
					active.exiting = 1;
					return;
				}
				break;
#endif
			case 0x14:	/* ^T */
				ctrlt++;
				if (ctrlt > 2)
					ctrlt = 2;
				continue;
		}

		if (ctrlt != 2)
			continue;

		/* ^T escapes */
		ctrlt = 0;
		switch (*p) {
#if 0
			case 'S':{
					int8_t x = 0;
					disable_irqsave(&x);
					dumpstack();
					procdump();
					enable_irqsave(&x);
					return;
				}
#endif
			case 's':
				dumpstack();
				return;
#if 0
			case 'x':
				xsummary();
				ixsummary();
				mallocsummary();
				memorysummary();
				pagersummary();
				return;
			case 'd':
				if (consdebug == NULL)
					consdebug = rdb;
				else
					consdebug = NULL;
				printd("consdebug now %#p\n", consdebug);
				return;
			case 'D':
				if (consdebug == NULL)
					consdebug = rdb;
				consdebug();
				return;
			case 'p':
				x = spllo();
				procdump();
				splx(x);
				return;
			case 'q':
				scheddump();
				return;
			case 'k':
				killbig("^t ^t k");
				return;
#endif
			case 'r':
				exit(0);
				return;
		}
	}

	qwrite(kbdq, buf, n);	/* was once qproduce, YMMV */
	if (kbd.raw)
		return;
	kmesgputs(buf, n);
	if (screenputs != NULL)
		echoscreen(buf, n);
	if (serialoq)
		echoserialoq(buf, n);
}

/*
 *  Called by a uart interrupt for console input.
 *
 *  turn '\r' into '\n' before putting it into the queue.
 */
int kbdcr2nl(struct queue *ignored_queue, int ch)
{
	char *next;

	spin_lock_irqsave(&kbd.lockputc);	/* just a mutex */
	if (ch == '\r' && !kbd.raw)
		ch = '\n';
	next = kbd.iw + 1;
	if (next >= kbd.ie)
		next = kbd.istage;
	if (next != kbd.ir) {
		*kbd.iw = ch;
		kbd.iw = next;
	}
	spin_unlock_irqsave(&kbd.lockputc);
	return 0;
}

/*
 *  Put character, possibly a rune, into read queue at interrupt time.
 *  Called at interrupt time to process a character.
 */
int kbdputc(struct queue *unused_queue, int ch)
{
	int i, n;
	char buf[3];
	// Akaros does not use Rune et al.
	//Rune r;
	int r;
	char *next;

	if (kbd.ir == NULL)
		return 0;	/* in case we're not inited yet */

	spin_lock_irqsave(&kbd.lockputc);	/* just a mutex */
	r = ch;
	//n = runetochar(buf, &r);
	// Fake Rune support.
	n = 1;
	buf[0] = r;
	for (i = 0; i < n; i++) {
		next = kbd.iw + 1;
		if (next >= kbd.ie)
			next = kbd.istage;
		if (next == kbd.ir)
			break;
		*kbd.iw = buf[i];
		kbd.iw = next;
	}
	spin_unlock_irqsave(&kbd.lockputc);
	return 0;
}

/*
 *  we save up input characters till clock time to reduce
 *  per character interrupt overhead.
 */
static void kbdputcclock(void)
{
	char *iw;

	/* this amortizes cost of qproduce */
	if (kbd.iw != kbd.ir) {
		iw = kbd.iw;
		if (iw < kbd.ir) {
			echo(kbd.ir, kbd.ie - kbd.ir);
			kbd.ir = kbd.istage;
		}
		if (kbd.ir != iw) {
			echo(kbd.ir, iw - kbd.ir);
			kbd.ir = iw;
		}
	}
}

enum {
	Qdir,
	Qbintime,
	Qconfig,
	Qcons,
	Qconsctl,
	Qcputime,
	Qdrivers,
	Qhostdomain,
	Qhostowner,
	Qklog,
	Qkmesg,
	Qkprint,
	Qnull,
	Qosversion,
	Qpgrpid,
	Qpid,
	Qppid,
	Qreboot,
	Qswap,
	Qsysctl,
	Qsysname,
	Qsysstat,
	Qtime,
	Quser,
	Qzero,
	Qkillkid,
};

enum {
	VLNUMSIZE = 22,
	DOMLEN = 256,
};

static struct dirtab consdir[] = {
	{".", {Qdir, 0, QTDIR}, 0, DMDIR | 0555},
	{"bintime", {Qbintime}, 24, 0664},
	{"config", {Qconfig}, 0, 0444},
	{"cons", {Qcons}, 0, 0660},
	{"consctl", {Qconsctl}, 0, 0220},
	// FIXME -- we don't have real permissions yet so we set it to 222, not 220
	{"killkid", {Qkillkid}, 0, 0220 | /* BOGUS */ 2},
	{"cputime", {Qcputime}, 6 * NUMSIZE, 0444},
	{"drivers", {Qdrivers}, 0, 0444},
	{"hostdomain", {Qhostdomain}, DOMLEN, 0664},
	{"hostowner", {Qhostowner}, 0, 0664},
	{"klog", {Qklog}, 0, 0440},
	{"kmesg", {Qkmesg}, 0, 0440},
	{"kprint", {Qkprint, 0, QTEXCL}, 0, DMEXCL | 0440},
	{"null", {Qnull}, 0, 0666},
	{"osversion", {Qosversion}, 0, 0444},
	{"pgrpid", {Qpgrpid}, NUMSIZE, 0444},
	{"pid", {Qpid}, NUMSIZE, 0444},
	{"ppid", {Qppid}, NUMSIZE, 0444},
	{"reboot", {Qreboot}, 0, 0660},
	{"swap", {Qswap}, 0, 0664},
	{"sysctl", {Qsysctl}, 0, 0666},
	{"sysname", {Qsysname}, 0, 0664},
	{"sysstat", {Qsysstat}, 0, 0666},
	{"time", {Qtime}, NUMSIZE + 3 * VLNUMSIZE, 0664},
	{"user", {Quser}, 0, 0666},
	{"zero", {Qzero}, 0, 0444},
};

int consreadnum(uint32_t off, char *buf, uint32_t n, uint32_t val, int size)
{
	char tmp[64];

	snprintf(tmp, sizeof(tmp), "%*lud", size - 1, val);
	tmp[size - 1] = ' ';
	if (off >= size)
		return 0;
	if (off + n > size)
		n = size - off;
	memmove(buf, tmp + off, n);
	return n;
}

int consreadstr(uint32_t off, char *buf, uint32_t n, char *str)
{
	int size;

	size = strlen(str);
	if (off >= size)
		return 0;
	if (off + n > size)
		n = size - off;
	memmove(buf, str + off, n);
	return n;
}

static void consinit(void)
{
#if 0
	todinit();
#endif
	/*
	 * at 115200 baud, the 1024 char buffer takes 56 ms to process,
	 * processing it every 22 ms should be fine
	 */
#if 0
	addclock0link(kbdputcclock, 22);
#endif
}

static char *devname(void);

static struct chan *consattach(char *spec)
{
	return devattach(devname(), spec);
}

static struct walkqid *conswalk(struct chan *c, struct chan *nc, char **name,
								int nname)
{
	return devwalk(c, nc, name, nname, consdir, ARRAY_SIZE(consdir), devgen);
}

static int consstat(struct chan *c, uint8_t * dp, int n)
{
	return devstat(c, dp, n, consdir, ARRAY_SIZE(consdir), devgen);
}

static struct chan *consopen(struct chan *c, int omode)
{
	c->aux = NULL;
	c = devopen(c, omode, consdir, ARRAY_SIZE(consdir), devgen);
	switch ((uint32_t) c->qid.path) {
		case Qconsctl:
			kref_get(&kbd.ctl, 1);
			break;

		case Qkprint:
			if (atomic_swap(&kprintinuse, 1) != 0) {
				c->flag &= ~COPEN;
				error(EADDRINUSE, "kprintinuse lock failed");
			}
			if (kprintoq == NULL) {
				kprintoq = qopen(8 * 1024, Qcoalesce, 0, 0);
				if (kprintoq == NULL) {
					c->flag &= ~COPEN;
					error(ENOMEM, "Can't allocate kprintoq");
				}
				qdropoverflow(kprintoq, 1);
			} else
				qreopen(kprintoq);
			c->iounit = qiomaxatomic;
			break;
	}
	return c;
}

static void consclose(struct chan *c)
{
	switch ((uint32_t) c->qid.path) {
			/* last close of control file turns off raw */
		case Qconsctl:
			if (c->flag & COPEN) {
				if (kref_put(&kbd.ctl) == 0)
					kbd.raw = 0;
			}
			break;

			/* close of kprint allows other opens */
		case Qkprint:
			if (c->flag & COPEN) {
				kprintinuse = 0;
				qhangup(kprintoq, NULL);
			}
			break;
	}
}

static long consread(struct chan *c, void *buf, long n, int64_t off)
{
	ERRSTACK(1);
	uint32_t l;
#if 0
	Mach *mp;
#endif
	char *b, *bp, ch;
	char tmp[256];				/* must be >= 18*NUMSIZE (Qswap) */
	int i, k, id, send;
	int64_t offset = off;
#if 0
	extern char configfile[];
#endif

	if (n <= 0)
		return n;

	switch ((uint32_t) c->qid.path) {
		case Qdir:
			return devdirread(c, buf, n, consdir, ARRAY_SIZE(consdir), devgen);

		case Qcons:
			qlock(&(&kbd)->qlock);
			if (waserror()) {
				qunlock(&(&kbd)->qlock);
				nexterror();
			}
			while (!qcanread(lineq)) {
				if (qread(kbdq, &ch, 1) == 0)
					continue;
				send = 0;
				if (ch == 0) {
					/* flush output on rawoff -> rawon */
					if (kbd.x > 0)
						send = !qcanread(kbdq);
				} else if (kbd.raw) {
					kbd.line[kbd.x++] = ch;
					send = !qcanread(kbdq);
				} else {
					switch (ch) {
						case '\b':
							if (kbd.x > 0)
								kbd.x--;
							break;
						case 0x15:	/* ^U */
							kbd.x = 0;
							break;
						case '\n':
						case 0x04:	/* ^D */
							send = 1;
						default:
							if (ch != 0x04)
								kbd.line[kbd.x++] = ch;
							break;
					}
				}
				if (send || kbd.x == sizeof kbd.line) {
					qwrite(lineq, kbd.line, kbd.x);
					kbd.x = 0;
				}
			}
			n = qread(lineq, buf, n);
			qunlock(&(&kbd)->qlock);
			poperror();
			return n;

#if 0
		case Qcputime:
			k = offset;
			if (k >= 6 * NUMSIZE)
				return 0;
			if (k + n > 6 * NUMSIZE)
				n = 6 * NUMSIZE - k;
			/* easiest to format in a separate buffer and copy out */
			for (i = 0; i < 6 && NUMSIZE * i < k + n; i++) {
				l = current->time[i];
				if (i == TReal)
					l = MACHP(0)->ticks - l;
				l = TK2MS(l);
				consreadnum(0, tmp + NUMSIZE * i, NUMSIZE, l, NUMSIZE);
			}
			memmove(buf, tmp + k, n);
			return n;
#endif

		case Qkmesg:
			/*
			 * This is unlocked to avoid tying up a process
			 * that's writing to the buffer.  kmesg.n never
			 * gets smaller, so worst case the reader will
			 * see a slurred buffer.
			 */
			if (off >= kmesg.n)
				n = 0;
			else {
				if (off + n > kmesg.n)
					n = kmesg.n - off;
				memmove(buf, kmesg.buf + off, n);
			}
			return n;

		case Qkprint:
			return qread(kprintoq, buf, n);

		case Qpgrpid:
			return consreadnum((uint32_t) offset, buf, n, current->pgrp->pgrpid,
							   NUMSIZE);

		case Qpid:
			return consreadnum((uint32_t) offset, buf, n, current->pid,
							   NUMSIZE);

		case Qppid:
			return consreadnum((uint32_t) offset, buf, n, current->ppid,
							   NUMSIZE);

		case Qtime:
			return readtime((uint32_t) offset, buf, n);

		case Qbintime:
			return readbintime(buf, n);

		case Qhostowner:
			return consreadstr((uint32_t) offset, buf, n, eve);

		case Qhostdomain:
			return consreadstr((uint32_t) offset, buf, n, hostdomain);

		case Quser:
			return consreadstr((uint32_t) offset, buf, n, current->user);

		case Qnull:
			return 0;

#if 0
		case Qconfig:
			return consreadstr((uint32_t) offset, buf, n, configfile);

		case Qsysstat:
			b = kzmalloc(conf.nmach * (NUMSIZE * 11 + 1) + 1, 0);	/* +1 for NUL */
			bp = b;
			for (id = 0; id < 32; id++) {
				if (active.machs & (1 << id)) {
					mp = MACHP(id);
					consreadnum(0, bp, NUMSIZE, id, NUMSIZE);
					bp += NUMSIZE;
					consreadnum(0, bp, NUMSIZE, mp->cs, NUMSIZE);
					bp += NUMSIZE;
					consreadnum(0, bp, NUMSIZE, mp->intr, NUMSIZE);
					bp += NUMSIZE;
					consreadnum(0, bp, NUMSIZE, mp->syscall, NUMSIZE);
					bp += NUMSIZE;
					consreadnum(0, bp, NUMSIZE, mp->pfault, NUMSIZE);
					bp += NUMSIZE;
					consreadnum(0, bp, NUMSIZE, mp->tlbfault, NUMSIZE);
					bp += NUMSIZE;
					consreadnum(0, bp, NUMSIZE, mp->tlbpurge, NUMSIZE);
					bp += NUMSIZE;
					consreadnum(0, bp, NUMSIZE, mp->load, NUMSIZE);
					bp += NUMSIZE;
					consreadnum(0, bp, NUMSIZE,
								(mp->perf.avg_inidle * 100) / mp->perf.period,
								NUMSIZE);
					bp += NUMSIZE;
					consreadnum(0, bp, NUMSIZE,
								(mp->perf.avg_inintr * 100) / mp->perf.period,
								NUMSIZE);
					bp += NUMSIZE;
					*bp++ = '\n';
				}
			}
			if (waserror()) {
				kfree(b);
				nexterror();
			}
			n = consreadstr((uint32_t) offset, buf, n, b);
			kfree(b);
			poperror();
			return n;

		case Qswap:
			snprintf(tmp, sizeof tmp,
					 "%lud memory\n"
					 "%d pagesize\n"
					 "%lud kernel\n"
					 "%lud/%lud user\n"
					 "%lud/%lud swap\n"
					 "%lud/%lud kernel malloc\n"
					 "%lud/%lud kernel draw\n",
					 conf.npage * BY2PG,
					 BY2PG,
					 conf.npage - conf.upages,
					 palloc.user - palloc.freecount, palloc.user,
					 conf.nswap - swapalloc.free, conf.nswap,
					 mainmem->cursize, mainmem->maxsize,
					 imagmem->cursize, imagmem->maxsize);

			return consreadstr((uint32_t) offset, buf, n, tmp);
#endif

		case Qsysname:
			if (sysname == NULL)
				return 0;
			return consreadstr((uint32_t) offset, buf, n, sysname);

		case Qdrivers:
			b = kzmalloc(READSTR, 0);
			if (b == NULL)
				error(ENOMEM, "allocation for /dev/drivers read failed");
			k = 0;
			for (int i = 0; &devtab[i] < __devtabend; i++)
				k += snprintf(b + k, READSTR - k, "#%s\n", devtab[i].name);
			if (waserror()) {
				kfree(b);
				nexterror();
			}
			n = consreadstr((uint32_t) offset, buf, n, b);
			kfree(b);
			poperror();
			return n;

		case Qklog:
			//return qread(klogq, buf, n);
			/* the queue gives us some elasticity for log reading. */
			if (!logqueue)
				logqueue = qopen(1 << 20, 0, 0, 0);
			if (logqueue) {
				int ret;
				/* atomic sets/gets are not that important in this case. */
				reading_kmesg = 1;
				qwrite(logqueue, logbuffer, index);
				index = 0;
				ret = qread(logqueue, buf, n);
				reading_kmesg = 0;
				return ret;
			}
			break;

		case Qzero:
			memset(buf, 0, n);
			return n;

		case Qosversion:
			snprintf(tmp, sizeof tmp, "2000");
			n = consreadstr((uint32_t) offset, buf, n, tmp);
			return n;

		default:
			printd("consread %#llux\n", c->qid.path);
			error(EINVAL, "bad QID in consread");
	}
	return -1;	/* never reached */
}

static long conswrite(struct chan *c, void *va, long n, int64_t off)
{
	ERRSTACK(1);
	char buf[256], ch;
	long l, bp;
	char *a;
	//Mach *mp;
	int id, fd;
	struct chan *swc;
	uint32_t offset;
	struct cmdbuf *cb;
	struct cmdtab *ct;
	int x;
	uint64_t rip, rsp, cr3, flags, vcpu;
	int ret;

	a = va;
	offset = off;

	switch ((uint32_t) c->qid.path) {
		case Qcons:
			/*
			 * Can't page fault in putstrn, so copy the data locally.
			 */
			l = n;
			while (l > 0) {
				bp = l;
				if (bp > sizeof buf)
					bp = sizeof buf;
				memmove(buf, a, bp);
				putstrn0(buf, bp, 1);
				a += bp;
				l -= bp;
			}
			break;

		/* TODO: have it take a command about just *how* to kill the kid? */
		case Qkillkid:
			killkid();
			break;

		case Qconsctl:
			if (n >= sizeof(buf))
				n = sizeof(buf) - 1;
			strncpy(buf, a, n);
			buf[n] = 0;
			for (a = buf; a;) {
				if (strncmp(a, "rawon", 5) == 0) {
					kbd.raw = 1;
					/* clumsy hack - wake up reader */
					ch = 0;
					qwrite(kbdq, &ch, 1);
				} else if (strncmp(a, "rawoff", 6) == 0) {
					kbd.raw = 0;
				} else if (strncmp(a, "ctlpon", 6) == 0) {
					kbd.ctlpoff = 0;
				} else if (strncmp(a, "ctlpoff", 7) == 0) {
					kbd.ctlpoff = 1;
				}
				if ((a = strchr(a, ' ')) != NULL)
					a++;
			}
			break;

		case Qtime:
			if (!iseve())
				error(EPERM, "Hodie Natus Est Radici Frater");
			return writetime(a, n);

		case Qbintime:
			if (!iseve())
				error(EPERM, ERROR_FIXME);
			return writebintime(a, n);

#if 0
		case Qhostowner:
			return hostownerwrite(a, n);

		case Qhostdomain:
			return hostdomainwrite(a, n);

		case Quser:
			return userwrite(a, n);
#endif

		case Qnull:
			break;

		case Qconfig:
			error(EPERM, "Cannot write to config QID");
			break;

		case Qsysctl:
			//if (!iseve()) error(EPERM, ERROR_FIXME);
			cb = parsecmd(a, n);
			if (cb->nf > 1)
			printd("cons sysctl cmd %s\n", cb->f[0]);

		case Qreboot:
			if (!iseve())
				error(EPERM, ERROR_FIXME);
			cb = parsecmd(a, n);

			if (waserror()) {
				kfree(cb);
				nexterror();
			}
			ct = lookupcmd(cb, rebootmsg, ARRAY_SIZE(rebootmsg));
			switch (ct->index) {
				case CMhalt:
					cpu_halt();
					break;
				case CMbroken:
					keepbroken = 1;
					break;
				case CMnobroken:
					keepbroken = 0;
					break;
				case CMreboot:
					reboot();
					break;
				case CMpanic:
					*(uint32_t *) 0 = 0;
					panic("/dev/reboot");
					break;
			}
			poperror();
			kfree(cb);
			break;

#if 0
		case Qsysstat:
			for (id = 0; id < 32; id++) {
				if (active.machs & (1 << id)) {
					mp = MACHP(id);
					mp->cs = 0;
					mp->intr = 0;
					mp->syscall = 0;
					mp->pfault = 0;
					mp->tlbfault = 0;
					mp->tlbpurge = 0;
				}
			}
			break;

		case Qswap:
			if (n >= sizeof buf)
				error(EINVAL, "n is bigger than sizeof buf for Qswap");
			memmove(buf, va, n);	/* so we can NUL-terminate */
			buf[n] = 0;
			/* start a pager if not already started */
			if (strncmp(buf, "start", 5) == 0) {
				kickpager();
				break;
			}
			if (!iseve())
				error(EPERM, ERROR_FIXME);
			if (buf[0] < '0' || '9' < buf[0])
				error(EINVAL, ERROR_FIXME);
			fd = strtoul(buf, 0, 0);
			swc = fdtochan(fd, -1, 1, 1);
			setswapchan(swc);
			break;
#endif

		case Qsysname:
			if (offset != 0)
				error(EINVAL, ERROR_FIXME);
			if (n <= 0 || n >= sizeof buf)
				error(EINVAL, ERROR_FIXME);
			strncpy(buf, a, n);
			buf[n] = 0;
			if (buf[n - 1] == '\n')
				buf[n - 1] = 0;
			kstrdup(&sysname, buf);
			break;

		default:
			printd("conswrite: %#llux\n", c->qid.path);
			error(EINVAL, "bad QID in conswrite");
	}
	return n;
}

struct dev consdevtab __devtab = {
	.name = "cons",

	.reset = devreset,
	.init = consinit,
	.shutdown = devshutdown,
	.attach = consattach,
	.walk = conswalk,
	.stat = consstat,
	.open = consopen,
	.create = devcreate,
	.close = consclose,
	.read = consread,
	.bread = devbread,
	.write = conswrite,
	.bwrite = devbwrite,
	.remove = devremove,
	.wstat = devwstat,
	.power = devpower,
	.chaninfo = devchaninfo,
};

static char *devname(void)
{
	return consdevtab.name;
}

static uint64_t uvorder = 0x0001020304050607ULL;

static uint8_t *le2int64_t(int64_t * to, uint8_t * f)
{
	uint8_t *t, *o;
	int i;

	t = (uint8_t *) to;
	o = (uint8_t *) & uvorder;
	for (i = 0; i < sizeof(int64_t); i++)
		t[o[i]] = f[i];
	return f + sizeof(int64_t);
}

static uint8_t *int64_t2le(uint8_t * t, int64_t from)
{
	uint8_t *f, *o;
	int i;

	f = (uint8_t *) & from;
	o = (uint8_t *) & uvorder;
	for (i = 0; i < sizeof(int64_t); i++)
		t[i] = f[o[i]];
	return t + sizeof(int64_t);
}

static long order = 0x00010203;

static uint8_t *le2long(long *to, uint8_t * f)
{
	uint8_t *t, *o;
	int i;

	t = (uint8_t *) & to;
	o = (uint8_t *) & order;
	for (i = 0; i < sizeof(long); i++)
		t[o[i]] = f[i];
	return f + sizeof(long);
}

static uint8_t *long2le(uint8_t * t, long from)
{
	uint8_t *f, *o;
	int i;

	f = (uint8_t *) & from;
	o = (uint8_t *) & order;
	for (i = 0; i < sizeof(long); i++)
		t[i] = f[o[i]];
	return t + sizeof(long);
}

char *Ebadtimectl = "bad time control";

/*
 *  like the old #c/time but with added info.  Return
 *
 *	secs	nanosecs	fastticks	fasthz
 */
static int readtime(uint32_t off, char *buf, int n)
{
	int64_t nsec, ticks;
	long sec;
	char str[7 * NUMSIZE];

	if (fasthz == 0LL)
		fasthz = __proc_global_info.tsc_freq;
#if 0
	fastticks((uint64_t *) & fasthz);
	nsec = todget(&ticks);
#endif
	ticks = read_tsc();
	nsec = tsc2nsec(ticks);
	sec = nsec / 1000000000ULL;
	snprintf(str, sizeof(str), "%*lud %*llud %*llud %*llud ",
			 NUMSIZE - 1, sec,
			 VLNUMSIZE - 1, nsec, VLNUMSIZE - 1, ticks, VLNUMSIZE - 1, fasthz);
	return consreadstr(off, buf, n, str);
}

/*
 *  set the time in seconds
 */
static int writetime(char *buf, int n)
{
	char b[13];
	long i;
	int64_t now;

	if (n >= sizeof(b))
		error(EINVAL, "bad size in writetime");
	strncpy(b, buf, n);
	b[n] = 0;
	i = strtol(b, 0, 0);
	if (i <= 0)
		error(EINVAL, "Bad time in write");
	now = i * 1000000000LL;
#if 0
	todset(now, 0, 0);
#endif
	return n;
}

/*
 *  read binary time info.  all numbers are little endian.
 *  ticks and nsec are syncronized.
 */
static int readbintime(char *buf, int n)
{
	int i;
	int64_t nsec, ticks;
	uint8_t *b = (uint8_t *) buf;

	i = 0;
	if (fasthz == 0LL)
		fasthz = __proc_global_info.tsc_freq;
#if 0
	fastticks((uint64_t *) & fasthz);
	nsec = todget(&ticks);
#endif
	ticks = read_tsc();
	nsec = tsc2nsec(ticks);
	if (n >= 3 * sizeof(uint64_t)) {
		int64_t2le(b + 2 * sizeof(uint64_t), fasthz);
		i += sizeof(uint64_t);
	}
	if (n >= 2 * sizeof(uint64_t)) {
		int64_t2le(b + sizeof(uint64_t), ticks);
		i += sizeof(uint64_t);
	}
	if (n >= 8) {
		int64_t2le(b, nsec);
		i += sizeof(int64_t);
	}
	return i;
}

/*
 *  set any of the following
 *	- time in nsec
 *	- nsec trim applied over some seconds
 *	- clock frequency
 */
static int writebintime(char *buf, int n)
{
	uint8_t *p;
	int64_t delta = 0;
	long period = 0;

	n--;
	p = (uint8_t *) buf + 1;
	switch (*buf) {
		case 'n':
			if (n < sizeof(int64_t))
				error(EINVAL, ERROR_FIXME);
			le2int64_t(&delta, p);
#if 0
			todset(delta, 0, 0);
#endif
			break;
		case 'd':
			if (n < sizeof(int64_t) + sizeof(long))
				error(EINVAL, ERROR_FIXME);
			p = le2int64_t(&delta, p);
			le2long(&period, p);
#if 0
			todset(-1, delta, period);
#endif
			break;
		case 'f':
			if (n < sizeof(uint64_t))
				error(EINVAL, ERROR_FIXME);
			le2int64_t(&fasthz, p);
			if (fasthz <= 0)
				error(EINVAL, ERROR_FIXME);
#if 0
			todsetfreq(fasthz);
#endif
			break;
	}
	return n;
}

/*
 * find_first_kid finds your immediate descendant. Not because we're
 * trying to give it a check from the estate, mind you. We're here on
 * much more unpleasant business. To make it easy to call this
 * multiple times without lots of fussy checking, we allow it to be
 * called with NULL pointers; hence find_first_kid(find_first_kid(x))
 * works even if x is chaste and will return NULL.
 */
static struct proc *find_first_kid(struct proc *p)
{
	struct proc *kid;

	cv_lock(&p->child_wait);
	kid = TAILQ_FIRST(&p->children);
	if (kid) {
		proc_incref(kid, 1);
		proc_decref(p);
	}
	cv_unlock(&p->child_wait);
	return kid;
}

/*
 * killkid manages population issues by killing your kids.  This is a
 * particular temporary (we think) function for ssh. As such, we are
 * going to make a Command Decision to never kill the top level
 * kid. We start on grandkids, in other words.  Hey, the parent/child
 * terminology was Ken's idea; go yell at him.  If you want, we can
 * rename this to DrownCuteKittens.
 *
 * This was hard to get right so it's way more verbose than you might think we need.
 * Sorry.
 */
void killkid(void)
{
	struct proc *check, *kid, *grandkid, *victim;

	/* find first grandkid */
	proc_incref(current, 1);
	kid = find_first_kid(current);
	if (!kid) {
		proc_decref(current);
		return;
	}
	grandkid = find_first_kid(kid);
	if (!grandkid) {
		proc_decref(kid);
		return;
	}
	victim = grandkid;
	while (1) {
		check = find_first_kid(victim);
		if (!check)
			break;
		victim = check;
	}
	send_posix_signal(victim, SIGINT);
	proc_decref(victim);
}
