~kris/9p

9hist

11c9b9cca1406fa23455b4f42ad05c260b67b215 — David du Colombier 25 years ago 00226ba
Plan 9 from Bell Labs 2000-10-13
6 files changed, 61 insertions(+), 97 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 +2 -2
@@ 80,8 80,8 @@ enum

struct PMMU
{
	ulong	tlbpid;		/* current pid (0 if none) */
	Page	*l1[Nmeg];	/* this's process' level 1 entries */
	Page	*l1page[Nmeg];	/* this's process' level 1 entries */
	ulong	l1table[Nmeg];	/* ... */
};

/*

M bitsy/fns.h => bitsy/fns.h +1 -0
@@ 34,6 34,7 @@ void	procsetup(Proc*);
void	putdac(ulong);
void	putttb(ulong);
void	putpid(ulong);
void	qpanic(char *, ...);
void	reset(void);
void	rs232power(int);
Uart*	uartsetup(PhysUart*, void*, ulong, char*);

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

/* flush instruction cache */
TEXT flushicache(SB), $-4
	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x5), 0
	/* drain prefetch */
	MOVW	R0,R0					
	MOVW	R0,R0
	MOVW	R0,R0
	MOVW	R0,R0
	RET

/* flush data cache */
TEXT flushdcache(SB), $-4
	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x6), 0
	RET

/* flush i and d caches */
TEXT flushcache(SB), $-4
	/* write back any dirty data */


@@ 72,7 57,6 @@ _wbloop:
	MOVW	R0,R0
	MOVW	R0,R0
	MOVW	R0,R0
	RET

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


@@ 104,13 88,13 @@ TEXT putttb(SB), $-4
 */
TEXT mmuenable(SB), $-4
	MRC	CpMMU, 0, R0, C(CpControl), C(0x0)
	ORR	$(CpCmmuena|CpCdcache|CpCicache), R0
	ORR	$(CpCmmuena), R0
	MCR     CpMMU, 0, R0, C(CpControl), C(0x0)
	RET

TEXT mmudisable(SB), $-4
	MRC	CpMMU, 0, R0, C(CpControl), C(0x0)
	BIC	$(CpCmmuena|CpCdcache|CpCicache|CpCvivec), R0
	BIC	$(CpCmmuena|CpCvivec), R0
	MCR     CpMMU, 0, R0, C(CpControl), C(0x0)
	RET



@@ 387,13 371,3 @@ TEXT gotolabel(SB), $-4
	MOVW	4(R0), R14			/* pc */
	MOVW	$1, R0
	RET

TEXT mmuctlregr(SB), $-4
	MRC		CpMMU, 0, R0, C(CpControl), C(0)
	RET	

TEXT mmuctlregw(SB), $-4
	MCR		CpMMU, 0, R0, C(CpControl), C(0)
	MOVW		R0, R0
	MOVW		R0, R0
	RET	

M bitsy/main.c => bitsy/main.c +22 -0
@@ 64,6 64,28 @@ exit(int ispanic)
	(*f)();
}

/*
 *  quicker panic
 */
void
qpanic(char *fmt, ...)
{
	int n;
	va_list arg;
	char buf[PRINTSIZE];

	splhi();
	strcpy(buf, "panic: ");
	va_start(arg, fmt);
	n = doprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg) - buf;
	va_end(arg);
	buf[n] = '\n';
	serialputs(buf, n+1);

	exit(1);
}


static uchar *sp;

/*

M bitsy/mmu.c => bitsy/mmu.c +21 -55
@@ 67,8 67,14 @@ mmuinit(void)
	l1table = xspanalloc(16*1024, 16*1024, 0);
	memset(l1table, 0, 16*1024);

	/* map low mem */
	for(o = 0; o < 1*OneMeg; o += OneMeg)
		l1table[(0+o)>>20] = L1Section | L1KernelRW| L1Domain0 
			| L1Cached | L1Buffered
			| ((0+o)&L1SectBaseMask);

	/* map DRAM */
	for(o = 0; o < DRAMTOP; o += OneMeg)
	for(o = 0; o < 128*OneMeg; o += OneMeg)
		l1table[(DRAMZERO+o)>>20] = L1Section | L1KernelRW| L1Domain0 
			| L1Cached | L1Buffered
			| ((PHYSDRAM0+o)&L1SectBaseMask);


@@ 194,37 200,6 @@ mapspecial(ulong pa, int len)
}

/*
 *  maintain pids
 */
static Lock pidlock;

void
flushpids(void)
{
	memset(l1table, 0, BY2WD*nelem(m->pid2proc)*32);
	memset(m->pid2proc, 0, sizeof(m->pid2proc));
	flushcache();
	flushmmu();
}

int
newtlbpid(Proc *p)
{
	int i;

	ilock(&pidlock);
	i = ++(m->lastpid);
	if(i >= nelem(m->pid2proc)){
		flushpids();
		i = m->lastpid = 0;
	}
	m->pid2proc[i] = p;
	p->tlbpid = i+1;
	iunlock(&pidlock);
	return p->tlbpid;
}

/*
 *  table to map fault.c bits to physical bits
 */
static ulong mmubits[16] =


