~kris/9p

9hist

fd71a85ff948f7c3058aaa8e67195015d11709ce — David du Colombier 35 years ago 1216123
Plan 9 from Bell Labs 1991-04-25
M gnot/dat.h => gnot/dat.h +8 -0
@@ 223,6 223,14 @@ struct Mach
	Lock	alarmlock;		/* access to alarm list */
	void	*alarm;			/* alarms bound to this clock */
	int	fpstate;		/* state of fp registers on machine */

	int	tlbfault;
	int	pfault;
	int	cs;
	int	syscall;
	int	spinlock;
	int	intr;

	int	stack[1];
};


M port/devcons.c => port/devcons.c +33 -2
@@ 320,6 320,7 @@ enum{
	Qtime,
	Quser,
	Qvmereset,
	Qsysstat,
};

Dirtab consdir[]={


@@ 334,6 335,7 @@ Dirtab consdir[]={
	"time",		{Qtime},	12,	0600,
	"user",		{Quser},	0,	0600,
	"vmereset",	{Qvmereset},	0,	0600,
	"sysstat",	{Qsysstat},	0,	0600,
};

#define	NCONS	(sizeof consdir/sizeof(Dirtab))


@@ 443,13 445,14 @@ consclose(Chan *c)
long
consread(Chan *c, void *buf, long n, ulong offset)
{
	int ch, i, j, k;
	int ch, i, j, k, id;
	ulong l;
	uchar *out;
	char *cbuf = buf;
	char *user;
	int userlen;
	char tmp[6*NUMSIZE];
	char tmp[6*NUMSIZE], xbuf[512];
	Mach *mp;

	if(n <= 0)
		return n;


@@ 532,6 535,18 @@ consread(Chan *c, void *buf, long n, ulong offset)
	case Qlog:
		return readlog(offset, buf, n);

	case Qsysstat:
		j = 0;
		for(id = 0; id < 32; id++) {
			if(active.machs & (1<<id)) {
				mp = MACHP(id);
				j += sprint(&xbuf[j], "%d %d %d %d %d %d %d %d\n",
					id, mp->cs, mp->intr, mp->syscall, mp->pfault,
					    mp->tlbfault, mp->tlbpurge, mp->spinlock);
			}
		}

		return readstr(offset, buf, n, xbuf);
	case Qnull:
		return 0;



@@ 547,7 562,9 @@ conswrite(Chan *c, void *va, long n, ulong offset)
	char cbuf[64];
	char buf[256];
	long l, m;
	int id;
	char *a = va;
	Mach *mp;

	switch(c->qid.path){
	case Qcons:


@@ 601,7 618,21 @@ conswrite(Chan *c, void *va, long n, ulong offset)
			error(Eperm);
		vmereset();
		break;
	case Qsysstat:
		for(id = 0; id < 32; id++) {
			if(active.machs & (1<<id)) {
				mp = MACHP(id);
				mp->cs = 0;
				mp->intr = 0;
				mp->syscall = 0;
				mp->pfault = 0;
				mp->tlbfault = 0;
				mp->tlbpurge = 0;
				mp->spinlock = 0;
			}
		}

		break;
	default:
		error(Egreg);
	}

M port/devdup.c => port/devdup.c +12 -1
@@ 61,7 61,18 @@ dupwalk(Chan *c, char *name)
void
dupstat(Chan *c, char *db)
{
	devstat(c, db, (Dirtab *)0, 0L, dupgen);
	int fd;
	Chan *f;

	if(c->qid.path == CHDIR){
		devstat(c, db, (Dirtab *)0, 0L, dupgen);
	}else{
		fd = c->qid.path;
		SET(f);
		if(fd<0 || NFD<=fd || (f=u->fd[fd])==0)
			error(Ebadfd);
		(*devtab[f->type].stat)(f, (char*)db);
	}
}

Chan *

M port/devmnt.c => port/devmnt.c +23 -10
@@ 397,11 397,6 @@ mntclwalk(Chan *c, char *name)
	Mnthdr *mh;
	Chan *nc;

	if(waserror()){	/* BUG: can check type of error? */
		freechan(nc);
		nc = 0;
		goto Out;
	}
	nc = newchan();
	nc->type = c->type;
	nc->dev = c->dev;


@@ 413,6 408,13 @@ mntclwalk(Chan *c, char *name)
	nc->aux = c->aux;
	nc->mchan = c->mchan;
	nc->mqid = c->qid;
	mh = 0;
	if(waserror()){
		close(nc);
		if(mh)
			mhfree(mh);
		return 0;
	}
	m = mntdev(c, 0);
	mh = mhalloc();
	mh->thdr.type = Tclwalk;


@@ 420,12 422,21 @@ mntclwalk(Chan *c, char *name)
	mh->thdr.newfid = nc->fid;
	strcpy(mh->thdr.name, name);
	mntxmit(m, mh);
	if(mh->rhdr.fid == mh->thdr.fid)
		errors("directory entry not found");
	poperror();
	nc->qid = mh->rhdr.qid;
	incref(m);
    Out:
	if(mh->rhdr.fid == mh->thdr.fid){
		/*
		 *  just free the chan, the other side has
		 *  already clunked
		 */
		freechan(nc);
		nc = 0;
	} else {
		/*
		 *  it worked, keep the channel
		 */
		nc->qid = mh->rhdr.qid;
		incref(m);
	}
	mhfree(mh);
	return nc;
}


@@ 780,10 791,12 @@ mntxmit(Mnt *m, Mnthdr *mh)
		print("type mismatch %d %d\n", mh->rhdr.type, mh->thdr.type+1);
		error(Ebadmsg);
	}
