~kris/9p

9hist

43b828beaacd10f8c9a561a982d1c84270c1f313 — David du Colombier 35 years ago 94cff37
Plan 9 from Bell Labs 1991-08-06
M pc/clock.c => pc/clock.c +1 -0
@@ 62,6 62,7 @@ clock(Ureg *ur)

	checkalarms();
	mouseclock();
	uartintr0(ur);

	p = m->proc;
	if(p){

M pc/devfloppy.c => pc/devfloppy.c +1 -0
@@ 754,6 754,7 @@ print("new offset %d instead of %d\n", offset, off+dp->len);
static void
floppyintr(Ureg *ur)
{
print("floppy intr\n");
	floppy.intr = 1;
	wakeup(&floppy.r);
}

M pc/devuart.c => pc/devuart.c +53 -39
@@ 206,44 206,39 @@ uartintr(Uart *up)
{
	int ch;
	IOQ *cq;
	int s;
	int s, l;

	l = uartrdreg(up, Lstat);
	s = uartrdreg(up, Istat);
print("uartintr %lux\n", s);
	switch(s){
	case 3:
		/*
		 *  get any input characters
		 */
		cq = up->iq;
		while(uartrdreg(up, Lstat) & Inready){
			ch = uartrdreg(up, Data) & 0xff;
			if(cq->putc)
				(*cq->putc)(cq, ch);
			else {
				putc(cq, ch);
				if(up->delim[ch/8] & (1<<(ch&7)) )
					wakeup(&cq->r);
			}
		}
		break;
	case 5:
		/*
		 *  send next output character
		 */
		if(uartrdreg(up, Lstat)&Outready){
			cq = up->oq;
			lock(cq);
			ch = getc(cq);
print("<cont %2.2ux>", ch);/**/
			if(ch < 0){
				up->printing = 0;

	cq = up->iq;
	while(l & Inready){
		ch = uartrdreg(up, Data) & 0xff;
print("<get %2.2ux>", ch);
		if(cq->putc)
			(*cq->putc)(cq, ch);
		else {
			putc(cq, ch);
			if(up->delim[ch/8] & (1<<(ch&7)) )
				wakeup(&cq->r);
			}else
				outb(up->port + Data, ch);
			unlock(cq);
		}
		break;
		l = uartrdreg(up, Lstat);
	}

	/*
	 *  send next output character
	 */
	if(up->printing && (l&Outready)){
		cq = up->oq;
		lock(cq);
		ch = getc(cq);
print("<put %2.2ux>", ch);/**/
		if(ch < 0){
			up->printing = 0;
			wakeup(&cq->r);
		}else
			outb(up->port + Data, ch);
		unlock(cq);
	}
}
void


@@ 263,6 258,8 @@ uartintr1(Ureg *ur)
void
uartenable(Uart *up)
{
	int x;

	/*
	 *  set up i/o routines
	 */


@@ 287,6 284,15 @@ uartenable(Uart *up)
	 */
	uartdtr(up, 1);
	uartrts(up, 1);

	/*
	 *  read interrupt status till there aren't any pending
	 */
	while(uartrdreg(up, Istat) != 1){
		x = splhi();
		uartintr(up);
		splx(x);
	}
}

/*


@@ 303,6 309,10 @@ uartspecial(int port, IOQ *oq, IOQ *iq, int baud)
	up->iq = iq;
	uartenable(up);
	uartsetbaud(up, baud);
	if(port == 0){
		if(serial(0) < 0)
			print("can't turn on serial port power\n");
	}

	if(iq){
		/*


@@ 366,9 376,14 @@ uartstopen(Queue *q, Stream *s)
	Uart *up;
	char name[NAMELEN];

	kprint("uartstopen: q=0x%ux, inuse=%d, type=%d, dev=%d, id=%d\n",
print("uartstopen: q=0x%ux, inuse=%d, type=%d, dev=%d, id=%d\n",
		q, s->inuse, s->type, s->dev, s->id);

	up = &uart[s->id];
	uartenable(up);
	if(s->id==0 && serial(0)<0)
		print("can't turn on serial power\n");

	qlock(up);
	up->wq = WR(q);
	WR(q)->ptr = up;


@@ 399,6 414,9 @@ uartstclose(Queue *q)
	WR(q)->ptr = 0;
	RD(q)->ptr = 0;
	qunlock(up);

	if(serial(1) < 0)
		print("can't turn off serial power\n");
}

static void


@@ 511,9 529,6 @@ uartreset(void)
{
	Uart *up;

	if(serial(0) < 0)
		print("can't turn on power\n");

	uartsetup();
	for(up = uart; up < &uart[2]; up++){
		if(up->nostream)


@@ 522,7 537,6 @@ uartreset(void)
		initq(up->iq);
		up->oq = ialloc(sizeof(IOQ), 0);
		initq(up->oq);
		uartenable(up);
	}
}


M pc/io.h => pc/io.h +2 -2
@@ 7,8 7,8 @@ enum
	Int0vec=	16,		/* first 8259 */
	 Clockvec=	Int0vec+0,	/*  clock interrupts */
	 Kbdvec=	Int0vec+1,	/*  keyboard interrupts */
	 Uart0vec=	Int0vec+3,	/*  inerrupt from uart b */
	 Uart1vec=	Int0vec+4,	/*  inerrupt from uart a */
	 Uart0vec=	Int0vec+3,	/*  serial line */
	 Uart1vec=	Int0vec+4,	/*  modem line */
	 Floppyvec=	Int0vec+6,	/*  floppy interrupts */
	Int1vec=	Int0vec+8,	/* second 8259 */
	 Mousevec=	Int1vec+4,	/*  mouse interrupt */

M pc/l.s => pc/l.s +10 -0
@@ 488,3 488,13 @@ TEXT	fpsave(SB),$0
TEXT	fprestore(SB),$0
	RET


/*
 *  set configuration register
 */
TEXT	config(SB),$0
	MOVL	l+0(FP),AX
	MOVL	$0x3F3,DX
	OUTB
	OUTB
	RET

M pc/main.c => pc/main.c +14 -1
@@ 285,7 285,12 @@ enum
	Pmudata=	0x198,

	Pmucsr=		0x199,
	 Busy=	0x1,
	 Busy=		0x1,

	/*
	 *  configuration port
	 */
	Pconfig=	0x3F3,
};

/*


@@ 368,6 373,14 @@ pmuwrbit(int index, int bit, int pos)
int
serial(int onoff)
{
	int x;

	/*
	 *  set config (enable everything)
	 */
	x = splhi();
	config(0x00);
	splx(x);
	return pmuwrbit(1, onoff, 6);
}


M pc/trap.c => pc/trap.c +25 -1
@@ 176,6 176,9 @@ trap(Ureg *ur)
	if(v>=256 || ivec[v] == 0)
		panic("bad trap type %d %lux\n", v, ur->pc);

	if(v==19 || v==20)
		print("trap = %d\n", v);

	/*
	 *  tell the 8259 that we're done with the
	 *  highest level interrupt (interrupts are still


@@ 183,9 186,9 @@ trap(Ureg *ur)
	 */
	c = v&~0x7;
	if(c==Int0vec || c==Int1vec){
		outb(Int0ctl, EOI);
		if(c == Int1vec)
			outb(Int1ctl, EOI);
		outb(Int0ctl, EOI);
	}

	/*


@@ 195,6 198,27 @@ trap(Ureg *ur)
}

/*
 *  print 8259 status
 */
void
dump8259(void)
{
	int c;

	outb(Int0ctl, 0x0a);	/* read ir */
	print("ir0 %lux\n", inb(Int0ctl));
	outb(Int0ctl, 0x0b);	/* read is */
	print("is0 %lux\n", inb(Int0ctl));
	print("im0 %lux\n", inb(Int0aux));

	outb(Int1ctl, 0x0a);	/* read ir */
	print("ir1 %lux\n", inb(Int1ctl));
	outb(Int1ctl, 0x0b);	/* read is */
	print("is1 %lux\n", inb(Int1ctl));
	print("im1 %lux\n", inb(Int1aux));
}

/*
 *  dump registers
 */
void

M port/page.c => port/page.c +11 -1
@@ 168,16 168,26 @@ newpage(int clear, Segment **s, ulong va)
	/* The kp test is a poor guard against the pager deadlocking */
	while((palloc.freecount < HIGHWATER && u->p->kp == 0) || palloc.freecount == 0) {
		palloc.wanted++;
		unlock(&palloc);			
		unlock(&palloc);
		if(s && *s) {
			qunlock(&((*s)->lk));
			*s = 0;
		}
		qlock(&palloc.pwait);			/* Hold memory requesters here */

		if(waserror()) {
			qunlock(&palloc.pwait);
			lock(&palloc);
			palloc.wanted--;
			unlock(&palloc);
			nexterror();
		}

		kickpager();
		tsleep(&palloc.r, ispages, 0, 1000);

		poperror();

		qunlock(&palloc.pwait);
		lock(&palloc);
		palloc.wanted--;

M port/pgrp.c => port/pgrp.c +1 -0
@@ 120,6 120,7 @@ newpgrp(void)
			p->ref = 1;
			p->pgrpid = ++pgrpalloc.pgrpid;
			p->nmtab = 0;
			memset(p->rendhash, 0, sizeof(p->rendhash));
			unlock(&pgrpalloc);
			return p;
		}

M port/portdat.h => port/portdat.h +9 -0
@@ 355,6 355,9 @@ struct Segment
	Pte	*map[SEGMAPSIZE];	/* segment pte map */
};

