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.
This commit is contained in:
cinap_lenrek 2019-05-15 16:19:20 +02:00
parent 47d3e8fc63
commit b24ed2bfac
2 changed files with 35 additions and 61 deletions

View file

@ -125,16 +125,12 @@ struct MMMU
struct PMMU struct PMMU
{ {
Page* mmul1; union {
Page* mmul1tail; Page *mmufree; /* mmuhead[0] is freelist head */
Page *mmuhead[PTLEVELS];
Page* mmul2; };
Page* mmul2tail; Page *mmutail[PTLEVELS];
Page* mmufree;
int asid; int asid;
uintptr tpidr; uintptr tpidr;
}; };

View file

@ -12,6 +12,9 @@ mmu0init(uintptr *l1)
/* 0 identity map */ /* 0 identity map */
pe = PHYSDRAM + soc.dramsize; pe = PHYSDRAM + soc.dramsize;
if(pe > (uintptr)-KZERO)
pe = (uintptr)-KZERO;
for(pa = PHYSDRAM; pa < pe; pa += PGLSZ(1)) for(pa = PHYSDRAM; pa < pe; pa += PGLSZ(1))
l1[PTL1X(pa, 1)] = pa | PTEVALID | PTEBLOCK | PTEWRITE | PTEAF l1[PTL1X(pa, 1)] = pa | PTEVALID | PTEBLOCK | PTEWRITE | PTEAF
| PTEKERNEL | PTESH(SHARE_INNER); | PTEKERNEL | PTESH(SHARE_INNER);
@ -52,6 +55,8 @@ mmu0clear(uintptr *l1)
uintptr va, pa, pe; uintptr va, pa, pe;
pe = PHYSDRAM + soc.dramsize; pe = PHYSDRAM + soc.dramsize;
if(pe > (uintptr)-KZERO)
pe = (uintptr)-KZERO;
for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1)){ for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1)){
if(PTL1X(pa, 1) != PTL1X(va, 1)) if(PTL1X(pa, 1) != PTL1X(va, 1))
@ -78,6 +83,8 @@ mmuidmap(uintptr *l1)
flushtlb(); flushtlb();
pe = PHYSDRAM + soc.dramsize; pe = PHYSDRAM + soc.dramsize;
if(pe > (uintptr)-KZERO)
pe = (uintptr)-KZERO;
for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1)){ for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1)){
if(PTL1X(pa, 1) != PTL1X(va, 1)) if(PTL1X(pa, 1) != PTL1X(va, 1))
@ -189,33 +196,18 @@ mmuwalk(uintptr va, int level)
pte &= ~(0xFFFFULL<<48 | BY2PG-1); pte &= ~(0xFFFFULL<<48 | BY2PG-1);
table = KADDR(pte); table = KADDR(pte);
} else { } else {
if(i < 2){
pg = up->mmufree; pg = up->mmufree;
if(pg == nil) if(pg == nil)
return nil; return nil;
up->mmufree = pg->next; up->mmufree = pg->next;
switch(i){ pg->va = va & -PGLSZ(i+1);
case 0: if((pg->next = up->mmuhead[i+1]) == nil)
pg->va = va & -PGLSZ(1); up->mmutail[i+1] = pg;
if((pg->next = up->mmul1) == nil) up->mmuhead[i+1] = pg;
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); memset(KADDR(pg->pa), 0, BY2PG);
coherence(); coherence();
table[x] = pg->pa | PTEVALID | PTETABLE; table[x] = pg->pa | PTEVALID | PTETABLE;
table = KADDR(pg->pa); table = KADDR(pg->pa);
} else {
table[x] = PADDR(&m->mmul1[L1TABLEX(va, 2)]) | PTEVALID | PTETABLE;
table = &m->mmul1[L1TABLEX(va, 2)];
}
} }
x = PTLX(va, (uintptr)i); x = PTLX(va, (uintptr)i);
} }
@ -318,20 +310,16 @@ putmmu(uintptr va, uintptr pa, Page *pg)
static void static void
mmufree(Proc *p) mmufree(Proc *p)
{ {
int i;
freeasid(p); freeasid(p);
if(p->mmul1 == nil){ for(i=1; i<PTLEVELS; i++){
assert(p->mmul2 == nil); if(p->mmuhead[i] == nil)
return; break;
} p->mmutail[i]->next = p->mmufree;
p->mmul1tail->next = p->mmufree; p->mmufree = p->mmuhead[i];
p->mmufree = p->mmul1; p->mmuhead[i] = p->mmutail[i] = nil;
p->mmul1 = p->mmul1tail = nil;
if(PTLEVELS > 2){
p->mmul2tail->next = p->mmufree;
p->mmufree = p->mmul2;
p->mmul2 = p->mmul2tail = nil;
} }
} }
@ -354,19 +342,9 @@ mmuswitch(Proc *p)
p->newtlb = 0; p->newtlb = 0;
} }
if(PTLEVELS == 2){ for(t = p->mmuhead[PTLEVELS-1]; t != nil; t = t->next){
for(t = p->mmul1; t != nil; t = t->next){
va = t->va; va = t->va;
m->mmul1[PTL1X(va, 1)] = t->pa | PTEVALID | PTETABLE; m->mmul1[PTL1X(va, PTLEVELS-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;
}
} }
if(allocasid(p)) if(allocasid(p))