~kris/9p

9hist

ad0410379b8f06c1fa5e8ea7d6d36929fd0b780d — David du Colombier 25 years ago 11c9b9c
Plan 9 from Bell Labs 2000-10-14
6 files changed, 98 insertions(+), 37 deletions(-)

M bitsy/dat.h
M bitsy/fns.h
M bitsy/l.s
M bitsy/main.c
M bitsy/mmu.c
M bitsy/trap.c
M bitsy/dat.h => bitsy/dat.h +1 -14
@@ 99,14 99,9 @@ struct Mach
	int	machno;			/* physical id of processor */
	ulong	splpc;			/* pc of last caller to splhi */

	ulong*	pdb;			/* page directory base for this processor (va) */

	Proc*	proc;			/* current process on this processor */
	Proc*	externup;		/* extern register Proc *up */

	Page*	pdbpool;
	int	pdbcnt;

	ulong	ticks;			/* of the clock since boot time */
	Label	sched;			/* scheduler wakeup */
	Lock	alarmlock;		/* access to alarm list */


@@ 172,15 167,7 @@ struct
	int	ispanic;		/* shutdown in response to a panic */
}active;

/*
 *  Each processor sees its own Mach structure at address MACHADDR.
 *  However, the Mach structures must also be available via the per-processor
 *  MMU information array machp, mainly for disambiguation and access to
 *  the clock which is only maintained by the bootstrap processor (0).
 */
Mach* machp[MAXMACH];
	
#define	MACHP(n)	(machp[n])
#define	MACHP(n)	((Mach*)MACHADDR)

extern Mach	*m;
#define up	(((Mach*)MACHADDR)->externup)

M bitsy/fns.h => bitsy/fns.h +2 -0
@@ 2,6 2,8 @@

int	cistrcmp(char*, char*);
int	cistrncmp(char*, char*, int);
void	cleancache(void);
void	cleanaddr(ulong);
#define	clearmmucache()				/* x86 doesn't have one */
void	clockinit(void);
#define	coherence()

M bitsy/l.s => bitsy/l.s +28 -5
@@ 39,8 39,8 @@ TEXT flushmmu(SB), $-4
	MCR	CpMMU, 0, R0, C(CpTLBFlush), C(0x7)
	RET

/* flush i and d caches */
TEXT flushcache(SB), $-4
/* clean and flush i and d caches */
TEXT cleancache(SB), $-4
	/* write back any dirty data */
	MOVW	$0xe0000000,R0
	ADD	$(8*1024),R0,R1


@@ 57,6 57,24 @@ _wbloop:
	MOVW	R0,R0
	MOVW	R0,R0
	MOVW	R0,R0
	RET

/* clean a single virtual address */
TEXT cleanaddr(SB), $-4
	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 1
	RET

/* flush i and d caches */
TEXT flushcache(SB), $-4
	/* flush cache contents */
	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x7), 0

	/* drain prefetch */
	MOVW	R0,R0						
	MOVW	R0,R0
	MOVW	R0,R0
	MOVW	R0,R0
	RET

/* drain write buffer */
TEXT wbflush(SB), $-4


@@ 78,6 96,11 @@ TEXT getfar(SB), $-4
	MRC	CpMMU, 0, R0, C(CpFAR), C(0x0)
	RET

/* return fault address */
TEXT putfar(SB), $-4
	MRC	CpMMU, 0, R0, C(CpFAR), C(0x0)
	RET

/* set the translation table base */
TEXT putttb(SB), $-4
	MCR	CpMMU, 0, R0, C(CpTTB), C(0x0)


@@ 167,11 190,11 @@ TEXT _vrst(SB), $-4
	BL	reset(SB)

TEXT _vsvc(SB), $-4			/* SWI */
	MOVW.DB.W R14, (R13)		/* ureg->pc = interupted PC */
	MOVW.W	R14, -4(R13)		/* ureg->pc = interupted PC */
	MOVW	SPSR, R14		/* ureg->psr = SPSR */
	MOVW.DB.W R14, (R13)		/* ... */
	MOVW.W	R14, -4(R13)		/* ... */
	MOVW	$PsrMsvc, R14		/* ureg->type = PsrMsvc */
	MOVW.DB.W R14, (R13)		/* ... */
	MOVW.W	R14, -4(R13)		/* ... */
	MOVM.DB.W.S [R0-R14], (R13)	/* save user level registers, at end r13 points to ureg */
	MOVW	$setR12(SB), R12	/* Make sure we've got the kernel's SB loaded */
	MOVW	R13, R0			/* first arg is pointer to ureg */

