|
|
1.1 ! root 1: #include "u.h" ! 2: #include "../port/lib.h" ! 3: #include "mem.h" ! 4: #include "dat.h" ! 5: #include "fns.h" ! 6: ! 7: struct ! 8: { ! 9: Lock; ! 10: int init; ! 11: KMap *free; ! 12: KMap arena[MB4/BY2PG]; /* kernel mmu maps up to 4MB */ ! 13: }kmapalloc; ! 14: ! 15: /* ! 16: * Called splhi, not in Running state ! 17: */ ! 18: void ! 19: mapstack(Proc *p) ! 20: { ! 21: ulong tlbvirt, tlbphys; ! 22: ! 23: ! 24: if(p->upage->va != (USERADDR|(p->pid&0xFFFF)) && p->pid != 0) ! 25: panic("mapstack %d 0x%lux 0x%lux", p->pid, p->upage->pa, p->upage->va); ! 26: tlbvirt = USERADDR; ! 27: tlbphys = PPN(p->upage->pa) | PTEVALID | PTEKERNEL; ! 28: putkmmu(tlbvirt, tlbphys); ! 29: u = (User*)USERADDR; ! 30: ! 31: if(p->newtlb) { ! 32: flushmmu(); ! 33: p->newtlb = 0; ! 34: } ! 35: ! 36: /* ! 37: * if not a kernel process and this process was not the ! 38: * last process on this machine, flush & preload mmu ! 39: */ ! 40: if(!p->kp && p!=m->lproc){ ! 41: flushmmu(); ! 42: m->lproc = p; ! 43: } ! 44: } ! 45: ! 46: void ! 47: mmurelease(Proc *p) ! 48: { ! 49: USED(p); ! 50: } ! 51: ! 52: void ! 53: putkmmu(ulong tlbvirt, ulong tlbphys) ! 54: { ! 55: if(!(tlbvirt&KZERO)) ! 56: panic("putkmmu"); ! 57: tlbvirt &= ~KZERO; ! 58: KMAP[(tlbvirt&0x003FE000L)>>2] = tlbphys; ! 59: } ! 60: ! 61: void ! 62: putmmu(ulong tlbvirt, ulong tlbphys, Page *pg) ! 63: { ! 64: USED(pg); ! 65: if(tlbvirt&KZERO) ! 66: panic("putmmu"); ! 67: tlbphys |= VTAG(tlbvirt)<<24; ! 68: tlbvirt = (tlbvirt&0x003FE000L)>>2; ! 69: UMAP[tlbvirt] = tlbphys; ! 70: } ! 71: ! 72: void ! 73: flushmmu(void) ! 74: { ! 75: flushcpucache(); ! 76: *PARAM &= ~TLBFLUSH_; ! 77: *PARAM |= TLBFLUSH_; ! 78: } ! 79: ! 80: void ! 81: kmapinit(void) ! 82: { ! 83: int i; ! 84: ulong endscreen; ! 85: Page *p; ! 86: KMap *k; ! 87: ! 88: if(kmapalloc.init == 0){ ! 89: k = &kmapalloc.arena[0]; ! 90: k->va = KZERO|(MB4-BY2PG); ! 91: k->next = 0; ! 92: kmapalloc.free = k; ! 93: kmapalloc.init = 1; ! 94: return; ! 95: } ! 96: ! 97: i = 0; ! 98: /* ! 99: * Reclaim map register for pages in bank0; ! 100: * screen is in virtual space overlaying physical pages; be careful ! 101: */ ! 102: endscreen = (PGROUND((ulong)end)&~KZERO) + 256*1024; ! 103: for(p = palloc.head; p; p = p->next) { ! 104: if(p->pa >= endscreen && p->pa < MB4) { ! 105: k = &kmapalloc.arena[p->pa/BY2PG]; ! 106: k->va = p->pa|KZERO; ! 107: kunmap(k); ! 108: i++; ! 109: } ! 110: } ! 111: print("%lud free map registers\n", i); ! 112: } ! 113: ! 114: KMap* ! 115: kmap(Page *pg) ! 116: { ! 117: KMap *k; ! 118: int s; ! 119: ! 120: s = splhi(); ! 121: lock(&kmapalloc); ! 122: k = kmapalloc.free; ! 123: if(k == 0){ ! 124: dumpstack(); ! 125: panic("kmap"); ! 126: } ! 127: kmapalloc.free = k->next; ! 128: unlock(&kmapalloc); ! 129: splx(s); ! 130: ! 131: k->pa = pg->pa; ! 132: putkmmu(k->va, PPN(k->pa) | PTEVALID | PTEKERNEL); ! 133: ! 134: return k; ! 135: } ! 136: ! 137: void ! 138: kunmap(KMap *k) ! 139: { ! 140: int s; ! 141: ! 142: k->pa = 0; ! 143: putkmmu(k->va, INVALIDPTE); ! 144: ! 145: s = splhi(); ! 146: lock(&kmapalloc); ! 147: k->next = kmapalloc.free; ! 148: kmapalloc.free = k; ! 149: unlock(&kmapalloc); ! 150: splx(s); ! 151: } ! 152: ! 153: void ! 154: invalidateu(void) ! 155: { ! 156: putkmmu(USERADDR, INVALIDPTE); ! 157: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.