| plan 9 kernel history: overview | file list | diff list |
1992/0630/gnot/mmu.c (diff list | history)
| gnot/mmu.c on 1990/03091 | ||
| 1990/03091 | #include "u.h" | |
| 1992/0321 | #include "../port/lib.h" | |
| 1990/03091 | #include "mem.h" #include "dat.h" #include "fns.h" | |
| 1990/06021 | struct { Lock; int init; KMap *free; | |
| 1991/0821 | KMap arena[MB4/BY2PG]; /* kernel mmu maps up to 4MB */ | |
| 1990/06021 | }kmapalloc; | |
| 1990/03091 | /* * Called splhi, not in Running state */ void mapstack(Proc *p) { ulong tlbvirt, tlbphys; | |
| 1990/1004 | ulong next; MMU *mm, *mn, *me; | |
| 1990/03091 | ||
| 1991/0705 | ||
| 1991/0928 | if(p->upage->va != (USERADDR|(p->pid&0xFFFF)) && p->pid != 0) | |
| 1990/03091 | panic("mapstack %d 0x%lux 0x%lux", p->pid, p->upage->pa, p->upage->va); tlbvirt = USERADDR; tlbphys = PPN(p->upage->pa) | PTEVALID | PTEKERNEL; putkmmu(tlbvirt, tlbphys); | |
| 1990/1211 | u = (User*)USERADDR; | |
| 1990/1004 | ||
| 1991/0705 | if(p->newtlb) { flushmmu(); p->newtlb = 0; } | |
| 1990/1004 | /* * if not a kernel process and this process was not the * last process on this machine, flush & preload mmu */ if(!p->kp && p!=m->lproc){ flushmmu(); m->lproc = p; } | |
| 1990/03091 | } void | |
| 1991/0507 | mmurelease(Proc *p) { USED(p); } void | |
| 1990/03091 | putkmmu(ulong tlbvirt, ulong tlbphys) { if(!(tlbvirt&KZERO)) panic("putkmmu"); tlbvirt &= ~KZERO; KMAP[(tlbvirt&0x003FE000L)>>2] = tlbphys; } void | |
| 1991/0705 | putmmu(ulong tlbvirt, ulong tlbphys, Page *p) | |
| 1990/03091 | { if(tlbvirt&KZERO) panic("putmmu"); tlbphys |= VTAG(tlbvirt)<<24; | |
| 1990/1004 | tlbvirt = (tlbvirt&0x003FE000L)>>2; UMAP[tlbvirt] = tlbphys; | |
| 1990/03091 | } void flushmmu(void) { flushcpucache(); *PARAM &= ~TLBFLUSH_; *PARAM |= TLBFLUSH_; | |
| 1990/06021 | } void kmapinit(void) { | |
| 1992/0625 | int i; | |
| 1992/0630 | ulong endscreen; | |
| 1992/0625 | Page *p; | |
| 1990/06021 | KMap *k; if(kmapalloc.init == 0){ k = &kmapalloc.arena[0]; | |
| 1992/0630 | k->va = KZERO|(MB4-BY2PG); | |
| 1990/06021 | k->next = 0; kmapalloc.free = k; kmapalloc.init = 1; return; } | |
| 1991/0821 | ||
| 1992/0625 | i = 0; | |
| 1992/0630 | /* * Reclaim map register for pages in bank0; * screen is in virtual space overlaying physical pages; be careful */ endscreen = (PGROUND((ulong)end)&~KZERO) + 256*1024; | |
| 1992/0625 | for(p = palloc.head; p; p = p->next) { | |
| 1992/0630 | if(p->pa >= endscreen && p->pa < MB4) { | |
| 1992/0625 | k = &kmapalloc.arena[p->pa/BY2PG]; k->va = p->pa|KZERO; kunmap(k); i++; } | |
| 1990/06021 | } | |
| 1992/0625 | print("%lud free map registers\n", i); | |
| 1990/06021 | } KMap* kmap(Page *pg) { KMap *k; | |
| 1991/1004 | int s; s = splhi(); | |
| 1990/06021 | lock(&kmapalloc); k = kmapalloc.free; | |
| 1990/0709 | if(k == 0){ dumpstack(); | |
| 1990/06021 | panic("kmap"); | |
| 1990/0709 | } | |
| 1990/06021 | kmapalloc.free = k->next; unlock(&kmapalloc); | |
| 1991/1004 | splx(s); | |
| 1991/0821 | ||
| 1990/06021 | k->pa = pg->pa; putkmmu(k->va, PPN(k->pa) | PTEVALID | PTEKERNEL); | |
| 1991/0828 | ||
| 1990/06021 | return k; } void kunmap(KMap *k) { | |
| 1991/0827 | int s; | |
| 1990/06021 | k->pa = 0; | |
| 1991/0821 | putkmmu(k->va, INVALIDPTE); | |
| 1991/0827 | s = splhi(); | |
| 1990/06021 | lock(&kmapalloc); k->next = kmapalloc.free; kmapalloc.free = k; unlock(&kmapalloc); | |
| 1991/0827 | splx(s); | |
| 1990/1211 | } void invalidateu(void) { putkmmu(USERADDR, INVALIDPTE); | |
| 1990/03091 | } | |