#define RENDHASH	32
#define REND(p,s)	((p)->rendhash[(s)%RENDHASH])

struct Pgrp
{
	Ref;				/* also used as a lock when mounting */


@@ 365,6 368,7 @@ struct Pgrp
	int	nmtab;			/* highest active mount table entry, +1 */
	QLock	debug;			/* single access via devproc.c */
	Mtab	*mtab;
	Proc	*rendhash[RENDHASH];	/* Rendezvous tag hash */
};

struct Egrp


@@ 437,6 441,7 @@ enum
	Wakeme,
	Broken,
	Stopped,
	Rendezvous,
};

/*


@@ 499,6 504,10 @@ struct Proc
	int 	hasspin;		/* I hold a spin lock */
	int	newtlb;			/* Pager has touched my tables so I must flush */
	int	procctl;		/* Control for /proc debugging */

	ulong	rendtag;		/* Tag for rendezvous */ 
	ulong	rendval;		/* Value for rendezvous */
	Proc	*rendhash;		/* Hash list for tag values */
	/*
	 *  machine specific MMU goo
	 */

M port/proc.c => port/proc.c +19 -0
@@ 41,6 41,7 @@ char *statename[]={	/* BUG: generate automatically */
	"Wakeme",
	"Broken",
	"Stopped",
	"Rendez",
};

