shithub: riscv

Download patch

ref: 1fd5f5205dd80e00b9a069567e46dd3a261ecd24
parent: 015180f99be4553dc4851f63edff04d0fc16a66a
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Oct 29 13:43:24 EDT 2023

bcm64: use generic 9/arm64/mmu.c

--- a/sys/src/9/bcm64/fns.h
+++ b/sys/src/9/bcm64/fns.h
@@ -68,15 +68,17 @@
 #define	VA(k)	((uintptr)(k))
 extern KMap *kmap(Page*);
 extern void kunmap(KMap*);
+extern void kmapram(uintptr, uintptr);
 extern uintptr mmukmap(uintptr, uintptr, usize);
 extern void* vmap(uvlong, vlong);
 extern void vunmap(void*, vlong);
+extern void mmu1init(void);
+extern void putasid(Proc*);
 
+/* mem */
+extern void mmuidmap(uintptr*);
 extern void mmu0init(uintptr*);
-extern void mmu1init(void);
 extern void meminit(void);
-
-extern void putasid(Proc*);
 
 /* clock */
 extern void clockinit(void);
--- /dev/null
+++ b/sys/src/9/bcm64/mem.c
@@ -1,0 +1,146 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "../arm64/sysreg.h"
+
+#define INITMAP	(ROUND((uintptr)end + BY2PG, PGLSZ(1))-KZERO)
+
+/*
+ * Create initial identity map in top-level page table
+ * (L1BOT) for TTBR0. This page table is only used until
+ * mmu1init() loads m->mmutop.
+ */
+void
+mmuidmap(uintptr *l1bot)
+{
+	uintptr pa, pe, attr;
+
+	attr = PTEWRITE | PTEAF | PTEKERNEL | PTEUXN | PTESH(SHARE_INNER);
+	pe = -KZERO;
+	for(pa = PHYSDRAM; pa < pe; pa += PGLSZ(PTLEVELS-1))
+		l1bot[PTLX(pa, PTLEVELS-1)] = pa | PTEVALID | PTEBLOCK | attr;
+}
+
+/*
+ * Create initial shared kernel page table (L1) for TTBR1.
+ * This page table coveres the KZERO and VIRTIO.
+ */
+void
+mmu0init(uintptr *l1)
+{
+	uintptr va, pa, pe, attr;
+
+	/* KZERO */
+	attr = PTEWRITE | PTEAF | PTEKERNEL | PTEUXN | PTESH(SHARE_INNER);
+	pe = -KZERO;
+	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1))
+		l1[PTL1X(va, 1)] = pa | PTEVALID | PTEBLOCK | attr;
+
+	/* VIRTIO */
+	attr = PTEWRITE | PTEAF | PTEKERNEL | PTEUXN | PTEPXN | PTESH(SHARE_OUTER) | PTEDEVICE;
+	pe = soc.physio + soc.iosize;
+	for(pa = soc.physio, va = soc.virtio; pa < pe; pa += PGLSZ(1), va += PGLSZ(1)){
+		if(((pa|va) & PGLSZ(1)-1) != 0){
+			l1[PTL1X(va, 1)] = (uintptr)l1 | PTEVALID | PTETABLE;
+			for(; pa < pe && ((va|pa) & PGLSZ(1)-1) != 0; pa += PGLSZ(0), va += PGLSZ(0)){
+				assert(l1[PTLX(va, 0)] == 0);
+				l1[PTLX(va, 0)] = pa | PTEVALID | PTEPAGE | attr;
+			}
+			break;
+		}
+		l1[PTL1X(va, 1)] = pa | PTEVALID | PTEBLOCK | attr;
+	}
+
+	/* ARMLOCAL */
+	attr = PTEWRITE | PTEAF | PTEKERNEL | PTEUXN | PTEPXN | PTESH(SHARE_OUTER) | PTEDEVICE;
+	pe = soc.armlocal + MB;
+	for(pa = soc.armlocal, va = ARMLOCAL; pa < pe; pa += PGLSZ(1), va += PGLSZ(1)){
+		if(((pa|va) & PGLSZ(1)-1) != 0){
+			l1[PTL1X(va, 1)] = (uintptr)l1 | PTEVALID | PTETABLE;
+			for(; pa < pe && ((va|pa) & PGLSZ(1)-1) != 0; pa += PGLSZ(0), va += PGLSZ(0)){
+				assert(l1[PTLX(va, 0)] == 0);
+				l1[PTLX(va, 0)] = pa | PTEVALID | PTEPAGE | attr;
+			}
+			break;
+		}
+		l1[PTL1X(va, 1)] = pa | PTEVALID | PTEBLOCK | attr;
+	}
+
+	if(PTLEVELS > 2)
+	for(va = KSEG0; va != 0; va += PGLSZ(2))
+		l1[PTL1X(va, 2)] = (uintptr)&l1[L1TABLEX(va, 1)] | PTEVALID | PTETABLE;
+	if(PTLEVELS > 3)
+	for(va = KSEG0; va != 0; va += PGLSZ(3))
+		l1[PTL1X(va, 3)] = (uintptr)&l1[L1TABLEX(va, 2)] | PTEVALID | PTETABLE;
+}
+
+void
+meminit(void)
+{
+	uvlong memsize = 0;
+	uintptr pa, va;
+	char *p, *e;
+	int i;
+
+	if(p = getconf("*maxmem")){
+		memsize = strtoull(p, &e, 0) - PHYSDRAM;
+		for(i = 1; i < nelem(conf.mem); i++){
+			if(e <= p || *e != ' ')
+				break;
+			p = ++e;
+			conf.mem[i].base = strtoull(p, &e, 0);
+			if(e <= p || *e != ' ')
+				break;
+			p = ++e;
+			conf.mem[i].limit = strtoull(p, &e, 0);
+		}
+	}
+
+	if (memsize < INITMAP)		/* sanity */
+		memsize = INITMAP;
+
+	getramsize(&conf.mem[0]);
+	if(conf.mem[0].limit == 0){
+		conf.mem[0].base = PHYSDRAM;
+		conf.mem[0].limit = PHYSDRAM + memsize;
+	}else if(p != nil)
+		conf.mem[0].limit = conf.mem[0].base + memsize;
+
+	/*
+	 * now we know the real memory regions, unmap
+	 * everything above INITMAP and map again with
+	 * the proper sizes.
+	 */
+	coherence();
+	for(va = INITMAP+KZERO; va != 0; va += PGLSZ(1))
+		((uintptr*)L1)[PTL1X(va, 1)] = 0;
+	flushtlb();
+
+	pa = PGROUND((uintptr)end)-KZERO;
+	for(i=0; i<nelem(conf.mem); i++){
+		if(conf.mem[i].limit >= KMAPEND-KMAP)
+			conf.mem[i].limit = KMAPEND-KMAP;
+
+		if(conf.mem[i].limit <= conf.mem[i].base){
+			conf.mem[i].limit = conf.mem[i].base = 0;
+			continue;
+		}
+
+		if(conf.mem[i].base < PHYSDRAM + soc.dramsize
+		&& conf.mem[i].limit > PHYSDRAM + soc.dramsize)
+			conf.mem[i].limit = PHYSDRAM + soc.dramsize;
+
+		/* take kernel out of allocatable space */
+		if(pa > conf.mem[i].base && pa < conf.mem[i].limit)
+			conf.mem[i].base = pa;
+
+		kmapram(conf.mem[i].base, conf.mem[i].limit);
+	}
+	flushtlb();
+
+	/* rampage() is now done, count up the pages for each bank */
+	for(i=0; i<nelem(conf.mem); i++)
+		conf.mem[i].npage = (conf.mem[i].limit - conf.mem[i].base)/BY2PG;
+}
--- a/sys/src/9/bcm64/mem.h
+++ b/sys/src/9/bcm64/mem.h
@@ -54,6 +54,7 @@
 #define	ARMLOCAL	(0xFFFFFFFFBF800000ULL)	/* -		0x40000000	0xFF800000 */
 
 #define	VGPIO		(0xFFFFFFFFBFA00000ULL|PTEUNCACHED)	/* virtual gpio for pi3 ACT LED */
