2 #include "../port/lib.h"
15 m->l1.va = KADDR(m->l1.pa);
16 memset((uchar*)TMAPL2(m->machno), 0, TMAPL2SZ);
17 m->l1.va[L1X(TMAP)] = PADDR(TMAPL2(m->machno)) | L1PT;
21 mpcore = vmap(MPCORE_BASE, 0x2000);
22 slcr = vmap(SLCR_BASE, 0x1000);
23 ocm = vmap(OCM_BASE, -OCM_BASE);
27 l1switch(L1 *p, int flush)
55 p = smalloc(sizeof(L1));
57 p->va = mallocalign(L1SZ, L1SZ, 0, 0);
61 resrcwait("no memory for L1 table");
66 memmove(p->va, m->l1.va, L1SZ);
74 panic("l1free: islo");
96 panic("upalloc1: up->l1 != nil");
108 if(proc->l1 == nil || proc->mmuused == nil)
111 for(p = *l; p != nil; p = p->next){
112 t = proc->l1->va + p->daddr;
119 proc->l1->va[L1X(TMAP)] = 0;
121 proc->mmufree = proc->mmuused;
139 putmmu(uintptr va, uintptr pa, Page *pg)
150 e = &up->l1->va[L1RX(va)];
154 up->mmufree = p->next;
156 p = newpage(0, 0, 0);
158 p->next = up->mmuused;
163 memset(l2, 0, BY2PG);
172 l2p = *e & ~(BY2PG - 1);
177 *e = pa | L2VALID | L2USER | L2LOCAL;
180 if((old & L2VALID) != 0)
181 flushpg((void *) va);
182 if(pg->txtflush & (1<<m->machno)){
183 cleandse((void *) va, (void *) (va + BY2PG));
184 invalise((void *) va, (void *) (va + BY2PG));
185 pg->txtflush &= ~(1<<m->machno);
190 checkmmu(uintptr, uintptr)
206 mmurelease(Proc *proc)
211 panic("mmurelease: islo");
214 if(proc->kmaptable != nil){
216 panic("mmurelease: no l1");
217 if(decref(proc->kmaptable) != 0)
218 panic("mmurelease: kmap ref %ld", proc->kmaptable->ref);
220 panic("mmurelease: nkmap %d", proc->nkmap);
221 if(PPN(proc->l1->va[L1X(KMAP)]) != proc->kmaptable->pa)
222 panic("mmurelease: bad kmap l2 %#.8lux kmap %#.8lux", proc->l1->va[L1X(KMAP)], proc->kmaptable->pa);
223 proc->l1->va[L1X(KMAP)] = 0;
224 pagechainhead(proc->kmaptable);
225 proc->kmaptable = nil;
232 for(p = proc->mmufree; p != nil; p = n){
235 panic("mmurelease: p->ref %ld", p->ref);
238 if(proc->mmufree != nil)
246 if((uintptr)v >= KZERO)
247 return (uintptr)v-KZERO;
248 if((uintptr)v >= VMAP)
249 return ((uintptr)v & (BY2PG-1)) | PPN(((ulong*)VMAPL2)[(uintptr)v-VMAP >> PGSHIFT]);
250 panic("paddr: va=%#p pc=%#p", v, getcallerpc(&v));
257 if(u < (uintptr)-KZERO)
258 return (void *)(u + KZERO);
260 return (void *)(ocm + (u - OCM_BASE));
261 panic("kaddr: pa=%#p pc=%#p", u, getcallerpc(&u));
268 if(u < (uintptr)-KZERO)
281 if(cankaddr(page->pa))
282 return (KMap*)KADDR(page->pa);
284 panic("kmap: up=0 pc=%#.8lux", getcallerpc(&page));
288 panic("kmap %lud %s: nkmap=%d", up->pid, up->text, up->nkmap);
290 e = &up->l1->va[L1X(KMAP)];
292 if(up->kmaptable != nil)
293 panic("kmaptable != nil");
294 up->kmaptable = newpage(0, 0, 0);
296 v = tmpmap(up->kmaptable->pa);
298 v[0] = page->pa | L2KERRW | L2VALID | L2CACHED | L2LOCAL;
299 v[NKMAP] = up->kmaptable->pa | L2KERRW | L2VALID | L2CACHED | L2LOCAL;
302 *e = up->kmaptable->pa | L1PT;
304 return (KMap *) KMAP;
306 if(up->kmaptable == nil)
307 panic("kmaptable == nil");
308 e = (ulong *) (KMAP + NKMAP * BY2PG);
309 for(i = 0; i < NKMAP; i++)
311 e[i] = page->pa | L2KERRW | L2VALID | L2CACHED | L2LOCAL;
313 return (KMap *) (KMAP + i * BY2PG);
315 panic("out of kmap");
328 if(up->l1 == nil || (up->l1->va[L1X(KMAP)] & 3) == 0)
329 panic("kunmap: no kmaps");
330 if(va < KMAP || va >= KMAP + NKMAP * BY2PG)
331 panic("kunmap: bad address %#.8lux pc=%#p", va, getcallerpc(&arg));
332 e = (ulong *) (KMAP + NKMAP * BY2PG) + L2X(va);
334 panic("kunmap: not mapped %#.8lux pc=%#p", va, getcallerpc(&arg));
337 panic("kunmap %lud %s: nkmap=%d", up->pid, up->text, up->nkmap);
340 flushpg((void *) va);
349 panic("tmpmap: islow %#p", getcallerpc(&pa));
352 ub = (ulong *) TMAPL2(m->machno);
354 for(u = ub; u < ue; u++)
356 *u = pa | L2VALID | L2CACHED | L2KERRW;
358 assert(m->l1.va[L1X(TMAP)] != 0);
359 if(up != nil && up->l1 != nil)
360 up->l1->va[L1X(TMAP)] = m->l1.va[L1X(TMAP)];
363 return (void *) ((u - ub) * BY2PG + TMAP);
365 panic("tmpmap: full (pa=%#.8lux)", pa);
374 if(v >= (void*) KZERO)
376 if(v < (void*)TMAP || v >= (void*)(TMAP + TMAPSZ))
377 panic("tmpunmap: invalid address (va=%#.8lux)", (uintptr) v);
378 u = (ulong *) TMAPL2(m->machno) + L2X(v);
380 panic("tmpunmap: double unmap (va=%#.8lux)", (uintptr) v);
387 vmap(uintptr pa, ulong sz)
391 static ulong *vp = (ulong *) VMAPL2 + 1; /* first page is uart */
393 if((pa & BY2PG - 1) != 0)
394 panic("vmap: misaligned pa=%#.8lux", pa);
395 np = (sz + BY2PG - 1) >> PGSHIFT;
396 vr = (char*) VMAP + (vp - (ulong *)VMAPL2 << PGSHIFT);
397 ve = (ulong *) (VMAPL2 + VMAPL2SZ);
400 panic("vmap: out of vmap space (pa=%#.8lux)", pa);
401 *vp++ = pa | L2VALID | L2DEVICE | L2NOEXEC | L2KERRW;
408 /* nasty things happen when there are cache entries for uncached memory
409 so must make sure memory is not mapped ANYWHERE cached */
413 static uchar *free = nil;
418 panic("ualloc: len == 0");
422 free = ocm + -OCM_BASE - BY2PG; /* last page is cpu1 bootstrap */
426 panic("ualloc: out of uncached memory");
430 invaldse(va, va + len);