/*


@@ 390,6 391,7 @@ postnote(Proc *p, int dolock, char *n, int flag)
	KMap *k;
	int s;
	Rendez *r;
	Proc *d, **l;

	SET(k);
	USED(k);


@@ 436,6 438,23 @@ postnote(Proc *p, int dolock, char *n, int flag)
		unlock(r);
		splx(s);
	}
	if(p->state == Rendezvous) {
		lock(p->pgrp);
		if(p->state == Rendezvous) {
			p->rendval = 0;
			l = &REND(p->pgrp, p->rendtag);
			for(d = *l; d; d = d->rendhash) {
				if(d == p) {
					*l = p->rendhash;
					break;
				}
				l = &d->rendhash;
			}
			ready(p);
		}
		unlock(p->pgrp);
	}

	return 1;
}


M port/sysproc.c => port/sysproc.c +43 -0
@@ 562,3 562,46 @@ sysbrk_(ulong *arg)
{
	return ibrk(arg[0], BSEG);
}

long
sysrendezvous(ulong *arg)
{
	Proc *p, *d, **l;
	int s, tag;
	ulong val;

	tag = arg[0];
	l = &REND(u->p->pgrp, tag);

	lock(u->p->pgrp);
	for(p = *l; p; p = p->rendhash) {
		if(p->rendtag == tag) {
			*l = p->rendhash;
			val = p->rendval;
			p->rendval = arg[1];

			if(p->state != Rendezvous)
				panic("rendezvous");
			ready(p);
			unlock(u->p->pgrp);
			return val;	
		}
		l = &p->rendhash;
	}

	/* Going to sleep here */
	p = u->p;
	p->rendtag = tag;
	p->rendval = arg[1];
	p->rendhash = *l;
	*l = p;

	unlock(p->pgrp);

	s = splhi();
	u->p->state = Rendezvous;
	sched();
	splx(s);

	return u->p->rendval;
}

M port/systab.h => port/systab.h +2 -0
@@ 8,6 8,7 @@ Syscall	sysfstat, sysfwstat, sysgetpid, sysmount, sysnoted;
Syscall	sysnotify, sysopen, syspipe, sysr1, sysread, sysremove, sysseek;
Syscall syssleep, sysstat, syswait, syswrite, syswstat, sysalarm, syssegbrk;
Syscall syssegattach, syssegdetach, syssegfree, syssegflush;
Syscall sysrendezvous;

Syscall *systab[]={
	[SYSR1]		sysr1,


@@ 44,4 45,5 @@ Syscall *systab[]={
	[SEGDETACH]	syssegdetach,
	[SEGFREE]	syssegfree,
	[SEGFLUSH]	syssegflush,
	[RENDEZVOUS]	sysrendezvous,
};

M power/boot.c => power/boot.c +0 -1
@@ 485,7 485,6 @@ error(char *s)
 *  prompt and get input
 */
int
int
outin(char *prompt, char *def, int len)
{
	int n;

M power/devhotrod.c => power/devhotrod.c +3 -2
@@ 13,7 13,6 @@
/*
 * If defined, ENABMEMTEST causes memory test to be run at device open
 */
#define	ENABMEMTEST
#ifdef	ENABMEMTEST
void	mem(Hot*, ulong*, ulong);
#define	NTESTBUF	256


@@ 22,6 21,7 @@ ulong	testbuf[NTESTBUF];
/*
 * If defined, ENABBUSTEST causes bus error diagnostic to be run at device open
 */
#define	ENABBUSTEST

/*
 * If 1, ENABCKSUM causes data transfers to have checksums


@@ 224,8 224,9 @@ hotrodopen(Chan *c, int omode)
		 */
		mp = &u->khot;
		mp->cmd = Ubus;
		hmp = hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot, 0);
		hmp = hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot);
		hotwait(hmp);
for(;;) ;
#endif
	}
	c->mode = openmode(omode);