diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-08-18 21:16:30 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-08-18 21:16:30 +0200 |
commit | f35d5ee5b036b7b4fa59b1839f52fca15b7f99f9 (patch) | |
tree | 3971890bfe57a66680d85baf2ab358b7b8496432 /sys/src/9/bcm64/mmu.c | |
parent | 3fc8d1bdae10955e0b31ee1766d17367e0d0caa1 (diff) |
bcm64: add support for more than 1GB of ram (untested)
this adds a 4GB KMAP window into the kernel address space
so we can access all physical ram on raspberry pi 4 for
user pages.
note that kernel memory above KZERO is still limited
to 1GB because of DMA restrictions.
Diffstat (limited to 'sys/src/9/bcm64/mmu.c')
-rw-r--r-- | sys/src/9/bcm64/mmu.c | 49 |
1 files changed, 39 insertions, 10 deletions
diff --git a/sys/src/9/bcm64/mmu.c b/sys/src/9/bcm64/mmu.c index 4fdf35749..78ff77eac 100644 --- a/sys/src/9/bcm64/mmu.c +++ b/sys/src/9/bcm64/mmu.c @@ -28,10 +28,29 @@ mmu0init(uintptr *l1) } if(PTLEVELS > 2) for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(2), va += PGLSZ(2)) - l1[PTL1X(pa, 2)] = (uintptr)&l1[L1TABLEX(pa, 1)] | PTEVALID | PTETABLE; + l1[PTL1X(va, 2)] = (uintptr)&l1[L1TABLEX(va, 1)] | PTEVALID | PTETABLE; if(PTLEVELS > 3) for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(3), va += PGLSZ(3)) - l1[PTL1X(pa, 3)] = (uintptr)&l1[L1TABLEX(pa, 2)] | PTEVALID | PTETABLE; + l1[PTL1X(va, 3)] = (uintptr)&l1[L1TABLEX(va, 2)] | PTEVALID | PTETABLE; + + /* KMAP */ + attr = PTEWRITE | PTEAF | PTEKERNEL | PTEUXN | PTEPXN | PTESH(SHARE_INNER); + pe = PHYSDRAM + soc.dramsize; + for(pa = PHYSDRAM, va = KMAP; pa < pe; pa += PGLSZ(1), va += PGLSZ(1)){ + if(pe - pa < PGLSZ(1)){ + l1[PTL1X(va, 1)] = (uintptr)l1 | PTEVALID | PTETABLE; + for(; pa < pe; pa += PGLSZ(0), va += PGLSZ(0)) + l1[PTLX(va, 0)] = pa | PTEVALID | PTEPAGE | attr; + break; + } + l1[PTL1X(va, 1)] = pa | PTEVALID | PTEBLOCK | attr; + } + if(PTLEVELS > 2) + for(pa = PHYSDRAM, va = KMAP; pa < pe; pa += PGLSZ(2), va += PGLSZ(2)) + l1[PTL1X(va, 2)] = (uintptr)&l1[L1TABLEX(va, 1)] | PTEVALID | PTETABLE; + if(PTLEVELS > 3) + for(pa = PHYSDRAM, va = KMAP; pa < pe; pa += PGLSZ(3), va += PGLSZ(3)) + l1[PTL1X(va, 3)] = (uintptr)&l1[L1TABLEX(va, 2)] | PTEVALID | PTETABLE; /* VIRTIO */ attr = PTEWRITE | PTEAF | PTEKERNEL | PTEUXN | PTEPXN | PTESH(SHARE_OUTER) | PTEDEVICE; @@ -130,6 +149,7 @@ mmu1init(void) mmuswitch(nil); } +/* KZERO maps the first 1GB of ram */ uintptr paddr(void *va) { @@ -156,15 +176,19 @@ kaddr(uintptr pa) return nil; } -void -kmapinval(void) +/* KMAP maps all of ram (up to 4GB) */ +static void* +kmapaddr(uintptr pa) { + if(pa < (uintptr)-KZERO) + return (void*)(pa + KZERO); + return (void*)(pa + KMAP); } KMap* kmap(Page *p) { - return kaddr(p->pa); + return kmapaddr(p->pa); } void @@ -172,6 +196,11 @@ kunmap(KMap*) { } +void +kmapinval(void) +{ +} + uintptr mmukmap(uintptr va, uintptr pa, usize size) { @@ -228,7 +257,6 @@ mmuwalk(uintptr va, int level) if(pte & (0xFFFFULL<<48)) iprint("strange pte %#p va %#p\n", pte, va); pte &= ~(0xFFFFULL<<48 | BY2PG-1); - table = KADDR(pte); } else { pg = up->mmufree; if(pg == nil) @@ -238,11 +266,12 @@ mmuwalk(uintptr va, int level) if((pg->next = up->mmuhead[i+1]) == nil) up->mmutail[i+1] = pg; up->mmuhead[i+1] = pg; - memset(KADDR(pg->pa), 0, BY2PG); + pte = pg->pa; + memset(kmapaddr(pte), 0, BY2PG); coherence(); - table[x] = pg->pa | PTEVALID | PTETABLE; - table = KADDR(pg->pa); + table[x] = pte | PTEVALID | PTETABLE; } + table = kmapaddr(pte); x = PTLX(va, (uintptr)i); } return &table[x]; @@ -333,7 +362,7 @@ putmmu(uintptr va, uintptr pa, Page *pg) *pte = pa | PTEPAGE | PTEUSER | PTEPXN | PTENG | PTEAF | PTESH(SHARE_INNER); if(pg->txtflush & (1UL<<m->machno)){ /* pio() sets PG_TXTFLUSH whenever a text pg has been written */ - cachedwbinvse((void*)KADDR(pg->pa), BY2PG); + cachedwbinvse(kmap(pg), BY2PG); cacheiinvse((void*)va, BY2PG); pg->txtflush &= ~(1UL<<m->machno); } |