#ifdef PHILW_HACK
	if(mh->rhdr.fid != mh->thdr.fid){
		print("fid mismatch %d %d type %d\n", mh->rhdr.fid, mh->thdr.fid, mh->rhdr.type);
		error(Ebadmsg);
	}
#endif

	/*
	 * Copy out on read

M port/fault.c => port/fault.c +5 -2
@@ 16,7 16,7 @@ fault(ulong addr, int read)
	char *l;
	Page *pg;
	int zeroed = 0, head = 1;
	int i;
	int i, touched = 0;
	KMap *k, *k1;

	s = seg(u->p, addr);


@@ 61,6 61,7 @@ fault(ulong addr, int read)
			pte = opte;
	}
	if(pte->page == 0){
		touched = 1;
		if(o->chan==0 || addr>(o->va+(o->maxca-o->minca))){
			/*
			 * Zero fill page.  If we are really doing a copy-on-write


@@ 114,7 115,7 @@ fault(ulong addr, int read)
	if((o->flag & OWRPERM) && (conf.copymode || !read)
	&& ((head && ((o->flag&OPURE) || o->nproc>1))
	    || (!head && pte->page->ref>1))){

		touched = 1;
		/*
		 * Look for the easy way out: are we the last non-modified?
		 */


@@ 194,6 195,8 @@ fault(ulong addr, int read)
		panic("addr %lux seg %d wrong proc in tail", addr, s-u->p->seg);
	}
	unlock(o);
	if(touched == 0)
		m->tlbfault++;
	putmmu(mmuvirt, mmuphys);
	return 0;
}

M port/page.c => port/page.c +2 -0
@@ 47,6 47,8 @@ struct{
	PTEA	*free;
}modalloc;

extern long end;

/*
 * Called to allocate permanent data structures, before calling pageinit().
 */

M port/proc.c => port/proc.c +8 -1
@@ 84,6 84,7 @@ sched(void)

	if(u){
		splhi();
		m->cs++;
		procsave(procstate, sizeof(procstate));
		if(setlabel(&u->p->sched)){	/* woke up */
			p = u->p;


@@ 190,6 191,7 @@ loop:
		p->exiting = 0;
		p->pgrp = 0;
		p->fpstate = FPinit;
		p->kp = 0;
		memset(p->pidonmach, 0, sizeof p->pidonmach);
		memset(p->seg, 0, sizeof p->seg);
		lock(&pidalloc);


@@ 327,13 329,18 @@ postnote(Proc *p, int dolock, char *n, int flag)
	int s;
	Rendez *r;

	SET(k);
	USED(k);

	if(dolock)
		lock(&p->debug);

	if(p != u->p){
		k = kmap(p->upage);
		up = (User*)VA(k);
	}else
	}else 
		up = u;

	if(flag!=NUser && (up->notify==0 || up->notified))
		up->nnote = 0;	/* force user's hand */
	else if(up->nnote == NNOTE-1){

M port/tcpoutput.c => port/tcpoutput.c +1 -0
@@ 93,6 93,7 @@ tcp_output(Ipconv *s)
		stop_timer(&tcb->acktimer);

		tcb->flags &= ~FORCE;
		tcprcvwin(s);

		seg.source = s->psrc;
		seg.dest = s->pdst;

M power/dat.h => power/dat.h +18 -2
@@ 18,6 18,7 @@ typedef struct Label	Label;
typedef struct List	List;
typedef struct Lock	Lock;
typedef struct Mach	Mach;
typedef struct Softtlb	Softtlb;
typedef struct Mount	Mount;
typedef struct Mtab	Mtab;
typedef struct Note	Note;


@@ 218,10 219,16 @@ struct Envp
	int	chref;			/* # chans from pgrp pointing here */
};

struct Softtlb
{
	ulong	virt;
	ulong	phys;
};

struct Mach
{
	int	machno;			/* physical id of processor */
	int	mmask;			/* 1<<m->machno */
	int	machno;			/* physical id of processor NB. MUST BE FIRST */
	Softtlb *stb;			/* Software tlb simulation NB. MUST BE SECOND */
	ulong	ticks;			/* of the clock since boot time */
	Proc	*proc;			/* current process on this processor */
	Label	sched;			/* scheduler wakeup */


@@ 230,6 237,15 @@ struct Mach
	char	pidhere[NTLBPID];	/* is this pid possibly in this mmu? */
	int	lastpid;		/* last pid allocated on this machine */
	Proc	*pidproc[NTLBPID];	/* process that owns this tlbpid on this mach */

	int	tlbfault;
	int	tlbpurge;
	int	pfault;
	int	cs;
	int	syscall;
	int	spinlock;
	int	intr;

	int	stack[1];
};


M power/devbit3.c => power/devbit3.c +2 -0
@@ 30,6 30,7 @@ enum
void
bit3send(Bit3msg *bp, ulong cmd, void *addr, ulong count)
{

	do; while(*BIT3ADDR);
	bp->cmd = cmd;
	bp->addr = (ulong)addr;


@@ 38,6 39,7 @@ bit3send(Bit3msg *bp, ulong cmd, void *addr, ulong count)
	wbflush();
	do; while(*BIT3HOLD);
	*BIT3INTR = 0x20;

}

void

M power/faultmips.c => power/faultmips.c +1 -0
@@ 17,6 17,7 @@ faultmips(Ureg *ur, int user, int code)
	extern char *excname[];
	int read;

	m->pfault++;
	addr = ur->badvaddr;
	addr &= ~(BY2PG-1);
	read = !(code==CTLBM || code==CTLBS);

M power/fns.h => power/fns.h +2 -0
@@ 147,6 147,7 @@ Block	*pullup(Block *, int);
void	purgetlb(int);
Queue	*pushq(Stream*, Qinfo*);
void	putmmu(ulong, ulong);
void	putstlb(ulong, ulong);
void	puttlb(ulong, ulong);
void	puttlbx(int, ulong, ulong);
int	putb(Blist*, Block*);


@@ 207,6 208,7 @@ void	userinit(void);
void	validaddr(ulong, ulong, int);
void	vecinit(void);
void	vector80(void);
void	vector0(void);
void	*vmemchr(void*, int, int);
void	vmereset(void);
void	wakeme(Alarm*);

M power/l.s => power/l.s +47 -0
@@ 175,6 175,7 @@ TEXT	puttlb(SB), $4
	NOOP
	JAL	splx(SB)
	RET

index:
	TLBWI
	NOOP


@@ 241,6 242,52 @@ TEXT	vector80(SB), $-4
	MOVW	$exception(SB), R26
	JMP	(R26)

TEXT	vector0(SB), $-4

	MOVW	$utlbmiss(SB), R26
	MOVW	M(TLBVIRT), R27
	SLL	$(STLBLOG-9), R27		/* delay slot fodder */
	JMP	(R26)

TEXT	utlbmiss(SB), $-4

	SRL	$(STLBLOG), R27, R26
	XOR	R26, R27
	AND	$((STLBSIZE-1)<<3), R27
	MOVW	R27, M(TLBPHYS)			/* scratch register, store */

	MOVW	$((MACHADDR+4) & 0xffff0000), R26
	MOVW	$MPID, R27
	MOVB	3(R27), R27
	AND	$7, R27
	SLL	$PGSHIFT, R27
	ADDU	R27, R26
	
	MOVW	M(TLBPHYS), R27			/* scratch register, load */
	MOVW	((MACHADDR+4) & 0xffff)(R26), R26
	ADDU	R26, R27
	MOVW	4(R27), R26
	MOVW	R26, M(TLBPHYS)

	MOVW	M(TLBVIRT), R26
	MOVW	(R27), R27
	BNE	R26, R27, stlbm

	TLBP
	MOVW	M(EPC), R27
	MOVW	M(INDEX), R26
	BGEZ	R26, uind
	TLBWR
	NOOP
	RFE	(R27)
uind:
	TLBWI
	NOOP
	RFE	(R27)		
stlbm:	
	MOVW	$exception(SB), R26
	JMP	(R26)

TEXT	exception(SB), $-4

	MOVW	M(STATUS), R26

M power/main.c => power/main.c +7 -2
@@ 8,6 8,11 @@
#include	"init.h"

/*
 * software tlb simulation
 */
Softtlb stlb[4][STLBSIZE];

/*
 *  args passed by boot process
 */
int _argc; char **_argv; char **_env;


@@ 77,7 82,7 @@ machinit(void)
	n = m->machno;
	memset(m, 0, sizeof(Mach));
	m->machno = n;
	m->mmask = 1<<m->machno;
	m->stb = &stlb[n][0];
}

