~kris/9p

9hist

023f5277aa279aef626051dd1657bd151e5ca7b1 — David du Colombier 36 years ago 437dd1f
Plan 9 from Bell Labs 1990-09-07
M gnot/errno.h => gnot/errno.h +1 -1
@@ 56,5 56,5 @@ enum{
	Ebadcnt,	/* read count greater than requested */
	Enofont,	/* out of font descriptors */
	Enovmem,	/* virtual memory allocation failed */
	Egreg,		/* rob made me do it */
	Egreg,		/* ken hasn't implemented datakit */
};

M gnot/stream.c => gnot/stream.c +1 -1
@@ 246,7 246,7 @@ padb(Block *bp, int n)
		nbp = allocb(n);
		nbp->wptr = nbp->lim;
		nbp->rptr = nbp->wptr - n;
		nbp->next = nbp;
		nbp->next = bp;
		return nbp;
	}
} 

M port/chan.c => port/chan.c +3 -0
@@ 96,11 96,14 @@ loop:
void
close(Chan *c)
{
	if(c->flag & CFREE)
		panic("close");
	if(decref(c) == 0){
		if(!waserror()){
			(*devtab[c->type].close)(c);
			poperror();
		}
		c->flag = CFREE;
		lock(&chanalloc);
		c->next = chanalloc.free;
		chanalloc.free = c;

M port/devcons.c => port/devcons.c +1 -0
@@ 169,6 169,7 @@ panic(char *fmt, ...)
	n = doprint(buf+7, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
	buf[n] = '\n';
	putstrn(buf, n+1);
	dumpstack();
	exit();
}


M port/stream.c => port/stream.c +72 -42
@@ 24,6 24,19 @@ Qinfo procinfo = { stputq, nullput, 0, 0, "process" };
 */
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;
}

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


@@ 55,14 68,6 @@ Bclass bclass[Nclass]={
};

/*
 *  the per stream directory structure
 */
Dirtab streamdir[]={
	"data",		Sdataqid,	0,			0600,
	"ctl",		Sctlqid,	0,			0600,
};

/*
 *  Dump all block information of how many blocks are in which queues
 */
void


@@ 115,26 120,19 @@ dumpqueues(void)
 *  Allocate streams, queues, and blocks.  Allocate n block classes with
 *	1/2(m+1) to class m < n-1
 *	1/2(n-1) to class n-1
 *
 *  All data areas are alligned to their size.
 *
 *  No data area crosses a 4k boundary.  This allows us to use the
 *  VME/SCSI/LANCE to MP bus maps on the SGI power series machines.
 */
void
streaminit(void)
{
	int class, i, n, left;
	int class, i, n;
	Block *bp;
	Bclass *bcp;
	uchar *ptr;

	slist = (Stream *)ialloc(conf.nstream * sizeof(Stream), 0);
	qlist = (Queue *)ialloc(conf.nqueue * sizeof(Queue), 0);
	blist = (Block *)ialloc(conf.nblock * sizeof(Block), 0);
	bp = blist;
	n = conf.nblock;
	left = 0;
	for(class = 0; class < Nclass; class++){
		if(class < Nclass-1)
			n = n/2;


@@ 145,15 143,8 @@ streaminit(void)
			 *  starts on a page boundary.  This makes sure
			 *  no block crosses a page boundary.
			 */
			if(bcp->size){
				if(bcp->size > left){
					left = bcp->size>4096 ? bcp->size : 4096;
					ptr = (uchar *)ialloc(left, 1);
				}
				bp->base = ptr;
				ptr += bcp->size;
				left -= bcp->size;
			}
			if(bcp->size)
				bp->base = (uchar *)ialloc(bcp->size, i == 0);
			bp->lim = bp->base + bcp->size;
			bp->flags = class;
			freeb(bp);


@@ 488,6 479,54 @@ getb(Blist *q)
}

/*
 *  make sure the first block has n bytes
 */
Block *
pullup(Block *bp, int n)
{
	Block *nbp;
	int i;

	/*
	 *  this should almost always be true, the rest it
	 *  just for to avoid every caller checking.
	 */
	if(BLEN(bp) >= n)
		return bp;

	/*
	 *  if not enough room in the first block,
	 *  add another to the front of the list.
	if(bp->lim - bp->rptr < n){
		nbp = allocb(n);
		nbp->next = bp;
		bp = nbp;
	}

	/*
	 *  copy bytes from the trailing blocks into the first
	 */
	n -= BLEN(bp);
	while(nbp = bp->next){
		i = BLEN(nbp);
		if(i > n) {
			memcpy(bp->wptr, nbp->rptr, n);
			bp->wptr += n;
			nbp->rptr += n;
			return bp;
		} else {
			memcpy(bp->wptr, nbp->rptr, i);
			bp->wptr += i;
			bp->next = nbp->next;
			nbp->next = 0;
			freeb(nbp);
		}
	}
	freeb(bp);
	return 0;
}

/*
 *  grow the front of a list of blocks by n bytes
 */
Block *


@@ 587,6 626,14 @@ streamparse(char *name, Block *bp)
}

/*
 *  the per stream directory structure
 */
Dirtab streamdir[]={
	"data",		Sdataqid,	0,			0600,
	"ctl",		Sctlqid,	0,			0600,
};

/*
 *  A stream device consists of the contents of streamdir plus
 *  any directory supplied by the actual device.
 *


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

/*
 *  announce a line discipline that can be pushed
 */
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;
}