+#define VDRAM		KZERO
 
 #define	KZERO		(0xFFFFFFFFC0000000ULL)	/* kernel address space */
 
--- a/sys/src/9/bcm64/mkfile
+++ b/sys/src/9/bcm64/mkfile
@@ -47,6 +47,7 @@
 	fpu.$O\
 	main.$O\
 	mmu.$O\
+	mem.$O\
 	sysreg.$O\
 	random.$O\
 	trap.$O\
@@ -97,7 +98,7 @@
 init9.$O:	../arm64/init9.s
 	$AS $AFLAGS -I. -. ../arm64/init9.s
 
-REPCC=`{../port/mkfilelist ../bcm | sed 's/(fpu|trap)[|)]//g'}
+REPCC=`{../port/mkfilelist ../bcm | sed 's/(mmu|fpu|trap)[|)]//g'}
 ^($REPCC)\.$O:R:	'../bcm/\1.c'
 	$CC $CFLAGS -I. -. ../bcm/$stem1.c
 
@@ -108,8 +109,8 @@
 arch.$O clock.$O fpiarm.$O main.$O mmu.$O screen.$O syscall.$O trap.$O: \
 	/$objtype/include/ureg.h
 trap.$O main.$O: /sys/include/tos.h
-l.$O cache.v8.$O mmu.$O rebootcode.$O: mem.h
-l.$O cache.v8.$O archbcm3.$O clock.$O fpu.$O trap.$O mmu.$O rebootcode.$O: ../arm64/sysreg.h
+l.$O cache.v8.$O mmu.$O mem.$O rebootcode.$O: mem.h
+l.$O cache.v8.$O archbcm3.$O clock.$O fpu.$O trap.$O rebootcode.$O: ../arm64/sysreg.h
 main.$O: rebootcode.i
 pcibcm.$O: ../port/pci.h
 
