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.
This commit is contained in:
parent
3fc8d1bdae
commit
f35d5ee5b0
3 changed files with 42 additions and 13 deletions
|
@ -17,7 +17,7 @@ typedef struct Mboxes Mboxes;
|
|||
#define POWERREGS (VIRTIO+0x100000)
|
||||
|
||||
Soc soc = {
|
||||
.dramsize = 0x40000000,
|
||||
.dramsize = 0xFC000000,
|
||||
.busdram = 0xC0000000,
|
||||
.iosize = 0x03000000,
|
||||
.busio = 0x7C000000,
|
||||
|
|
|
@ -39,7 +39,8 @@
|
|||
#define STACKALIGN(sp) ((sp) & ~7) /* bug: assure with alloc */
|
||||
#define TRAPFRAMESIZE (38*8)
|
||||
|
||||
#define KSEG0 (0xFFFFFFFF00000000ULL)
|
||||
#define KSEG0 (0xFFFFFFFE00000000ULL)
|
||||
#define KMAP (0xFFFFFFFE00000000ULL)
|
||||
#define FRAMEBUFFER (0xFFFFFFFF00000000ULL|PTEWT)
|
||||
#define VGPIO 0 /* virtual gpio for pi3 ACT LED */
|
||||
|
||||
|
@ -54,7 +55,6 @@
|
|||
|
||||
#define SPINTABLE (KZERO+0xd8)
|
||||
#define CONFADDR (KZERO+0x100)
|
||||
#define VECTORSEL2 (0x1000)
|
||||
#define REBOOTADDR (0x1c00) /* reboot code - physical address */
|
||||
#define VCBUFFER (KZERO+0x3400) /* videocore mailbox buffer */
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue