~kris/9p

9hist

1df06c3df9f1a30d692026c45bbe3a48800b322c — David du Colombier 36 years ago 023f527
Plan 9 from Bell Labs 1990-09-11
A gnot/crc_16.h => gnot/crc_16.h +35 -0
@@ 0,0 1,35 @@
/*
 *	CRC 0120001
 */
    0x0, 0xc0c1, 0xc181, 0x140, 0xc301, 0x3c0, 0x280, 0xc241, 
    0xc601, 0x6c0, 0x780, 0xc741, 0x500, 0xc5c1, 0xc481, 0x440, 
    0xcc01, 0xcc0, 0xd80, 0xcd41, 0xf00, 0xcfc1, 0xce81, 0xe40, 
    0xa00, 0xcac1, 0xcb81, 0xb40, 0xc901, 0x9c0, 0x880, 0xc841, 
    0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, 
    0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, 
    0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, 
    0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, 
    0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, 
    0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, 
    0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, 
    0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, 
    0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 
    0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, 
    0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, 
    0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, 
    0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, 
    0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, 
    0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, 
    0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, 
    0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, 
    0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, 
    0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, 
    0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, 
    0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, 
    0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, 
    0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, 
    0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, 
    0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, 
    0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, 
    0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 
    0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040 

M gnot/dat.h => gnot/dat.h +3 -0
@@ 144,6 144,7 @@ struct Conf
	int	nbitbyte;	/* bytes of bitmap data (devbit.c) */
	int	nfont;		/* font structs (devbit.c) */
	int	nurp;		/* max urp conversations */
	int	nasync;		/* number of async protocol modules */
};

struct Dev


@@ 371,6 372,8 @@ struct Qinfo
	void (*open)(Queue*, Stream*);
	void (*close)(Queue*);
	char *name;
	void (*reset)(void);		/* initialization */
	Qinfo *next;
};

/*

M gnot/devcons.c => gnot/devcons.c +33 -8
@@ 70,6 70,7 @@ struct Rs232{
	Queue	*wq;
	Alarm	*a;		/* alarm for waking the rs232 kernel process */
	int	started;
	int	delay;		/* time between character input and waking kproc */
	Rendez	r;
};



@@ 290,7 291,7 @@ echo(int c)
		DEBUG();
	if(c == 0x16)
		dumpqueues();
	if(c == 0x18)
	if(c == 0x1A)
		mntdump();
	if(raw.ref)
		return;


@@ 788,12 789,21 @@ rs232output(Rs232 *r)
	q = r->wq;

	/*
	 *  free old blocks
	 */
	for(next = r->out.f; next != r->out.r; next = NEXT(next)){
		freeb(r->out.bp[next]);
		r->out.bp[next] = 0;
	}
	r->out.f = next;

	/*
	 *  stage new blocks
	 *
	 *  if we run into a control block, wait till the queue
	 *  is empty before doing the control.
	 */
	for(next = NEXT(r->out.w); next != r->out.r; next = NEXT(next)){
	for(next = NEXT(r->out.w); next != r->out.f; next = NEXT(next)){
		bp = getq(q);
		if(bp == 0)
			break;


@@ 803,11 813,22 @@ rs232output(Rs232 *r)
			l = strtoul((char *)(bp->rptr+1), 0, 0);
			switch(*bp->rptr){
			case 'B':
				duartbaud(l); break;
			case 'b':
				duartbaud(l);
				break;
			case 'D':
				duartdtr(l); break;
			case 'd':
				duartdtr(l);
				break;
			case 'K':
				duartbreak(l); break;
			case 'k':
				duartbreak(l);
				break;
			case 'W':
			case 'w':
				if(l>=0 && l<1000)
					r->delay = l;
				break;
			}
			freeb(bp);
			break;


@@ 919,7 940,7 @@ rs232close(Queue *q)
static void
rs232oput(Queue *q, Block *bp)
{
	if(bp->rptr == bp->wptr)
	if(bp->rptr >= bp->wptr)
		freeb(bp);
	else
		putq(q, bp);


@@ 952,8 973,12 @@ rs232ichar(int c)
	/*
	 *  pass upstream within 1/16 second
	 */
	if(r->a==0)
		r->a = alarm(64, rs232timer, r);
	if(r->a==0){
		if(r->delay == 0)
			wakeup(&r->r);
		else
			r->a = alarm(r->delay, rs232timer, r);
	}
}

/*

M gnot/devdk.c => gnot/devdk.c +0 -1
@@ 558,7 558,6 @@ void
dkreset(void)
{
	newqinfo(&dkmuxinfo);
	urpreset();
}

/*

M gnot/errno.h => gnot/errno.h +1 -0
@@ 56,5 56,6 @@ enum{
	Ebadcnt,	/* read count greater than requested */
	Enofont,	/* out of font descriptors */
	Enovmem,	/* virtual memory allocation failed */
	Enoasync,	/* out of async stream modules */
	Egreg,		/* ken hasn't implemented datakit */
};

M gnot/fns.h => gnot/fns.h +0 -1
@@ 168,7 168,6 @@ void	touser(void);
void	tsleep(Rendez*, int (*)(void*), void*, int);
void	twakeme(Alarm*);
void	unlock(Lock*);
void	urpreset(void);
void	usepage(Page*, int);
void	userinit(void);
void	validaddr(ulong, ulong, int);

M gnot/main.c => gnot/main.c +2 -1
@@ 308,7 308,7 @@ confinit(void)
	conf.nmnthdr = 2*conf.nmntdev;
	conf.nstream = 64;
	conf.nqueue = 5 * conf.nstream;
	conf.nblock = 24 * conf.nstream;
	conf.nblock = 32 * conf.nstream;
	conf.nsrv = 32*mul;
	conf.nbitmap = 300*mul;
	conf.nbitbyte = 300*1024*mul;


@@ 316,4 316,5 @@ confinit(void)
		conf.nbitbyte *= 2;	/* ldepth 1 */
	conf.nfont = 10*mul;
	conf.nurp = 32;
	conf.nasync = 1;
}

M gnot/stasync.c => gnot/stasync.c +152 -130
@@ 7,18 7,41 @@

#define DPRINT 	if(asyncdebug)kprint

/*
 *  configuration
 */
enum {
	MAXFRAME=	246,
	Nasync=		1,
};

/* input states */
enum { Hunt=0, Framing, Framed, Data, Escape };

