|
|
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.