--- a/sys/src/9/bcm64/mmu.c
+++ /dev/null
@@ -1,516 +1,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../arm64/sysreg.h"
-
-#define INITMAP	(ROUND((uintptr)end + BY2PG, PGLSZ(1))-KZERO)
-
-/*
- * Create initial identity map in top-level page table
- * (L1BOT) for TTBR0. This page table is only used until
- * mmu1init() loads m->mmutop.
- */
-void
-mmuidmap(uintptr *l1bot)
-{
-	uintptr pa, pe, attr;
-
-	attr = PTEWRITE | PTEAF | PTEKERNEL | PTEUXN | PTESH(SHARE_INNER);
-	pe = -KZERO;
-	for(pa = PHYSDRAM; pa < pe; pa += PGLSZ(PTLEVELS-1))
-		l1bot[PTLX(pa, PTLEVELS-1)] = pa | PTEVALID | PTEBLOCK | attr;
-}
-
-/*
- * Create initial shared kernel page table (L1) for TTBR1.
- * This page table coveres the KZERO and VIRTIO.
- */
-void
-mmu0init(uintptr *l1)
-{
-	uintptr va, pa, pe, attr;
-
-	/* KZERO */
-	attr = PTEWRITE | PTEAF | PTEKERNEL | PTEUXN | PTESH(SHARE_INNER);
-	pe = -KZERO;
-	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1))
-		l1[PTL1X(va, 1)] = pa | PTEVALID | PTEBLOCK | attr;
-
-	/* VIRTIO */
-	attr = PTEWRITE | PTEAF | PTEKERNEL | PTEUXN | PTEPXN | PTESH(SHARE_OUTER) | PTEDEVICE;
-	pe = soc.physio + soc.iosize;
-	for(pa = soc.physio, va = soc.virtio; pa < pe; pa += PGLSZ(1), va += PGLSZ(1)){
-		if(((pa|va) & PGLSZ(1)-1) != 0){
-			l1[PTL1X(va, 1)] = (uintptr)l1 | PTEVALID | PTETABLE;
-			for(; pa < pe && ((va|pa) & PGLSZ(1)-1) != 0; pa += PGLSZ(0), va += PGLSZ(0)){
-				assert(l1[PTLX(va, 0)] == 0);
-				l1[PTLX(va, 0)] = pa | PTEVALID | PTEPAGE | attr;
-			}
-			break;
-		}
-		l1[PTL1X(va, 1)] = pa | PTEVALID | PTEBLOCK | attr;
-	}
-
-	/* ARMLOCAL */
-	attr = PTEWRITE | PTEAF | PTEKERNEL | PTEUXN | PTEPXN | PTESH(SHARE_OUTER) | PTEDEVICE;
-	pe = soc.armlocal + MB;
-	for(pa = soc.armlocal, va = ARMLOCAL; pa < pe; pa += PGLSZ(1), va += PGLSZ(1)){
-		if(((pa|va) & PGLSZ(1)-1) != 0){
-			l1[PTL1X(va, 1)] = (uintptr)l1 | PTEVALID | PTETABLE;
-			for(; pa < pe && ((va|pa) & PGLSZ(1)-1) != 0; pa += PGLSZ(0), va += PGLSZ(0)){
-				assert(l1[PTLX(va, 0)] == 0);
-				l1[PTLX(va, 0)] = pa | PTEVALID | PTEPAGE | attr;
-			}
-			break;
-		}
-		l1[PTL1X(va, 1)] = pa | PTEVALID | PTEBLOCK | attr;
-	}
-
-	if(PTLEVELS > 2)
-	for(va = KSEG0; va != 0; va += PGLSZ(2))
-		l1[PTL1X(va, 2)] = (uintptr)&l1[L1TABLEX(va, 1)] | PTEVALID | PTETABLE;
-	if(PTLEVELS > 3)
-	for(va = KSEG0; va != 0; va += PGLSZ(3))
-		l1[PTL1X(va, 3)] = (uintptr)&l1[L1TABLEX(va, 2)] | PTEVALID | PTETABLE;
-}
-
-void
-mmu1init(void)
-{
-	m->mmutop = mallocalign(L1TOPSIZE, BY2PG, 0, 0);
-	if(m->mmutop == nil)
-		panic("mmu1init: no memory for mmutop");
-	memset(m->mmutop, 0, L1TOPSIZE);
-	mmuswitch(nil);
-}
-
-/* KZERO maps the first 1GB of ram */
-uintptr
-paddr(void *va)
-{
-	if((uintptr)va >= KZERO)
-		return (uintptr)va-KZERO;
-	panic("paddr: va=%#p pc=%#p", va, getcallerpc(&va));
-	return 0;
-}
-
-uintptr
-cankaddr(uintptr pa)
-{
-	if(pa < (uintptr)-KZERO)
-		return -KZERO - pa;
-	return 0;
-}
-
-void*
-kaddr(uintptr pa)
-{
-	if(pa < (uintptr)-KZERO)
-		return (void*)(pa + KZERO);
-	panic("kaddr: pa=%#p pc=%#p", pa, getcallerpc(&pa));
-	return nil;
-}
-
-static void*
-kmapaddr(uintptr pa)
-{
-	if(pa < (uintptr)-KZERO)
-		return (void*)(pa + KZERO);
-	if(pa >= KMAPEND-KMAP)
-		panic("kmapaddr: pa=%#p pc=%#p", pa, getcallerpc(&pa));
-	return (void*)(pa + KMAP);
-}
-
-KMap*
-kmap(Page *p)
-{
-	return kmapaddr(p->pa);
-}
-
-void
-kunmap(KMap*)
-{
-}
-
-void
-kmapinval(void)
-{
-}
-
-static void*
-rampage(void)
-{
-	uintptr pa;
-
-	if(conf.npage)
-		return mallocalign(BY2PG, BY2PG, 0, 0);
-
-	pa = conf.mem[0].base;
-	assert((pa % BY2PG) == 0);
-	assert(pa < INITMAP);
-	conf.mem[0].base += BY2PG;
-	return KADDR(pa);
-}
-
-static void
-l1map(uintptr va, uintptr pa, uintptr pe, uintptr attr)
-{
-	uintptr *l1, *l0;
-
-	assert(pa < pe);
-
-	va &= -BY2PG;
-	pa &= -BY2PG;
-	pe = PGROUND(pe);
-
-	attr |= PTEKERNEL | PTEAF;
-
-	l1 = (uintptr*)L1;
-
-	while(pa < pe){
-		if(l1[PTL1X(va, 1)] == 0 && (pe-pa) >= PGLSZ(1) && ((va|pa) & PGLSZ(1)-1) == 0){
-			l1[PTL1X(va, 1)] = PTEVALID | PTEBLOCK | pa | attr;
-			va += PGLSZ(1);
-			pa += PGLSZ(1);
-			continue;
-		}
-		if(l1[PTL1X(va, 1)] & PTEVALID) {
-			assert((l1[PTL1X(va, 1)] & PTETABLE) == PTETABLE);
-			l0 = KADDR(l1[PTL1X(va, 1)] & -PGLSZ(0));
-		} else {
-			l0 = rampage();
-			memset(l0, 0, BY2PG);
-			l1[PTL1X(va, 1)] = PTEVALID | PTETABLE | PADDR(l0);
-		}
-		assert(l0[PTLX(va, 0)] == 0);
-		l0[PTLX(va, 0)] = PTEVALID | PTEPAGE | pa | attr;
-		va += BY2PG;
-		pa += BY2PG;
-	}
-}
-
-static void
-kmapram(uintptr base, uintptr limit)
-{
-	if(base < (uintptr)-KZERO && limit > (uintptr)-KZERO){
-		kmapram(base, (uintptr)-KZERO);
-		kmapram((uintptr)-KZERO, limit);
-		return;
-	}
-	if(base < INITMAP)
-		base = INITMAP;
-	if(base >= limit || limit <= INITMAP)
-		return;
-
-	l1map((uintptr)kmapaddr(base), base, limit,
-		PTEWRITE | PTEPXN | PTEUXN | PTESH(SHARE_INNER));
-}
-
-void
-meminit(void)
-{
-	uvlong memsize = 0;
-	uintptr pa, va;
-	char *p, *e;
-	int i;
-
-	if(p = getconf("*maxmem")){
-		memsize = strtoull(p, &e, 0) - PHYSDRAM;
-		for(i = 1; i < nelem(conf.mem); i++){
-			if(e <= p || *e != ' ')
-				break;
-			p = ++e;
-			conf.mem[i].base = strtoull(p, &e, 0);
-			if(e <= p || *e != ' ')
-				break;
-			p = ++e;
-			conf.mem[i].limit = strtoull(p, &e, 0);
-		}
-	}
-
-	if (memsize < INITMAP)		/* sanity */
-		memsize = INITMAP;
-
-	getramsize(&conf.mem[0]);
-	if(conf.mem[0].limit == 0){
-		conf.mem[0].base = PHYSDRAM;
-		conf.mem[0].limit = PHYSDRAM + memsize;
-	}else if(p != nil)
-		conf.mem[0].limit = conf.mem[0].base + memsize;
-
-	/*
-	 * now we know the real memory regions, unmap
-	 * everything above INITMAP and map again with
-	 * the proper sizes.
-	 */
-	coherence();
-	for(va = INITMAP+KZERO; va != 0; va += PGLSZ(1))
-		((uintptr*)L1)[PTL1X(va, 1)] = 0;
-	flushtlb();
-
-	pa = PGROUND((uintptr)end)-KZERO;
-	for(i=0; i<nelem(conf.mem); i++){
-		if(conf.mem[i].limit >= KMAPEND-KMAP)
-			conf.mem[i].limit = KMAPEND-KMAP;
-
-		if(conf.mem[i].limit <= conf.mem[i].base){
-			conf.mem[i].limit = conf.mem[i].base = 0;
-			continue;
-		}
-
-		if(conf.mem[i].base < PHYSDRAM + soc.dramsize
-		&& conf.mem[i].limit > PHYSDRAM + soc.dramsize)
-			conf.mem[i].limit = PHYSDRAM + soc.dramsize;
-
-		/* take kernel out of allocatable space */
-		if(pa > conf.mem[i].base && pa < conf.mem[i].limit)
-			conf.mem[i].base = pa;
-
-		kmapram(conf.mem[i].base, conf.mem[i].limit);
-	}
-	flushtlb();
-
-	/* rampage() is now done, count up the pages for each bank */
-	for(i=0; i<nelem(conf.mem); i++)
-		conf.mem[i].npage = (conf.mem[i].limit - conf.mem[i].base)/BY2PG;
-}
-
-uintptr
-mmukmap(uintptr va, uintptr pa, usize size)
-{
-	uintptr attr, off;
-
-	if(va == 0)
-		return 0;
-
-	off = pa & BY2PG-1;
-
-	attr = va & PTEMA(7);
-	attr |= PTEWRITE | PTEUXN | PTEPXN | PTESH(SHARE_OUTER);
-
-	va &= -BY2PG;
-	pa &= -BY2PG;
-
-	l1map(va, pa, pa + off + size, attr);
-	flushtlb();
-
-	return va + off;
-}
-
-void*
-vmap(uvlong pa, vlong size)
-{
-	static uintptr base = VMAP;
-	uvlong pe = pa + size;
-	uintptr va;
-
-	va = base;
-	base += PGROUND(pe) - (pa & -BY2PG);
-	
-	return (void*)mmukmap(va | PTEDEVICE, pa, size);
-}
-
-void
-vunmap(void *, vlong)
-{
-}
-
-static uintptr*
-mmuwalk(uintptr va, int level)
-{
-	uintptr *table, pte;
-	Page *pg;
-	int i, x;
-
-	x = PTLX(va, PTLEVELS-1);
-	table = m->mmutop;
-	for(i = PTLEVELS-2; i >= level; i--){
-		pte = table[x];
-		if(pte & PTEVALID) {
-			if(pte & (0xFFFFULL<<48))
-				iprint("strange pte %#p va %#p\n", pte, va);
-			pte &= ~(0xFFFFULL<<48 | BY2PG-1);
-		} else {
-			pg = up->mmufree;
-			if(pg == nil)
-				return nil;
-			up->mmufree = pg->next;
-			pg->va = va & -PGLSZ(i+1);
-			if((pg->next = up->mmuhead[i+1]) == nil)
-				up->mmutail[i+1] = pg;
-			up->mmuhead[i+1] = pg;
-			pte = pg->pa;
-			memset(kmapaddr(pte), 0, BY2PG);
-			coherence();
-			table[x] = pte | PTEVALID | PTETABLE;
-		}
-		table = kmapaddr(pte);
-		x = PTLX(va, (uintptr)i);
-	}
-	return &table[x];
-}
-
-static Proc *asidlist[256];
-
-static int
-allocasid(Proc *p)
-{
-	static Lock lk;
-	Proc *x;
-	int a;
-
-	lock(&lk);
-	a = p->asid;
-	if(a < 0)
-		a = -a;
-	if(a == 0)
-		a = p->pid;
-	for(;; a++){
-		a %= nelem(asidlist);
-		if(a == 0)
-			continue;	// reserved
-		x = asidlist[a];
-		if(x == p || x == nil || (x->asid < 0 && x->mach == nil))
-			break;
-	}
-	p->asid = a;
-	asidlist[a] = p;
-	unlock(&lk);
-
-	return x != p;
-}
-
-static void
-freeasid(Proc *p)
-{
-	int a;
-
-	a = p->asid;
-	if(a < 0)
-		a = -a;
-	if(a > 0 && asidlist[a] == p)
-		asidlist[a] = nil;
-	p->asid = 0;
-}
-
-void
-putasid(Proc *p)
-{
-	/*
-	 * Prevent the following scenario:
-	 *	pX sleeps on cpuA, leaving its page tables in mmutop
-	 *	pX wakes up on cpuB, and exits, freeing its page tables
-	 *  pY on cpuB allocates a freed page table page and overwrites with data
-	 *  cpuA takes an interrupt, and is now running with bad page tables
-	 * In theory this shouldn't hurt because only user address space tables
-	 * are affected, and mmuswitch will clear mmutop before a user process is
-	 * dispatched.  But empirically it correlates with weird problems, eg
-	 * resetting of the core clock at 0x4000001C which confuses local timers.
-	 */
-	if(conf.nmach > 1)
-		mmuswitch(nil);
-
-	if(p->asid > 0)
-		p->asid = -p->asid;
-}
-
-void
-putmmu(uintptr va, uintptr pa, Page *pg)
-{
-	uintptr *pte, old;
-	int s;
-
-	s = splhi();
-	while((pte = mmuwalk(va, 0)) == nil){
-		spllo();
-		up->mmufree = newpage(0, nil, 0);
-		splhi();
-	}
-	old = *pte;
-	*pte = 0;
-	if((old & PTEVALID) != 0)
-		flushasidvall((uvlong)up->asid<<48 | va>>12);
-	else
-		flushasidva((uvlong)up->asid<<48 | va>>12);
-	*pte = pa | PTEPAGE | PTEUSER | PTEPXN | PTENG | PTEAF |
-		(((pa & PTEMA(7)) == PTECACHED)? PTESH(SHARE_INNER): PTESH(SHARE_OUTER));
-	if(needtxtflush(pg)){
-		cachedwbinvse(kmap(pg), BY2PG);
-		cacheiinvse((void*)va, BY2PG);
-		donetxtflush(pg);
-	}
-	splx(s);
-}
-
-static void
-mmufree(Proc *p)
-{
-	int i;
-
-	freeasid(p);
-
-	for(i=1; i<PTLEVELS; i++){
-		if(p->mmuhead[i] == nil)
-			break;
-		p->mmutail[i]->next = p->mmufree;
-		p->mmufree = p->mmuhead[i];
-		p->mmuhead[i] = p->mmutail[i] = nil;
-	}
-}
-
-void
-mmuswitch(Proc *p)
-{
-	uintptr va;
-	Page *t;
-
-	for(va = UZERO; va < USTKTOP; va += PGLSZ(PTLEVELS-1))
-		m->mmutop[PTLX(va, PTLEVELS-1)] = 0;
-
-	if(p == nil){
-		setttbr(PADDR(m->mmutop));
-		return;
-	}
-
-	if(p->newtlb){
-		mmufree(p);
-		p->newtlb = 0;
-	}
-
-	if(allocasid(p))
-		flushasid((uvlong)p->asid<<48);
-
-	setttbr((uvlong)p->asid<<48 | PADDR(m->mmutop));
-
-	for(t = p->mmuhead[PTLEVELS-1]; t != nil; t = t->next){
-		va = t->va;
-		m->mmutop[PTLX(va, PTLEVELS-1)] = t->pa | PTEVALID | PTETABLE;
-	}
-}
-
-void
-mmurelease(Proc *p)
-{
-	mmuswitch(nil);
-	mmufree(p);
-	freepages(p->mmufree, nil, 0);
-	p->mmufree = nil;
-}
-
-void
-flushmmu(void)
-{
-	int x;
-
-	x = splhi();
-	up->newtlb = 1;
-	mmuswitch(up);
-	splx(x);
-}
-
-void
-checkmmu(uintptr, uintptr)
-{
-}