~kris/9p

9hist

fd21a503ae1d591cf9cea82f15cbada4c4e245e9 — David du Colombier 34 years ago 790abd1
Plan 9 from Bell Labs 1992-08-05
M gnot/clock.c => gnot/clock.c +3 -1
@@ 24,8 24,10 @@ clock(Ureg *ur)
	int user, nrun = 0;

	user = (ur->sr&SUPER) == 0;
	if(user)
	if(user){
		u->dbgreg = ur;
		u->p->pc = ur->pc;
	}

	SYNCREG[1] = 0x5F;	/* clear interrupt */
	m->ticks++;

M gnot/trap.c => gnot/trap.c +8 -15
@@ 105,10 105,9 @@ trap(Ureg *ur)

	user = !(ur->sr&SUPER);

	if(u) {
		u->p->pc = ur->pc;		/* BUG */
	if(u)
		u->dbgreg = ur;
	}

	if(user){
		sprint(buf, "sys: %s", excname(ur->vo, ur->pc));
		postnote(u->p, 1, buf, NDebug);


@@ 283,19 282,13 @@ syscall(Ureg *aur)
	u->p->pc = ur->pc;
	if(ur->sr & SUPER)
		panic("recursive system call");
	/*
	 * since the system call interface does not
	 * guarantee anything about registers, but the fpcr is more than
	 * just a register...  BUG
	 */
	splhi();
	fpsave(&u->fpsave);
	if(u->p->fpstate==FPactive || u->fpsave.type){
		fprestore(&initfp);
		u->p->fpstate = FPinit;
		m->fpstate = FPinit;

	/* must save FP registers before fork */
	if(u->p->fpstate==FPactive && ur->r0==RFORK){
		splhi();
		procsave(u->p);
		spllo();
	}
	spllo();

	if(u->p->procctl)
		procctl(u->p);

M pc/fault386.c => pc/fault386.c +1 -0
@@ 23,6 23,7 @@ fault386(Ureg *ur)
	addr = getcr2();
	read = !(ur->ecode & 2);
	user = (ur->cs&0xffff) == UESEL;
	spllo();
	n = fault(addr, read);
	if(n < 0){
		if(user){

M pc/l.s => pc/l.s +1 -1
@@ 290,7 290,7 @@ TEXT	getcr2(SB),$0		/* fault address */
#define	FPOFF\
	WAIT;\
	MOVL	CR0,AX;\
	ORL	$0x4,AX		/* EM=1 */;\
	ORL	$0x24,AX	/* EM=1, NE=1 */;\
	MOVL	AX,CR0

#define	FPON\

M pc/main.c => pc/main.c +10 -8
@@ 295,6 295,7 @@ matherror(Ureg *ur)
			break;
		}
	sprint(note, "sys: fp: %s, status 0x%ux, pc 0x%lux", msg, status, ur->pc);
print("%s cr0 %lux\n", note, getcr0());
	postnote(u->p, 1, note, NDebug);
}



@@ 315,7 316,7 @@ mathemu(Ureg *ur)
		u->p->fpstate = FPactive;
		break;
	case FPactive:
		pexit("Math emu", 0);
		panic("math emu", 0);
		break;
	}
}


@@ 327,7 328,8 @@ void
mathover(Ureg *ur)
{
	USED(ur);
	pexit("Math overrun", 0);
print("sys: fp: math overrun pc 0x%lux pid %d\n", ur->pc, u->p->pid);
	pexit("math overrun", 0);
}

void


