~kris/9p

9hist

b73e35c1decbee5d23ff469df61d6a190cd4545f — David du Colombier 31 years ago efd425b
Plan 9 from Bell Labs 1995-01-15
8 files changed, 73 insertions(+), 21 deletions(-)

M carrera/dat.h
M carrera/mem.h
M carrera/trap.c
M pc/devastar.c
M pc/trap.c
M port/lib.h
M port/proc.c
M port/sysproc.c
M carrera/dat.h => carrera/dat.h +1 -1
@@ 79,7 79,7 @@ struct PMMU
 */
struct Notsave
{
	ulong	svstatus;
	ulong	UNUSED;
};

#include "../port/portdat.h"

M carrera/mem.h => carrera/mem.h +4 -1
@@ 66,7 66,10 @@
#define ERL		0x00000004
#define KSUPER		0x00000008
#define KUSER		0x00000010
#define KSU		0x00000018
#define UX		0x00000020
#define SX		0x00000040
#define KX		0x00000080
#define INTMASK		0x0000ff00
#define INTR0		0x00000100
#define INTR1		0x00000200


@@ 93,7 96,7 @@
 * Magic registers
 */
#define	USER		24		/* R24 is up-> */
#define	MACH		25		/* R25 is m-> */
#define	MACH	25		/* R25 is m-> */

/*
 * Fundamental addresses

M carrera/trap.c => carrera/trap.c +59 -11
@@ 7,7 7,7 @@
#include	"io.h"
#include	"../port/error.h"

void	noted(Ureg**, ulong);
void	noted(Ureg*, Ureg**, ulong);
void	rfnote(Ureg**);
void	kernfault(Ureg*, int);



@@ 527,20 527,20 @@ notify(Ureg *ur)
		qunlock(&up->debug);
		pexit(n->msg, n->flag!=NDebug);
	}
	up->svstatus = ur->status;
	sp = ur->usp & ~(BY2V-1);
	sp -= sizeof(Ureg);

	if(!okaddr((ulong)up->notify, BY2WD, 0) ||
	   !okaddr(sp-ERRLEN-3*BY2WD, sizeof(Ureg)+ERRLEN-3*BY2WD, 1)) {
	   !okaddr(sp-ERRLEN-4*BY2WD, sizeof(Ureg)+ERRLEN-4*BY2WD, 1)) {
		pprint("suicide: bad address or sp in notify\n");
		qunlock(&up->debug);
		pexit("Suicide", 0);
	}

	up->ureg = (void*)sp;
	memmove((Ureg*)sp, ur, sizeof(Ureg));
	sp -= ERRLEN;
	*(Ureg**)(sp-BY2WD) = up->ureg;	/* word under Ureg is old up->ureg */
	up->ureg = (void*)sp;
	sp -= BY2WD+ERRLEN;
	memmove((char*)sp, up->note[0].msg, ERRLEN);
	sp -= 3*BY2WD;
	*(ulong*)(sp+2*BY2WD) = sp+3*BY2WD;	/* arg 2 is string */


@@ 563,15 563,31 @@ notify(Ureg *ur)
}

/*
 * Check that status is OK to return from note.
 */
int
validstatus(ulong kstatus, ulong ustatus)
{
	if((kstatus & (INTMASK|KX|SX|UX)) != (ustatus & (INTMASK|KX|SX|UX)))
		return 0;
	if((ustatus&(KSU|ERL|EXL|IE)) != (KUSER|EXL|IE))
		return 0;
	if(ustatus & (0xFFFF0000&~CU1))	/* no CU3, CU2, CU0, RP, FR, RE, DS */
		return 0;
	return 1;
}

/*
 * Return user to state before notify()
 */