@@ 246,34 221,30 @@ static ulong mmubits[16] =
void
putmmu(ulong va, ulong pa, Page*)
{
	ulong pva;
	Page *p;
	ulong *t;

iprint("putmmu(0x%.8lux, 0x%.8lux)\n", va, pa);
	/* if user memory, add pid value */
	if((va & 0xfe000000) == 0)
		pva = va | (up->tlbpid << 25);
	else
		pva = va;

	/* always point L1 entry to L2 page, can't hurt */
	p = up->l1[va>>20];
	p = up->l1page[va>>20];
	if(p == nil){
		p = auxpage();
		if(p == nil)
			pexit("out of memory", 1);
		p->va = VA(kmap(p));
		up->l1[va>>20] = p;
		up->l1page[va>>20] = p;
	}
	l1table[pva>>20] = L1PageTable | L1Domain0 | (p->pa & L1PTBaseMask);
	l1table[va>>20] = L1PageTable | L1Domain0 | (p->pa & L1PTBaseMask);
iprint("%lux[%lux] = %lux\n", l1table, va>>20, l1table[va>>20]);
	up->l1table[va>>20] = l1table[va>>20];
	t = (ulong*)p->va;

	/* set L2 entry */
	t[(pva & (OneMeg-1))>>PGSHIFT] = mmubits[pa & (PTEKERNEL|PTEVALID|PTEUNCACHED|PTEWRITE)]
	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]);

	wbflush();
	flushmmu();
}

/*


@@ 285,26 256,21 @@ mmurelease(Proc* p)
	Page *pg;
	int i;

	for(i = 0; i < nelem(p->l1); i++){
		pg = p->l1[i];
	for(i = 0; i < nelem(p->l1page); i++){
		pg = p->l1page[i];
		if(pg == nil)
			continue;
		if(--pg->ref)
			panic("mmurelease: pg->ref %d\n", pg->ref);
		pagechainhead(pg);
		p->l1[i] = nil;
		p->l1page[i] = nil;
	}
}

void
mmuswitch(Proc* p)
{
	/* set pid */
	if(p->tlbpid <= 0)
		p->tlbpid = newtlbpid(p);
iprint("using tlbpid %d\n", p->tlbpid);
	putpid(p->tlbpid<<25);

	/* set domain register to this + the kernel's domains */
	putdac((Dclient<<(2*p->tlbpid)) | Dclient);
//	flushcache();	/* drain and flush the cache */
//	flushmmu();
//	memmove(l1table, p->l1table, sizeof(p->l1table));
}

M bitsy/trap.c => bitsy/trap.c +13 -12
@@ 87,7 87,7 @@ trapdump(char *tag)
void
dumpregs(Ureg *ur)
{
	iprint("r0  0x%.8lux r1  0x%.8lux r3  0x%.8lux r3  0x%.8lux\n",
	iprint("r0  0x%.8lux r1  0x%.8lux r2  0x%.8lux r3  0x%.8lux\n",
		ur->r0, ur->r1, ur->r2, ur->r3);
	iprint("r4  0x%.8lux r5  0x%.8lux r6  0x%.8lux r7  0x%.8lux\n",
		ur->r4, ur->r5, ur->r6, ur->r7);


@@ 136,7 136,7 @@ iprint("fault returns %d\n", n);
	if(n < 0){
		if(!user){
			dumpregs(ureg);
			panic("fault: 0x%lux\n", va);
			qpanic("fault: 0x%lux\n", va);
		}
		sprint(buf, "sys: trap: fault %s va=0x%lux",
			read? "read" : "write", va);


@@ 160,18 160,19 @@ trap(Ureg *ureg)
	user = (ureg->psr & PsrMask) == PsrMusr;
	switch(ureg->type){
	default:
		panic("unknown trap");
		qpanic("unknown trap");
		break;
	case PsrMabt:	/* prefetch fault */
		iprint("prefetch abort at %lux\n", ureg->pc-4);
		iprint("prefetch abort at 0x%lux\n", ureg->pc-4);
		faultarm(ureg, ureg->pc - 4, 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());
		switch(getfsr() & 0xf){
		case 0x0:
			panic("vector exception at %lux\n", pc);
			qpanic("vector exception at %lux\n", pc);
			break;
		case 0x1:
		case 0x3:


@@ 180,10 181,10 @@ trap(Ureg *ureg)
					pc, va);
				postnote(up, 1, buf, NDebug);
			} else
				panic("kernel alignment: pc 0x%lux va 0x%lux", pc, va);
				qpanic("kernel alignment: pc 0x%lux va 0x%lux", pc, va);
			break;
		case 0x2:
			panic("terminal exception at %lux\n", pc);
			qpanic("terminal exception at %lux\n", pc);
			break;
		case 0x4:
		case 0x6:


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


@@ 205,7 206,7 @@ trap(Ureg *ureg)
				sprint(buf, "sys: access violation: pc 0x%lux va 0x%lux\n", pc, va);
				postnote(up, 1, buf, NDebug);
			} else
				panic("kernel access violation: pc 0x%lux va 0x%lux\n", pc, va);
				qpanic("kernel access violation: pc 0x%lux va 0x%lux\n", pc, va);
			break;
		case 0xd:
		case 0xf:


@@ 215,7 216,7 @@ trap(Ureg *ureg)
		}
		break;
	case PsrMund:	/* undefined instruction */
		panic("undefined instruction");
		qpanic("undefined instruction");
		break;
	case PsrMirq:	/* device interrupt */
		for(i = 0; i < 32; i++)


@@ 249,7 250,7 @@ syscall(Ureg* ureg)
	int	i, scallnr;

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

	m->syscall++;
	up->insyscall = 1;


@@ 285,7 286,7 @@ syscall(Ureg* ureg)
		for(i = 0; i < NERR; i++)
			print("sp=%lux pc=%lux\n",
				up->errlab[i].sp, up->errlab[i].pc);
		panic("error stack");
		qpanic("error stack");
	}

	up->insyscall = 0;