@@ 355,12 357,12 @@ procsetup(Proc *p)
void
procsave(Proc *p)
{
	USED(p);
	if(u->p->state == Moribund)
		return;
	if(u->p->fpstate == FPactive){
		fpsave(&u->fpsave);
		u->p->fpstate = FPinactive;
	if(p->fpstate == FPactive){
		if(p->state == Moribund)
			fpoff();
		else
			fpsave(&u->fpsave);
		p->fpstate = FPinactive;
	}
}


M pc/mem.h => pc/mem.h +3 -3
@@ 99,9 99,9 @@
/*
 *  virtual MMU
 */
#define PTEMAPMEM	(1024*1024)	/* ??? */	
#define SEGMAPSIZE	16		/* ??? */
#define	PTEPERTAB	(PTEMAPMEM/BY2PG)	/* ??? */
#define PTEMAPMEM	(1024*1024)	
#define SEGMAPSIZE	64
#define	PTEPERTAB	(PTEMAPMEM/BY2PG)
#define PPN(x)		((x)&~(BY2PG-1))

/*

M pc/mmu.c => pc/mmu.c +17 -9
@@ 180,24 180,31 @@ flushmmu(void)
void
mapstack(Proc *p)
{
	Page *pg, **l;
	Page *pg;
	ulong *top;

	if(p->upage->va != (USERADDR|(p->pid&0xFFFF)) && p->pid != 0)
		panic("mapstack %d 0x%lux 0x%lux", p->pid, p->upage->pa, p->upage->va);

	if(p->newtlb){
		/*
		 *  bin the current second level page tables.
		 *  newtlb set means that they are inconsistent
		 *  with the segment.c data structures.
		 *
		 *  bin the current second level page tables and
		 *  the pointers to them in the top level page.
		 *  pg->daddr is used by putmmu to save the offset into
		 *  the top level page.
		 */
		if(p->mmutop)
			memmove((void*)p->mmutop->va, (void*)ktoppg.va, BY2PG);
		l = &p->mmufree;
		for(pg = p->mmufree; pg; pg = pg->next)
			l = &pg->next;
		*l = p->mmuused;
		p->mmuused = 0;
		if(p->mmutop && p->mmuused){
			top = (ulong*)p->mmutop->va;
			for(pg = p->mmuused; pg->next; pg = pg->next)
				top[pg->daddr] = 0;
			top[pg->daddr] = 0;
			pg->next = p->mmufree;
			p->mmufree = p->mmuused;
			p->mmuused = 0;
		}
		p->newtlb = 0;
	}



@@ 289,6 296,7 @@ putmmu(ulong va, ulong pa, Page *pg)
			memset((void*)pg->va, 0, BY2PG);
		}
		top[topoff] = PPN(pg->pa) | PTEVALID | PTEUSER | PTEWRITE;
		pg->daddr = topoff;
		pg->next = p->mmuused;
		p->mmuused = pg;
	}

M pc/trap.c => pc/trap.c +13 -6
@@ 110,7 110,7 @@ trapinit(void)
	sethvec(11, intr11, SEGTG, 0);
	sethvec(12, intr12, SEGTG, 0);
	sethvec(13, intr13, SEGTG, 0);
	sethvec(14, intr14, SEGTG, 0);
	sethvec(14, intr14, SEGIG, 0);
	sethvec(15, intr15, SEGTG, 0);
	sethvec(16, intr16, SEGTG, 0);



@@ 333,10 333,19 @@ syscall(Ureg *ur)
	if((ur->cs)&0xffff == KESEL)
		panic("recursive system call");

	/*
	 *  do something about floating point!!!
	 */
	u->scallnr = ur->ax;
	if(u->scallnr == RFORK && u->p->fpstate == FPactive){
		/*
		 *  so that the child starts out with the
		 *  same registers as the parent
		 */
		splhi();
		if(u->p->fpstate == FPactive){
			fpsave(&u->fpsave);
			u->p->fpstate = FPinactive;
		}
		spllo();
	}
	sp = ur->usp;
	u->nerrlab = 0;
	ret = -1;


@@ 353,10 362,8 @@ syscall(Ureg *ur)
		u->s = *((Sargs*)(sp+1*BY2WD));
		u->p->psstate = sysctab[u->scallnr];

if(u->p->fgrp->ref <= 0) print("before syscall %s\n", u->p->psstate);
		ret = (*systab[u->scallnr])(u->s.args);
		poperror();
