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 if((pa & PTEUNCACHED) == 0)
152 e = &up->l1->va[L1RX(va)];
156 up->mmufree = p->next;
158 p = newpage(0, 0, 0);
160 p->next = up->mmuused;
165 memset(l2, 0, BY2PG);
174 l2p = *e & ~(BY2PG - 1);
179 *e = pa | L2VALID | L2USER | L2LOCAL;
182 if((old & L2VALID) != 0)
183 flushpg((void *) va);
184 if(pg->txtflush & (1<<m->machno)){
185 cleandse((void *) va, (void *) (va + BY2PG));
186 invalise((void *) va, (void *) (va + BY2PG));
187 pg->txtflush &= ~(1<<m->machno);
192 checkmmu(uintptr, uintptr)
208 mmurelease(Proc *proc)
213 panic("mmurelease: islo");
216 if(proc->kmaptable != nil){
218 panic("mmurelease: no l1");
219 if(decref(proc->kmaptable) != 0)
220 panic("mmurelease: kmap ref %ld", proc->kmaptable->ref);
222 panic("mmurelease: nkmap %d", proc->nkmap);
223 if(PPN(proc->l1->va[L1X(KMAP)]) != proc->kmaptable->pa)
224 panic("mmurelease: bad kmap l2 %#.8lux kmap %#.8lux", proc->l1->va[L1X(KMAP)], proc->kmaptable->pa);
225 proc->l1->va[L1X(KMAP)] = 0;
226 pagechainhead(proc->kmaptable);
227 proc->kmaptable = nil;
234 for(p = proc->mmufree; p != nil; p = n){
237 panic("mmurelease: p->ref %ld", p->ref);
240 if(proc->mmufree != nil)
246 countpagerefs(ulong *, int)
248 print("countpagerefs\n");
254 if((uintptr)v >= KZERO)
255 return (uintptr)v-KZERO;
256 if((uintptr)v >= VMAP)
257 return ((uintptr)v & (BY2PG-1)) | PPN(((ulong*)VMAPL2)[(uintptr)v-VMAP >> PGSHIFT]);
258 panic("paddr: va=%#p pc=%#p", v, getcallerpc(&v));
265 if(u < (uintptr)-KZERO)
266 return (void *)(u + KZERO);
268 return (void *)(ocm + (u - OCM_BASE));
269 panic("kaddr: pa=%#p pc=%#p", u, getcallerpc(&u));
276 if(u < (uintptr)-KZERO)
289 if(cankaddr(page->pa))
290 return (KMap*)KADDR(page->pa);
292 panic("kmap: up=0 pc=%#.8lux", getcallerpc(&page));
296 panic("kmap %lud %s: nkmap=%d", up->pid, up->text, up->nkmap);
298 e = &up->l1->va[L1X(KMAP)];
300 if(up->kmaptable != nil)
301 panic("kmaptable != nil");
302 up->kmaptable = newpage(0, 0, 0);
304 v = tmpmap(up->kmaptable->pa);
306 v[0] = page->pa | L2KERRW | L2VALID | L2CACHED | L2LOCAL;
307 v[NKMAP] = up->kmaptable->pa | L2KERRW | L2VALID | L2CACHED | L2LOCAL;
310 *e = up->kmaptable->pa | L1PT;
312 return (KMap *) KMAP;
314 if(up->kmaptable == nil)
315 panic("kmaptable == nil");
316 e = (ulong *) (KMAP + NKMAP * BY2PG);
317 for(i = 0; i < NKMAP; i++)
319 e[i] = page->pa | L2KERRW | L2VALID | L2CACHED | L2LOCAL;
321 return (KMap *) (KMAP + i * BY2PG);
323 panic("out of kmap");
336 if(up->l1 == nil || (up->l1->va[L1X(KMAP)] & 3) == 0)
337 panic("kunmap: no kmaps");
338 if(va < KMAP || va >= KMAP + NKMAP * BY2PG)
339 panic("kunmap: bad address %#.8lux pc=%#p", va, getcallerpc(&arg));
340 e = (ulong *) (KMAP + NKMAP * BY2PG) + L2X(va);
342 panic("kunmap: not mapped %#.8lux pc=%#p", va, getcallerpc(&arg));
345 panic("kunmap %lud %s: nkmap=%d", up->pid, up->text, up->nkmap);
348 flushpg((void *) va);
357 panic("tmpmap: islow %#p", getcallerpc(&pa));
360 ub = (ulong *) TMAPL2(m->machno);
362 for(u = ub; u < ue; u++)
364 *u = pa | L2VALID | L2CACHED | L2KERRW;
366 assert(m->l1.va[L1X(TMAP)] != 0);
367 if(up != nil && up->l1 != nil)
368 up->l1->va[L1X(TMAP)] = m->l1.va[L1X(TMAP)];
371 return (void *) ((u - ub) * BY2PG + TMAP);
373 panic("tmpmap: full (pa=%#.8lux)", pa);
382 if(v >= (void*) KZERO)
384 if(v < (void*)TMAP || v >= (void*)(TMAP + TMAPSZ))
385 panic("tmpunmap: invalid address (va=%#.8lux)", (uintptr) v);
386 u = (ulong *) TMAPL2(m->machno) + L2X(v);
388 panic("tmpunmap: double unmap (va=%#.8lux)", (uintptr) v);
395 vmap(uintptr pa, ulong sz)
399 static ulong *vp = (ulong *) VMAPL2 + 1; /* first page is uart */
401 if((pa & BY2PG - 1) != 0)
402 panic("vmap: misaligned pa=%#.8lux", pa);
403 np = (sz + BY2PG - 1) >> PGSHIFT;
404 vr = (char*) VMAP + (vp - (ulong *)VMAPL2 << PGSHIFT);
405 ve = (ulong *) (VMAPL2 + VMAPL2SZ);
408 panic("vmap: out of vmap space (pa=%#.8lux)", pa);
409 *vp++ = pa | L2VALID | L2DEVICE | L2KERRW;
416 /* nasty things happen when there are cache entries for uncached memory
417 so must make sure memory is not mapped ANYWHERE cached */
421 static uchar *free = nil;
426 panic("ualloc: len == 0");
430 free = ocm + -OCM_BASE - BY2PG; /* last page is cpu1 bootstrap */
434 panic("ualloc: out of uncached memory");
438 invaldse(va, va + len);