From ee5b1de1db9d8e1cb7635acbc71897fb2a7d0623 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 21 Sep 1990 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1990-09-21 --- gnot/dat.h | 17 +++++++++++++++++ gnot/fns.h | 1 + gnot/main.c | 2 ++ gnot/mmu.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ gnot/proc.c | 1 + gnot/sysproc.c | 2 ++ 6 files changed, 67 insertions(+) diff --git a/gnot/dat.h b/gnot/dat.h index 0cb7c68fc0be883661ee8dbe6c7f7974ae7b9a82..579dfe2f0903ee91a847a971791a6060c514c2b5 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -16,6 +16,8 @@ typedef struct KMap KMap; typedef struct Label Label; typedef struct List List; typedef struct Lock Lock; +typedef struct MMU MMU; +typedef struct MMUCache MMUCache; typedef struct Mach Mach; typedef struct Mount Mount; typedef struct Mtab Mtab; @@ -337,6 +339,20 @@ struct Proc ulong pc; /* DEBUG only */ }; +struct MMU +{ + ulong va; + ulong pa; + int pid; +}; + +#define NMMU 16 +struct MMUCache +{ + ulong next; + MMU mmu[NMMU]; +}; + #define NERR 15 #define NNOTE 5 #define NFD 100 @@ -360,6 +376,7 @@ struct User short nnote; short notified; /* sysnoted is due */ int (*notify)(void*, char*); + MMUCache mc; void *ureg; }; diff --git a/gnot/fns.h b/gnot/fns.h index 1cb1920aeb49e3d3c011c1294c733a2ed43880c6..872f3597e3681d9c9d4d7bc3208adcce176d1bc0 100644 --- a/gnot/fns.h +++ b/gnot/fns.h @@ -51,6 +51,7 @@ void firmware(void); void flowctl(Queue*); void flushcpucache(void); void flushmmu(void); +void flushmmucache(void); void forkmod(Seg*, Seg*, Proc*); int fpcr(int); void fpsave(FPsave*); diff --git a/gnot/main.c b/gnot/main.c index cafe974bab99b314c1729b306e4ab53fcea9fa20..b33e1ba9444ed43ea825f818b268c4ae1215b2ce 100644 --- a/gnot/main.c +++ b/gnot/main.c @@ -31,6 +31,7 @@ void unloadboot(void); void main(void) { + u = 0; unloadboot(); machinit(); mmuinit(); @@ -154,6 +155,7 @@ userinit(void) k = kmap(p->upage); up = (User*)VA(k); up->p = p; + up->mc.next = 0; kunmap(k); /* diff --git a/gnot/mmu.c b/gnot/mmu.c index 3c90915cb6786d38eb360325a61daaceb5d67959..f0f6d4020c7c89b046deb007d7dd1a8f6ebb2432 100644 --- a/gnot/mmu.c +++ b/gnot/mmu.c @@ -12,6 +12,17 @@ struct KMap arena[4*1024*1024/BY2PG]; /* kernel mmu maps up to 4MB */ }kmapalloc; +void +putxmmu(ulong tlbvirt, ulong tlbphys, int pid) +{ + if(pid != u->p->pid) + panic("putxmmu %ld %ld\n", pid, u->p->pid); + if(tlbvirt&KZERO) + panic("putmmu"); + tlbphys |= VTAG(tlbvirt)<<24; + UMAP[(tlbvirt&0x003FE000L)>>2] = tlbphys; +} + /* * Called splhi, not in Running state */ @@ -19,6 +30,7 @@ void mapstack(Proc *p) { ulong tlbvirt, tlbphys; + ulong i; if(p->upage->va != (USERADDR|(p->pid&0xFFFF))) panic("mapstack %d 0x%lux 0x%lux", p->pid, p->upage->pa, p->upage->va); @@ -27,6 +39,14 @@ mapstack(Proc *p) putkmmu(tlbvirt, tlbphys); flushmmu(); u = (User*)USERADDR; + + if(u->mc.next >= NMMU){ + u->mc.next &= NMMU - 1; + for(i = u->mc.next; i < NMMU; i++) + putxmmu(u->mc.mmu[i].va, u->mc.mmu[i].pa, u->mc.mmu[i].pid); + } + for(i = 0; i < u->mc.next; i++) + putxmmu(u->mc.mmu[i].va, u->mc.mmu[i].pa, u->mc.mmu[i].pid);/**/ } void @@ -43,6 +63,14 @@ putmmu(ulong tlbvirt, ulong tlbphys) { if(tlbvirt&KZERO) panic("putmmu"); + if(u){ + MMU *mp; + mp = &(u->mc.mmu[u->mc.next&(NMMU-1)]); + mp->pa = tlbphys; + mp->va = tlbvirt; + mp->pid = u->p->pid; + u->mc.next++; + }/**/ tlbphys |= VTAG(tlbvirt)<<24; UMAP[(tlbvirt&0x003FE000L)>>2] = tlbphys; } @@ -55,6 +83,22 @@ flushmmu(void) *PARAM |= TLBFLUSH_; } +void +flushmmucache(void) +{ + if(u == 0) + panic("flushmmucache"); + u->mc.next = 0; +} + +void +clearmmucache(void) +{ + if(u == 0) + panic("clearmmucache"); + memset(&u->mc, 0, sizeof u->mc); +} + void kmapinit(void) { diff --git a/gnot/proc.c b/gnot/proc.c index 800806ea5ec08adcf33dec33ba27919a502bdc83..e34209871a6f61894f1dd157295a92367d01e226 100644 --- a/gnot/proc.c +++ b/gnot/proc.c @@ -621,6 +621,7 @@ kproc(char *name, void (*func)(void *), void *arg) /* * Save time: only copy u-> data and useful stack */ + clearmmucache(); memcpy(up, u, sizeof(User)); n = USERADDR+BY2PG - (ulong)&lastvar; n = (n+32) & ~(BY2WD-1); /* be safe & word align */ diff --git a/gnot/sysproc.c b/gnot/sysproc.c index 6c76c2bca961311f8bc90c24fbea7f2eb18428d7..bad416d4d1ce678a93902582e4cb0c6ed3332d69 100644 --- a/gnot/sysproc.c +++ b/gnot/sysproc.c @@ -41,6 +41,7 @@ sysfork(ulong *arg) /* * Save time: only copy u-> data and useful stack */ + clearmmucache(); memcpy((void*)upa, u, sizeof(User)); n = USERADDR+BY2PG - (ulong)&lastvar; n = (n+32) & ~(BY2WD-1); /* be safe & word align */ @@ -361,6 +362,7 @@ sysexec(ulong *arg) unlock(o); flushmmu(); + clearmmucache(); ((Ureg*)UREGADDR)->pc = exec.entry; sp = (ulong*)(USTKTOP - ssize); *--sp = nargs;