From 2c3633d2e20d276322394326adff8f5d4a0466ec Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 29 Sep 2000 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2000-09-29 --- alphapc/main.c | 3 ++- bitsy/dat.h | 9 ++++--- bitsy/fns.h | 7 ++++-- bitsy/l.s | 28 +++++++++++++++++---- bitsy/main.c | 3 +++ bitsy/mem.h | 3 ++- bitsy/mmu.c | 66 +++++++++++++++++++++++++++++++------------------- bitsy/trap.c | 23 +++++++++++++++++- carrera/l.s | 2 ++ pc/l.s | 6 +++-- 10 files changed, 109 insertions(+), 41 deletions(-) diff --git a/alphapc/main.c b/alphapc/main.c index 6799c1700045339bb2c0a26d32a8300723f5b688..7295870555d155c0dadb1815e748de5388e8d4df 100644 --- a/alphapc/main.c +++ b/alphapc/main.c @@ -15,7 +15,8 @@ Hwrpb *hwrpb; Bootconf *bootconf; Conf conf; FPsave initfp; -uvlong initfpcr = 0x2800800000000000LL; + /* setfcr(FPPDBL|FPRNR|FPINVAL|FPZDIV|FPOVFL) */ +uvlong initfpcr = (1LL<62)|(1LL<61)|(1LL<60)|(2LL<<58)|(1LL<48); char bootargs[BOOTARGSLEN]; char *confname[MAXCONF]; diff --git a/bitsy/dat.h b/bitsy/dat.h index 6b49b222c34292be481904b5d2e37d30cd36c43b..9699990855754788b1d7ec0dbd4c49b126786443 100644 --- a/bitsy/dat.h +++ b/bitsy/dat.h @@ -167,10 +167,10 @@ struct }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). + * 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]; @@ -183,3 +183,4 @@ enum { OneMeg= 1024*1024, }; + diff --git a/bitsy/fns.h b/bitsy/fns.h index cc95eb0481e6cc0566d9a2fdc578c7daa4128a91..0d1b0267ad8959f87303f69d27cab9803f1b5de2 100644 --- a/bitsy/fns.h +++ b/bitsy/fns.h @@ -5,17 +5,21 @@ int cistrncmp(char*, char*, int); #define clearmmucache() /* x86 doesn't have one */ void clockintr(Ureg*, void*); void clockintrsched(void); -void (*coherence)(void); +#define coherence() void delay(int); void evenaddr(ulong); +void exceptionvectors(void); ulong getfar(void); ulong getfsr(void); #define getpgcolor(a) 0 void idle(void); #define idlehands() /* nothing to do in the runproc */ int iprint(char*, ...); +ulong* mapspecial(ulong, int); void meminit(void); void mmuinit(void); +void mmuenable(void); +void mmudisable(void); #define procrestore(p) void procsave(Proc*); void procsetup(Proc*); @@ -26,7 +30,6 @@ void screeninit(void); int screenprint(char*, ...); /* debugging */ void (*screenputs)(char*, int); void touser(void*); -void trapenable(int, void (*)(Ureg*, void*), void*, char*); void trapinit(void); int tas(void*); void wbflush(void); diff --git a/bitsy/l.s b/bitsy/l.s index 9bb7f507dce63dbca664a1b277bbb38c6a7927b3..d05c03906fde423e07f2ce3ad845aa0f0755076c 100644 --- a/bitsy/l.s +++ b/bitsy/l.s @@ -65,13 +65,13 @@ TEXT flushcache(SB), $-4 RET /* drain write buffer */ -TEXT drainwb(SB), $-4 +TEXT wbflush(SB), $-4 MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x0), 4 RET /* return cpu id */ TEXT getcpuid(SB), $-4 - MRC CpMMU, 0, R0, C(CpControl), C(0x0) + MRC CpMMU, 0, R0, C(CpCPUID), C(0x0) RET /* return fault status */ @@ -87,14 +87,32 @@ TEXT getfar(SB), $-4 /* set the translation table base */ TEXT putttb(SB), $-4 MCR CpMMU, 0, R0, C(CpTTB), C(0x0) + RET + +/* + * enable mmu, i and d caches, and exception vectors at 0xffff0000 + */ +TEXT mmuenable(SB), $-4 + MRC CpMMU, 0, R0, C(CpControl), C(0x0) + ORR $(CpCmmuena|CpCdcache|CpCicache|CpCvivec), 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 + MCR CpMMU, 0, R0, C(CpControl), C(0x0) + RET /* set the translation table base */ TEXT putdac(SB), $-4 MCR CpMMU, 0, R0, C(CpDAC), C(0x0) + RET -/* set the translation table base */ +/* set address translation pid */ TEXT putpid(SB), $-4 MCR CpMMU, 0, R0, C(CpPID), C(0x0) + RET /* * set the stack value for the mode passed in R0 @@ -116,7 +134,7 @@ TEXT setr13(SB), $-4 /* * exception vectors, copied by trapinit() to somewhere useful */ -TEXT vectors(SB), $-4 +TEXT exceptionvectors(SB), $-4 MOVW 0x18(R15), R15 /* reset */ MOVW 0x18(R15), R15 /* undefined */ MOVW 0x18(R15), R15 /* SWI */ @@ -206,7 +224,7 @@ _vexcep: MOVW $setR12(SB), R12 /* Make sure we've got the kernel's SB loaded */ MOVW R13, R0 /* first arg is pointer to ureg */ SUB $8, R13 /* space for argument+link */ - BL exception(SB) + BL trap(SB) _vrfe: ADD $(8+4*15), R13 /* make r13 point to ureg->type */ diff --git a/bitsy/main.c b/bitsy/main.c index 2b15de499c27daabefbc529fac590e28a34867a0..59e0035db5d3d6d0bbc8a5af013021600dcf9ddb 100644 --- a/bitsy/main.c +++ b/bitsy/main.c @@ -24,6 +24,8 @@ main(void) iprint("after xinit\n"); mmuinit(); iprint("after mmuinit\n"); + trapinit(); + iprint("after trapinit\n"); delay(100000); exit(1); } @@ -39,6 +41,7 @@ exit(int ispanic) USED(ispanic); delay(1000); + mmudisable(); f = nil; (*f)(); } diff --git a/bitsy/mem.h b/bitsy/mem.h index 3f4a835b219ab8fb2530d2c786a0dfa8247b40a2..9f6158297476dea12856c357b83efa9a05b36884 100644 --- a/bitsy/mem.h +++ b/bitsy/mem.h @@ -53,6 +53,7 @@ #define TSTKTOP (USTKTOP-USTKSIZE) /* end of new stack in sysexec */ #define TSTKSIZ 100 #define MACHADDR (KZERO+0x00001000) +#define EVECTORS 0xFFFF0000 /* base of exception vectors (also mapped to KZERO) */ #define KSTACK (16*1024) /* Size of kernel stack */ @@ -134,7 +135,7 @@ /* * CpControl */ -#define CpCmmu 0x00000001 /* M: MMU enable */ +#define CpCmmuena 0x00000001 /* M: MMU enable */ #define CpCalign 0x00000002 /* A: alignment fault enable */ #define CpCdcache 0x00000004 /* C: data cache on */ #define CpCwb 0x00000008 /* W: write buffer turned on */ diff --git a/bitsy/mmu.c b/bitsy/mmu.c index 9d794570ed1ae54de51f4214b328e29daa1496ba..677deb4e0bcf9c9c148ec2fb6ab355ea24b296a6 100644 --- a/bitsy/mmu.c +++ b/bitsy/mmu.c @@ -62,6 +62,7 @@ void mmuinit(void) { ulong a, e; + ulong *t; /* get a prototype level 1 page */ l1table = xspanalloc(BY2PG, 16*1024, 0); @@ -70,33 +71,39 @@ mmuinit(void) /* direct map DRAM */ e = conf.base1 + BY2PG*conf.npage1; for(a = PHYSDRAM0; a < e; a += OneMeg) - l1table[a>>20] = L1Section | L1KernelRW | - L1Cached | L1Buffered | (a&L1SectBaseMask); - - /* direct map devs */ - for(a = REGZERO; a < REGTOP; a += OneMeg) - l1table[a>>20] = L1Section | L1KernelRW | (a&L1SectBaseMask); + l1table[a>>20] = L1Section | L1KernelRW | (a&L1SectBaseMask) | + L1Cached | L1Buffered; /* direct map zeros area */ for(a = PHYSNULL0; a < PHYSNULL0 + 128 * OneMeg; a += OneMeg) - l1table[a>>20] = L1Section | L1KernelRW | - L1Cached | L1Buffered | (a&L1SectBaseMask); + l1table[a>>20] = L1Section | L1KernelRW | (a&L1SectBaseMask); /* direct map flash */ for(a = PHYSFLASH0; a < PHYSFLASH0 + 128 * OneMeg; a += OneMeg) - l1table[a>>20] = L1Section | L1KernelRW | - L1Cached | L1Buffered | (a&L1SectBaseMask); + l1table[a>>20] = L1Section | L1KernelRW | (a&L1SectBaseMask) | + L1Cached | L1Buffered; - /* map the uart so that we can continue using iprint */ -// uart3regs = mapspecial(UART3REGS, 64); + /* map first page of DRAM also into 0xFFFF0000 for the interrupt vectors */ + t = xspanalloc(BY2PG, 16*1024, 0); + memset(t, 0, BY2PG); + l1table[0xFFFF0000>>20] = L1PageTable | L1Domain0 | (((ulong)t) & L1PTBaseMask); + t[0xF0000>>PGSHIFT] = L2SmallPage | L2KernelRW | PHYSDRAM0; /* set up the domain register to cause all domains to obey pte access bits */ iprint("setting up domain access\n"); - putdac(0x55555555); + putdac(0xFFFFFFFF); /* point to map */ iprint("setting tlb map %lux\n", (ulong)l1table); putttb((ulong)l1table); + + /* map the uart so that we can continue using iprint */ + uart3regs = (Uartregs*)mapspecial(UART3REGS, 64); + + /* enable mmu, and make 0xFFFF0000 the virtual address of the exception vecs */ + mmuenable(); + + iprint("uart3regs now at %lux\n", uart3regs); } /* @@ -121,26 +128,35 @@ mapspecial(ulong pa, int len) } off = pa - base; - for(va = REGZERO; va < REGTOP && base >= end; va += OneMeg){ - if((l1table[va>>20] & L1TypeMask) != L1PageTable){ - + for(va = REGZERO; va < REGTOP && base <= end; va += OneMeg){ + switch(l1table[va>>20] & L1TypeMask){ + default: /* found unused entry on level 1 table */ if(livelarge){ if(rv == nil) - rv = (ulong*)(va+i*BY2PG+off); + rv = (ulong*)(va+off); l1table[va>>20] = L1Section | L1KernelRW | - (base&L1SectBaseMask); + (base & L1SectBaseMask); base += OneMeg; continue; - } + } else { - /* create a page table and keep going */ - t = xspanalloc(BY2PG, 1024, 0); - memset(t, 0, BY2PG); - l1table[va>>20] = L1PageTable | L1Domain0 | - (((ulong)t) & L1PTBaseMask); + /* create an L2 page table and keep going */ + t = xspanalloc(BY2PG, 1024, 0); + memset(t, 0, BY2PG); + l1table[va>>20] = L1PageTable | L1Domain0 | + (((ulong)t) & L1PTBaseMask); + } + break; + case L1Section: + continue; + case L1PageTable: + if(livelarge) + continue; + break; } + /* here if we're using page maps instead of sections */ t = (ulong*)(l1table[va>>20] & L1PTBaseMask); for(i = 0; i < OneMeg; i += BY2PG){ entry = t[i>>PGSHIFT]; @@ -148,7 +164,7 @@ mapspecial(ulong pa, int len) /* found unused entry on level 2 table */ if((entry & L2TypeMask) != L2SmallPage){ if(rv == nil) - rv = (ulong*)(va+i*BY2PG+off); + rv = (ulong*)(va+i+off); t[i>>PGSHIFT] = L2SmallPage | L2KernelRW | (base & L2PageBaseMask); base += BY2PG; diff --git a/bitsy/trap.c b/bitsy/trap.c index cf2cf967a18f80a0bbf1c64f3d2256a9ab54585d..bc92a93c67ce5ad334c5b5d217b845b9e30e547e 100644 --- a/bitsy/trap.c +++ b/bitsy/trap.c @@ -19,8 +19,29 @@ evenaddr(ulong addr) } } +/* + * set up for exceptioons + */ +void +trapinit(void) +{ + /* + * exceptionvectors points to a prototype in l.s of the + * exception vectors that save the regs and then call + * trap(). The actual vectorrs are double mapped + * to 0xffff0000 and to KZERO. We write them via + * KZERO since a data access to them will cause an + * exception. + */ + memmove((void*)KZERO, exceptionvectors, 2*4*8); + wbflush(); +} + +/* + * here on all exceptions with registers saved + */ void -exception(void) +trap(Ureg *ureg) { } diff --git a/carrera/l.s b/carrera/l.s index cc6a7dd100b2bdfd62588de12ad5fbc581acd916..8ee69c0ee951dd0dfa1b530372865f9216dd283d 100644 --- a/carrera/l.s +++ b/carrera/l.s @@ -28,6 +28,8 @@ TEXT start(SB), $-4 MOVW $TLBROFF, R1 MOVW R1, M(WIRED) + /* setfcr(FPPDBL|FPRNR|FPINVAL|FPZDIV|FPOVFL) */ + /* bit 24 is R4000-specific; underflow goes to zero */ MOVW $((0x1C<<7)|(1<<24)), R1 MOVW R1, FCR31 /* permit only inexact and underflow */ NOOP diff --git a/pc/l.s b/pc/l.s index c4792ac9eace465b3cdf3cafc47453d86e489836..c83941e7679a707dbe45567fa93eb77445f48f15 100644 --- a/pc/l.s +++ b/pc/l.s @@ -390,8 +390,10 @@ TEXT fpinit(SB), $0 /* enable and init */ FPON FINIT WAIT - PUSHW $0x033E - FLDCW 0(SP) /* ignore underflow/precision, signal others */ + /* setfcr(FPPDBL|FPRNR|FPINVAL|FPZDIV|FPOVFL) */ + /* note that low 6 bits are masks, not enables, on this chip */ + PUSHW $0x0232 + FLDCW 0(SP) POPW AX WAIT RET