From ad0410379b8f06c1fa5e8ea7d6d36929fd0b780d Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 14 Oct 2000 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2000-10-14 --- bitsy/dat.h | 15 +-------------- bitsy/fns.h | 2 ++ bitsy/l.s | 33 ++++++++++++++++++++++++++++----- bitsy/main.c | 10 +++++++++- bitsy/mmu.c | 36 ++++++++++++++++++++++++++++++++---- bitsy/trap.c | 39 ++++++++++++++++++++++++++------------- 6 files changed, 98 insertions(+), 37 deletions(-) diff --git a/bitsy/dat.h b/bitsy/dat.h index bbfdcebedbdd2b3a4ce3330adcec45a337091e48..32bc43dd0deeb85ad2a1694e2e6bb0b4a799326f 100644 --- a/bitsy/dat.h +++ b/bitsy/dat.h @@ -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) diff --git a/bitsy/fns.h b/bitsy/fns.h index 4e98a5218f5492a5717c3d8337c5b5b5128af207..d1001f249495a158597104e01fceba6ada507372 100644 --- a/bitsy/fns.h +++ b/bitsy/fns.h @@ -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() diff --git a/bitsy/l.s b/bitsy/l.s index 5d3178cb725a33f466ef6fff36e3f87386a6457c..290b307a4a3a5f4b3098fc550f6e5f7ea644f4c6 100644 --- a/bitsy/l.s +++ b/bitsy/l.s @@ -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 */ diff --git a/bitsy/main.c b/bitsy/main.c index a879d430e7cf12205c19dc6e1139f62a3cf53c5c..b60eb6c587102ecceec1c6d7868aebcab38bd8d2 100644 --- a/bitsy/main.c +++ b/bitsy/main.c @@ -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); } diff --git a/bitsy/mmu.c b/bitsy/mmu.c index 8578169d944ab1025ca1dcaea42ce7e26562a3a9..4646c14cb15544cc38b5fecc5f85eeafc3f7c41e 100644 --- a/bitsy/mmu.c +++ b/bitsy/mmu.c @@ -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; + } } diff --git a/bitsy/trap.c b/bitsy/trap.c index 388ba084c031fd7e304e7828febc889d78bfc6da..ec99efd4093df21b08a2e6c2ab3307a4ab94f63c 100644 --- a/bitsy/trap.c +++ b/bitsy/trap.c @@ -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<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){