void


@@ 100,7 105,7 @@ vecinit(void)
	for(size=0; size<4; size++)
		*p++ = *q++;
	p = (ulong*)UTLBMISS;
	q = (ulong*)vector80;
	q = (ulong*)vector0;
	for(size=0; size<4; size++)
		*p++ = *q++;
}

M power/mem.h => power/mem.h +5 -0
@@ 96,6 96,11 @@
#define	PTEWRITE	(1<<10)
#define PTERONLY	0
#define	PTEPID(n)	((n)<<6)
#define TLBPID(n)	(((n)>>6)&0x3F)

/* N.B. MUST CHANGE l.s utlbmiss if you want to change this */
#define STLBLOG		13
#define STLBSIZE	(1<<STLBLOG)

#define	NTLBPID	64	/* number of pids */
#define	NTLB	64	/* number of entries */

M power/mmu.c => power/mmu.c +70 -10
@@ 25,6 25,7 @@ mapstack(Proc *p)
	tlbvirt = USERADDR | PTEPID(tp);
	tlbphys = p->upage->pa | PTEWRITE | PTEVALID | PTEGLOBL;
	puttlbx(0, tlbvirt, tlbphys);
	putstlb(tlbvirt, tlbphys);
	u = (User*)USERADDR;
}



@@ 34,19 35,44 @@ mapstack(Proc *p)
int
newtlbpid(Proc *p)
{
	int i;
	int i, s;
	Proc *sp;

	char *h;
/*
	s = m->lastpid;
	if(s >= NTLBPID)
		s = 1;
	i = s;
	h = m->pidhere;
	do{
		i++;
		if(i >= NTLBPID)
			i = 1;
	}while(h[i] && i != s);
	
	if(i == s){
		sp = m->pidproc[i];
		if(sp){
			if(sp->pidonmach[m->machno] == i)
				sp->pidonmach[m->machno] = 0;
			purgetlb(i);
		}
	}
*/
	i = m->lastpid+1;
	if(i >= NTLBPID)
		i = 1;
	sp = m->pidproc[i];
	if(sp){
		if(sp->pidonmach[m->machno] == i)
			sp->pidonmach[m->machno] = 0;

		sp->pidonmach[m->machno] = 0;
		purgetlb(i);
	}
	m->pidproc[i] = p;

	m->lastpid = i;
	m->pidproc[i] = p;
	return i;
}