M bitsy/main.c => bitsy/main.c +9 -1
@@ 18,12 18,15 @@ int  noprint;
void
main(void)
{
	cleancache();

	/* zero out bss */
	memset(edata, 0, end-edata);

	/* point to Mach structure */
	m = (Mach*)MACHADDR;
	memset(m, 0, sizeof(Mach));
	m->ticks = 1;

	rs232power(1);
	iprint("bitsy kernel\n");


@@ 193,6 196,9 @@ userinit(void)
	KMap *k;
	Page *pg;

	/* no processes yet */
	up = nil;

	p = newproc();
	p->pgrp = newpgrp();
	p->egrp = smalloc(sizeof(Egrp));


@@ 226,7 232,6 @@ userinit(void)
	 * Text
	 */
	s = newseg(SG_TEXT, UTZERO, 1);
	s->flushme++;
	p->seg[TSEG] = s;
	pg = newpage(1, 0, UTZERO);
	memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));


@@ 234,6 239,9 @@ userinit(void)
	k = kmap(s->map[0]->pages[0]);
	memmove((ulong*)VA(k), initcode, sizeof initcode);
	kunmap(k);
	cleancache();
	wbflush();
iprint("userinit %lux[0x20] = %lux\n", VA(k), *((ulong*)(VA(k)+0x20)));

	ready(p);
}

M bitsy/mmu.c => bitsy/mmu.c +32 -4
@@ 233,8 233,10 @@ iprint("putmmu(0x%.8lux, 0x%.8lux)\n", va, pa);
			pexit("out of memory", 1);
		p->va = VA(kmap(p));
		up->l1page[va>>20] = p;
		memset((uchar*)(p->va), 0, BY2PG);
	}
	l1table[va>>20] = L1PageTable | L1Domain0 | (p->pa & L1PTBaseMask);
	cleanaddr((ulong)&l1table[va>>20]);
iprint("%lux[%lux] = %lux\n", l1table, va>>20, l1table[va>>20]);
	up->l1table[va>>20] = l1table[va>>20];
	t = (ulong*)p->va;


@@ 243,8 245,9 @@ iprint("%lux[%lux] = %lux\n", l1table, va>>20, l1table[va>>20]);
	t[(va & (OneMeg-1))>>PGSHIFT] = mmubits[pa & (PTEKERNEL|PTEVALID|PTEUNCACHED|PTEWRITE)]
		| (pa & ~(PTEKERNEL|PTEVALID|PTEUNCACHED|PTEWRITE));
iprint("%lux[%lux] = %lux\n", (ulong)t, (va & (OneMeg-1))>>PGSHIFT, t[(va & (OneMeg-1))>>PGSHIFT]);
	cleanaddr((ulong)&t[(va & (OneMeg-1))>>PGSHIFT]);

	flushmmu();
	wbflush();
}

/*


@@ 270,7 273,32 @@ mmurelease(Proc* p)
void
mmuswitch(Proc* p)
{
//	flushcache();	/* drain and flush the cache */
//	flushmmu();
//	memmove(l1table, p->l1table, sizeof(p->l1table));
iprint("switching to proc %d\n", p->pid);
	memmove(l1table, p->l1table, sizeof(p->l1table));
	cleanaddr((ulong)l1table);
	wbflush();
}

void
peekmmu(ulong va)
{
	ulong e;

	e = l1table[va>>20];
	switch(e & L1TypeMask){
	default:
		iprint("l1: %lux invalid\n", e);
		break;
	case L1PageTable:
		iprint("l1: %lux pt\n", e);
		va &= OneMeg-1;
		va >>= PGSHIFT;
		e &= L1PTBaseMask;
		e = ((ulong*)e)[va];
		iprint("l2: %lux\n", e);
		break;
	case L1Section:
		iprint("l1: %lux section\n", e);
		break;
	}
}

M bitsy/trap.c => bitsy/trap.c +26 -13
@@ 131,6 131,7 @@ faultarm(Ureg *ureg, ulong va, int user, int read)

	insyscall = up->insyscall;
	up->insyscall = 1;
