~kris/9p

9hist

4d8c533e33bf91d700db485b68b64d76586666e2 — David du Colombier 35 years ago 2f75ede
Plan 9 from Bell Labs 1991-07-20
10 files changed, 234 insertions(+), 36 deletions(-)

M pc/dat.h
M pc/fault386.c
M pc/headland.c
M pc/l.s
M pc/main.c
M pc/mmu.c
M pc/trap.c
M port/devcons.c
M port/proc.c
M port/swap.c
M pc/dat.h => pc/dat.h +3 -2
@@ 165,8 165,9 @@ struct User
	Note	lastnote;
	int	(*notify)(void*, char*);
	void	*ureg;
	ushort	svvo;
	ushort	svsr;
	ulong	svcs;		/* cs before a notify */
	ulong	svss;		/* ss before a notify */
	ulong	svflags;		/* flags before a notify */
};

/*

M pc/fault386.c => pc/fault386.c +9 -5
@@ 15,24 15,27 @@ fault386(Ureg *ur)
	int read;
	int user;
	int n;
	int insyscall;
	static int times;

	insyscall = u->p->insyscall;
	u->p->insyscall = 1;
	addr = getcr2();
print("fault386 %lux ur %lux\n", addr, ur);
dumpregs(ur);
if(++times==3)
	panic("3rd time");
	if(faulting)
		panic("double fault\n");
	faulting = 1;
	read = !(ur->ecode & 2);
	user = (ur->ecode & 4);
	n = fault(addr, read);
print("fault returns %d\n", n);
if(++times==3)
	panic("3rd time in fault");
	if(n < 0){
		if(user){
			pprint("user %s error addr=0x%lux\n", read? "read" : "write", addr);
			pprint("status=0x%lux pc=0x%lux sp=0x%lux\n", ur->flags, ur->pc, ur->usp);
			pprint("user %s error addr=0x%lux\n", read?"read":"write", addr);
			pprint("status=0x%lux pc=0x%lux sp=0x%lux\n", ur->flags,
				ur->pc, ur->usp);
			pexit("Suicide", 0);
		}
		u->p->state = MMUing;


@@ 40,6 43,7 @@ print("fault returns %d\n", n);
		panic("fault: 0x%lux", addr);
	}
	faulting = 0;
	u->p->insyscall = insyscall;
}

void

M pc/headland.c => pc/headland.c +0 -1
@@ 36,6 36,5 @@ exit(void)

	u = 0;
	print("exiting\n");
	delay(5000);
	outb(Head, Reset);
}

M pc/l.s => pc/l.s +10 -5
@@ 9,6 9,11 @@ TEXT	origin(SB),$0

#ifdef BOOT
/*
 *	This part of l.s is used only in the boot kernel.
 *	It assumes that we are in real address mode, i.e.,
 *	that we look like an 8086.
 */
/*
 *	relocate everything to a half meg and jump there
 *	- looks wierd because it is being assembled by a 32 bit
 *	  assembler for a 16 bit world


@@ 431,11 436,11 @@ TEXT	setlabel(SB),$0
 *  Set up an interrupt return frame and IRET to user level.
 */
TEXT	touser(SB),$0
	PUSHL	$(UDSEL)			/* old ss */
	PUSHL	$(USTKTOP-16)			/* old sp */
	PUSHFL					/* old flags */
	PUSHL	$(UESEL)			/* old cs */
	PUSHL	$(UTZERO+32)			/* old pc */
	PUSHL	$(UDSEL)		/* old ss */
	PUSHL	$(USTKTOP)		/* old sp */
	PUSHFL				/* old flags */
	PUSHL	$(UESEL)		/* old cs */
	PUSHL	$(UTZERO+32)		/* old pc */
	MOVL	$(UDSEL),AX
	MOVW	AX,DS
	MOVW	AX,ES

M pc/main.c => pc/main.c +6 -13
@@ 65,6 65,9 @@ init0(void)
	u->p->state = Running;
	u->p->mach = m;

print("go low\n");
	spllo();

	/*
	 * These are o.k. because rootinit is null.
	 * Then early kproc's will have a root and dot.


@@ 74,17 77,8 @@ init0(void)

	chandevinit();

	/*
	 *  fault in the first executable page and user stack
	 */
	print("text is %lux\n", *((ulong *)(UTZERO+32)));

	/*  fault in the first stack page
	 */
	print("stack is %lux\n", *((ulong *)(USTKTOP-4)));
	*((ulong *)(USTKTOP-4)) = 0xdeadbeef;
	print("stack is %lux\n", *((ulong *)(USTKTOP-4)));
	delay(5000);
print("going to user\n");
delay(1000);

	touser();
}