@@ 68,6 94,7 @@ putmmu(ulong tlbvirt, ulong tlbphys)
		p->pidonmach[m->machno] = tp;
	}
	tlbvirt |= PTEPID(tp);
	putstlb(tlbvirt, tlbphys);
	puttlb(tlbvirt, tlbphys);
	m->pidhere[tp] = 1;
	p->state = Running;


@@ 77,18 104,38 @@ putmmu(ulong tlbvirt, ulong tlbphys)
void
purgetlb(int pid)
{
	Softtlb *entry, *etab;
	char p[NTLBPID];
	Proc *sp;
	int i, rpid;

	if(m->pidhere[pid] == 0)
	if(m->pidproc[pid] == 0)
		return;
	memset(m->pidhere, 0, sizeof m->pidhere);
	for(i=TLBROFF; i<NTLB; i++){
		rpid = (gettlbvirt(i)>>6) & 0x3F;
		if(rpid == pid)

	m->tlbpurge++;
	m->pidproc[pid] = 0;
	memset(p, 0, sizeof p);
	for(i=TLBROFF; i<NTLB; i++)
		if(TLBPID(gettlbvirt(i)) == pid)
			puttlbx(i, KZERO | PTEPID(i), 0);
		else
			m->pidhere[rpid] = 1;
	entry = m->stb;
	etab = &entry[STLBSIZE];
	for(; entry < etab; entry++){
		rpid = TLBPID(entry->virt);
		if(rpid == pid){
			entry->phys = 0;
			entry->virt = 0;
		}else
			p[rpid] = 1;
	}
	for(i = 0; i < NTLBPID; i++)
		if(p[i] == 0){
			sp = m->pidproc[i];
			if(sp && sp->pidonmach[m->machno] == i)
				sp->pidonmach[m->machno] = 0;
			m->pidproc[i] = 0;
			m->pidhere[i] = 0;
		}
}

void


@@ 111,4 158,17 @@ void
invalidateu(void)
{
	puttlbx(0, KZERO | PTEPID(0), 0);
	putstlb(KZERO | PTEPID(0), 0);
}

void
putstlb(ulong tlbvirt, ulong tlbphys)
{
	Softtlb *entry;

	entry = &m->stb[((tlbvirt<<1) ^ (tlbvirt>>12)) & (STLBSIZE-1)];
	entry->phys = tlbphys;
	entry->virt = tlbvirt;
	if(tlbphys == 0)
		entry->virt = 0;
}

M power/trap.c => power/trap.c +4 -0
@@ 151,6 151,7 @@ trap(Ureg *ur)
				sprint(buf, "sys: fp: %s FCR31 %lux", fpexcname(x), x);
			else
				sprint(buf, "sys: trap: %s[%d]", excname[ecode], m->machno);

			postnote(u->p, 1, buf, NDebug);
		}else{
			print("%s %s pc=%lux\n", user? "user": "kernel", excname[ecode], ur->pc);


@@ 182,6 183,7 @@ intr(Ureg *ur)
	ulong cause;
	static int bogies;

	m->intr++;
	cause = ur->cause&(INTR5|INTR4|INTR3|INTR2|INTR1);
	if(cause & (INTR2|INTR4)){
		clock(ur);


@@ 237,6 239,7 @@ intr(Ureg *ur)
			print("new pend %ux\n", xxx);
			npend = pend |= xxx;
			i = SBCCREG->flevel;
			USED(i);
		}

		/*


@@ 468,6 471,7 @@ syscall(Ureg *aur)
	Ureg *ur;
	char *msg;

	m->syscall++;
	u->p->insyscall = 1;
	ur = aur;
	u->p->pc = ur->pc;		/* BUG */