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){