changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: bcm64: generalize mmu code

changeset 7239: c0e23a8829f7
parent 7238: 9fe2319844b6
child 7240: b0b9d97f9ed8
child 7241: 4b6277dd0535
author: cinap_lenrek@felloff.net
date: Wed, 15 May 2019 16:19:20 +0200
files: sys/src/9/bcm64/dat.h sys/src/9/bcm64/mmu.c
description: bcm64: generalize mmu code

make user page table list heads arrays so we can
index into the right level avoiding the special
cases for differen PTLEVELS.
     1.1--- a/sys/src/9/bcm64/dat.h
     1.2+++ b/sys/src/9/bcm64/dat.h
     1.3@@ -125,16 +125,12 @@ struct MMMU
     1.4 
     1.5 struct PMMU
     1.6 {
     1.7-	Page*	mmul1;
     1.8-	Page*	mmul1tail;
     1.9-
    1.10-	Page*	mmul2;
    1.11-	Page*	mmul2tail;
    1.12-
    1.13-	Page*	mmufree;
    1.14-
    1.15+	union {
    1.16+	Page	*mmufree;	/* mmuhead[0] is freelist head */
    1.17+	Page	*mmuhead[PTLEVELS];
    1.18+	};
    1.19+	Page	*mmutail[PTLEVELS];
    1.20 	int	asid;
    1.21-
    1.22 	uintptr	tpidr;
    1.23 };
    1.24 
     2.1--- a/sys/src/9/bcm64/mmu.c
     2.2+++ b/sys/src/9/bcm64/mmu.c
     2.3@@ -12,6 +12,9 @@ mmu0init(uintptr *l1)
     2.4 
     2.5 	/* 0 identity map */
     2.6 	pe = PHYSDRAM + soc.dramsize;
     2.7+	if(pe > (uintptr)-KZERO)
     2.8+		pe = (uintptr)-KZERO;
     2.9+
    2.10 	for(pa = PHYSDRAM; pa < pe; pa += PGLSZ(1))
    2.11 		l1[PTL1X(pa, 1)] = pa | PTEVALID | PTEBLOCK | PTEWRITE | PTEAF
    2.12 			 | PTEKERNEL | PTESH(SHARE_INNER);
    2.13@@ -52,6 +55,8 @@ mmu0clear(uintptr *l1)
    2.14 	uintptr va, pa, pe;
    2.15 
    2.16 	pe = PHYSDRAM + soc.dramsize;
    2.17+	if(pe > (uintptr)-KZERO)
    2.18+		pe = (uintptr)-KZERO;
    2.19 
    2.20 	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1)){
    2.21 		if(PTL1X(pa, 1) != PTL1X(va, 1))
    2.22@@ -78,6 +83,8 @@ mmuidmap(uintptr *l1)
    2.23 	flushtlb();
    2.24 
    2.25 	pe = PHYSDRAM + soc.dramsize;
    2.26+	if(pe > (uintptr)-KZERO)
    2.27+		pe = (uintptr)-KZERO;
    2.28 
    2.29 	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1)){
    2.30 		if(PTL1X(pa, 1) != PTL1X(va, 1))
    2.31@@ -189,33 +196,18 @@ mmuwalk(uintptr va, int level)
    2.32 			pte &= ~(0xFFFFULL<<48 | BY2PG-1);
    2.33 			table = KADDR(pte);
    2.34 		} else {
    2.35-			if(i < 2){
    2.36-				pg = up->mmufree;
    2.37-				if(pg == nil)
    2.38-					return nil;
    2.39-				up->mmufree = pg->next;
    2.40-				switch(i){
    2.41-				case 0:
    2.42-					pg->va = va & -PGLSZ(1);
    2.43-					if((pg->next = up->mmul1) == nil)
    2.44-						up->mmul1tail = pg;
    2.45-					up->mmul1 = pg;
    2.46-					break;
    2.47-				case 1:
    2.48-					pg->va = va & -PGLSZ(2);
    2.49-					if((pg->next = up->mmul2) == nil)
    2.50-						up->mmul2tail = pg;
    2.51-					up->mmul2 = pg;
    2.52-					break;
    2.53-				}
    2.54-				memset(KADDR(pg->pa), 0, BY2PG);
    2.55-				coherence();
    2.56-				table[x] = pg->pa | PTEVALID | PTETABLE;
    2.57-				table = KADDR(pg->pa);
    2.58-			} else {
    2.59-				table[x] = PADDR(&m->mmul1[L1TABLEX(va, 2)]) | PTEVALID | PTETABLE;
    2.60-				table = &m->mmul1[L1TABLEX(va, 2)];
    2.61-			}
    2.62+			pg = up->mmufree;
    2.63+			if(pg == nil)
    2.64+				return nil;
    2.65+			up->mmufree = pg->next;
    2.66+			pg->va = va & -PGLSZ(i+1);
    2.67+			if((pg->next = up->mmuhead[i+1]) == nil)
    2.68+				up->mmutail[i+1] = pg;
    2.69+			up->mmuhead[i+1] = pg;
    2.70+			memset(KADDR(pg->pa), 0, BY2PG);
    2.71+			coherence();
    2.72+			table[x] = pg->pa | PTEVALID | PTETABLE;
    2.73+			table = KADDR(pg->pa);
    2.74 		}
    2.75 		x = PTLX(va, (uintptr)i);
    2.76 	}
    2.77@@ -318,20 +310,16 @@ putmmu(uintptr va, uintptr pa, Page *pg)
    2.78 static void
    2.79 mmufree(Proc *p)
    2.80 {
    2.81+	int i;
    2.82+
    2.83 	freeasid(p);
    2.84 
    2.85-	if(p->mmul1 == nil){
    2.86-		assert(p->mmul2 == nil);
    2.87-		return;
    2.88-	}
    2.89-	p->mmul1tail->next = p->mmufree;
    2.90-	p->mmufree = p->mmul1;
    2.91-	p->mmul1 = p->mmul1tail = nil;
    2.92-
    2.93-	if(PTLEVELS > 2){
    2.94-		p->mmul2tail->next = p->mmufree;
    2.95-		p->mmufree = p->mmul2;
    2.96-		p->mmul2 = p->mmul2tail = nil;
    2.97+	for(i=1; i<PTLEVELS; i++){
    2.98+		if(p->mmuhead[i] == nil)
    2.99+			break;
   2.100+		p->mmutail[i]->next = p->mmufree;
   2.101+		p->mmufree = p->mmuhead[i];
   2.102+		p->mmuhead[i] = p->mmutail[i] = nil;
   2.103 	}
   2.104 }
   2.105 
   2.106@@ -354,19 +342,9 @@ mmuswitch(Proc *p)
   2.107 		p->newtlb = 0;
   2.108 	}
   2.109 
   2.110-	if(PTLEVELS == 2){
   2.111-		for(t = p->mmul1; t != nil; t = t->next){
   2.112-			va = t->va;
   2.113-			m->mmul1[PTL1X(va, 1)] = t->pa | PTEVALID | PTETABLE;
   2.114-		}
   2.115-	} else {
   2.116-		for(t = p->mmul2; t != nil; t = t->next){
   2.117-			va = t->va;
   2.118-			m->mmul1[PTL1X(va, 2)] = t->pa | PTEVALID | PTETABLE;
   2.119-			if(PTLEVELS > 3)
   2.120-				m->mmul1[PTL1X(va, 3)] = PADDR(&m->mmul1[L1TABLEX(va, 2)]) |
   2.121-					PTEVALID | PTETABLE;
   2.122-		}
   2.123+	for(t = p->mmuhead[PTLEVELS-1]; t != nil; t = t->next){
   2.124+		va = t->va;
   2.125+		m->mmul1[PTL1X(va, PTLEVELS-1)] = t->pa | PTEVALID | PTETABLE;
   2.126 	}
   2.127 
   2.128 	if(allocasid(p))