M power/dat.h => power/dat.h +1 -0
@@ 635,6 635,7 @@ extern	char	*statename[];
#define	CMOUNT	2	/* is result of a mount/bind */
#define	CCREATE	4	/* permits creation if CMOUNT */
#define	CCEXEC	8	/* close on exec */
#define	CFREE	16	/* not in use */

/*
 * Proc.time

M power/duart.c => power/duart.c +20 -0
@@ 202,3 202,23 @@ duartxmit(int c)
	duart->cmnd = ENB_TX;
	duart->data = c;
}

void
duartputs(char *s)
{
	int i;
	while(*s){
		duartputc(*s++);
	}
	for(i=0; i < 1000000; i++)
		;
}

void
iprint(char *s, void *a, void *b, void *c, void *d)
{
	char buf[1024];

	sprint(buf, s, a, b, c, d);
	duartputs(buf);
}

M power/errno.h => power/errno.h +1 -1
@@ 51,5 51,5 @@ enum{
	Ebadcnt,	/* read count greater than requested */
	Enoannounce,	/* listening on an unannounced network connection */
	Enovmem,	/* virtual memory allocation failed */
	Egreg,		/* rob made me do it */
	Egreg,		/* ken hasn't implemented datakit */
};

M power/fns.h => power/fns.h +4 -1
@@ 43,6 43,7 @@ int	devwalk(Chan*, char*, Dirtab*, int, Devgen*);
void	duartinit(void);
void	duartintr(void);
int	duartputc(int);
void	duartputs(char*);
void	duartreset(void);
void	duartxmit(int);
void	dumpregs(Ureg*);


@@ 97,7 98,6 @@ Orig	*lookorig(ulong, ulong, int, Chan*);
void	machinit(void);
void	mapstack(Proc*);
int	mount(Chan*, Chan*, int);
void	mpbuserror(void);
Chan	*namec(char*, int, int, ulong);
void	nexterror(void);
Alarm	*newalarm(void);


@@ 160,11 160,14 @@ Seg	*seg(Proc*, ulong);
int	segaddr(Seg*, ulong, ulong);
int	setlabel(Label*);
void	setvmevec(int, void (*)(int));
void	sinit(void);
char*	skipslash(char*);
void	sleep(Rendez*, int(*)(void*), void*);
uchar*	smap(int, uchar*);
int	splhi(void);
int	spllo(void);
void	splx(int);
void	sunmap(int, uchar*);
Devgen	streamgen;
void	streamclose(Chan*);
int	streamenter(Stream*);

M power/io.h => power/io.h +3 -3
@@ 44,8 44,8 @@ struct SBCC

#define LANCERAM	IO2(uchar, 0xE00000)
#define LANCEEND	IO2(uchar, 0xF00000)
#define LANCE3RAM	IO2(uchar, 0xFF4000)
#define LANCE3END	IO2(uchar, 0xFF8000)
#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)


@@ 102,4 102,4 @@ enum {
	Scsi0map,	/* SCSI bus 0 address space */
	Nomap,
};
#define	WRITEMAP	IO2(ulong, 0xFA0000);
#define	WRITEMAP	IO2(ulong, 0xFA0000)

M power/main.c => power/main.c +20 -31
@@ 35,17 35,13 @@ char confbuf[4*1024];
char sysname[64];

/*
 *  IO board type, number of interrupt levels, and interrupt enable mask
 *  IO board type
 */
int ioid;
int iolevels;
int iomask;

void
main(void)
{
	int i;

	machinit();
	active.exiting = 0;
	active.machs = 1;


@@ 61,12 57,12 @@ main(void)
	clockinit();
	alarminit();
	ioboardinit();
	ioboardid();
	chandevreset();
	streaminit();
	sysloginit();
	pageinit();
	userinit();
	ioboardid();
	launchinit();
	schedinit();
}


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


