ref: b24ed2bfac81798221977ffed8980d2b4eeab199
parent: 47d3e8fc6394dac68e0cec8ef5f74534cfb68747
author: cinap_lenrek <[email protected]>
date: Wed May 15 12:19:20 EDT 2019
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.
--- a/sys/src/9/bcm64/dat.h
+++ b/sys/src/9/bcm64/dat.h
@@ -125,16 +125,12 @@
struct PMMU
{
- Page* mmul1;
- Page* mmul1tail;
-
- Page* mmul2;
- Page* mmul2tail;
-
- Page* mmufree;
-
+ union {
+ Page *mmufree; /* mmuhead[0] is freelist head */
+ Page *mmuhead[PTLEVELS];
+ };
+ Page *mmutail[PTLEVELS];
int asid;
-
uintptr tpidr;
};
--- a/sys/src/9/bcm64/mmu.c
+++ b/sys/src/9/bcm64/mmu.c
@@ -12,6 +12,9 @@
/* 0 identity map */
pe = PHYSDRAM + soc.dramsize;
+ if(pe > (uintptr)-KZERO)
+ pe = (uintptr)-KZERO;
+
for(pa = PHYSDRAM; pa < pe; pa += PGLSZ(1))
l1[PTL1X(pa, 1)] = pa | PTEVALID | PTEBLOCK | PTEWRITE | PTEAF
| PTEKERNEL | PTESH(SHARE_INNER);
@@ -52,6 +55,8 @@
uintptr va, pa, pe;
pe = PHYSDRAM + soc.dramsize;
+ if(pe > (uintptr)-KZERO)
+ pe = (uintptr)-KZERO;
for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1)){
if(PTL1X(pa, 1) != PTL1X(va, 1))
@@ -78,6 +83,8 @@
flushtlb();
pe = PHYSDRAM + soc.dramsize;
+ if(pe > (uintptr)-KZERO)
+ pe = (uintptr)-KZERO;
for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1)){
if(PTL1X(pa, 1) != PTL1X(va, 1))
@@ -189,33 +196,18 @@
pte &= ~(0xFFFFULL<<48 | BY2PG-1);
table = KADDR(pte);
} else {
- if(i < 2){
- pg = up->mmufree;
- if(pg == nil)
- return nil;
- up->mmufree = pg->next;
- switch(i){
- case 0:
- pg->va = va & -PGLSZ(1);
- if((pg->next = up->mmul1) == nil)
- up->mmul1tail = pg;
- up->mmul1 = pg;
- break;
- case 1:
- pg->va = va & -PGLSZ(2);
- if((pg->next = up->mmul2) == nil)
- up->mmul2tail = pg;
- up->mmul2 = pg;
- break;
- }
- memset(KADDR(pg->pa), 0, BY2PG);
- coherence();
- table[x] = pg->pa | PTEVALID | PTETABLE;
- table = KADDR(pg->pa);
- } else {
- table[x] = PADDR(&m->mmul1[L1TABLEX(va, 2)]) | PTEVALID | PTETABLE;
- table = &m->mmul1[L1TABLEX(va, 2)];
- }
+ 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;
+ memset(KADDR(pg->pa), 0, BY2PG);
+ coherence();
+ table[x] = pg->pa | PTEVALID | PTETABLE;
+ table = KADDR(pg->pa);
}
x = PTLX(va, (uintptr)i);
}
@@ -318,21 +310,17 @@
static void
mmufree(Proc *p)
{
+ int i;
+
freeasid(p);
- if(p->mmul1 == nil){
- assert(p->mmul2 == nil);
- return;
+ 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;
}
- p->mmul1tail->next = p->mmufree;
- p->mmufree = p->mmul1;
- p->mmul1 = p->mmul1tail = nil;
-
- if(PTLEVELS > 2){
- p->mmul2tail->next = p->mmufree;
- p->mmufree = p->mmul2;
- p->mmul2 = p->mmul2tail = nil;
- }
}
void
@@ -354,19 +342,9 @@
p->newtlb = 0;
}
- if(PTLEVELS == 2){
- for(t = p->mmul1; t != nil; t = t->next){
- va = t->va;
- m->mmul1[PTL1X(va, 1)] = t->pa | PTEVALID | PTETABLE;
- }
- } else {
- for(t = p->mmul2; t != nil; t = t->next){
- va = t->va;
- m->mmul1[PTL1X(va, 2)] = t->pa | PTEVALID | PTETABLE;
- if(PTLEVELS > 3)
- m->mmul1[PTL1X(va, 3)] = PADDR(&m->mmul1[L1TABLEX(va, 2)]) |
- PTEVALID | PTETABLE;
- }
+ for(t = p->mmuhead[PTLEVELS-1]; t != nil; t = t->next){
+ va = t->va;
+ m->mmul1[PTL1X(va, PTLEVELS-1)] = t->pa | PTEVALID | PTETABLE;
}
if(allocasid(p))