void
noted(Ureg **urp, ulong arg0)
noted(Ureg *kur, Ureg **urp, ulong arg0)
{
	Ureg *nur;
	ulong oureg, sp;

	qlock(&up->debug);
	if(!up->notified) {
	if(arg0!=NRSTR && !up->notified) {
		qunlock(&up->debug);
		pprint("call to noted() when not notified\n");
		pexit("Suicide", 0);


@@ 579,22 595,54 @@ noted(Ureg **urp, ulong arg0)
	up->notified = 0;

	nur = up->ureg;
	if(nur->status!=up->svstatus) {
	if(!validstatus(kur->status, nur->status)) {
		qunlock(&up->debug);
		pprint("bad noted ureg status %lux\n", nur->status);
		pexit("Suicide", 0);
	}

	oureg = (ulong)up->ureg;
	if(oureg){
		if(oureg>=USTKTOP || oureg<USTKTOP-USTKSIZE
		|| (oureg & (BY2V-1))
		|| !okaddr((ulong)oureg-BY2WD, BY2WD+sizeof(Ureg), 0)){
			pprint("suicide: bad up->ureg in noted\n");
			qunlock(&up->debug);
			pexit("Suicide", 0);
		}
	}

	memmove(*urp, up->ureg, sizeof(Ureg));
	switch(arg0) {
	case NCONT:
		if(!okaddr(nur->pc, 1, 0) || !okaddr(nur->usp, BY2WD, 0)){
	case NRSTR:
		if(!okaddr(nur->pc, BY2WD, 0) || !okaddr(nur->usp, BY2WD, 0)){
			pprint("suicide: trap in noted\n");
			qunlock(&up->debug);
			pexit("Suicide", 0);
		}
		up->ureg = (Ureg*)(*(ulong*)(oureg-BY2WD));
		qunlock(&up->debug);
		splhi();
		rfnote(urp);
		break;

	case NSAVE:
		if(!okaddr(nur->pc, BY2WD, 0) || !okaddr(nur->usp, BY2WD, 0)){
			pprint("suicide: trap in noted\n");
			qunlock(&up->debug);
			pexit("Suicide", 0);
		}
		qunlock(&up->debug);
		sp = oureg-4*BY2WD-ERRLEN;
		splhi();
		(*urp)->sp = sp;
		((ulong*)sp)[1] = (ulong)up->ureg;	/* arg 1 0(FP) is ureg* */
		((ulong*)sp)[0] = 0;			/* arg 0 is pc */
		(*urp)->r1 = oureg;		/* arg 1 is ureg* */
		(*urp)->hr1 = 0;
		if(oureg < 0)
			(*urp)->hr1 = ~0;
		rfnote(urp);
		break;



@@ 672,8 720,8 @@ error:
	up->nerrlab = 0;
	up->psstate = 0;
	up->insyscall = 0;
	if(up->scallnr == NOTED)			/* ugly hack */
		noted(&aur, *(ulong*)(sp+BY2WD));	/* doesn't return */
	if(up->scallnr == NOTED)		/* ugly hack */
		noted(ur, &aur, *(ulong*)(sp+BY2WD));	/* doesn't return */

	splhi();
	if(up->scallnr!=RFORK && (up->procctl || up->nnote)){

M pc/devastar.c => pc/devastar.c +1 -1
@@ 418,7 418,7 @@ astarreset(void)
		a->mem = getisa(a->mem, Pagesize, Pagesize);
		if(a->mem == 0)
			panic("astarreset: %lux", a->mem);
		a->mem & ~KZERO;
		a->mem &= ~KZERO;

		if(astarsetup(a) < 0){
			xfree(a);

M pc/trap.c => pc/trap.c +1 -0
@@ 472,6 472,7 @@ syscall(Ureg *ur, void *arg)

	if(up->scallnr!=RFORK && (up->procctl || up->nnote))
		notify(ur);

}

/*

M port/lib.h => port/lib.h +2 -0
@@ 93,6 93,8 @@ extern	char	end[];

#define	NCONT	0	/* continue after note */
#define	NDFLT	1	/* terminate after note */
#define	NSAVE	2	/* clear note but hold state */
#define	NRSTR	3	/* restore saved state */

typedef struct Qid	Qid;
typedef struct Dir	Dir;

M port/proc.c => port/proc.c +1 -0
@@ 313,6 313,7 @@ newproc(void)
	p->mp = 0;
	p->movetime = 0;
	p->wired = 0;
	p->ureg = 0;
	memset(p->seg, 0, sizeof p->seg);
	p->pid = incref(&pidalloc);
	p->noteid = incref(&noteidalloc);

M port/sysproc.c => port/sysproc.c +4 -7
@@ 92,7 92,7 @@ sysrfork(ulong *arg)
	p->notified = 0;
	p->lastnote = up->lastnote;
	p->notify = up->notify;
	p->ureg = 0;
	p->ureg = up->ureg;
	p->dbgreg = 0;

	/* Make a new set of memory segments */


@@ 126,10 126,8 @@ sysrfork(ulong *arg)
		incref(p->pgrp);
	}

	if(flag & RFREND) {
		closergrp(up->rgrp);
		up->rgrp = newrgrp();
	}
	if(flag & RFREND)
		p->rgrp = newrgrp();
	else {
		incref(up->rgrp);
		p->rgrp = up->rgrp;


@@ 549,8 547,7 @@ sysnotify(ulong *arg)
long
sysnoted(ulong *arg)
{
	USED(arg);
	if(up->notified == 0)
	if(arg[0]!=NRSTR && !up->notified)
		error(Egreg);
	return 0;
}