@@ 135,31 131,16 @@ void
ioboardinit(void)
{
	long i;
	int intrs;

	/*
	 *  set up interrupts based on IO board type
	 */
	ioid = *IOID;
	switch(ioid){
	case IO2R1:
	case IO2R2:
		iolevels = 8;
		iomask = 0xff;
		break;
	case IO3R1:
		iolevels = 11;
		iomask = 0x7fe;
		break;
	}

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

	/*


@@ 169,9 150,9 @@ ioboardinit(void)
		setvmevec(i, novme);

	/*
	 *  tell IO2 to send all interrupts to CPU 0's SBCC
	 *  tell IO2 to sent all interrupts to CPU 0's SBCC
	 */
	for(i=0; i<iolevels; i++)
	for(i=0; i<8; i++)
		INTVECREG->i[i].vec = 0<<8;

	/*


@@ 191,13 172,13 @@ ioboardinit(void)
	 *  The SBCC 16 bit registers are read/written as ulong, but only
	 *  bits 23-16 and 7-0 are meaningful.
	 */
	SBCCREG->fintenable |= iomask;	/* turn on all interrupts */
	SBCCREG->fintenable |= 0xff;	  /* allow all interrupts on the IO2 */
	SBCCREG->idintenable |= 0x800000; /* allow interrupts from the IO2 */

	/*
	 *  enable all interrupts on the IO2
	 */
	*IO2SETMASK = iomask;
	*IO2SETMASK = 0xff;
}

void


@@ 606,6 587,11 @@ confinit(void)
	conf.npage = conf.npage0;

	/*
 	 *  clear MP bus error caused by sizing memory
	 */
	i = *SBEADDR;

	/*
	 *  set minimal default values
	 */
	conf.nmach = 1;


@@ 628,6 614,9 @@ confinit(void)
	conf.npte = 4 * conf.npage;
	conf.nqueue = 5 * conf.nstream;
	conf.nblock = 16 * conf.nstream;
	conf.nnoifc = 1;
	conf.nnoconv = 32;
	conf.nurp = 256;

	confread();


M power/mem.h => power/mem.h +1 -1
@@ 109,7 109,7 @@
#define	USTKTOP	KZERO			/* byte just beyond user stack */
#define	TSTKTOP	(USERADDR+100*BY2PG)	/* top of temporary stack */
#define	KZERO	KSEG0			/* base of kernel address space */
#define	KTZERO	(KSEG0+0x20000)		/* first address in kernel text */
#define	KTZERO	(KZERO+0x20000)		/* first address in kernel text */
#define	USTACKSIZE	(4*1024*1024)	/* size of user stack */
/*
 * Exception codes

M power/trap.c => power/trap.c +32 -38
@@ 180,14 180,6 @@ trap(Ureg *ur)
}

void
mpbuserror(void)
{
	print("io2 mp bus error %d %lux %lux\n", 0,
		*MPBERR0, *MPBERR1);
	*MPBERR0 = 0;
}

void
intr(ulong cause, ulong pc)
{
	int i, pend;


@@ 205,7 197,7 @@ intr(ulong cause, ulong pc)
	if(cause & INTR5){

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


@@ 235,34 227,33 @@ intr(ulong cause, ulong pc)
		/*
		 *  5a. process lance, scsi
		 */
	loop:
		if(pend & 1) {
			v = INTVECREG->i[0].vec;
			if(!(v & (1<<12)))
				mpbuserror();
			if(!(v & (1<<2)))
				lanceintr();
			if(!(v & (1<<1)))
				lanceparity();
			if(!(v & (1<<0)))
				print("SCSI interrupt\n");
		}
		if(pend & (1<<10)) {
			v = INTVECREG->i[10].vec;
			if(!(v & (1<<12)))
				mpbuserror();
			lance3intr();
		}
		if(pend & (1<<8)) {
			v = INTVECREG->i[10].vec;
			if(!(v & (1<<12)))
				mpbuserror();
			print("SCSI0 interrupt\n");
		}
		if(pend & (1<<9)) {
			v = INTVECREG->i[10].vec;
			if(!(v & (1<<12)))
				mpbuserror();
			print("SCSI1 interrupt\n");
			if(!(v & (1<<12))){
				print("io2 mp bus error %d %lux %lux\n", 0,
					*MPBERR0, *MPBERR1);
				*MPBERR0 = 0;
			}
			switch(ioid){
			case IO2R1:
			case IO2R2:
				if(!(v & (1<<2)))
					lanceintr();
				if(!(v & (1<<1)))
					lanceparity();
				if(!(v & (1<<0)))
					print("SCSI interrupt\n");
				break;
			case IO3R1:
				if(v & (1<<2))
					lance3intr();
				if(v & (1<<1))
					print("SCSI 1 interrupt\n");
				if(v & (1<<0))
					print("SCSI 0 interrupt\n");
				break;
			}
		}
		/*
		 *  5b. process vme


@@ 272,8 263,11 @@ intr(ulong cause, ulong pc)
		for(i=1; pend; i++) {
			if(pend & 1) {
				v = INTVECREG->i[i].vec;
				if(!(v & (1<<12)))
					mpbuserror();
				if(!(v & (1<<12))){
					print("io2 mp bus error %d %lux %lux\n", i,
						*MPBERR0, *MPBERR1);
					*MPBERR0 = 0;
				}
				v &= 0xff;
				(*vmevec[v])(v);
			}


@@ 282,7 276,7 @@ intr(ulong cause, ulong pc)
		/*
		 *  6. re-enable interrupts
		 */
		*IO2SETMASK = iomask;
		*IO2SETMASK = 0xff;
		cause &= ~INTR5;
	}
	if(cause)