@@ 110,10 104,9 @@ userinit(void)
	 *
	 * N.B. The -12 for the stack pointer is important.
	 *	4 bytes for gotolabel's return PC
	 *	8 bytes for optional sp and ss pushed during interrupts
	 */
	p->sched.pc = (ulong)init0;
	p->sched.sp = USERADDR + BY2PG - 12;
	p->sched.sp = USERADDR + BY2PG - 4;
	p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF));

	/*

M pc/mmu.c => pc/mmu.c +3 -2
@@ 242,15 242,16 @@ print("putmmu %lux %lux\n", va, pa); /**/
		pg = p->mmu[i] = newpage(1, 0, 0);
		p->mmue[i] = PPN(pg->pa) | PTEVALID | PTEUSER | PTEWRITE;
		toppt[topoff] = p->mmue[i];
print("toppt[%d] = %lux\n", topoff, p->mmue[i]);
print("toppt[%d] = %lux\n", topoff, toppt[topoff]);
	}

	/*
	 *  fill in the bottom level page table
	 */
print("%lux[%d] was %lux\n", pt, BTMOFF(va), pt[BTMOFF(va)]);
	pt = (ulong*)(p->mmu[i]->pa|KZERO);
	pt[BTMOFF(va)] = pa | PTEUSER;
print("%lux[%d] = %lux\n", pt, BTMOFF(va), pa | PTEUSER);
print("%lux[%d] now %lux\n", pt, BTMOFF(va), pt[BTMOFF(va)]);

	/* flush cached mmu entries */
	putcr3(((ulong)toppt)&~KZERO);

M pc/trap.c => pc/trap.c +194 -4
@@ 5,6 5,10 @@
#include	"fns.h"
#include	"io.h"
#include	"ureg.h"
#include	"errno.h"

void	noted(Ureg*, ulong);
void	notify(Ureg*);

/*
 *  8259 interrupt controllers


@@ 155,25 159,211 @@ dumpregs(Ureg *ur)
		ur->si, ur->di, ur->bp, ur->ds);
}

void
dumpstack(void)
{
}

void
execpc(ulong entry)
{
	((Ureg*)UREGADDR)->pc = entry;
}

/*
 *  system calls
 */
#undef	CHDIR	/* BUG */
#include "/sys/src/libc/9syscall/sys.h"

typedef long Syscall(ulong*);
Syscall	sysr1, sysfork, sysexec, sysgetpid, syssleep, sysexits, sysdeath, syswait;
Syscall	sysopen, sysclose, sysread, syswrite, sysseek, syserrstr, sysaccess, sysstat, sysfstat;
Syscall sysdup, syschdir, sysforkpgrp, sysbind, sysmount, syspipe, syscreate;
Syscall	sysbrk_, sysremove, syswstat, sysfwstat, sysnotify, sysnoted, sysalarm;

Syscall *systab[]={
	sysr1,
	syserrstr,
	sysbind,
	syschdir,
	sysclose,
	sysdup,
	sysalarm,
	sysexec,
	sysexits,
	sysfork,
	sysforkpgrp,
	sysfstat,
	sysdeath,
	sysmount,
	sysopen,
	sysread,
	sysseek,
	syssleep,
	sysstat,
	syswait,
	syswrite,
	syspipe,
	syscreate,
	sysdeath,
	sysbrk_,
	sysremove,
	syswstat,
	sysfwstat,
	sysnotify,
	sysnoted,
	sysdeath,	/* sysfilsys */
};

long
syscall(Ureg *ur)
{
	ulong	ax;
	ulong	sp;
	long	ret;
	int	i;
	static int times;
ulong	*z;

	u->p->insyscall = 1;
	u->p->pc = ur->pc;
	if((ur->cs)&0xffff == KESEL)
		panic("recursive system call");
	u->p->insyscall = 0;

	/*
	 *  do something about floating point!!!
	 */

	panic("syscall");
	ax = ur->ax;
	sp = ur->usp;
	u->nerrlab = 0;
	ret = -1;
z = (ulong *)sp;
print("syscall %lux %lux %lux %lux\n", *z, *(z+1), *(z+2), *(z+3));
dumpregs(ur);
if(++times==3)
	panic("3rd time in syscall");
	if(!waserror()){
		if(ax >= sizeof systab/BY2WD){
			pprint("bad sys call number %d pc %lux\n", ax, ur->pc);
			postnote(u->p, 1, "sys: bad sys call", NDebug);
			error(Ebadarg);
		}
		if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-(1+MAXSYSARG)*BY2WD))
			validaddr(sp, (1+MAXSYSARG)*BY2WD, 0);
		ret = (*systab[ax])((ulong*)(sp+BY2WD));
		poperror();
	}
print("return from syscall\n");
	if(u->nerrlab){
		print("bad errstack [%d]: %d extra\n", ax, u->nerrlab);
		for(i = 0; i < NERR; i++)
			print("sp=%lux pc=%lux\n", u->errlab[i].sp, u->errlab[i].pc);
		panic("error stack");
	}
	u->p->insyscall = 0;
	if(ax == NOTED){
		noted(ur, *(ulong*)(sp+BY2WD));
		ret = -1;
	} else if(u->nnote){
		ur->ax = ret;
		notify(ur);
	}
	return ret;
}

/*
 *  Call user, if necessary, with note.
 *  Pass user the Ureg struct and the note on his stack.
 */
