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:
parent
47d3e8fc63
commit
b24ed2bfac
2 changed files with 35 additions and 61 deletions
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
|
|
Loading…
Reference in a new issue