summaryrefslogtreecommitdiff
path: root/sys/src
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2019-05-15 16:19:20 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2019-05-15 16:19:20 +0200
commitb24ed2bfac81798221977ffed8980d2b4eeab199 (patch)
tree9a8738b6f7d3b79db72f58b42d08cd352fbc639b /sys/src
parent47d3e8fc6394dac68e0cec8ef5f74534cfb68747 (diff)
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.
Diffstat (limited to 'sys/src')
-rw-r--r--sys/src/9/bcm64/dat.h14
-rw-r--r--sys/src/9/bcm64/mmu.c82
2 files changed, 35 insertions, 61 deletions
diff --git a/sys/src/9/bcm64/dat.h b/sys/src/9/bcm64/dat.h
index 89336b4cd..7a1747029 100644
--- a/sys/src/9/bcm64/dat.h
+++ b/sys/src/9/bcm64/dat.h
@@ -125,16 +125,12 @@ struct MMMU
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;
};
diff --git a/sys/src/9/bcm64/mmu.c b/sys/src/9/bcm64/mmu.c
index d78458ec8..29313d3ac 100644
--- a/sys/src/9/bcm64/mmu.c
+++ b/sys/src/9/bcm64/mmu.c
@@ -12,6 +12,9 @@ mmu0init(uintptr *l1)
/* 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 @@ mmu0clear(uintptr *l1)
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 @@ mmuidmap(uintptr *l1)
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 @@ mmuwalk(uintptr va, int level)
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,20 +310,16 @@ putmmu(uintptr va, uintptr pa, Page *pg)
static void
mmufree(Proc *p)
{
+ int i;
+
freeasid(p);
- if(p->mmul1 == nil){
- assert(p->mmul2 == nil);
- return;
- }
- 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;
+ 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;
}
}
@@ -354,19 +342,9 @@ mmuswitch(Proc *p)
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))