if(u->p->fgrp->ref <= 0) print("after syscall %s\n", u->p->psstate);
	}
	if(u->nerrlab){
		print("bad errstack [%d]: %d extra\n", u->scallnr, u->nerrlab);

M port/fault.c => port/fault.c +3 -15
@@ 43,7 43,7 @@ int
fixfault(Segment *s, ulong addr, int read, int doputmmu)
{
	ulong mmuphys=0, soff;
	Page **pg, *lkp, *new = 0;
	Page **pg, *lkp, *new;
	Pte **p, *etp;
	int type;



@@ 85,13 85,11 @@ fixfault(Segment *s, ulong addr, int read, int doputmmu)
	case SG_SHARED:				/* Zero fill on demand */
	case SG_STACK:	
		if(*pg == 0) {
			if(new == 0)
			if(new = newpage(1, &s, addr))
			new = newpage(1, &s, addr);
			if(s == 0)
				return -1;

			*pg = new;
			new = 0;
		}
		/* NO break */



@@ 112,12 110,10 @@ fixfault(Segment *s, ulong addr, int read, int doputmmu)
		lock(lkp);
		if(lkp->ref > 1) {
			unlock(lkp);
			if(new == 0)
			if(new = newpage(0, &s, addr))
			new = newpage(0, &s, addr);
			if(s == 0)
				return -1;
			*pg = new;
			new = 0;
			copypage(lkp, *pg);
			putpage(lkp);
		}


@@ 147,13 143,6 @@ fixfault(Segment *s, ulong addr, int read, int doputmmu)

	qunlock(&s->lk);

	/*
	 * A race may provide a page we never used when	
	 * a fault is fixed while process slept in newpage
	 */
	if(new)
		putpage(new);

	if(doputmmu)
		putmmu(addr, mmuphys, *pg);



@@ 255,7 244,6 @@ pio(Segment *s, ulong addr, ulong soff, Page **p)
			cachepage(new, &swapimage);
			putswap(*p);
			*p = new;
/*			print("l %lux %d\n", addr, daddr);*/
		}
		else
			putpage(new);

M port/lib.h => port/lib.h +1 -0
@@ 31,6 31,7 @@ extern	int	runetochar(char*, Rune*);
extern	int	chartorune(Rune*, char*);
extern	int	countrune(char*);
extern	char*	utfrune(char*, long);
extern	int	utflen(char*);

/*
 * print routines

M port/page.c => port/page.c +14 -4
@@ 64,18 64,19 @@ newpage(int clear, Segment **s, ulong va)
{
	Page *p;
	KMap *k;
	int i;
	int hw, i, dontalloc;

	lock(&palloc);

	/* The kp test is a poor guard against the pager deadlocking */
	while((palloc.freecount < swapalloc.highwater && u->p->kp == 0) ||
	       palloc.freecount == 0) {
	hw = swapalloc.highwater;
	while((palloc.freecount < hw && u->p->kp == 0) || palloc.freecount == 0) {
		palloc.wanted++;
		unlock(&palloc);
		dontalloc = 0;
		if(s && *s) {
			qunlock(&((*s)->lk));
			*s = 0;
			dontalloc = 1;
		}
		qlock(&palloc.pwait);			/* Hold memory requesters here */



@@ 88,6 89,15 @@ newpage(int clear, Segment **s, ulong va)
		poperror();

		qunlock(&palloc.pwait);

		/*
		 * If called from fault and we lost the segment from underneath
		 * don't waste time allocating and freeing a page. Fault will call
		 * newpage again when it has reaquired the segment locks
		 */
		if(dontalloc)
			return 0;

		lock(&palloc);
		palloc.wanted--;
	}

M port/portdat.h => port/portdat.h +3 -3
@@ 351,9 351,9 @@ enum
};

#define PG_ONSWAP	1
#define pagedout(s)	(((ulong)s)==0 || (((ulong)s)&PG_ONSWAP))
#define swapaddr(s)	(((ulong)s)&~PG_ONSWAP)
#define onswap(s)	(((ulong)s)&PG_ONSWAP)
#define pagedout(s)	(((ulong)s)==0 || onswap(s))
#define swapaddr(s)	(((ulong)s)&~PG_ONSWAP)

#define SEGMAXSIZE	(SEGMAPSIZE*PTEMAPMEM)



@@ 511,7 511,7 @@ struct Proc
	ulong	qlockpc;		/* pc of last call to qlock */
	int	state;
	char	*psstate;		/* What /proc/#/status reports */
	Page	*upage;			/* BUG: should be unlinked from page list */
	Page	*upage;			/* page from palloc */
	Segment	*seg[NSEG];
	ulong	pid;
	ulong	noteid;			/* Equivalent of note group */

M port/proc.c => port/proc.c +17 -4
@@ 531,8 531,12 @@ pexit(char *exitstr, int freemem)
	if(c->kp == 0) {
		if((p = c->parent) == 0)
			panic("boot process died");
			

		while(waserror())
			;	
		wq = smalloc(sizeof(Waitq));
		poperror();

		readnum(0, wq->w.pid, NUMSIZE, c->pid, NUMSIZE);
		utime = c->time[TUser] + c->time[TCUser];
		stime = c->time[TSys] + c->time[TCSys];


@@ 657,15 661,24 @@ void
procdump(void)
{
	int i;
	char *s;
	Proc *p;
	ulong bss;

	for(i=0; i<conf.nproc; i++){
		p = procalloc.arena+i;
		if(p->state != Dead){
			print("%d:%s %s upc %lux %s ut %ld st %ld r %lux qpc %lux\n",
			bss = 0;
			if(p->seg[BSEG])
				bss = p->seg[BSEG]->top;

			s = p->psstate;
			if(s == 0)
				s = "kproc";
			print("%3d:%10s %10s pc %8lux %8s (%s) ut %ld st %ld r %lux qpc %lux bss %lux\n",
				p->pid, p->text, p->user, p->pc, 
				statename[p->state], p->time[0],
				p->time[1], p->r, p->qlockpc);
				s, statename[p->state], p->time[0],
				p->time[1], p->r, p->qlockpc, bss);
		}
	}
}

M port/swap.c => port/swap.c +22 -21
@@ 21,7 21,7 @@ enum
Image 	swapimage;
static 	int swopen;
Page	*iolist[Maxpages];
int	ioptr, npage;
int	ioptr;

void
swapinit(void)


@@ 87,7 87,7 @@ pager(void *junk)
{
	Proc *p, *ep;
	Segment *s;
	int i, type;
	int i;

	if(waserror()) 
		panic("pager: os error\n");


@@ 99,9 99,7 @@ pager(void *junk)
loop:
	u->p->psstate = "Idle";
	sleep(&swapalloc.r, needpages, 0);
	u->p->psstate = "Pageout";

	npage = 0;
	for(;;) {
		p++;
		if(p >= ep)


@@ 116,22 114,28 @@ loop:
					goto loop;

				if(s = p->seg[i]) {
					type = s->type&SG_TYPE;
					switch(type) {
					switch(s->type&SG_TYPE) {
					default:
						break;
					case SG_TEXT:
						pageout(p, s);
						break;
					case SG_DATA:
					case SG_BSS:
					case SG_STACK:
					case SG_SHARED:
						u->p->psstate = "Pageout";
						pageout(p, s);
						executeio();
						if(ioptr != 0) {
							u->p->psstate = "I/O";
							executeio();
						}
					}
				}
			}
			continue;
		}
		else 

		if(palloc.freecount < swapalloc.highwater) {
			if(!cpuserver)
				freebroken();	/* can use the memory */


@@ 142,17 146,15 @@ loop:
			wakeup(&palloc.r);
		}
	}
	if(npage == 0)
		print("swap: pass took no pages\n");
	goto loop;
}

void			
pageout(Proc *p, Segment *s)
{
	Pte **sm, **endsm, *l;
	int type, i;
	Pte *l;
	Page **pg, *entry;
	int type;

	if(!canqlock(&s->lk))	/* We cannot afford to wait, we will surely deadlock */
		return;


@@ 177,9 179,8 @@ pageout(Proc *p, Segment *s)

	/* Pass through the pte tables looking for memory pages to swap out */
	type = s->type&SG_TYPE;
	endsm = &s->map[SEGMAPSIZE];
	for(sm = s->map; sm < endsm; sm++) {
		l = *sm;
	for(i = 0; i < SEGMAPSIZE; i++) {
		l = s->map[i];
		if(l == 0)
			continue;
		for(pg = l->first; pg < l->last; pg++) {


@@ 187,10 188,12 @@ pageout(Proc *p, Segment *s)
			if(pagedout(entry))
				continue;

			if(entry->modref & PG_REF)
			if(entry->modref & PG_REF) {
				entry->modref &= ~PG_REF;
			else 
				pagepte(type, pg);
				continue;
			}

			pagepte(type, pg);

			if(ioptr >= Maxpages)
				goto out;


@@ 206,8 209,8 @@ out:
int
canflush(Proc *p, Segment *s)
{
	Proc *ep;
	int i;
	Proc *ep;

	lock(s);
	if(s->ref == 1) {		/* Easy if we are the only user */


@@ 232,7 235,6 @@ canflush(Proc *p, Segment *s)
		}
		p++;
	}

	return 1;						
}



@@ 272,7 274,6 @@ pagepte(int type, Page **pg)
		/* Add me to IO transaction list */
		iolist[ioptr++] = outp;
	}
	npage++;
}

void

M power/clock.c => power/clock.c +2 -0
@@ 86,6 86,8 @@ clock(Ureg *ur)
			LEDON(LEDpulse);
		else
			LEDOFF(LEDpulse);
		if(m->proc)
			m->proc->pc = ur->pc;

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

M power/trap.c => power/trap.c +4 -4
@@ 83,10 83,9 @@ trap(Ureg *ur)
	ecode = EXCCODE(ur->cause);
	LEDON(ecode);
	user = ur->status&KUP;
	if(u) {
		u->p->pc = ur->pc;		/* BUG */
	if(u)
		u->dbgreg = ur;
	}

	switch(ecode){
	case CINT:
		if(u && u->p->state==Running){


@@ 505,7 504,7 @@ syscall(Ureg *aur)
	p = u->p;
	p->insyscall = 1;
	ur = aur;
	p->pc = ur->pc;		/* BUG */
	p->pc = ur->pc;
	u->dbgreg = aur;
	ur->cause = 15<<2;		/* for debugging: system call is undef 15;
	/*


@@ 574,6 573,7 @@ execregs(ulong entry, ulong ssize, ulong nargs)
	*--sp = nargs;
	((Ureg*)UREGADDR)->usp = (ulong)sp;
	((Ureg*)UREGADDR)->pc = entry - 4;	/* syscall advances it */
	u->fpsave.fpstatus = initfp.fpstatus;
	return USTKTOP-BY2WD;			/* address of user-level clock */
}


M ss/fptrap.c => ss/fptrap.c +7 -10
@@ 187,15 187,8 @@ fixq(FPsave *f, int n)
		instr = f->q[0].i;
		/*
		 * Sparc says you have to emulate.  To hell with that.
		 * Let's compile!
		 */
		ip = bbmalloc(3*sizeof(ulong));
		ip[0] = instr;
		ip[1] = 0x81c3e008;	/* JMPL #8(R15), R0 [RETURN] */
		ip[2] = 0x01000000;	/* SETHI #0, R0 [NOP] */
		/*
		 * You can always pump one instruction without immediate trap.
		 * Therefore run one and wait for it to complete or trap.
		 * We can compile on the fly instead.
		 * Run one instruction and wait for it to complete or trap.
		 * If it traps, we'll recurse but we won't overwrite
		 * our own data structures because there will be only
		 * one instruction uncompleted in the FPU.


@@ 206,8 199,12 @@ fixq(FPsave *f, int n)
		 * the trap by examining the non-zero members of the FPQ.
		 * Tough.
		 */
		ip = bbmalloc(3*sizeof(ulong));
		ip[0] = instr;
		ip[1] = 0x81c3e008;	/* JMPL #8(R15), R0 [RETURN] */
		ip[2] = 0x01000000;	/* SETHI #0, R0 [NOP] */
		f->fppc = f->q[0].a;
		(*(void(*)(void))ip)();
		(*(void(*)(void))ip)();	 /* You are expected to understand this cast */
		f->fppc = 0;
		if(!fpquiet())
			break;

M ss/trap.c => ss/trap.c +3 -4
@@ 102,10 102,8 @@ trap(Ureg *ur)
	char buf[64];
	ulong tbr, iw;

	if(u) {
		u->p->pc = ur->pc;		/* BUG */
	if(u)
		u->dbgreg = ur;
	}

	fpunsafe = 0;
	user = !(ur->psr&PSRPSUPER);


@@ 166,7 164,7 @@ trap(Ureg *ur)
		case 4:				/* floating point disabled */
			if(u && u->p){
				if(u->p->fpstate == FPinit)
					restfpregs(initfpp, initfpp->fsr);
					restfpregs(initfpp, u->fpsave.fsr);
				else if(u->p->fpstate == FPinactive)
					restfpregs(&u->fpsave, u->fpsave.fsr);
				else


@@ 590,6 588,7 @@ execregs(ulong entry, ulong ssize, ulong nargs)
	*--sp = nargs;
	((Ureg*)UREGADDR)->usp = (ulong)sp;
	((Ureg*)UREGADDR)->pc = entry - 4;	/* syscall advances it */
	u->fpsave.fsr = initfpp->fsr;
	return USTKTOP-BY2WD;			/* address of user-level clock */
}