#include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" /* * return physical address corresponding to a given virtual address, * or 0 if there is no such address */ ulong va2pa(void *v) { int idx; ulong pte, ste, *ttb; idx = MmuL1x((ulong)v); ttb = (ulong*)KTTB; ste = ttb[idx]; switch(ste & MmuL1type) { case MmuL1section: return MmuSBA(ste)|((ulong)v & 0x000fffff); case MmuL1page: pte = ((ulong *)MmuPTBA(ste))[MmuL2x((ulong)v)]; switch(pte & 3) { case MmuL2large: return (pte & 0xffff0000)|((ulong)v & 0x0000ffff); case MmuL2small: return (pte & 0xfffff000)|((ulong)v & 0x00000fff); } } return 0; } enum { SectionPages = MmuSection/MmuSmallPage, PtAlign = 1<<10, MINICACHED = 0x10000000, }; /* for debugging */ void prs(char *s) { for(; *s; s++) uartputc(*s); } void pr16(ulong n) { int i; for(i=28; i>=0; i-=4) uartputc("0123456789ABCDEF"[(n>>i)&0xF]); } void* mmuphysmap(ulong phys, ulong) { ulong *ttb; void *va; ttb = (ulong*)KTTB; va = KADDR(phys); ttb[MmuL1x((ulong)va)] = phys | 0xC10 | MmuL1section; return va; } /* * Set a 1-1 map of virtual to physical memory, except: * doubly-map page0 at the alternative interrupt vector address, * doubly-map physical memory at KZERO+256*MB as uncached but buffered, and * disable access to 0 (nil pointers). */ void mmuinit(void) { int i; ulong *ttb, *ptable, va; ttb = (ulong*)KTTB; for(i=0; i