M alphapc/main.c => alphapc/main.c +2 -1
@@ 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];
M bitsy/dat.h => bitsy/dat.h +5 -4
@@ 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,
};
+
M bitsy/fns.h => bitsy/fns.h +5 -2
@@ 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);
M bitsy/l.s => bitsy/l.s +23 -5
@@ 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 */
M bitsy/main.c => bitsy/main.c +3 -0
@@ 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)();
}
M bitsy/mem.h => bitsy/mem.h +2 -1
@@ 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 */
M bitsy/mmu.c => bitsy/mmu.c +41 -25
@@ 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;
M bitsy/trap.c => bitsy/trap.c +22 -1
@@ 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)
{
}
M carrera/l.s => carrera/l.s +2 -0
@@ 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
M pc/l.s => pc/l.s +4 -2
@@ 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