typedef struct Async {
	QLock;

	int	inuse;
	Queue	*wq;

	/* output state */

	QLock	xmit;		/* transmit lock */
	int	chan;		/* current urp channel */
	Block	*bp;		/* current buffer */
	Block	*bp;		/* current output buffer */
	int	count;
	ushort	crc;

	/* input state */

	int	state;		/* input state */
	uchar	buf[MAXFRAME];	/* current input buffer */
	int	icount;
	ushort	icrc;

	/* statistics */

	ulong	chan0;
	ulong	toolong;
	ulong	tooshort;
	ulong	badcrc;


@@ 27,7 50,7 @@ typedef struct Async {
	ulong	out;		/* bytes out */
} Async;

Async async[Nasync];
Async *async;

/*
 *  async stream module definition


@@ 36,7 59,8 @@ static void asynciput(Queue*, Block*);
static void asyncoput(Queue*, Block*);
static void asyncopen(Queue*, Stream*);
static void asyncclose(Queue*);
Qinfo asyncinfo = { asynciput, asyncoput, asyncopen, asyncclose, "async" };
static void asyncreset(void);
Qinfo asyncinfo = { asynciput, asyncoput, asyncopen, asyncclose, "async", asyncreset };

int asyncdebug = 1;
int asyncerror;


@@ 49,7 73,6 @@ static ushort crc_table[256] = {
#define	BOTM	0051		/* begin trailer, more data follows */
#define	BOTS	0052		/* seq update alg. on this trailer */

#define	MAXFRAME	256
#define	FRAME		0x7e
#define	STUF		0x9d



@@ 57,12 80,23 @@ static ushort crc_table[256] = {
#define	CRCFUNC(crc,x)	(crc_table[((crc)^(x))&0xff]^((crc)>>8))

/*
 *  create the kernel process for input
 *  create the async structures
 */
static void
asyncreset(void)
{
	async = (Async *)ialloc(conf.nasync*sizeof(Async), 0);
}

/*
 *  allocate an async structure
 */
static void
asyncopen(Queue *q, Stream *s)
{
	DPRINT("asyncstopen %d\n", s->dev);
	Async *ap;

	DPRINT("asyncopen %d\n", s->dev);

	for(ap = async; ap < &async[Nasync]; ap++){
		qlock(ap);


@@ 74,7 108,7 @@ asyncopen(Queue *q, Stream *s)
		error(0, Enoasync);
	q->ptr = q->other->ptr = ap;

	ap->bp = allocb(256);
	ap->bp = 0;
	ap->chan = -1;
	ap->count = 0;
	ap->toolong = 0;


@@ 84,6 118,8 @@ asyncopen(Queue *q, Stream *s)
	ap->chan0 = 0;
	ap->in = 0;
	ap->out = 0;
	ap->wq = WR(q);
	ap->state = Hunt;
}

static void


@@ 125,37 161,36 @@ showframe(char *t, Async *ap, uchar *buf, int n)
void
aswrite(Async *ap)
{
	int n = ap->bp - ap->buf;
	if (n <= 0)
	if(ap->bp->rptr == ap->bp->wptr)
		return;
	if (asyncdebug > 2)
		showframe("out", ap, ap->buf, n);
	(*devtab[ap->c->type].write)(ap->c, ap->buf, n);
	ap->out += n;
	ap->bp = ap->buf;
	FLOWCTL(ap->wq);
	PUTNEXT(ap->wq, ap->bp);
	ap->bp = 0;
}

void
asputf(Async *ap, int frame)
{
	uchar *p = ap->bp;
	uchar *p;
	int c;
	if (ap->count > 0) {
		if (asyncerror)

	p = ap->bp->wptr;
	if(ap->count > 0) {
		if(asyncerror)
			ap->crc^=1, asyncerror=0;
		*p++ = c = ap->crc&0xff;
		if (c == FRAME)
		if(c == FRAME)
			*p++ = 0x00;
		*p++ = c = (ap->crc>>8)&0xff;
		if (c == FRAME)
		if(c == FRAME)
			*p++ = 0x00;
		ap->count = 0;
	}
	if (frame) {
	if(frame) {
		*p++ = FRAME;
		*p++ = FRAME;
	}
	ap->bp = p;
	ap->bp->wptr = p;
	aswrite(ap);
}



@@ 163,8 198,12 @@ void
asputc(Async *ap, int c)
{
	int d;
	uchar *p = ap->bp;
	if (ap->count <= 0) {
	uchar *p;

	if(ap->bp == 0)
		ap->bp = allocb(MAXFRAME+4);
	p = ap->bp->wptr;
	if(ap->count <= 0) {
		*p++ = FRAME;
		*p++ = FRAME;
		*p++ = d = 0x80|((ap->chan>>5)&0x7e);


@@ 173,13 212,13 @@ asputc(Async *ap, int c)
		ap->crc = CRCFUNC(ap->crc, d);
	}
	*p++ = c;
	if (c == FRAME)
	if(c == FRAME)
		*p++ = 0x00;
	ap->crc = CRCFUNC(ap->crc, c);
	ap->bp = p;
	if (++ap->count >= MAXFRAME-4)
	ap->bp->wptr = p;
	if(++ap->count >= MAXFRAME-4)
		asputf(ap, 0);
	else if (p-ap->buf >= sizeof(ap->buf)-8)
	else if(ap->bp->lim - p < 8)
		aswrite(ap);
}



@@ 228,11 267,11 @@ asyncoput(Queue *q, Block *bp)
	/*
	 *  new frame if the channel number has changed
	 */
	if (chan != ap->chan && ap->count > 0)
	if(chan != ap->chan && ap->count > 0)
		asputf(ap, 0);
	ap->chan = chan;

	if (asyncdebug > 1)
	if(asyncdebug > 1)
		kprint("a%d->(%d)%3.3uo %d\n",
			ap-async, chan, ctl, bp->wptr - bp->rptr);



@@ 245,7 284,7 @@ asyncoput(Queue *q, Block *bp)
		 */
		while (bp->rptr < bp->wptr) {
			asputc(ap, c = *bp->rptr++);
			if (c == STUF)
			if(c == STUF)
				asputc(ap, 0);
		}



@@ 287,23 326,22 @@ asyncoput(Queue *q, Block *bp)
 */

void
asdeliver(Async *ap, uchar *p, int n)
asdeliver(Queue *q, Async *ap)
{
	Block *bp = 0;
	int chan, c;
	Block *bp;
	uchar *p = ap->buf;
	int n = ap->icount;

	if (!ap->rq)
		return;

	chan = *p++ & 0x7e;
	chan = (chan<<5)|((*p++ & 0x7e)>>1);
	if (chan==0) {
	chan = p[1] & 0x7e;
	chan = (chan<<5)|((p[2] & 0x7e)>>1);
	if(chan==0) {
		DPRINT("a%d deliver chan 0\n", ap-async);
		ap->chan0++;
		return;
	}
	for (n-=4; n>0; n--) {
		if (!bp) {
		if(!bp) {
			bp = allocb(n+2);
			bp->flags |= S_DELIM;
			bp->wptr[0] = chan;


@@ 311,15 349,15 @@ asdeliver(Async *ap, uchar *p, int n)
			bp->wptr[2] = 0;
			bp->wptr += 3;
		}
		if ((c = *p++) == STUF) {
		if((c = *p++) == STUF) {
			--n;
			if ((c = *p++) != 0) {
			if((c = *p++) != 0) {
				bp->rptr[2] = c;
				if (asyncdebug > 1)
				if(asyncdebug > 1)
					kprint("a%d<-(%d)%3.3uo %d\n",
						ap-async, chan, bp->rptr[2],
						bp->wptr - bp->rptr - 3);
				PUTNEXT(ap->rq, bp);
				PUTNEXT(q, bp);
				bp = 0;
				continue;
			} else


@@ 327,106 365,90 @@ asdeliver(Async *ap, uchar *p, int n)
		}
		*bp->wptr++ = c;
	}
	if (bp) {
		if (asyncdebug > 1)
	if(bp) {
		if(asyncdebug > 1)
			kprint("a%d<-(%d)%3.3uo %d\n",
				ap-async, chan, bp->rptr[2],
				bp->wptr - bp->rptr - 3);
		PUTNEXT(ap->rq, bp);
		PUTNEXT(q, bp);
	}
}

enum { Hunt=0, Framing, Framed, Data, Escape };

static void
asynckproc(void *arg)
asynciput(Queue *q, Block *bp)
{
	Async *ap = (Async *)arg;
	int c, state, count; unsigned short crc;
	uchar buf[MAXFRAME], ibuf[MAXFRAME], *p;
	int nibuf;

	DPRINT("asynckproc %d\n", ap-async);
	nibuf = 0;
	state = Hunt;
Loop:
	if (--nibuf < 0) {
		if (ap->rq)
			nibuf = (*devtab[ap->c->type].read)(ap->c,
					ibuf, sizeof ibuf);
		if (nibuf <= 0) {
			unlock(&ap->kstart);
			wakeup(&ap->r);
			return;
		}
		ap->in += nibuf--;
		p = ibuf;
	}
	c = *p++;
	switch (state) {
	case Hunt:	/* wait for framing byte */
		if (c == FRAME)
			state = Framing;
		break;

	case Framing:	/* saw 1 framing byte after Hunt */
		if (c == FRAME)
			state = Framed;
		else
			state = Hunt;
		break;

	case Framed:	/* saw 2 or more framing bytes */
		if (c == FRAME)
			break;
		state = Data;
		crc = CRCSTART;
		count = 0;
		goto Datachar;

	case Data:	/* mid-frame */
		if (c == FRAME) {
			state = Escape;
			break;
		}
	Datachar:
		if (count >= MAXFRAME) {
			DPRINT("a%d pkt too long\n", ap-async);
			ap->toolong++;
			state = Hunt;
	int c;
	Async *ap = q->ptr;
	int state = ap->state;

	while(bp->wptr > bp->rptr){
		c = *bp->rptr++;
		switch(state) {
		case Hunt:	/* wait for framing byte */
			if(c == FRAME)
				state = Framing;
			break;
		}
		crc = CRCFUNC(crc, c);
		buf[count++] = c;
		break;

	case Escape:	/* saw framing byte in Data */
		switch (c) {
		case FRAME:
			if (asyncdebug > 2)
				showframe("in", ap, buf, count);
			if (count < 5) {
				DPRINT("a%d pkt too short\n", ap-async);
				ap->tooshort++;
			} else if (crc != 0) {
				DPRINT("a%d bad crc\n", ap-async);
				ap->badcrc++;
			} else {
				asdeliver(ap, buf, count);
			}
			state = Framed;
	
		case Framing:	/* saw 1 framing byte after Hunt */
			if(c == FRAME)
				state = Framed;
			else
				state = Hunt;
			break;
		case 0:
			c = FRAME;
	
		case Framed:	/* saw 2 or more framing bytes */
			if(c == FRAME)
				break;
			state = Data;
			ap->icrc = CRCSTART;
			ap->icount = 0;
			goto Datachar;
		default:
			DPRINT("a%d bad escape\n", ap-async);
			ap->badescape++;
			state = Hunt;
	
		case Data:	/* mid-frame */
			if(c == FRAME) {
				state = Escape;
				break;
			}
		Datachar:
			if(ap->icount >= MAXFRAME) {
				DPRINT("a%d pkt too long\n", ap-async);
				ap->toolong++;
				state = Hunt;
				break;
			}
			ap->icrc = CRCFUNC(ap->icrc, c);
			ap->buf[ap->icount++] = c;
			break;
	
		case Escape:	/* saw framing byte in Data */
			switch (c) {
			case FRAME:
				if(asyncdebug > 2)
					showframe("in", ap, ap->buf, ap->icount);
				if(ap->icount < 5) {
					DPRINT("a%d pkt too short\n", ap-async);
					ap->tooshort++;
				} else if(ap->icrc != 0) {
					DPRINT("a%d bad crc\n", ap-async);
					ap->badcrc++;
				} else {
					asdeliver(q, ap);
				}
				state = Framed;
				break;
			case 0:
				c = FRAME;
				state = Data;
				goto Datachar;
			default:
				DPRINT("a%d bad escape\n", ap-async);
				ap->badescape++;
				state = Hunt;
				break;
			}
			break;
		}
		break;
	}
	goto Loop;
	ap->state = state;
	freeb(bp);
}

M gnot/stream.c => gnot/stream.c +76 -76
@@ 10,7 10,6 @@

enum {
	Nclass=4,	/* number of block classes */
	Nlds=32,	/* max number of pushable line disciplines */
};

/*


@@ 22,20 21,7 @@ Qinfo procinfo = { stputq, nullput, 0, 0, "process" };
/*
 *  line disciplines that can be pushed
 */
static Qinfo *lds[Nlds+1];

void
newqinfo(Qinfo *qi)
{
	int i;

	for(i=0; i<Nlds && lds[i]; i++)
		if(lds[i] == qi)
			return;
	if(i == Nlds)
		panic("pushable");
	lds[i] = qi;
}
static Qinfo *lds;

/*
 *  All stream structures are ialloc'd at boot time


@@ 62,54 48,7 @@ Bclass bclass[Nclass]={
	{ 4096 },
};

/*
 *  Dump all block information of how many blocks are in which queues
 */
void
dumpblocks(Queue *q, char c)
{
	Block *bp;
	uchar *cp;

	lock(q);
	for(bp = q->first; bp; bp = bp->next){
		print("%c%d%c", c, bp->wptr-bp->rptr, (bp->flags&S_DELIM));
		for(cp = bp->rptr; cp<bp->wptr && cp<bp->rptr+10; cp++)
			print(" %uo", *cp);
		print("\n");
	}
	unlock(q);
}

void
dumpqueues(void)
{
	Queue *q;
	int count;
	Block *bp;
	Bclass *bcp;

	print("\n");
	for(q = qlist; q < qlist + conf.nqueue; q++, q++){
		if(!(q->flag & QINUSE))
			continue;
		print("%s %ux  R n %d l %d f %ux r %ux", q->info->name, q, q->nb,
			q->len, q->flag, &(q->r));
		print("  W n %d l %d f %ux r %ux\n", WR(q)->nb, WR(q)->len, WR(q)->flag,
			&(WR(q)->r));
		dumpblocks(q, 'R');
		dumpblocks(WR(q), 'W');
	}
	print("\n");
	for(bcp=bclass; bcp<&bclass[Nclass]; bcp++){
		lock(bcp);
		for(count = 0, bp = bcp->first; bp; count++, bp = bp->next)
			;
		unlock(bcp);
		print("%d blocks of size %d\n", count, bcp->size);
	}
	print("\n");
}
#include "stream.h"

/*
 *  Allocate streams, queues, and blocks.  Allocate n block classes with


@@ 123,6 62,9 @@ streaminit(void)
	Block *bp;
	Bclass *bcp;

	/*
	 *  allocate blocks, queues, and streams
	 */
	slist = (Stream *)ialloc(conf.nstream * sizeof(Stream), 0);
	qlist = (Queue *)ialloc(conf.nqueue * sizeof(Queue), 0);
	blist = (Block *)ialloc(conf.nblock * sizeof(Block), 0);


@@ 141,6 83,24 @@ streaminit(void)
			bp++;
		}
	}

	/*
	 *  make stream modules available
	 */
	streaminit0();
}

/*
 *  make known a stream module and call its initialization routine, if
 *  it has one.
 */
void
newqinfo(Qinfo *qi)
{
	qi->next = lds;
	lds = qi;
	if(qi->reset)
		(*qi->reset)();
}

/*


@@ 159,7 119,6 @@ allocb(ulong size)
{
	Block *bp;
	Bclass *bcp;
	int loop=0;

	/*
	 *  map size to class


@@ 173,10 132,6 @@ allocb(ulong size)
	lock(bcp);
	while(bcp->first == 0){
		unlock(bcp);
		if(loop++ == 10){
			dumpqueues();
			print("waiting for blocks\n");
		}
		qlock(bcp);
		tsleep(&bcp->r, isblock, (void *)bcp, 250);
		qunlock(bcp);


@@ 582,13 537,13 @@ nullput(Queue *q, Block *bp)
static Qinfo *
qinfofind(char *name)
{
	Qinfo **qip;
	Qinfo *qi;

	if(name == 0)
		error(0, Ebadld);
	for(qip = lds; *qip; qip++)
		if(strcmp((*qip)->name, name)==0)
			return *qip;
	for(qi = lds; qi; qi = qi->next)
		if(strcmp(qi->name, name)==0)
			return qi;
	error(0, Ebadld);
}



@@ 1006,10 961,6 @@ streamread(Chan *c, void *vbuf, long n)

	qunlock(&s->rdlock);
	poperror();
	if(left<0 || left>n){
		print("streamread returns %d for a %d read\n", n-left, n);
		panic("streamread");
	}
	return n - left;	
}



@@ 1211,3 1162,52 @@ streamstat(Chan *c, char *db, char *name)
	devdir(c, c->qid, name, n, 0, &dir);
	convD2M(&dir, db);
}

/*
 *  Dump all block information of how many blocks are in which queues
 */
void
dumpblocks(Queue *q, char c)
{
	Block *bp;
	uchar *cp;

	lock(q);
	for(bp = q->first; bp; bp = bp->next){
		print("%c%d%c", c, bp->wptr-bp->rptr, (bp->flags&S_DELIM));
		for(cp = bp->rptr; cp<bp->wptr && cp<bp->rptr+10; cp++)
			print(" %uo", *cp);
		print("\n");
	}
	unlock(q);
}

void
dumpqueues(void)
{
	Queue *q;
	int count;
	Block *bp;
	Bclass *bcp;

	print("\n");
	for(q = qlist; q < qlist + conf.nqueue; q++, q++){
		if(!(q->flag & QINUSE))
			continue;
		print("%s %ux  R n %d l %d f %ux r %ux", q->info->name, q, q->nb,
			q->len, q->flag, &(q->r));
		print("  W n %d l %d f %ux r %ux\n", WR(q)->nb, WR(q)->len, WR(q)->flag,
			&(WR(q)->r));
		dumpblocks(q, 'R');
		dumpblocks(WR(q), 'W');
	}
	print("\n");
	for(bcp=bclass; bcp<&bclass[Nclass]; bcp++){
		lock(bcp);
		for(count = 0, bp = bcp->first; bp; count++, bp = bp->next)
			;
		unlock(bcp);
		print("%d blocks of size %d\n", count, bcp->size);
	}
	print("\n");
}

A gnot/stream.h => gnot/stream.h +7 -0
@@ 0,0 1,7 @@
extern	Qinfo 	 urpinfo;
extern	Qinfo 	 asyncinfo;

void streaminit0(void){
	newqinfo(&urpinfo);
	newqinfo(&asyncinfo);
}

M gnot/sturp.c => gnot/sturp.c +3 -3
@@ 101,6 101,7 @@ Urp	*urp;
/*
 *  predeclared
 */
static void	urpreset(void);
static void	urpciput(Queue*, Block*);
static void	urpiput(Queue*, Block*);
static void	urpoput(Queue*, Block*);


@@ 119,12 120,11 @@ static void	urpkproc(void *arg);
static void	urptimer(Alarm*);
static void	urpvomit(char*, Urp*);

Qinfo urpinfo = { urpciput, urpoput, urpopen, urpclose, "urp" };
Qinfo urpinfo = { urpciput, urpoput, urpopen, urpclose, "urp", urpreset };

void
static void
urpreset(void)
{
	newqinfo(&urpinfo);
	urp = (Urp *)ialloc(conf.nurp*sizeof(Urp), 0);
	alarm(500, urptimer, 0);
}

M port/devbit.c => port/devbit.c +2 -2
@@ 415,7 415,7 @@ bitread(Chan *c, void *va, long n)
			p = va;
			for(y=miny; y<maxy; y++){
				q = (uchar*)addr(src, Pt(src->r.min.x, y));
				q += (src->r.min.x&((sizeof(ulong))*ws-1))/8;
				q += (src->r.min.x&((sizeof(ulong))*ws-1))/ws;
				for(x=0; x<l; x++)
					*p++ = K2U(*q++);
				n += l;


@@ 939,7 939,7 @@ bitwrite(Chan *c, void *va, long n)
			}
			for(y=miny; y<maxy; y++){
				q = (uchar*)addr(dst, Pt(dst->r.min.x, y));
				q += (dst->r.min.x&((sizeof(ulong))*ws-1))/8;
				q += (dst->r.min.x&((sizeof(ulong))*ws-1))/ws;
				for(x=0; x<l; x++)
					*q++ = U2K(*p++);
				m -= l;

M port/devdk.c => port/devdk.c +28 -21
@@ 6,8 6,9 @@
#include	"io.h"
#include	"errno.h"

#define NOW (MACHP(0)->ticks)
#define DPRINT if(0)
#define	DPRINT	if(0)	/*kprint*/

#define	NOW	(MACHP(0)->ticks)

enum {
	/*


@@ 124,6 125,7 @@ struct Dk {
	Chan	*csc;		/* common signalling line */
	Line	line[Nline];
	int	restart;
	int	urpwindow;
};
static Dk dk[Ndk];



@@ 395,7 397,8 @@ dkiput(Queue *q, Block *bp)
/*
 *  we assume that each put is a message.
 *
 *  add a 2 byte channel number to the start of each message
 *  add a 2 byte channel number to the start of each message,
 *  low order byte first.
 */
static void
dkoput(Queue *q, Block *bp)


@@ 413,14 416,7 @@ dkoput(Queue *q, Block *bp)
	dp = lp->dp;
	line = lp - dp->line;

	if(bp->base && bp->rptr - bp->base >= 2)
		bp->rptr -= 2;
	else {
		print("dkoput l %d b %ux r %ux w %ux\n", line, bp->base, bp->rptr,
			bp->wptr);
		freeb(bp);
		return;
	}
	bp = padb(bp, 2);
	bp->rptr[0] = line;
	bp->rptr[1] = line>>8;



@@ 432,12 428,13 @@ dkoput(Queue *q, Block *bp)
}

/*
 *  configure a datakit multiplexor.  this takes 4 arguments separated
 *  configure a datakit multiplexor.  this takes 5 arguments separated
 *  by spaces:
 *	the line number of the common signalling channel (must be > 0)
 *	the number of lines in the device (optional)
 *	the word `restart' or `norestart' (optional/default==restart)
 *	the name of the dk (optional)
 *	the name of the dk (default==dk)
 *	the urp window size (default==WS_2K)
 *
 *  we can configure only once
 */


@@ 445,7 442,7 @@ static void
dkmuxconfig(Dk *dp, Block *bp)
{
	Chan *c;
	char *fields[4];
	char *fields[5];
	int n;
	char buf[64];
	static int dktimeron;


@@ 459,9 456,12 @@ dkmuxconfig(Dk *dp, Block *bp)
	 *  parse
	 */
	dp->restart = 1;
	n = getfields((char *)bp->rptr, fields, 4, ' ');
	n = getfields((char *)bp->rptr, fields, 5, ' ');
	strcpy(dp->name, "dk");
	dp->urpwindow = WS_2K;
	switch(n){
	case 5:
		dp->urpwindow = strtoul(fields[4], 0, 0);
	case 4:
		strncpy(dp->name, fields[3], sizeof(dp->name));
	case 3:


@@ 481,6 481,8 @@ dkmuxconfig(Dk *dp, Block *bp)
		dp->lines = 16;
		error(0, Ebadarg);
	}
	DPRINT("dkmuxconfig: ncsc=%d, lines=%d, restart=%d, name=\"%s\"\n",
		dp->ncsc, dp->lines, dp->restart, dp->name);

	/*
	 *  open a stream for the csc and push urp onto it


@@ 499,7 501,7 @@ dkmuxconfig(Dk *dp, Block *bp)
	/*
	 *  start a process to deal with it
	 */
	sprint(buf, "csckproc%d", dp->ncsc);
	sprint(buf, "csc.%s.%d", dp->name, dp->ncsc);
	kproc(buf, dkcsckproc, dp);
	poperror();



@@ 556,7 558,6 @@ void
dkreset(void)
{
	newqinfo(&dkmuxinfo);
	urpreset();
}

/*


@@ 866,8 867,10 @@ dkmesg(Dk *dp, int type, int srv, int p0, int p1)

	if(dp->csc == 0)
		return -1;
	if(waserror())
	if(waserror()){
		print("dkmesg: error\n");
		return -1;
	}
	d.type = type;
	d.srv = srv;
	d.param0l = p0;


@@ 977,7 980,7 @@ dkcall(int type, Chan *c, char *addr, char *nuser, char *machine)
	 *  tell the controller we want to make a call
	 */
	DPRINT("dialout\n");
	dkmesg(dp, t_val, d_val, line, W_WINDOW(WS_2K,WS_2K,2));
	dkmesg(dp, t_val, d_val, line, W_WINDOW(dp->urpwindow,dp->urpwindow,2));

	/*
	 *  if redial, wait for a dial tone (otherwise we might send


@@ 1318,8 1321,11 @@ dkcsckproc(void *a)
	/*
	 *  tell datakit we've rebooted. It should close all channels.
	 */
	if(dp->restart)
	if(dp->restart) {
		DPRINT("dkcsckproc: restart %s\n", dp->name);
		dkmesg(dp, T_ALIVE, D_RESTART, 0, 0);
	}
	DPRINT("dkcsckproc: closeall %s\n", dp->name);
	dkmesg(dp, T_CHG, D_CLOSEALL, 0, 0);

	/*


@@ 1484,7 1490,8 @@ dktimer(void *a)
	Dk *dp;
	Line *lp;

	waserror();
	while(waserror())
		print("dktimer: error\n");

	for(;;){
		/*

M port/devlance.c => port/devlance.c +200 -139
@@ 11,7 11,7 @@
 */
enum {
	Ntypes=		8,		/* max number of ethernet packet types */
	Ndir=		Ntypes+1,	/* entries in top level directory */
	Ndir=		Ntypes+2,	/* entries in top level directory */
	LogNrrb=	7,		/* log of number of receive buffers */
	Nrrb=		(1<<LogNrrb),	/* number of recieve buffers */
	LogNtrb=	7,		/* log of number of transmit buffers */


@@ 24,6 24,17 @@ enum {
#define NOW (MACHP(0)->ticks*MS2HZ)

/*
 *  Ethernet packet buffers.  These must also be in lance addressible RAM.
 */
typedef struct {
	uchar d[6];
	uchar s[6];
	uchar type[2];
	uchar data[1500];
	uchar crc[4];
} Pkt;

/*
 *  Communication with the lance is via a transmit and receive ring of
 *  message descriptors.  The Initblock contains pointers to and sizes of
 *  these rings.  The rings must be in RAM addressible by the lance


@@ 36,55 47,44 @@ typedef struct {
} Msg;

/*
 *  Ethernet packet buffers.  These must also be in lance addressible RAM.
 */
typedef struct {
	uchar d[6];
	uchar s[6];
	uchar type[2];
	uchar data[1500];
	uchar crc[4];
} Pkt;

/*
 *  lance memory map
 */
typedef
struct
typedef struct Lancemem
{
	/*
	 *  initialization block
	 */
	struct initblock {	
		ushort	mode;		/* chip control (see below) */
		ushort	etheraddr[3];	/* the ethernet physical address */
		ushort	multi[4];	/* multicast addresses, 1 bit for each of 64 */
		ushort	rdralow;	/* receive buffer ring */
		ushort	rdrahigh;	/* (top three bits define size of ring) */
		ushort	tdralow;	/* transmit buffer ring */
		ushort	tdrahigh;	/* (top three bits define size of ring) */
	};
	ushort	mode;		/* chip control (see below) */
	ushort	etheraddr[3];	/* the ethernet physical address */
	ushort	multi[4];	/* multicast addresses, 1 bit for each of 64 */
	ushort	rdralow;	/* receive buffer ring */
	ushort	rdrahigh;	/* (top three bits define size of ring) */
	ushort	tdralow;	/* transmit buffer ring */
	ushort	tdrahigh;	/* (top three bits define size of ring) */
	
	/*
	 * ring buffers
	 * first receive, then transmit
	 *  ring buffers
	 *  first receive, then transmit
	 */
	Msg	rmr[Nrrb];		/* recieve message ring */
	Msg	tmr[Ntrb];		/* transmit message ring */

	/*
	 * actual packets
	 *  packet buffers (for IO2 version)
	 */
	Pkt	p[1];
	Pkt	rp[Nrrb];
	Pkt	tp[Ntrb];
} Lancemem;
#define LANCEMEM ((Lancemem *)LANCERAM)
#define LANCEMEM ((Lancemem*)0)

/*
 *  Some macros for dealing with lance memory addresses.  The lance splits
 *  its 24 bit addresses across two 16 bit registers.
 */
#define HADDR(a) ((((ulong)(a))>>16)&0xF)
#define HADDR(a) ((((ulong)(a))>>16)&0xFF)
#define LADDR(a) (((ulong)a)&0xFFFF)
#define MPs(a) (*(short *)(l.lanceram + l.sep*((ushort*)&a - (ushort*)0)))
#define MPus(a) (*(ushort *)(l.lanceram + l.sep*((ushort*)&a - (ushort*)0)))

/*
 *  one per ethernet packet type


@@ 127,24 127,40 @@ typedef struct {
	uchar	*lmp;		/* location of parity test */
	ushort	*rap;		/* lance address register */
	ushort	*rdp;		/* lance data register */
	int	sep;		/* separaqtion between shorts in lance ram
				    as seen by host */
	ushort	*lanceram;	/* start of lance ram as seen by host */
	ushort	*lanceend;	/* end of lance ram as seen by host */
	Lancemem *lm;		/* start of lance memory as seen by lance */

	Rendez	rr;		/* rendezvous for an input buffer */
	ushort	rl;		/* first rcv Message belonging to Lance */	
	ushort	rc;		/* first rcv Message belonging to CPU */
	Pkt	*rp[Nrrb];	/* receive buffers */
	int	inpackets;

	Rendez	tr;		/* rendezvous for an output buffer */
	QLock	tlock;		/* semaphore on tc */
	ushort	tl;		/* first xmt Message belonging to Lance */	
	ushort	tc;		/* first xmt Message belonging to CPU */	
	Pkt	*tp[Ntrb];	/* transmit buffers */
	int	outpackets;

	Ethertype e[Ntypes];
	int	debug;
	int	kstarted;
	Debqueue dq;

	Pkt	*rp;		/* receive buffers */
	Pkt	*tp;		/* transmit buffers */
	uchar	*rpa[Nrrb];	/* receive buffer address in lance space */
	uchar	*tpa[Ntrb];	/* transmit buffer address in lance space */

	/* sadistics */

	int	inpackets;
	int	outpackets;
	int	crcs;		/* input crc errors */
	int	oerrs;		/* output erros */
	int	frames;		/* framing errors */
	int	overflows;	/* packet overflows */
	int	buffs;		/* buffering errors */
} Lance;
static Lance l;



@@ 231,7 247,7 @@ sprintpacket(char *buf, Trace *t)
		p->d[0], p->d[1], p->d[2], p->d[3], p->d[4], p->d[5],
		p->s[0], p->s[1], p->s[2], p->s[3], p->s[4], p->s[5],
		p->type[0], p->type[1]);
	for(i=0; i<41; i++)
	for(i=0; i<16; i++)
		sprint(buf+strlen(buf), "%.2ux", p->data[i]);
	sprint(buf+strlen(buf), ")\n");
}


@@ 262,19 278,6 @@ lancedebq(char tag, Pkt *p, int len)
}

/*
 *  copy to/from lance memory till we get it right
 */
void
slowcpy(uchar *to, uchar *from, int n)
{
	memcpy(to, from, n);
	while(memcmp(to, from, n)!=0){
		print("lance compare error\n");
		memcpy(to, from, n);
	}
}

/*
 *  lance stream module definition
 */
static void lanceoput(Queue*, Block*);


@@ 365,7 368,7 @@ lanceoput(Queue *q, Block *bp )
		sleep(&l.tr, isobuf, (void *)0);
		print("done");
	}
	p = l.tp[l.tc];
	p = &l.tp[l.tc];

	/*
	 *  copy message into lance RAM


@@ 395,16 398,17 @@ lanceoput(Queue *q, Block *bp )
	if(len < 60)
		len = 60;

	lancedebq('o', p, len);
	lancedebq('o', p, len);/**/

	/*
	 *  set up the ring descriptor and hand to lance
	 */
	l.outpackets++;
	m = &(LANCEMEM->tmr[l.tc]);
	m->size = -len;
	m->cntflags = 0;
	m->laddr = LADDR(l.tp[l.tc]);
	m->flags = OWN|STP|ENP|HADDR(l.tp[l.tc]);
	MPs(m->size) = -len;
	MPus(m->cntflags) = 0;
	MPus(m->laddr) = LADDR(l.tpa[l.tc]);
	MPus(m->flags) = OWN|STP|ENP|HADDR(l.tpa[l.tc]);
	l.tc = TSUCC(l.tc);
	*l.rdp = INEA|TDMD; /**/
	qunlock(&l.tlock);


@@ 416,40 420,93 @@ lanceoput(Queue *q, Block *bp )
enum {
	Lchanqid = 1,
	Ltraceqid = 2,
	Lstatsqid = 3,
};
Dirtab lancedir[Ndir];


/*
 *  stop the lance, disable all ring buffers, and free all staged rcv buffers
 */
void
lancereset(void)
{
	Lancemem *lm=LANCEMEM;
	int i;
	ushort *sp;
	ulong x;
	int index;
	static int already;

	/*
	 *  toggle lance's reset line
	 *  so that we don't have to indirect through constants
	 */
	MODEREG->promenet &= ~1;
	MODEREG->promenet |= 1;
	l.rap = LANCERAP;
	l.rdp = LANCERDP;

	/*
	 *  disable all ring entries
	 *  allocate the send and receive buffers and map them into
	 *  the lance's address space.
	 */
	l.tl = l.tc = 0;
	for(i = 0; i < Ntrb; i++)
		lm->tmr[i].flags = 0;
	l.rl = l.rc = 0;
	for(i = 0; i < Ntrb; i++)
		lm->rmr[i].flags = 0;
	if(already == 0){
		already = 1;
		if(ioid < IO3R1){
			/*
			 *  toggle lance's reset line
			 */
			MODEREG->promenet &= ~1;
			MODEREG->promenet |= 1;

			l.lanceram = LANCERAM;
			l.lanceend = LANCEEND;
			l.lm = (Lancemem *)0;
			l.sep = 1;

			/*
			 *  allocate packet buffers in lance memory
			 */
			for(i = 0; i < Nrrb; i++)
				l.rpa[i] = (uchar *)&l.lm->rp[i];
			for(i = 0; i < Ntrb; i++)
				l.tpa[i] = (uchar *)&l.lm->tp[i];
		} else {
			/*
			 *  toggle lance's reset line
			 */
			MODEREG->promenet |= 1;
			MODEREG->promenet &= ~1;

			l.lanceram = LANCE3RAM;
			l.lanceend = LANCE3END;
			l.lm = (Lancemem *)0x800000;
			l.sep = 4;

			/*
			 *  allocate packet buffers in MP bus memory
			 *  and map it into lance space
			 */
			l.rp = (Pkt *)ialloc((Nrrb + Ntrb)*sizeof(Pkt), 1);
			l.tp = l.rp + Nrrb;
			index = 0x1E00;
			for(i = 0; i < Nrrb; i++){
				x = (ulong)&l.rp[i];
				*WRITEMAP = (index<<16) | (x>>12)&0xFFFF;
				l.rpa[i] = (uchar *)((i<<12) | (x & 0xFFF));
				index++;
			}
			for(i = 0; i < Ntrb; i++){
				x = (ulong)&l.tp[i];
				*WRITEMAP = (index<<16) | (x>>12)&0xFFFF;
				l.tpa[i] = (uchar *)(((i+Nrrb)<<12) | (x & 0xFFF));
				index++;
			}
		}
	}

	/*
	 *  run through all lance memory to set parity
	 */
	for(l.lmp=LANCERAM; l.lmp<=LANCEEND; l.lmp++)
		*l.lmp = 55;
	for(sp = l.lanceram; sp < l.lanceend; sp += l.sep)
		*sp = 0;

}

/*


@@ 459,90 516,84 @@ lancereset(void)
static void
lancestart(void)
{
	Lancemem *lm=LANCEMEM;
	int i;
	Pkt *p;
	Lancemem *lm = LANCEMEM;
	Msg *m;

	lancereset();

	/*
	 *  create the initialization block
	 */
	lm->mode = 0;
	MPus(lm->mode) = 0;

	/*
	 *  set ether addr from the value in the id prom.
	 *  the id prom has them in reverse order, the init
	 *  structure wants them in byte swapped order
	 */
	lm->etheraddr[0] = (LANCEID[16]&0xff00)|((LANCEID[20]>>8)&0xff);
	lm->etheraddr[1] = (LANCEID[8]&0xff00)|((LANCEID[12]>>8)&0xff);
	lm->etheraddr[2] = (LANCEID[0]&0xff00)|((LANCEID[4]>>8)&0xff);
	MPus(lm->etheraddr[0]) = (LANCEID[16]&0xff00)|((LANCEID[20]>>8)&0xff);
	MPus(lm->etheraddr[1]) = (LANCEID[8]&0xff00)|((LANCEID[12]>>8)&0xff);
	MPus(lm->etheraddr[2]) = (LANCEID[0]&0xff00)|((LANCEID[4]>>8)&0xff);
	l.ea[0] = LANCEID[20]>>8;
	l.ea[1] = LANCEID[16]>>8;
	l.ea[2] = LANCEID[12]>>8;
	l.ea[3] = LANCEID[8]>>8;
	l.ea[4] = LANCEID[4]>>8;
	l.ea[5] = LANCEID[0]>>8;
/*
	print("lance addr = %.4ux %.4ux %.4ux\n", lm->etheraddr[0], lm->etheraddr[1],
		lm->etheraddr[2]);
/**/

	/*
	 *  ignore multicast addresses
	 */
	for(i=0; i<4; i++)
		lm->multi[i] = 0;
	MPus(lm->multi[0]) = 0;
	MPus(lm->multi[1]) = 0;
	MPus(lm->multi[2]) = 0;
	MPus(lm->multi[3]) = 0;

	/*
	 *  set up rcv message ring
	 */
	p = lm->p;
	for(i = 0; i < Nrrb; i++){
		l.rp[i] = p++;
		lm->rmr[i].size = -sizeof(Pkt);
		lm->rmr[i].cntflags = 0;
		lm->rmr[i].laddr = LADDR(l.rp[i]);
		lm->rmr[i].flags = HADDR(l.rp[i]);
	m = lm->rmr;
	for(i = 0; i < Nrrb; i++, m++){
		MPs(m->size) = -sizeof(Pkt);
		MPus(m->cntflags) = 0;
		MPus(m->laddr) = LADDR(l.rpa[i]);
		MPus(m->flags) = HADDR(l.rpa[i]);
	}
	lm->rdralow = LADDR(lm->rmr);
	lm->rdrahigh = (LogNrrb<<13)|HADDR(lm->rmr);
	MPus(lm->rdralow) = LADDR(l.lm->rmr);
	MPus(lm->rdrahigh) = (LogNrrb<<13)|HADDR(l.lm->rmr);


	/*
	 *  give the lance all the rcv buffers except one (as a sentinel)
	 */
	l.rc = Nrrb - 1;
	for(i = 0; i < l.rc; i++)
		lm->rmr[i].flags |= OWN;
	m = lm->rmr;
	for(i = 0; i < l.rc; i++, m++)
		MPus(m->flags) |= OWN;

	/*
	 *  set up xmit message ring
	 */
	for(i = 0; i < Ntrb; i++){
		l.tp[i] = p++;
		lm->tmr[i].size = 0;
		lm->tmr[i].cntflags = 0;
		lm->tmr[i].laddr = LADDR(l.tp[i]);
		lm->tmr[i].flags = HADDR(l.tp[i]);
	m = lm->tmr;
	for(i = 0; i < Ntrb; i++, m++){
		MPs(m->size) = 0;
		MPus(m->cntflags) = 0;
		MPus(m->laddr) = LADDR(l.tpa[i]);
		MPus(m->flags) = HADDR(l.tpa[i]);
	}
	lm->tdralow = LADDR(lm->tmr);
	lm->tdrahigh = (LogNtrb<<13)|HADDR(lm->tmr);

	/*
	 *  so that we don't have to indirect through constants
	 */
	l.rap = LANCERAP;
	l.rdp = LANCERDP;
	MPus(lm->tdralow) = LADDR(l.lm->tmr);
	MPus(lm->tdrahigh) = (LogNtrb<<13)|HADDR(l.lm->tmr);

	/*
	 *  point lance to the initialization block
	 */
	*l.rap = 1;
	*l.rdp = LADDR(lm);
	*l.rdp = LADDR(l.lm);
	wbflush();
	*l.rap = 2;
	*l.rdp = HADDR(lm);
	*l.rdp = HADDR(l.lm);

	/*
	 *  The lance byte swaps the ethernet packet unless we tell it not to


@@ 580,7 631,10 @@ lanceinit(void)
	lancedir[Ntypes].qid = Ltraceqid;
	lancedir[Ntypes].length = 0;
	lancedir[Ntypes].perm = 0600;

	strcpy(lancedir[Ntypes+1].name, "stats");
	lancedir[Ntypes+1].qid = Lstatsqid;
	lancedir[Ntypes+1].length = 0;
	lancedir[Ntypes+1].perm = 0600;
}

Chan*


@@ 589,7 643,7 @@ lanceattach(char *spec)
	Chan *c;

	if(l.kstarted == 0){
		kproc("lancekproc", lancekproc, 0);
		kproc("lancekproc", lancekproc, 0);/**/
		l.kstarted = 1;
		lancestart();
	}


@@ 620,7 674,7 @@ lancewalk(Chan *c, char *name)
void	 
lancestat(Chan *c, char *dp)
{
	if(c->qid==CHDIR || c->qid==Ltraceqid)
	if(c->qid==CHDIR || c->qid==Ltraceqid || c->qid==Lstatsqid)
		devstat(c, dp, lancedir, Ndir, devgen);
	else
		devstat(c, dp, 0, 0, streamgen);


@@ 637,6 691,7 @@ lanceopen(Chan *c, int omode)
	switch(c->qid){
	case CHDIR:
	case Ltraceqid:
	case Lstatsqid:
		if(omode != OREAD)
			error(0, Eperm);
		break;


@@ 663,6 718,7 @@ lanceclose(Chan *c)
	switch(c->qid){
	case CHDIR:
	case Ltraceqid:
	case Lstatsqid:
		break;
	default:
		streamclose(c);


@@ 706,9 762,16 @@ lancetraceread(Chan *c, void *a, long n)
long	 
lanceread(Chan *c, void *a, long n)
{
	char buf[256];

	switch(c->qid){
	case CHDIR:
		return devdirread(c, a, n, lancedir, Ndir, devgen);
	case Lstatsqid:
		sprint(buf, "in: %d\nout: %d\ncrc errs %d\noverflows: %d\nframe errs %d\nbuff errs: %d\noerrs %d\n",
			l.inpackets, l.outpackets, l.crcs, l.overflows, l.frames,
			l.buffs, l.oerrs);
		return stringread(c, a, n, buf);
	case Ltraceqid:
		return lancetraceread(c, a, n);
	default:


@@ 754,10 817,9 @@ lanceuserstr(Error *e, char *buf)
void
lanceintr(void)
{
	int i;
	ushort csr;
	Lancemem *lm;

	lm = LANCEMEM;
	Lancemem *lm = LANCEMEM;

	csr = *l.rdp;



@@ 778,17 840,16 @@ lanceintr(void)
	/*
	 *  look for rcv'd packets, just wakeup the input process
	 */
	if(l.rl!=l.rc && (lm->rmr[l.rl].flags & OWN)==0)
	if(l.rl!=l.rc && (MPus(lm->rmr[l.rl].flags) & OWN)==0)
		wakeup(&l.rr);

	/*
	 *  look for xmitt'd packets, wake any process waiting for a
	 *  transmit buffer
	 */
	while(l.tl != l.tc && (lm->tmr[l.tl].flags & OWN) == 0){
		if(lm->tmr[l.tl].flags & ERR)
			print("xmt error %ux %ux\n", lm->tmr[l.tl].flags,
				lm->tmr[l.tl].cntflags);
	while(l.tl!=l.tc && (MPus(lm->tmr[l.tl].flags) & OWN)==0){
		if(MPus(lm->tmr[l.tl].flags) & ERR)
			l.oerrs++;
		l.tl = TSUCC(l.tl);
		wakeup(&l.tr);
	}


@@ 800,39 861,45 @@ lanceintr(void)
static int
isinput(void *arg)
{
	return l.rl!=l.rc && (LANCEMEM->rmr[l.rl].flags & OWN)==0;
	Lancemem *lm = LANCEMEM;
	return l.rl!=l.rc && (MPus(lm->rmr[l.rl].flags) & OWN)==0;
}
void
lancekproc(void *arg)
{
	Block *bp;
	Lancemem *lm;
	Pkt *p;
	Ethertype *e;
	int t;
	Msg *m;
	int len;
	int i, last;

	lm = LANCEMEM;
	Lancemem *lm = LANCEMEM;
	Msg *m;

	for(;;){
		for(; l.rl!=l.rc && (lm->rmr[l.rl].flags & OWN)==0 ; l.rl=RSUCC(l.rl)){
		for(; l.rl!=l.rc && (MPus(lm->rmr[l.rl].flags) & OWN)==0 ; l.rl=RSUCC(l.rl)){
			l.inpackets++;
			m = &(lm->rmr[l.rl]);
			if(m->flags & ERR){
				print("rcv error %ux\n",
					m->flags&(FRAM|OFLO|CRC|BUFF));
			if(MPus(m->flags) & ERR){
				t = MPus(m->flags);
				if(t & FRAM)
					l.frames++;
				if(t & OFLO)
					l.overflows++;
				if(t & CRC)
					l.crcs++;
				if(t & BUFF)
					l.buffs++;
				goto stage;
			}
	
			/*
			 *  See if a queue exists for this packet type.
			 */
			p = l.rp[l.rl];
			p = &l.rp[l.rl];
			t = (p->type[0]<<8) | p->type[1];
			len = m->cntflags - 4;
			lancedebq('i', p, len);
			len = MPus(m->cntflags) - 4;
			lancedebq('i', p, len);/**/
			for(e = &l.e[0]; e < &l.e[Ntypes]; e++){
				if(!canqlock(e))
					continue;


@@ 854,7 921,7 @@ lancekproc(void *arg)
					qunlock(e);
				}
			}
			if(e != &l.e[Ntypes] && e->q->next->len <= Streamhi){
			if(e!=&l.e[Ntypes] && e->q->next->len<=Streamhi){
				/*
				 *  The lock on e makes sure the queue is still there.
				 */


@@ 871,10 938,10 @@ stage:
			 *  stage the next input buffer
			 */
			m = &(lm->rmr[l.rc]);
			m->size = -sizeof(Pkt);
			m->cntflags = 0;
			m->laddr = LADDR(l.rp[l.rc]);
			m->flags = OWN|HADDR(l.rp[l.rc]);
			MPs(m->size) = -sizeof(Pkt);
			MPus(m->cntflags) = 0;
			MPus(m->laddr) = LADDR(l.rpa[l.rc]);
			MPus(m->flags) = OWN|HADDR(l.rpa[l.rc]);
			l.rc = RSUCC(l.rc);
		}
		sleep(&l.rr, isinput, 0);


@@ 888,9 955,3 @@ lanceparity(void)
	MODEREG->promenet &= ~4;
	MODEREG->promenet |= 4;
}

void
lance3intr(void)
{
	panic("lance3 interrupt\n");
}

M port/stream.c => port/stream.c +106 -92
@@ 10,7 10,6 @@

enum {
	Nclass=4,	/* number of block classes */
	Nlds=32,	/* max number of pushable line disciplines */
};

/*


@@ 22,20 21,7 @@ Qinfo procinfo = { stputq, nullput, 0, 0, "process" };
/*
 *  line disciplines that can be pushed
 */
static Qinfo *lds[Nlds+1];

void
newqinfo(Qinfo *qi)
{
	int i;

	for(i=0; i<Nlds && lds[i]; i++)
		if(lds[i] == qi)
			return;
	if(i == Nlds)
		panic("pushable");
	lds[i] = qi;
}
static Qinfo *lds;

/*
 *  All stream structures are ialloc'd at boot time


@@ 48,11 34,6 @@ static Lock garbagelock;
/*
 *  The block classes.  There are Nclass block sizes, each with its own free list.
 *  All are ialloced at qinit() time.
 *
 *  NOTE: to help the mappings on the IO2 and IO3 boards, the data pointed
 *	  to by a block must not cross a 4k boundary.  Therefore:
 *	  1) all the following block sizes divide evenly into 4k
 *	  2) all the blocks are ialloc'd to not cross 4k boundaries
 */
typedef struct {
	int	size;


@@ 62,59 43,12 @@ typedef struct {
} Bclass;
Bclass bclass[Nclass]={
	{ 0 },
	{ 64 },
	{ 256 },
	{ 68 },
	{ 260 },
	{ 4096 },
};

/*
 *  Dump all block information of how many blocks are in which queues
 */
void
dumpblocks(Queue *q, char c)
{
	Block *bp;
	uchar *cp;

	lock(q);
	for(bp = q->first; bp; bp = bp->next){
		print("%c%d%c", c, bp->wptr-bp->rptr, (bp->flags&S_DELIM));
		for(cp = bp->rptr; cp<bp->wptr && cp<bp->rptr+10; cp++)
			print(" %uo", *cp);
		print("\n");
	}
	unlock(q);
}

void
dumpqueues(void)
{
	Queue *q;
	int count;
	Block *bp;
	Bclass *bcp;

	print("\n");
	for(q = qlist; q < qlist + conf.nqueue; q++, q++){
		if(!(q->flag & QINUSE))
			continue;
		print("%s %ux  R n %d l %d f %ux r %ux", q->info->name, q, q->nb,
			q->len, q->flag, &(q->r));
		print("  W n %d l %d f %ux r %ux\n", WR(q)->nb, WR(q)->len, WR(q)->flag,
			&(WR(q)->r));
		dumpblocks(q, 'R');
		dumpblocks(WR(q), 'W');
	}
	print("\n");
	for(bcp=bclass; bcp<&bclass[Nclass]; bcp++){
		lock(bcp);
		for(count = 0, bp = bcp->first; bp; count++, bp = bp->next)
			;
		unlock(bcp);
		print("%d blocks of size %d\n", count, bcp->size);
	}
	print("\n");
}
#include "stream.h"

/*
 *  Allocate streams, queues, and blocks.  Allocate n block classes with


@@ 128,6 62,9 @@ streaminit(void)
	Block *bp;
	Bclass *bcp;

	/*
	 *  allocate blocks, queues, and streams
	 */
	slist = (Stream *)ialloc(conf.nstream * sizeof(Stream), 0);
	qlist = (Queue *)ialloc(conf.nqueue * sizeof(Queue), 0);
	blist = (Block *)ialloc(conf.nblock * sizeof(Block), 0);


@@ 138,19 75,32 @@ streaminit(void)
			n = n/2;
		bcp = &bclass[class];
		for(i = 0; i < n; i++) {
			/*
			 *  The i == 0 means that each allocation range
			 *  starts on a page boundary.  This makes sure
			 *  no block crosses a page boundary.
			 */
			if(bcp->size)
				bp->base = (uchar *)ialloc(bcp->size, i == 0);
				bp->base = (uchar *)ialloc(bcp->size, 0);
			bp->lim = bp->base + bcp->size;
			bp->flags = class;
			freeb(bp);
			bp++;
		}
	}

	/*
	 *  make stream modules available
	 */
	streaminit0();
}

/*
 *  make known a stream module and call its initialization routine, if
 *  it has one.
 */
void
newqinfo(Qinfo *qi)
{
	qi->next = lds;
	lds = qi;
	if(qi->reset)
		(*qi->reset)();
}

/*


@@ 169,7 119,6 @@ allocb(ulong size)
{
	Block *bp;
	Bclass *bcp;
	int loop=0;

	/*
	 *  map size to class


@@ 183,10 132,6 @@ allocb(ulong size)
	lock(bcp);
	while(bcp->first == 0){
		unlock(bcp);
		if(loop++ == 10){
			dumpqueues();
			print("waiting for blocks\n");
		}
		qlock(bcp);
		tsleep(&bcp->r, isblock, (void *)bcp, 250);
		qunlock(bcp);


@@ 242,6 187,26 @@ freeb(Block *bp)
}

/*
 *  pad a block to the front with n bytes
 */
Block *
padb(Block *bp, int n)
{
	Block *nbp;

	if(bp->base && bp->rptr-bp->base>=n){
		bp->rptr -= n;
		return bp;
	} else {
		nbp = allocb(n);
		nbp->wptr = nbp->lim;
		nbp->rptr = nbp->wptr - n;
		nbp->next = bp;
		return nbp;
	}
} 

/*
 *  allocate a pair of queues.  flavor them with the requested put routines.
 *  the `QINUSE' flag on the read side is the only one used.
 */


@@ 572,13 537,13 @@ nullput(Queue *q, Block *bp)
static Qinfo *
qinfofind(char *name)
{
	Qinfo **qip;
	Qinfo *qi;

	if(name == 0)
		error(0, Ebadld);
	for(qip = lds; *qip; qip++)
		if(strcmp((*qip)->name, name)==0)
			return *qip;
	for(qi = lds; qi; qi = qi->next)
		if(strcmp(qi->name, name)==0)
			return qi;
	error(0, Ebadld);
}



@@ 1070,15 1035,16 @@ streamwrite(Chan *c, void *a, long n, int docopy)
	long rem;
	int i;

	s = c->stream;

	/*
	 *  one writer at a time
	 */
	s = c->stream;
	qlock(&s->wrlock);
	if(waserror()){
		qunlock(&s->wrlock);
		nexterror();
	}
	 */

	/*
	 *  decode the qid


@@ 1088,9 1054,7 @@ streamwrite(Chan *c, void *a, long n, int docopy)
		break;
	case Sctlqid:
		n = streamctlwrite(s, a, n);
		qunlock(&s->wrlock);
		poperror();
		return n;
		goto out;
	default:
		panic("bad stream qid\n");
	}


@@ 1139,8 1103,9 @@ streamwrite(Chan *c, void *a, long n, int docopy)
			}
		}
	}
	qunlock(&s->wrlock);
	poperror();
out:
/*	qunlock(&s->wrlock);
	poperror(); /**/
	return n;
}



@@ 1197,3 1162,52 @@ streamstat(Chan *c, char *db, char *name)
	devdir(c, c->qid, name, n, 0, &dir);
	convD2M(&dir, db);
}

/*
 *  Dump all block information of how many blocks are in which queues
 */
void
dumpblocks(Queue *q, char c)
{
	Block *bp;
	uchar *cp;

	lock(q);
	for(bp = q->first; bp; bp = bp->next){
		print("%c%d%c", c, bp->wptr-bp->rptr, (bp->flags&S_DELIM));
		for(cp = bp->rptr; cp<bp->wptr && cp<bp->rptr+10; cp++)
			print(" %uo", *cp);
		print("\n");
	}
	unlock(q);
}

void
dumpqueues(void)
{
	Queue *q;
	int count;
	Block *bp;
	Bclass *bcp;

	print("\n");
	for(q = qlist; q < qlist + conf.nqueue; q++, q++){
		if(!(q->flag & QINUSE))
			continue;
		print("%s %ux  R n %d l %d f %ux r %ux", q->info->name, q, q->nb,
			q->len, q->flag, &(q->r));
		print("  W n %d l %d f %ux r %ux\n", WR(q)->nb, WR(q)->len, WR(q)->flag,
			&(WR(q)->r));
		dumpblocks(q, 'R');
		dumpblocks(WR(q), 'W');
	}
	print("\n");
	for(bcp=bclass; bcp<&bclass[Nclass]; bcp++){
		lock(bcp);
		for(count = 0, bp = bcp->first; bp; count++, bp = bp->next)
			;
		unlock(bcp);
		print("%d blocks of size %d\n", count, bcp->size);
	}
	print("\n");
}

M port/sturp.c => port/sturp.c +4 -4
@@ 11,7 11,7 @@ enum {
	Nmask=		0x7,
};

#define DPRINT /*if(q->flag&QDEBUG)kprint*/
#define DPRINT if(q->flag&QDEBUG)print

typedef struct Urp	Urp;



@@ 101,6 101,7 @@ Urp	*urp;
/*
 *  predeclared
 */
static void	urpreset(void);
static void	urpciput(Queue*, Block*);
static void	urpiput(Queue*, Block*);
static void	urpoput(Queue*, Block*);


@@ 119,12 120,11 @@ static void	urpkproc(void *arg);
static void	urptimer(Alarm*);
static void	urpvomit(char*, Urp*);

Qinfo urpinfo = { urpciput, urpoput, urpopen, urpclose, "urp" };
Qinfo urpinfo = { urpciput, urpoput, urpopen, urpclose, "urp", urpreset };

void
static void
urpreset(void)
{
	newqinfo(&urpinfo);
	urp = (Urp *)ialloc(conf.nurp*sizeof(Urp), 0);
	alarm(500, urptimer, 0);
}

M power/bboot.c => power/bboot.c +23 -21
@@ 23,15 23,16 @@ typedef
struct address {
	char *name;
	char *cmd;
	char *srvname;
} Address;

Address addr[] = {
	{ "bitbootes", "bitconnect" },
	{ "ross", "connect 020701005eff" },
	{ "bootes", "connect 080069020205" },
	{ "helix", "connect 080069020427" },
	{ "spindle", "connect 0800690202df" },
	{ "r70", "connect 08002b04265d" },
	{ "bitbootes", "bitconnect", "bit!bootes" },
	{ "ross", "connect 020701005eff", "nonet!ross" },
	{ "bootes", "connect 080069020205", "nonet!bootes" },
	{ "helix", "connect 080069020427", "nonet!helix" },
	{ "spindle", "connect 0800690202df", "nonet!spindle" },
	{ "r70", "connect 08002b04265d", "nonet!r70" },
	{ 0 }
};



@@ 61,7 62,7 @@ struct a_out_h {
/*
 *  predeclared
 */
char	*lookup(char *);
Address* lookup(char *);
int	readseg(int, int, long, long, int);
int	readkernel(int);
int	readconf(int);


@@ 126,24 127,21 @@ boot(int ask, char *addr)
{
	int n;
	char conffile[128];
	Address *a;

	if(ask){
		outin("bootfile", bootfile, bbuf, sizeof(bbuf));
		bootfile = bbuf;
	}

	if(!ask)
		scmd = lookup(sys);
	else {
		outin("server", sys, sbuf, sizeof(sbuf));
		sys = sbuf;
		scmd = lookup(sys);
	}
	if(scmd == 0){

	a = lookup(sys);
	if(a == 0){
		fprint(2, "boot: %s unknown\n", sys);
		return;
	}

	scmd = a->cmd;

	/*
	 *  for the bit, we skip all the ether goo


@@ 174,18 172,22 @@ boot(int ask, char *addr)
		prerror("push noether");
		return;
	}
	if(write(cfd, "config nonet", sizeof("config nonet")-1)<0){
		prerror("config nonet");
		return;
	}

	/*
	 *  grab a nonet channel and call up the ross file server
	 */
	fd = open("#n/1/data", 2);
	fd = open("#nnonet/2/data", 2);
	if(fd < 0) {
		prerror("opening #n/1/data");
		prerror("opening #n/2/data");
		return;
	}
	cfd = open("#n/1/ctl", 2);
	cfd = open("#nnonet/2/ctl", 2);
	if(cfd < 0){
		prerror("opening #n/1/ctl");
		prerror("opening #n/2/ctl");
		return;
	}
	if(write(cfd, scmd, strlen(scmd))<0){


@@ 301,7 303,7 @@ error(char *s)
/*
 *  lookup the address for a system
 */
char *
Address *
lookup(char *arg)
{
	Address *a;


@@ 313,7 315,7 @@ lookup(char *arg)
	}
	for(a = addr; a->name; a++){
		if(strcmp(a->name, arg) == 0)
			return a->cmd;
			return a;
	}
	return 0;
}

M power/boot.h => power/boot.h +331 -339
@@ 1,7 1,7 @@
ulong bootcode[]={
	0x000000407,
	0x000004410,
	0x0000005d0,
	0x0000043f0,
	0x0000005d8,
	0x0000010d0,
	0x000000000,
	0x000001020,


@@ 23,21 23,21 @@ ulong bootcode[]={
	0x023bdffe4,
	0x0afbf0000,
	0x0afa00014,
	0x023c28239,
	0x023c2823d,
	0x0afa20004,
	0x00c000ed5,
	0x0afa00008,
	0x023c38241,
	0x023c38245,
	0x0afa30004,
	0x020020001,
	0x00c000ed5,
	0x0afa20008,
	0x023c38249,
	0x023c3824d,
	0x0afa30004,
	0x020020001,
	0x00c000ed5,
	0x0afa20008,
	0x023c28251,
	0x023c28255,
	0x0afa20004,
	0x020040001,
	0x0afa40008,


@@ 46,7 46,7 @@ ulong bootcode[]={
	0x0afa2000c,
	0x004210004,
	0x0afa10018,
	0x023c3825c,
	0x023c38260,
	0x00c0006ab,
	0x0afa30004,
	0x08fa40024,


@@ 68,7 68,7 @@ ulong bootcode[]={
	0x0afa4000c,
	0x01c200004,
	0x000000027,
	0x023c28264,
	0x023c28268,
	0x00c0006ab,
	0x0afa20004,
	0x08fa30018,


@@ 105,55 105,55 @@ ulong bootcode[]={
	0x000000027,
	0x01069fff1,
	0x000000027,
	0x023c2826c,
	0x023c28270,
	0x0afc28002,
	0x023c38276,
	0x023c3827a,
	0x038c20001,
	0x010400029,
	0x0afc3802e,
	0x0afc38032,
	0x038c20002,
	0x010400020,
	0x000000027,
	0x00c00049b,
	0x0afa70004,
	0x08fc58072,
	0x08fc58076,
	0x000000027,
	0x018a00003,
	0x000000027,
	0x00c000ebc,
	0x0afa50004,
	0x08fc2803e,
	0x08fc28042,
	0x000000027,
	0x018400004,
	0x000000027,
	0x08fc3803e,
	0x08fc38042,
	0x00c000ebc,
	0x0afa30004,
	0x08fc28042,
	0x08fc28046,
	0x000000027,
	0x018400004,
	0x000000027,
	0x08fc38042,
	0x08fc38046,
	0x00c000ebc,
	0x0afa30004,
	0x0afc08046,
	0x0afc08042,
	0x0afc0803e,
	0x0afc08072,
	0x0afc08076,
	0x020030001,
	0x00c00049b,
	0x0afa30004,
	0x08fc58072,
	0x08fc58076,
	0x008000477,
	0x000000027,
	0x08ca30000,
	0x000000027,
	0x0afc3802e,
	0x0afc38032,
	0x08ca20004,
	0x008000473,
	0x0afc28002,
	0x08ca20000,
	0x008000473,
	0x0afc2802e,
	0x0afc28032,
	0x023bdffd8,
	0x0afbf0000,
	0x08fc58002,


@@ 161,15 161,15 @@ ulong bootcode[]={
	0x000000027,
	0x01040000a,
	0x000000027,
	0x023c3827e,
	0x023c38282,
	0x0afa30004,
	0x0afa50008,
	0x023c38076,
	0x023c3807a,
	0x0afa3000c,
	0x020020038,
	0x00c000702,
	0x0afa20010,
	0x023c58076,
	0x023c5807a,
	0x0afc58002,
	0x00c0006c0,
	0x0afa50004,


@@ 177,7 177,7 @@ ulong bootcode[]={
	0x000000027,
	0x020020002,
	0x0afa20004,
	0x023c38285,
	0x023c38289,
	0x0afa30008,
	0x08fc28002,
	0x00c0007b0,


@@ 188,37 188,37 @@ ulong bootcode[]={
	0x023bd0028,
	0x0afa1001c,
	0x08c250004,
	0x023c48297,
	0x0afc5804e,
	0x023c4829b,
	0x0afc58052,
	0x0afa50004,
	0x00c0007ee,
	0x0afa40008,
	0x014200167,
	0x020050002,
	0x023c382a2,
	0x023c382a6,
	0x0afa30004,
	0x00c000ed5,
	0x0afa50008,
	0x004210008,
	0x0afc18072,
	0x023c282aa,
	0x0afc18076,
	0x023c282ae,
	0x00c000698,
	0x0afa20004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x023c3836e,
	0x023c38372,
	0x00c00078b,
	0x0afa30004,
	0x0a3c09656,
	0x023c39656,
	0x0a3c0965e,
	0x023c3965e,
	0x0afa30004,
	0x023c48656,
	0x023c4865e,
	0x00c00086f,
	0x0afa40008,
	0x08fc28072,
	0x023c48656,
	0x08fc28076,
	0x023c4865e,
	0x0afa20004,
	0x0afa40008,
	0x0afa10024,


@@ 228,19 228,19 @@ ulong bootcode[]={
	0x000000027,
	0x01025000c,
	0x000000027,
	0x023c28375,
	0x023c28379,
	0x0afa20004,
	0x00c00078b,
	0x0afa50008,
	0x023c2837d,
	0x023c28381,
	0x00c000698,
	0x0afa20004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x08fc28072,
	0x023c48656,
	0x08fc28076,
	0x023c4865e,
	0x0afa20004,
	0x0afa40008,
	0x020021000,


@@ 248,71 248,71 @@ ulong bootcode[]={
	0x0afa2000c,
	0x01c200008,
	0x000000027,
	0x023c38387,
	0x023c3838b,
	0x00c000698,
	0x0afa30004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x023c38656,
	0x023c3865e,
	0x0afa30004,
	0x023c49656,
	0x023c4965e,
	0x0afa40008,
	0x0afa10024,
	0x00c000c0c,
	0x0afa1000c,
	0x014200019,
	0x000000027,
	0x023c28390,
	0x023c28394,
	0x0afa20004,
	0x08fa30024,
	0x000000027,
	0x0afa30008,
	0x083c28656,
	0x083c2865e,
	0x000000027,
	0x0afa2000c,
	0x083c38657,
	0x083c3865f,
	0x000000027,
	0x0afa30010,
	0x083c28658,
	0x083c28660,
	0x000000027,
	0x0afa20014,
	0x083c38659,
	0x083c38661,
	0x00c00078b,
	0x0afa30018,
	0x023c283b3,
	0x023c283b7,
	0x00c000698,
	0x0afa20004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x083c39656,
	0x083c3965e,
	0x020020001,
	0x010620008,
	0x000000027,
	0x023c383be,
	0x023c383c2,
	0x00c000698,
	0x0afa30004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x023c283c7,
	0x023c283cb,
	0x00c00078b,
	0x0afa20004,
	0x020030002,
	0x0a3c39656,
	0x0a3c3965e,
	0x020020076,
	0x0a3c29662,
	0x023c29656,
	0x0a3c2966a,
	0x023c2965e,
	0x0afa20004,
	0x023c48656,
	0x023c4865e,
	0x00c00086f,
	0x0afa40008,
	0x08fc38072,
	0x023c48656,
	0x08fc38076,
	0x023c4865e,
	0x0afa30004,
	0x0afa40008,
	0x0afa10024,


@@ 322,15 322,15 @@ ulong bootcode[]={
	0x000000027,
	0x010240008,
	0x000000027,
	0x023c283d2,
	0x023c283d6,
	0x00c000698,
	0x0afa20004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x08fc28072,
	0x023c48656,
	0x08fc28076,
	0x023c4865e,
	0x0afa20004,
	0x0afa40008,
	0x020021000,


@@ 338,68 338,68 @@ ulong bootcode[]={
	0x0afa2000c,
	0x01c200008,
	0x000000027,
	0x023c383e0,
	0x023c383e4,
	0x00c000698,
	0x0afa30004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x023c38656,
	0x023c3865e,
	0x0afa30004,
	0x023c49656,
	0x023c4965e,
	0x0afa40008,
	0x00c000c0c,
	0x0afa1000c,
	0x014200008,
	0x000000027,
	0x023c283ed,
	0x023c283f1,
	0x00c000698,
	0x0afa20004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x083c39656,
	0x083c3965e,
	0x020020003,
	0x010620008,
	0x000000027,
	0x023c383fc,
	0x023c38400,
	0x00c000698,
	0x0afa30004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x087c2965a,
	0x087c29662,
	0x000000027,
	0x01040000d,
	0x000000027,
	0x023c38409,
	0x023c3840d,
	0x0afa30004,
	0x087c2965a,
	0x087c29662,
	0x00c00078b,
	0x0afa20008,
	0x023c38413,
	0x023c38417,
	0x00c000698,
	0x0afa30004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x023c28420,
	0x023c28424,
	0x00c00078b,
	0x0afa20004,
	0x023c38656,
	0x023c3865e,
	0x0afa30004,
	0x023c28428,
	0x023c2842c,
	0x0afa20008,
	0x08fa3001c,
	0x000000027,
	0x08c630008,
	0x00c0007d5,
	0x0afa3000c,
	0x023c38656,
	0x023c3865e,
	0x0afa30004,
	0x020040001,
	0x0afa40008,


@@ 408,26 408,26 @@ ulong bootcode[]={
	0x0afa3000c,
	0x004210004,
	0x0afa10020,
	0x023c2842e,
	0x023c28432,
	0x00c0006ab,
	0x0afa20004,
	0x023c38656,
	0x023c3865e,
	0x0afa30004,
	0x023c28435,
	0x023c28439,
	0x0afa20008,
	0x08fc38072,
	0x08fc38076,
	0x00c0007d5,
	0x0afa3000c,
	0x023c28656,
	0x023c2865e,
	0x00c000857,
	0x0afa20004,
	0x0afa10018,
	0x023c48656,
	0x023c4865e,
	0x00c000857,
	0x0afa40004,
	0x0afa10014,
	0x08fa40020,
	0x023c38656,
	0x023c3865e,
	0x0afa40004,
	0x0afa30008,
	0x08fa40014,


@@ 437,13 437,13 @@ ulong bootcode[]={
	0x000000027,
	0x010230004,
	0x000000027,
	0x023c28438,
	0x023c2843c,
	0x00c0006ab,
	0x0afa20004,
	0x08fa30020,
	0x00c000ebc,
	0x0afa30004,
	0x023c3843e,
	0x023c38442,
	0x0afa30004,
	0x020040001,
	0x0afa40008,


@@ 452,26 452,26 @@ ulong bootcode[]={
	0x0afa3000c,
	0x004210004,
	0x0afa10020,
	0x023c28446,
	0x023c2844a,
	0x00c0006ab,
	0x0afa20004,
	0x023c38656,
	0x023c3865e,
	0x0afa30004,
	0x023c2844d,
	0x023c28451,
	0x0afa20008,
	0x08fc38072,
	0x08fc38076,
	0x00c0007d5,
	0x0afa3000c,
	0x023c28656,
	0x023c2865e,
	0x00c000857,
	0x0afa20004,
	0x0afa10018,
	0x023c48656,
	0x023c4865e,
	0x00c000857,
	0x0afa40004,
	0x0afa10014,
	0x08fa40020,
	0x023c38656,
	0x023c3865e,
	0x0afa40004,
	0x0afa30008,
	0x08fa40014,


@@ 481,85 481,85 @@ ulong bootcode[]={
	0x000000027,
	0x010230004,
	0x000000027,
	0x023c28450,
	0x023c28454,
	0x00c0006ab,
	0x0afa20004,
	0x08fa30020,
	0x00c000ebc,
	0x0afa30004,
	0x023c28456,
	0x023c2845a,
	0x00c00078b,
	0x0afa20004,
	0x023c2845f,
	0x023c28463,
	0x0afa20004,
	0x023c48461,
	0x023c48465,
	0x0afa40008,
	0x00c000eb7,
	0x0afa0000c,
	0x004210004,
	0x000000027,
	0x023c28463,
	0x023c28467,
	0x00c0006ab,
	0x0afa20004,
	0x08fc28072,
	0x023c48468,
	0x08fc28076,
	0x023c4846c,
	0x0afa20004,
	0x0afa40008,
	0x020020006,
	0x0afa2000c,
	0x023c4846a,
	0x023c4846e,
	0x00c000ed0,
	0x0afa40010,
	0x004210004,
	0x000000027,
	0x023c2846b,
	0x023c2846f,
	0x00c0006ab,
	0x0afa20004,
	0x023c38471,
	0x023c38475,
	0x00c00078b,
	0x0afa30004,
	0x08fc28072,
	0x08fc28076,
	0x00c000ebc,
	0x0afa20004,
	0x08fa3002c,
	0x000000027,
	0x010600010,
	0x000000027,
	0x023c2847a,
	0x023c2847e,
	0x0afa20004,
	0x023c38485,
	0x023c38489,
	0x0afa30008,
	0x023c2848a,
	0x023c2848e,
	0x0afa2000c,
	0x00c000863,
	0x0afa00010,
	0x023c3849d,
	0x023c384a1,
	0x00c0006ab,
	0x0afa30004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x023c3848d,
	0x023c38491,
	0x0afa30004,
	0x023c28498,
	0x023c2849c,
	0x0afa20008,
	0x00c000863,
	0x0afa0000c,
	0x023c3849d,
	0x023c384a1,
	0x00c0006ab,
	0x0afa30004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x023c282ba,
	0x023c282be,
	0x0afa20004,
	0x00c000ed5,
	0x0afa50008,
	0x004210008,
	0x0afc18042,
	0x023c382c3,
	0x0afc18046,
	0x023c382c7,
	0x00c000698,
	0x0afa30004,
	0x08fa20000,


@@ 567,22 567,22 @@ ulong bootcode[]={
	0x000400008,
	0x023bd0028,
	0x0afa10004,
	0x023c482d4,
	0x023c482d8,
	0x0afa40008,
	0x02003000d,
	0x00c000edf,
	0x0afa3000c,
	0x004210008,
	0x000000027,
	0x023c282e2,
	0x023c282e6,
	0x00c000698,
	0x0afa20004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x08fc28042,
	0x023c482f0,
	0x08fc28046,
	0x023c482f4,
	0x0afa20004,
	0x0afa40008,
	0x02002000c,


@@ 590,15 590,15 @@ ulong bootcode[]={
	0x0afa2000c,
	0x004210008,
	0x000000027,
	0x023c382fd,
	0x023c38301,
	0x00c000698,
	0x0afa30004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x08fc38042,
	0x023c4830a,
	0x08fc38046,
	0x023c4830e,
	0x0afa30004,
	0x0afa40008,
	0x02003000c,


@@ 606,49 606,49 @@ ulong bootcode[]={
	0x0afa3000c,
	0x004210008,
	0x000000027,
	0x023c28317,
	0x023c2831b,
	0x00c000698,
	0x0afa20004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x023c28324,
	0x023c28328,
	0x0afa20004,
	0x020040002,
	0x00c000ed5,
	0x0afa40008,
	0x004210008,
	0x0afc18072,
	0x023c38333,
	0x0afc18076,
	0x023c38337,
	0x00c000698,
	0x0afa30004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x023c3834a,
	0x023c3834e,
	0x0afa30004,
	0x020040002,
	0x00c000ed5,
	0x0afa40008,
	0x004210008,
	0x0afc1803e,
	0x023c28358,
	0x0afc18042,
	0x023c2835c,
	0x00c000698,
	0x0afa20004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x08fc4804e,
	0x08fc48052,
	0x00c000857,
	0x0afa40004,
	0x0afa10018,
	0x08fc4803e,
	0x08fc48042,
	0x000000027,
	0x0afa40004,
	0x08fc2804e,
	0x08fc28052,
	0x000000027,
	0x0afa20008,
	0x08fa40018,


@@ 656,7 656,7 @@ ulong bootcode[]={
	0x0afa4000c,
	0x00421fe41,
	0x000000027,
	0x08fc2804e,
	0x08fc28052,
	0x00c000698,
	0x0afa20004,
	0x08fa20000,


@@ 671,7 671,7 @@ ulong bootcode[]={
	0x0afa20008,
	0x020030002,
	0x0afa30004,
	0x023c284a8,
	0x023c284ac,
	0x0afa20008,
	0x08fa30058,
	0x023a20014,


@@ 690,7 690,7 @@ ulong bootcode[]={
	0x0afa30008,
	0x020020002,
	0x0afa20004,
	0x023c384b6,
	0x023c384ba,
	0x0afa30008,
	0x08fa20058,
	0x023a30014,


@@ 706,20 706,20 @@ ulong bootcode[]={
	0x023bdfff0,
	0x0afbf0000,
	0x08fa30014,
	0x023c484c4,
	0x023c484c8,
	0x0afa30004,
	0x00c0007ee,
	0x0afa40008,
	0x010200024,
	0x000000027,
	0x08fa30014,
	0x023c484c6,
	0x023c484ca,
	0x0afa30004,
	0x00c0007ee,
	0x0afa40008,
	0x01020001d,
	0x000000027,
	0x023c5857e,
	0x023c58582,
	0x08ca30000,
	0x000000027,
	0x010600014,


@@ 747,12 747,12 @@ ulong bootcode[]={
	0x023bd0010,
	0x000400008,
	0x000000825,
	0x023c5857e,
	0x023c58582,
	0x08ca20000,
	0x000000027,
	0x01040000e,
	0x000000027,
	0x023c384cb,
	0x023c384cf,
	0x0afa30004,
	0x0afa5000c,
	0x08ca20000,


@@ 771,7 771,7 @@ ulong bootcode[]={
	0x000000825,
	0x023bdffec,
	0x0afbf0000,
	0x023c384cf,
	0x023c384d3,
	0x0afa30004,
	0x08fa20018,
	0x000000027,


@@ 792,7 792,7 @@ ulong bootcode[]={
	0x000000027,
	0x004210006,
	0x0afa10010,
	0x023c284d8,
	0x023c284dc,
	0x00c0006ab,
	0x0afa20004,
	0x08fa50010,


@@ 823,7 823,7 @@ ulong bootcode[]={
	0x000002025,
	0x028810021,
	0x010200011,
	0x023c585d2,
	0x023c585da,
	0x000040880,
	0x000250821,
	0x08c210000,


@@ 848,7 848,7 @@ ulong bootcode[]={
	0x000001825,
	0x028610021,
	0x01020000d,
	0x023c485d2,
	0x023c485da,
	0x000030880,
	0x000240821,
	0x08c210000,


@@ 871,7 871,7 @@ ulong bootcode[]={
	0x000000027,
	0x00c00076f,
	0x0afa00004,
	0x023c2805a,
	0x023c2805e,
	0x00c00076f,
	0x0afa20004,
	0x08fa20000,


@@ 880,7 880,7 @@ ulong bootcode[]={
	0x023bd0008,
	0x023bdfff0,
	0x0afbf0000,
	0x023c585d2,
	0x023c585da,
	0x020030020,
	0x004600010,
	0x000000027,


@@ 896,7 896,7 @@ ulong bootcode[]={
	0x00080f809,
	0x0ac200000,
	0x08fa3000c,
	0x023c585d2,
	0x023c585da,
	0x008000773,
	0x02463ffff,
	0x08fa20014,


@@ 916,7 916,7 @@ ulong bootcode[]={
	0x023a21020,
	0x0afa3000c,
	0x024420004,
	0x00c000f0b,
	0x00c000f02,
	0x0afa20010,
	0x023a6001c,
	0x020020001,


@@ 928,12 928,12 @@ ulong bootcode[]={
	0x0afa10014,
	0x00421000c,
	0x000012825,
	0x08fc28032,
	0x08fc28036,
	0x000000027,
	0x024410001,
	0x02822000a,
	0x014400006,
	0x0afc18032,
	0x0afc18036,
	0x020010001,
	0x00c000760,
	0x0afa10004,


@@ 953,7 953,7 @@ ulong bootcode[]={
	0x023a21024,
	0x0afa3000c,
	0x024420004,
	0x00c000f0b,
	0x00c000f02,
	0x0afa20010,
	0x08fa31020,
	0x023a6001c,


@@ 965,12 965,12 @@ ulong bootcode[]={
	0x0afa10014,
	0x00421000c,
	0x000012825,
	0x08fc28032,
	0x08fc28036,
	0x000000027,
	0x024410001,
	0x02822000a,
	0x014400006,
	0x0afc18032,
	0x0afc18036,
	0x020010001,
	0x00c000760,
	0x0afa10004,


@@ 983,7 983,7 @@ ulong bootcode[]={
	0x023bdffe4,
	0x0afbf0000,
	0x08fa50020,
	0x08fc18036,
	0x08fc1803a,
	0x024a21000,
	0x0afa10014,
	0x0afa50004,


@@ 992,12 992,12 @@ ulong bootcode[]={
	0x023a20024,
	0x0afa3000c,
	0x024420004,
	0x00c000f0b,
	0x00c000f02,
	0x0afa20010,
	0x000012825,
	0x08fa10014,
	0x000000027,
	0x0afc18036,
	0x0afc1803a,
	0x08fa20020,
	0x000000027,
	0x000a20823,


@@ 1115,7 1115,7 @@ ulong bootcode[]={
	0x08fa30010,
	0x000000027,
	0x0afa30004,
	0x00c0013e3,
	0x00c0013db,
	0x0afa00008,
	0x08fa30010,
	0x08fa20000,


@@ 1171,7 1171,7 @@ ulong bootcode[]={
	0x038220003,
	0x01040000a,
	0x000000027,
	0x023c180b2,
	0x023c180b6,
	0x0afa10004,
	0x080820000,
	0x00c00078b,


@@ 1217,7 1217,7 @@ ulong bootcode[]={
	0x0afa10004,
	0x024810008,
	0x0afa10008,
	0x00c00149c,
	0x00c001494,
	0x0afa6000c,
	0x08fa10010,
	0x02002001c,


@@ 1228,7 1228,7 @@ ulong bootcode[]={
	0x000000027,
	0x024210024,
	0x0afa10008,
	0x00c00149c,
	0x00c001494,
	0x0afa2000c,
	0x08fa10010,
	0x08fa2001c,


@@ 1338,7 1338,7 @@ ulong bootcode[]={
	0x0afa20004,
	0x02482000c,
	0x0afa20008,
	0x00c00149c,
	0x00c001494,
	0x0afa6000c,
	0x08fa20010,
	0x000000027,


@@ 1380,7 1380,7 @@ ulong bootcode[]={
	0x0afa10004,
	0x02481000c,
	0x0afa10008,
	0x00c00149c,
	0x00c001494,
	0x0afa6000c,
	0x08fa60018,
	0x08fa10010,


@@ 1480,7 1480,7 @@ ulong bootcode[]={
	0x000000027,
	0x0afa20008,
	0x08c81000c,
	0x00c00149c,
	0x00c001494,
	0x0afa1000c,
	0x08fa20018,
	0x08fa10010,


@@ 1521,7 1521,7 @@ ulong bootcode[]={
	0x000000027,
	0x0afa10008,
	0x08c82000c,
	0x00c00149c,
	0x00c001494,
	0x0afa2000c,
	0x08fa10018,
	0x08fa20010,


@@ 1663,7 1663,7 @@ ulong bootcode[]={
	0x0afa20004,
	0x024820008,
	0x0afa20008,
	0x00c00149c,
	0x00c001494,
	0x0afa7000c,
	0x08fa20010,
	0x000000027,


@@ 1693,7 1693,7 @@ ulong bootcode[]={
	0x0afa20004,
	0x024820008,
	0x0afa20008,
	0x00c00149c,
	0x00c001494,
	0x0afa7000c,
	0x08fa20010,
	0x000000027,


@@ 1760,7 1760,7 @@ ulong bootcode[]={
	0x0afa20004,
	0x024820008,
	0x0afa20008,
	0x00c00149c,
	0x00c001494,
	0x0afa6000c,
	0x08fa20010,
	0x000000027,


@@ 1811,7 1811,7 @@ ulong bootcode[]={
	0x0afa20004,
	0x024820008,
	0x0afa20008,
	0x00c00149c,
	0x00c001494,
	0x0afa7000c,
	0x08fa20010,
	0x000000027,


@@ 1874,7 1874,7 @@ ulong bootcode[]={
	0x000000027,
	0x0afa20008,
	0x08c81000c,
	0x00c00149c,
	0x00c001494,
	0x0afa1000c,
	0x08fa20018,
	0x08fa10010,


@@ 1916,7 1916,7 @@ ulong bootcode[]={
	0x000000027,
	0x0afa10008,
	0x08c82000c,
	0x00c00149c,
	0x00c001494,
	0x0afa2000c,
	0x08fa10018,
	0x08fa20010,


@@ 1939,7 1939,7 @@ ulong bootcode[]={
	0x08fa10018,
	0x000000027,
	0x0afa10008,
	0x00c00149c,
	0x00c001494,
	0x0afa2000c,
	0x08fa30018,
	0x08fa10010,


@@ 2098,7 2098,7 @@ ulong bootcode[]={
	0x038410003,
	0x01020000a,
	0x000000027,
	0x023c280c0,
	0x023c280c4,
	0x0afa20004,
	0x080a10000,
	0x00c00078b,


@@ 2144,7 2144,7 @@ ulong bootcode[]={
	0x0afa20004,
	0x0afa40010,
	0x0afa40008,
	0x00c00149c,
	0x00c001494,
	0x0afa6000c,
	0x08fa10010,
	0x08fa2001c,


@@ 2154,7 2154,7 @@ ulong bootcode[]={
	0x0afa40010,
	0x0afa40008,
	0x02002001c,
	0x00c00149c,
	0x00c001494,
	0x0afa2000c,
	0x08fa10010,
	0x008000c42,


@@ 2231,7 2231,7 @@ ulong bootcode[]={
	0x0afa20004,
	0x0afa40010,
	0x0afa40008,
	0x00c00149c,
	0x00c001494,
	0x0afa6000c,
	0x08fa10010,
	0x008000c42,


@@ 2265,7 2265,7 @@ ulong bootcode[]={
	0x0afa20004,
	0x0afa40010,
	0x0afa40008,
	0x00c00149c,
	0x00c001494,
	0x0afa6000c,
	0x08fa5001c,
	0x08fa10010,


@@ 2455,7 2455,7 @@ ulong bootcode[]={
	0x0afa10004,
	0x0afa40010,
	0x0afa40008,
	0x00c00149c,
	0x00c001494,
	0x0afa7000c,
	0x08fa20010,
	0x008000c42,


@@ 2476,7 2476,7 @@ ulong bootcode[]={
	0x0afa20004,
	0x0afa40010,
	0x0afa40008,
	0x00c00149c,
	0x00c001494,
	0x0afa7000c,
	0x08fa10010,
	0x008000c42,


@@ 2526,7 2526,7 @@ ulong bootcode[]={
	0x0afa20004,
	0x0afa40010,
	0x0afa40008,
	0x00c00149c,
	0x00c001494,
	0x0afa6000c,
	0x08fa10010,
	0x008000c42,


@@ 2560,7 2560,7 @@ ulong bootcode[]={
	0x0afa20004,
	0x0afa40010,
	0x0afa40008,
	0x00c00149c,
	0x00c001494,
	0x0afa7000c,
	0x08fa10010,
	0x008000c42,


@@ 2639,7 2639,7 @@ ulong bootcode[]={
	0x0afa40010,
	0x0afa40008,
	0x02001001c,
	0x00c00149c,
	0x00c001494,
	0x0afa1000c,
	0x08fa4001c,
	0x08fa20010,


@@ 2788,37 2788,28 @@ ulong bootcode[]={
	0x003e00008,
	0x023bd0004,
	0x023bdfffc,
	0x08fc780ae,
	0x023c684fe,
	0x08fc780b2,
	0x083a2000b,
	0x000000027,
	0x028e3001e,
	0x03042007f,
	0x000022e00,
	0x000052e03,
	0x000051600,
	0x000021603,
	0x000461021,
	0x080420000,
	0x000000027,
	0x01440000d,
	0x000000027,
	0x028e2001e,
	0x014400004,
	0x000000027,
	0x014600004,
	0x023c68502,
	0x023bd0004,
	0x003e00008,
	0x020010001,
	0x000051600,
	0x000021603,
	0x000461021,
	0x024e30001,
	0x0afc380ae,
	0x0a0470000,
	0x000051e00,
	0x000031e03,
	0x000661821,
	0x024e20001,
	0x0afc280b2,
	0x0a0670000,
	0x000051600,
	0x000021603,
	0x000461021,
	0x080420000,
	0x023c380de,
	0x023c380e2,
	0x000021080,
	0x08fa4000c,
	0x000431021,


@@ 2833,19 2824,19 @@ ulong bootcode[]={
	0x000004025,
	0x08fa60040,
	0x020120030,
	0x08fc280d2,
	0x08fc280d6,
	0x02011002a,
	0x0afa2001c,
	0x08fc3803a,
	0x08fc3803e,
	0x0200fffff,
	0x0afa30018,
	0x08fb00038,
	0x0200d002e,
	0x0afd080d2,
	0x0afd080d6,
	0x08fa3003c,
	0x0200b0039,
	0x02463ffff,
	0x0afc3803a,
	0x0afc3803e,
	0x000062825,
	0x080a50000,
	0x000000027,


@@ 2853,7 2844,7 @@ ulong bootcode[]={
	0x024c60001,
	0x014a00012,
	0x000000027,
	0x08fc3803a,
	0x08fc3803e,
	0x000000027,
	0x00203202b,
	0x014800002,


@@ 2862,31 2853,31 @@ ulong bootcode[]={
	0x0a2000000,
	0x08fa3001c,
	0x000000027,
	0x0afc380d2,
	0x0afc380d6,
	0x08fa20018,
	0x000000027,
	0x0afc2803a,
	0x0afc2803e,
	0x08fa20000,
	0x023bd0034,
	0x000400008,
	0x000100825,
	0x08fc3803a,
	0x08fc3803e,
	0x000000027,
	0x00203202b,
	0x010800005,
	0x000000027,
	0x000101025,
	0x026100001,
	0x0afd080d2,
	0x0afd080d6,
	0x0a0450000,
	0x08fc28036,
	0x08fc2803a,
	0x000000027,
	0x024420001,
	0x0afc28036,
	0x0afc2803a,
	0x02002000a,
	0x014a20071,
	0x000000027,
	0x0afc88036,
	0x0afc8803a,
	0x000062825,
	0x080a50000,
	0x000000027,


@@ 2902,14 2893,14 @@ ulong bootcode[]={
	0x000000027,
	0x014a00003,
	0x000000027,
	0x008000f1f,
	0x008000f16,
	0x024c6ffff,
	0x014ad0006,
	0x000000027,
	0x004e10002,
	0x000000027,
	0x000083825,
	0x008000f50,
	0x008000f47,
	0x000087025,
	0x028a30031,
	0x01460001f,


@@ 2928,11 2919,11 @@ ulong bootcode[]={
	0x000000027,
	0x014a0ffe9,
	0x000093825,
	0x008000f1f,
	0x008000f16,
	0x024c6ffff,
	0x014a0ffe5,
	0x000097025,
	0x008000f1f,
	0x008000f16,
	0x024c6ffff,
	0x02002000a,
	0x001220018,


@@ 2942,22 2933,22 @@ ulong bootcode[]={
	0x024c60001,
	0x0afa60040,
	0x080a50000,
	0x008000f67,
	0x008000f5e,
	0x02469ffd0,
	0x014b20005,
	0x000000027,
	0x004e00003,
	0x000000027,
	0x008000f66,
	0x008000f5d,
	0x000000027,
	0x014b10008,
	0x000000027,
	0x08d450000,
	0x004e10003,
	0x0254a0004,
	0x008000f50,
	0x008000f47,
	0x000053825,
	0x008000f50,
	0x008000f47,
	0x000057025,
	0x030a5007f,
	0x0afaa0044,


@@ 2969,17 2960,17 @@ ulong bootcode[]={
	0x0afac0028,
	0x0afac0010,
	0x0afa50014,
	0x023c284fe,
	0x023c28502,
	0x000451021,
	0x080420000,
	0x023c380de,
	0x023c380e2,
	0x000021080,
	0x000431021,
	0x08c420000,
	0x000000027,
	0x00040f809,
	0x000000027,
	0x08fd080d2,
	0x08fd080d6,
	0x020120030,
	0x08fae002c,
	0x02011002a,


@@ 2994,20 2985,20 @@ ulong bootcode[]={
	0x020130025,
	0x08fa40028,
	0x001011023,
	0x008000f50,
	0x008000f47,
	0x000826025,
	0x008000f1f,
	0x008000f16,
	0x001415021,
	0x020020009,
	0x014a2ff66,
	0x000000027,
	0x08fc38036,
	0x08fc3803a,
	0x000000027,
	0x024630007,
	0x0201cfff8,
	0x0007c1824,
	0x008000f1f,
	0x0afc38036,
	0x008000f16,
	0x0afc3803a,
	0x023bdffac,
	0x0afbf0000,
	0x08fa90068,


@@ 3100,7 3091,7 @@ ulong bootcode[]={
	0x08fa3005c,
	0x02002ffff,
	0x0afa30008,
	0x00c001091,
	0x00c001088,
	0x0afa2000c,
	0x08fa10024,
	0x08fa20000,


@@ 3117,7 3108,7 @@ ulong bootcode[]={
	0x0a0640000,
	0x024a5ffff,
	0x001651021,
	0x008001012,
	0x008001009,
	0x0a0510000,
	0x024a5ffff,
	0x001651021,


@@ 3125,7 3116,7 @@ ulong bootcode[]={
	0x0a0440000,
	0x024a5ffff,
	0x001651021,
	0x008001012,
	0x008001009,
	0x0a0510000,
	0x031030040,
	0x01060001c,


@@ 3145,26 3136,26 @@ ulong bootcode[]={
	0x000000027,
	0x01ce00003,
	0x000000027,
	0x008001005,
	0x008000ffc,
	0x000000027,
	0x01d400003,
	0x000000027,
	0x008001005,
	0x008000ffc,
	0x000000027,
	0x031020040,
	0x01440ffa5,
	0x024a5ffff,
	0x00149001b,
	0x008000ffb,
	0x008000ff2,
	0x000003010,
	0x00149001b,
	0x00800103f,
	0x008001036,
	0x000005012,
	0x000147825,
	0x008000ff3,
	0x008000fea,
	0x0024a5023,
	0x08cca0000,
	0x008000fee,
	0x008000fe5,
	0x0afa50024,
	0x08cc20000,
	0x0afa50024,


@@ 3172,13 3163,13 @@ ulong bootcode[]={
	0x000063403,
	0x000061c00,
	0x000031c03,
	0x008000fee,
	0x008000fe5,
	0x000035025,
	0x08cca0000,
	0x008000fee,
	0x008000fe5,
	0x0afa50024,
	0x08cca0000,
	0x008000fee,
	0x008000fe5,
	0x0afa50024,
	0x038430030,
	0x010600009,


@@ 3186,24 3177,24 @@ ulong bootcode[]={
	0x038430048,
	0x010600003,
	0x000000027,
	0x008000fec,
	0x008000fe3,
	0x000000027,
	0x08cc70000,
	0x008000fee,
	0x008000fe5,
	0x0afa50024,
	0x08cc30000,
	0x0afa50024,
	0x000033400,
	0x000063403,
	0x030c2ffff,
	0x008000fee,
	0x008000fe5,
	0x000025025,
	0x008000fdd,
	0x008000fd4,
	0x02009000a,
	0x000148025,
	0x008000fdd,
	0x008000fd4,
	0x000134825,
	0x008000fdd,
	0x008000fd4,
	0x000154825,
	0x039230075,
	0x010600006,


@@ 3211,10 3202,10 @@ ulong bootcode[]={
	0x039230078,
	0x01060fff7,
	0x000000027,
	0x008000fdd,
	0x008000fd4,
	0x000000027,
	0x02009000a,
	0x008000fdd,
	0x008000fd4,
	0x035080020,
	0x023bdfff0,
	0x0afbf0000,


@@ 3225,10 3216,10 @@ ulong bootcode[]={
	0x000007025,
	0x08fac0014,
	0x0200b0020,
	0x08fca803a,
	0x08fca803e,
	0x08fa9001c,
	0x08fc88036,
	0x08fc680d2,
	0x08fc8803a,
	0x08fc680d6,
	0x000012825,
	0x005a00010,
	0x0200f000a,


@@ 3240,13 3231,13 @@ ulong bootcode[]={
	0x000000027,
	0x000061025,
	0x024c60001,
	0x0afc680d2,
	0x0afc680d6,
	0x0a04b0000,
	0x025080001,
	0x024a50001,
	0x000ad202a,
	0x01480fff5,
	0x0afc88036,
	0x0afc8803a,
	0x0000c3825,
	0x080e70000,
	0x000000027,


@@ 3259,13 3250,13 @@ ulong bootcode[]={
	0x000000027,
	0x000061025,
	0x024c60001,
	0x0afc680d2,
	0x0afc680d6,
	0x0a0470000,
	0x025080001,
	0x014ef001e,
	0x0afc88036,
	0x0afc8803a,
	0x0000e4025,
	0x0afce8036,
	0x0afce803a,
	0x0000c3825,
	0x080e70000,
	0x0258c0001,


@@ 3282,13 3273,13 @@ ulong bootcode[]={
	0x000000027,
	0x000061825,
	0x024c60001,
	0x0afc680d2,
	0x0afc680d6,
	0x0a06b0000,
	0x025080001,
	0x024a50001,
	0x000a7202a,
	0x01480fff5,
	0x0afc88036,
	0x0afc8803a,
	0x08fa20000,
	0x000000027,
	0x000400008,


@@ 3299,8 3290,8 @@ ulong bootcode[]={
	0x025030007,
	0x0201cfff8,
	0x0007c4024,
	0x0080010c3,
	0x0afc88036,
	0x0080010ba,
	0x0afc8803a,
	0x023bdffec,
	0x0afbf0000,
	0x02004002a,


@@ 3313,7 3304,7 @@ ulong bootcode[]={
	0x023a30010,
	0x0afa30004,
	0x0afa00008,
	0x00c001091,
	0x00c001088,
	0x0afa2000c,
	0x08fa20000,
	0x023bd0014,


@@ 3331,7 3322,7 @@ ulong bootcode[]={
	0x08fa3001c,
	0x02002ffff,
	0x0afa30008,
	0x00c001091,
	0x00c001088,
	0x0afa2000c,
	0x08fa20000,
	0x023bd0014,


@@ 3348,28 3339,27 @@ ulong bootcode[]={
	0x000000027,
	0x0afa20008,
	0x08fa3001c,
	0x00c001091,
	0x00c001088,
	0x0afa3000c,
	0x08fa20000,
	0x023bd0010,
	0x000400008,
	0x020010004,
	0x023bdfffc,
	0x08fc580d2,
	0x08fc3803a,
	0x08fc580d6,
	0x08fc3803e,
	0x000000027,
	0x000a3202b,
	0x010800005,
	0x000000027,
	0x024a30001,
	0x0afc380d2,
	0x0afc380d6,
	0x020040025,
	0x0a0a40000,
	0x023bd0004,
	0x003e00008,
	0x000000825,
	0x023bdfffc,
	0x08fa40014,
	0x08fa30018,
	0x000000027,
	0x02462ff98,


@@ 3388,7 3378,7 @@ ulong bootcode[]={
	0x000000027,
	0x023bd0004,
	0x003e00008,
	0x000040825,
	0x000000825,
	0x023bd0004,
	0x003e00008,
	0x02001fffe,


@@ 3409,11 3399,13 @@ ulong bootcode[]={
	0x000000027,
	0x023bd0004,
	0x003e00008,
	0x000040825,
	0x000000825,
	0x023bd0004,
	0x003e00008,
	0x02001ffe0,
	0x030820008,
	0x08fa20014,
	0x000000027,
	0x030420008,
	0x010400004,
	0x000000027,
	0x023bd0004,


@@ 3472,10 3464,10 @@ ulong bootcode[]={
	0x023a20030,
	0x0e7a10004,
	0x0e7a00008,
	0x00c001415,
	0x00c00140d,
	0x0afa2000c,
	0x0c7c18052,
	0x0c7c08056,
	0x0c7c18056,
	0x0c7c0805a,
	0x0c7a20030,
	0x000000027,
	0x0468010a1,


@@ 3487,7 3479,7 @@ ulong bootcode[]={
	0x000023043,
	0x0afa6002c,
	0x000061023,
	0x00c0013b9,
	0x00c0013b1,
	0x0afa20004,
	0x0c7a30044,
	0x0c7a20048,


@@ 3499,7 3491,7 @@ ulong bootcode[]={
	0x08fa30030,
	0x000000027,
	0x000431023,
	0x00c0013b9,
	0x00c0013b1,
	0x0afa20004,
	0x08fad00b0,
	0x023ae0074,


@@ 3522,7 3514,7 @@ ulong bootcode[]={
	0x08fa30030,
	0x000000027,
	0x000431023,
	0x00c0013b9,
	0x00c0013b1,
	0x0afa20004,
	0x08fad00b0,
	0x08fac00a8,


@@ 3531,10 3523,10 @@ ulong bootcode[]={
	0x0c7a20038,
	0x000000027,
	0x046201182,
	0x0080011b7,
	0x0080011af,
	0x023ae0074,
	0x0c7c18046,
	0x0c7c0804a,
	0x0c7c1804a,
	0x0c7c0804e,
	0x000000027,
	0x04626003e,
	0x000000027,


@@ 3548,7 3540,7 @@ ulong bootcode[]={
	0x08fa30030,
	0x000000027,
	0x000431023,
	0x00c0013b9,
	0x00c0013b1,
	0x0afa20004,
	0x08fad00b0,
	0x08fac00a8,


@@ 3557,7 3549,7 @@ ulong bootcode[]={
	0x0c7a20038,
	0x000000027,
	0x046201182,
	0x0080011ce,
	0x0080011c6,
	0x023ae0074,
	0x005810002,
	0x000000027,


@@ 3591,7 3583,7 @@ ulong bootcode[]={
	0x0200cffff,
	0x0afac00a8,
	0x0200d0065,
	0x008001184,
	0x00800117c,
	0x0afad00b0,
	0x0c7a70044,
	0x0c7a60048,


@@ 3605,7 3597,7 @@ ulong bootcode[]={
	0x08fa30030,
	0x02002ffff,
	0x000431023,
	0x00c0013b9,
	0x00c0013b1,
	0x0afa20004,
	0x08fad00b0,
	0x023ae0074,


@@ 3627,7 3619,7 @@ ulong bootcode[]={
	0x000671823,
	0x004600129,
	0x0afa70028,
	0x00c0013b9,
	0x00c0013b1,
	0x0afa30004,
	0x0c7a3003c,
	0x0c7a20040,


@@ 3636,7 3628,7 @@ ulong bootcode[]={
	0x046201083,
	0x0e7a30004,
	0x0e7a20008,
	0x00c001377,
	0x00c00136f,
	0x000000027,
	0x08fad00b0,
	0x023ae0074,


@@ 3685,7 3677,7 @@ ulong bootcode[]={
	0x024e70001,
	0x02484fff6,
	0x0a0440001,
	0x008001254,
	0x00800124c,
	0x024c6ffff,
	0x010e00007,
	0x0200b0001,


@@ 3753,7 3745,7 @@ ulong bootcode[]={
	0x020030030,
	0x0a0430000,
	0x024e7ffff,
	0x00800129b,
	0x008001293,
	0x024c60001,
	0x019000013,
	0x000000027,


@@ 3773,7 3765,7 @@ ulong bootcode[]={
	0x0256b0001,
	0x0a0430000,
	0x02508ffff,
	0x0080012ac,
	0x0080012a4,
	0x024c60001,
	0x08fa300ac,
	0x000000027,


@@ 3800,7 3792,7 @@ ulong bootcode[]={
	0x08fa300a4,
	0x02002ffff,
	0x0afa30008,
	0x00c001091,
	0x00c001088,
	0x0afa2000c,
	0x08fa20000,
	0x023bd009c,


@@ 3856,19 3848,19 @@ ulong bootcode[]={
	0x000001810,
	0x024630030,
	0x0a0430000,
	0x0080012d3,
	0x0080012cb,
	0x024c60001,
	0x000061825,
	0x001231021,
	0x02003002b,
	0x0a0430000,
	0x0080012f2,
	0x0080012ea,
	0x024c60001,
	0x000061025,
	0x001221821,
	0x020020065,
	0x0a0620000,
	0x0080012e8,
	0x0080012e0,
	0x024c60001,
	0x020030067,
	0x011a30006,


@@ 3876,7 3868,7 @@ ulong bootcode[]={
	0x020030068,
	0x011a30003,
	0x000000027,
	0x0080012cd,
	0x0080012c5,
	0x000000027,
	0x024c7ffff,
	0x004e00006,


@@ 3896,11 3888,11 @@ ulong bootcode[]={
	0x000000027,
	0x01107ff95,
	0x000073025,
	0x0080012cd,
	0x0080012c5,
	0x024c60001,
	0x008001330,
	0x02508ffff,
	0x008001328,
	0x02508ffff,
	0x008001320,
	0x024e7ffff,
	0x08fa30030,
	0x02002ffff,


@@ 3910,7 3902,7 @@ ulong bootcode[]={
	0x000003825,
	0x08fa30030,
	0x0200d0068,
	0x008001288,
	0x008001280,
	0x001835023,
	0x08fa200ac,
	0x000000027,


@@ 3921,17 3913,17 @@ ulong bootcode[]={
	0x001221821,
	0x02002002b,
	0x0a0620000,
	0x008001279,
	0x008001271,
	0x024c60001,
	0x0c7c38046,
	0x0c7c2804a,
	0x0c7c3804a,
	0x0c7c2804e,
	0x000000027,
	0x046223182,
	0x0e7a7003c,
	0x0e7a60040,
	0x0e7a70004,
	0x0e7a60008,
	0x00c001377,
	0x00c00136f,
	0x000000027,
	0x08fad00b0,
	0x08fa80028,


@@ 3949,14 3941,14 @@ ulong bootcode[]={
	0x046201181,
	0x0e7a7003c,
	0x0e7a60040,
	0x00800124b,
	0x008001243,
	0x023ae0074,
	0x0080011f0,
	0x0080011e8,
	0x0258cffff,
	0x020020001,
	0x0afa20010,
	0x025ad0020,
	0x008001184,
	0x00800117c,
	0x0afad00b0,
	0x023bdffe8,
	0x0afbf0000,


@@ 3973,7 3965,7 @@ ulong bootcode[]={
	0x04624c081,
	0x0e7a30004,
	0x0e7a20008,
	0x00c001464,
	0x00c00145c,
	0x0afa1000c,
	0x04620c032,
	0x000000027,


@@ 4002,7 3994,7 @@ ulong bootcode[]={
	0x023a1001c,
	0x0e7a30004,
	0x0e7a20008,
	0x00c001464,
	0x00c00145c,
	0x0afa1000c,
	0x0c7a1001c,
	0x0c7a00020,


@@ 4018,7 4010,7 @@ ulong bootcode[]={
	0x04624c081,
	0x0e7a30004,
	0x0e7a20008,
	0x00c001377,
	0x00c00136f,
	0x000000027,
	0x08fa20000,
	0x023bd000c,


@@ 4031,7 4023,7 @@ ulong bootcode[]={
	0x004610008,
	0x000000027,
	0x000030823,
	0x00c0013b9,
	0x00c0013b1,
	0x0afa10004,
	0x08fa20000,
	0x023bd0014,


@@ 4053,12 4045,12 @@ ulong bootcode[]={
	0x000032043,
	0x0afa40010,
	0x000641023,
	0x00c0013b9,
	0x00c0013b1,
	0x0afa20004,
	0x0e7a10008,
	0x0e7a0000c,
	0x08fa10010,
	0x00c0013b9,
	0x00c0013b1,
	0x0afa10004,
	0x0c7a30008,
	0x0c7a2000c,


@@ 4219,7 4211,7 @@ ulong bootcode[]={
	0x00065102a,
	0x014400013,
	0x000000027,
	0x08fc180d6,
	0x08fc180da,
	0x08fa30008,
	0x000a10807,
	0x0201cffff,


@@ 4241,7 4233,7 @@ ulong bootcode[]={
	0x00065102a,
	0x01440fff3,
	0x000000027,
	0x08fc380da,
	0x08fc380de,
	0x024a1ffea,
	0x000230807,
	0x0201cffff,


@@ 4249,7 4241,7 @@ ulong bootcode[]={
	0x08fa3000c,
	0x000000027,
	0x000610824,
	0x008001484,
	0x00800147c,
	0x0afa1000c,
	0x023bdfffc,
	0x08fa30010,


@@ 4360,7 4352,7 @@ ulong bootcode[]={
	0x000000027,
	0x0a0c8ffff,
	0x024c6ffff,
	0x008001503,
	0x0080014fb,
	0x024e7ffff,
	0x000000000,
	0x000000000,


@@ 4380,6 4372,7 @@ ulong bootcode[]={
	0x000000000,
	0x000000000,
	0x000000000,
	0x000000000,
	0x040240000,
	0x000000000,
	0x000000000,


@@ 4418,13 4411,13 @@ ulong bootcode[]={
	0x000000000,
	0x0001fffff,
	0x07fffffff,
	0x000004398,
	0x0000044a4,
	0x000003f04,
	0x00000457c,
	0x0000043e0,
	0x000004428,
	0x00000446c,
	0x000004374,
	0x000004480,
	0x000003ee0,
	0x00000455c,
	0x0000043bc,
	0x000004404,
	0x000004448,
	0x000000000,
	0x000000000,
	0x000000000,


@@ 4714,29 4707,28 @@ ulong bootcode[]={
	0x000010000,
	0x002000000,
	0x000000000,
	0x000006154,
	0x00000615e,
	0x000006169,
	0x000006174,
	0x000006179,
	0x00000618e,
	0x000006199,
	0x0000061a0,
	0x0000061b5,
	0x0000061c2,
	0x0000061c8,
	0x0000061dd,
	0x0000061e9,
	0x0000061f1,
	0x000006206,
	0x000006214,
	0x000006158,
	0x000006162,
	0x00000616d,
	0x000006178,
	0x00000617d,
	0x000006192,
	0x00000619d,
	0x0000061a4,
	0x0000061b9,
	0x0000061c6,
	0x0000061cc,
	0x0000061e1,
	0x0000061ed,
	0x0000061f5,
	0x00000620a,
	0x000006218,
	0x00000622d,
	0x00000621c,
	0x000006231,
	0x000000000,
	0x000000000,
	0x000000000,
	0x00004a00,
	0x0,
	0x00004a00,
	0x000000000,
	0x000049e8,
	0x0,
};

M power/dat.h => power/dat.h +2 -0
@@ 387,6 387,8 @@ struct Qinfo
	void (*open)(Queue*, Stream*);
	void (*close)(Queue*);
	char *name;
	void (*reset)(void);
	Qinfo *next;
};

/*

M power/fns.h => power/fns.h +1 -3
@@ 78,12 78,10 @@ void	icflush(void *, int);
int	incref(Ref*);
void	insert(List**, List*, List*);
void	intr(ulong, ulong);
void	ioboardid(void);
void	ioboardinit(void);
void	isdir(Chan*);
void	kbdchar(int);
void	kproc(char*, void(*)(void*), void*);
void	lance3intr(void);
void	launchinit(void);
void	lancereset(void);
void	lanceinit(void);


@@ 120,6 118,7 @@ void	novme(int);
void	nullput(Queue*, Block*);
void	online(void);
int	openmode(ulong);
Block*	padb(Block*, int);
void	pageinit(void);
void	panic(char*, ...);
void	pexit(char*, int);


@@ 191,7 190,6 @@ void	unlock(Lock*);
void	unusepage(Page*, int);
void	usepage(Page*, int);
void	userinit(void);
void	urpreset(void);
void	validaddr(ulong, ulong, int);
void	vecinit(void);
void	vector80(void);

M power/io.h => power/io.h +4 -20
@@ 42,18 42,20 @@ struct SBCC

#define	DUARTREG	SYNCBUS(Duart, 0x1A00000)

#define LANCERAM	IO2(uchar, 0xE00000)
#define LANCEEND	IO2(uchar, 0xF00000)
#define LANCERAM	IO2(ushort, 0xE00000)
#define LANCEEND	IO2(ushort, 0xF00000)
#define LANCE3RAM	IO2(ushort, 0xFF4000)
#define LANCE3END	IO2(ushort, 0xFF8000)
#define LANCERDP	IO2(ushort, 0xFC0002)
#define LANCERAP	IO2(ushort, 0xFC000a)
#define LANCEID		IO2(ushort, 0xFF0002)
#define	WRITEMAP	IO2(ulong, 0xFA0000)

#define IOID		IO2(uchar, 0xFFFFF0)
#define IO2R1		1	/* IO2 revision level 1 */
#define IO2R2		2	/* IO2 revision level 2 */
#define IO3R1		3	/* IO3 revision level 1 */
extern int ioid;	/* io board type */

typedef struct MODE	MODE;
typedef struct INTVEC	INTVEC;


@@ 85,21 87,3 @@ struct INTVEC {
#define	MPBERR0		IO2(ulong, 0xF48000)
#define	MPBERR1		IO2(ulong, 0xF4C000)
#define SBEADDR		((ulong *)(UNCACHED|0x1F080000))

extern int ioid;	/* io board type */
extern int iolevels;	/* number of io levels */
extern int iomask;	/* interrupts to enable */

/*
 *  The IO2/IO3 slave maps.  These maps are used to map
 *  external addresses to MP bus addresses.
 */
enum {
	A24map,		/* VME A24 non-priv address space */
	A32map,		/* VME A32 non-priv address space */
	Lancemap,	/* Lance chip address space */
	Scsi1map,	/* SCSI bus 1 address space */
	Scsi0map,	/* SCSI bus 0 address space */
	Nomap,
};
#define	WRITEMAP	IO2(ulong, 0xFA0000)

M power/main.c => power/main.c +26 -40
@@ 57,7 57,6 @@ main(void)
	clockinit();
	alarminit();
	ioboardinit();
	ioboardid();
	chandevreset();
	streaminit();
	sysloginit();


@@ 104,25 103,6 @@ vecinit(void)
		*p++ = *q++;
}

void
ioboardid(void)
{
	switch(ioid){
	case IO2R1:
		iprint("IO2 revision 1\n");
		break;
	case IO2R2:
		iprint("IO2 revision 2\n");
		break;
	case IO3R1:
		iprint("IO3 revision 1\n");
		break;
	default:
		iprint("unknown IO board\n");
		break;
	}
}

/*
 *  We have to program both the IO2 board to generate interrupts
 *  and the SBCC on CPU 0 to accept them.


@@ 131,16 111,22 @@ void
ioboardinit(void)
{
	long i;
	int noforce;

	ioid = *IOID;
	if(ioid >= IO3R1)
		noforce = 1;
	else
		noforce = 0;


	/*
	 *  reset VME bus (MODEREG is on the IO2)
	 */
	MODEREG->resetforce = (1<<1) | (1<<0);
	MODEREG->resetforce = (1<<1) | noforce;
	for(i=0; i<1000000; i++)
		;
	MODEREG->resetforce = (1<<0);
	MODEREG->resetforce = noforce;
	MODEREG->masterslave = (SLAVE<<4) | MASTER;

	/*


@@ 596,27 582,27 @@ confinit(void)
	 */
	conf.nmach = 1;
	conf.nmod = 2000;
	conf.nalarm = 1000;
	conf.norig = 9;
	conf.nchan = 64;
	conf.nenv = 4;
	conf.nenvchar = 1000;
	conf.npgenv = 400;
	conf.nmtab = 4;
	conf.nmount = 4;
	conf.nmntdev = 4;
	conf.nmntbuf = 4;
	conf.nmnthdr = 4;
	conf.nstream = 4;
	conf.nsrv = 0;
	conf.nproc = 4;
	conf.npgrp = 4;
	conf.npte = 4 * conf.npage;
	conf.nqueue = 5 * conf.nstream;
	conf.nblock = 16 * conf.nstream;
	conf.nalarm = 10000;
	conf.norig = 500;
	conf.nchan = 1000;
	conf.npgenv = 800;
	conf.nmtab = 100;
	conf.nmount = 5000;
	conf.nmntdev = 150;
	conf.nmntbuf = 120;
	conf.nmnthdr = 120;
	conf.nstream = 128;
	conf.nsrv = 32;
	conf.nproc = 386;
	conf.npgrp = 100;
	conf.nnoifc = 1;
	conf.nnoconv = 32;
	conf.nurp = 256;
	conf.nenv = 15*conf.nproc;
	conf.nenvchar = 20 * conf.nenv;
	conf.npte = 4 * conf.npage;
	conf.nqueue = 3 * conf.nstream;
	conf.nblock = 10 * conf.nstream;

	confread();


A power/stream.h => power/stream.h +7 -0
@@ 0,0 1,7 @@
extern	Qinfo 	 urpinfo;
extern	Qinfo 	 noetherinfo;

void streaminit0(void){
	newqinfo(&urpinfo);
	newqinfo(&noetherinfo);
}

M power/trap.c => power/trap.c +4 -8
@@ 197,7 197,7 @@ intr(ulong cause, ulong pc)
	if(cause & INTR5){

		if(!(*MPBERR1 & (1<<8))){
			iprint("MP bus error %lux %lux\n", *MPBERR0, *MPBERR1); /**/
			print("MP bus error %lux %lux\n", *MPBERR0, *MPBERR1);
			*MPBERR0 = 0;
			i = *SBEADDR;
		}


@@ 235,24 235,20 @@ intr(ulong cause, ulong pc)
					*MPBERR0, *MPBERR1);
				*MPBERR0 = 0;
			}
			switch(ioid){
			case IO2R1:
			case IO2R2:
			if(ioid < IO3R1){
				if(!(v & (1<<2)))
					lanceintr();
				if(!(v & (1<<1)))
					lanceparity();
				if(!(v & (1<<0)))
					print("SCSI interrupt\n");
				break;
			case IO3R1:
			} else {
				if(v & (1<<2))
					lance3intr();
					lanceintr();
				if(v & (1<<1))
					print("SCSI 1 interrupt\n");
				if(v & (1<<0))
					print("SCSI 0 interrupt\n");
				break;
			}
		}
		/*