void
dumpstack(void)
notify(Ureg *ur)
{
	ulong sp;

	lock(&u->p->debug);
	if(u->nnote==0){
		unlock(&u->p->debug);
		return;
	}
	if(u->note[0].flag!=NUser && (u->notified || u->notify==0)){
		if(u->note[0].flag == NDebug)
			pprint("suicide: %s\n", u->note[0].msg);
    Die:
		unlock(&u->p->debug);
		pexit(u->note[0].msg, u->note[0].flag!=NDebug);
	}
	if(!u->notified){
		if(!u->notify)
			goto Die;
		u->svcs = ur->cs;
		u->svss = ur->ss;
		u->svflags = ur->flags;
		sp = ur->usp;
		sp -= sizeof(Ureg);
		u->ureg = (void*)sp;
		memmove((Ureg*)sp, ur, sizeof(Ureg));
		sp -= ERRLEN;
		memmove((char*)sp, u->note[0].msg, ERRLEN);
		sp -= 3*BY2WD;
		*(ulong*)(sp+2*BY2WD) = sp+3*BY2WD;	/* arg 2 is string */
		*(ulong*)(sp+1*BY2WD) = (ulong)u->ureg;	/* arg 1 is ureg* */
		*(ulong*)(sp+0*BY2WD) = 0;		/* arg 0 is pc */
		ur->usp = sp;
		ur->pc = (ulong)u->notify;
		u->notified = 1;
		u->nnote--;
		memmove(&u->lastnote, &u->note[0], sizeof(Note));
		memmove(&u->note[0], &u->note[1], u->nnote*sizeof(Note));
	}
	unlock(&u->p->debug);
}

/*
 *   Return user to state before notify()
 */
void
execpc(ulong entry)
noted(Ureg *ur, ulong arg0)
{
	((Ureg*)UREGADDR)->pc = entry;
	Ureg *nur;

	nur = u->ureg;
	validaddr(nur->pc, 1, 0);
	validaddr(nur->usp, BY2WD, 0);
	if(nur->cs!=u->svcs || nur->ss!=u->svss
	|| (nur->flags&0xff)!=(u->svflags&0xff)){
		pprint("bad noted ureg cs %ux ss %ux flags %ux\n", nur->cs, nur->ss,
			nur->flags);
		pexit("Suicide", 0);
	}
	lock(&u->p->debug);
	if(!u->notified){
		unlock(&u->p->debug);
		return;
	}
	u->notified = 0;
	nur->flags = (u->svflags&0xffffff00) | (ur->flags&0xff);
	memmove(ur, u->ureg, sizeof(Ureg));
	ur->ax = -1;	/* return error from the interrupted call */
	switch(arg0){
	case NCONT:
		splhi();
		unlock(&u->p->debug);
		rfnote(ur);
		break;
		/* never returns */

	default:
		pprint("unknown noted arg 0x%lux\n", arg0);
		u->lastnote.flag = NDebug;
		/* fall through */
		
	case NDFLT:
		if(u->lastnote.flag == NDebug)
			pprint("suicide: %s\n", u->lastnote.msg);
		unlock(&u->p->debug);
		pexit(u->lastnote.msg, u->lastnote.flag!=NDebug);
	}
}

M port/devcons.c => port/devcons.c +6 -1
@@ 159,6 159,9 @@ pprint(char *fmt, ...)
	Chan *c;
	int n;

	if(u->p->fgrp == 0)
		return 0;

	c = u->p->fgrp->fd[2];
	if(c==0 || (c->mode!=OWRITE && c->mode!=ORDWR))
		return 0;


@@ 418,6 421,9 @@ consopen(Chan *c, int omode)
			unlock(&lineq);
		}
		break;
	case Qswap:
		kickpager();		/* start a pager if not already started */
		break;
	}
	return devopen(c, omode, consdir, NCONS, devgen);
}


@@ 727,7 733,6 @@ conswrite(Chan *c, void *va, long n, ulong offset)
		fd = strtoul(buf, 0, 0);
		swc = fdtochan(fd, -1);
		setswapchan(swc);
		kickpager();
		return n;

	default:

M port/proc.c => port/proc.c +3 -2
@@ 634,15 634,16 @@ procdump(void)
	int i;
	Proc *p;

	print("process table:\n");
	print("process table %d:\n", conf.nproc);
	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\n",
				p->pid, p->text, p->pgrp->user, p->pc, 
				p->pid, p->text, p->pgrp ? p->pgrp->user : "pgrp=0", p->pc, 
				statename[p->state], p->time[0], p->time[1], p->r);
		}
	}
	print("procdump: ret\n");
}

void

M port/swap.c => port/swap.c +0 -1
@@ 124,7 124,6 @@ pager(void *junk)
			else {
				/* Emulate the old system if no swap channel */
				print("no physical memory\n");
				pprint("no physical memory\n");
				tsleep(&swapalloc.r, return0, 0, 1000);
				wakeup(&palloc.r);
			}