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:
cinap_lenrek 2019-08-18 21:16:30 +02:00
parent 3fc8d1bdae
commit f35d5ee5b0
3 changed files with 42 additions and 13 deletions

View file

@ -17,7 +17,7 @@ typedef struct Mboxes Mboxes;
#define POWERREGS (VIRTIO+0x100000)
Soc soc = {
.dramsize = 0x40000000,
.dramsize = 0xFC000000,
.busdram = 0xC0000000,
.iosize = 0x03000000,
.busio = 0x7C000000,

View file

@ -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 */

View file

@ -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);
}