peekmmu(va);
	n = fault(va, read);
iprint("fault returns %d\n", n);
	if(n < 0){


@@ 154,37 155,46 @@ trap(Ureg *ureg)
	int i;
	Vctl *v;
	int user;
	ulong pc, va;
	ulong va;
	char buf[ERRLEN];

	user = (ureg->psr & PsrMask) == PsrMusr;

	/*
	 * All interrupts/exceptions should be resumed at ureg->pc-4,
	 * except for Data Abort which resumes at ureg->pc-8.
	 */
	if(ureg->type == (PsrMabt+1))
		ureg->pc -= 8;
	else
		ureg->pc -= 4;

	switch(ureg->type){
	default:
		qpanic("unknown trap");
		break;
	case PsrMabt:	/* prefetch fault */
		iprint("prefetch abort at 0x%lux\n", ureg->pc-4);
		faultarm(ureg, ureg->pc - 4, user, 1);
		iprint("prefetch abort at 0x%lux\n", ureg->pc);
		faultarm(ureg, ureg->pc, user, 1);
		break;
	case PsrMabt+1:	/* data fault */
		pc = ureg->pc - 8;
		va = getfar();
		iprint("data fault pc 0x%lux va 0x%lux fsr 0x%lux\n", pc, va, getfsr());
		iprint("data fault pc 0x%lux va 0x%lux fsr 0x%lux\n", ureg->pc, va, getfsr());
		switch(getfsr() & 0xf){
		case 0x0:
			qpanic("vector exception at %lux\n", pc);
			qpanic("vector exception at %lux\n", ureg->pc);
			break;
		case 0x1:
		case 0x3:
			if(user){
				snprint(buf, sizeof(buf), "sys: alignment: pc 0x%lux va 0x%lux\n",
					pc, va);
					ureg->pc, va);
				postnote(up, 1, buf, NDebug);
			} else
				qpanic("kernel alignment: pc 0x%lux va 0x%lux", pc, va);
				qpanic("kernel alignment: pc 0x%lux va 0x%lux", ureg->pc, va);
			break;
		case 0x2:
			qpanic("terminal exception at %lux\n", pc);
			qpanic("terminal exception at %lux\n", ureg->pc);
			break;
		case 0x4:
		case 0x6:


@@ 192,7 202,7 @@ trap(Ureg *ureg)
		case 0xa:
		case 0xc:
		case 0xe:
			qpanic("external abort at %lux\n", pc);
			qpanic("external abort at %lux\n", ureg->pc);
			break;
		case 0x5:
		case 0x7:


@@ 203,10 213,10 @@ trap(Ureg *ureg)
		case 0xb:
			/* domain fault, accessing something we shouldn't */
			if(user){
				sprint(buf, "sys: access violation: pc 0x%lux va 0x%lux\n", pc, va);
				sprint(buf, "sys: access violation: pc 0x%lux va 0x%lux\n", ureg->pc, va);
				postnote(up, 1, buf, NDebug);
			} else
				qpanic("kernel access violation: pc 0x%lux va 0x%lux\n", pc, va);
				qpanic("kernel access violation: pc 0x%lux va 0x%lux\n", ureg->pc, va);
			break;
		case 0xd:
		case 0xf:


@@ 221,7 231,6 @@ trap(Ureg *ureg)
	case PsrMirq:	/* device interrupt */
		for(i = 0; i < 32; i++)
			if((1<<i) & intrregs->icip){
				iprint("irq: %d\n", i);
				for(v = vctl[i]; v != nil; v = v->next)
					v->f(ureg, v->a);
			}


@@ 249,6 258,8 @@ syscall(Ureg* ureg)
	long	ret;
	int	i, scallnr;

iprint("syscall in\n");
dumpregs(ureg);
	if((ureg->psr & PsrMask) != PsrMusr)
		qpanic("syscall: cs 0x%4.4uX\n", ureg->psr);



@@ 278,7 289,9 @@ syscall(Ureg* ureg)
		up->s = *((Sargs*)(sp+BY2WD));
		up->psstate = sysctab[scallnr];

iprint("before syscall\n");
		ret = systab[scallnr](up->s.args);
iprint("syscall retuns %d\n", ret);
		poperror();
	}
	if(up->nerrlab){