ref: a852f55b6c9e9c374fe35fafe6cf1fdfeea7211a
parent: 18d67944be2fdb709c67ed9a28e43e67188bd19a
parent: d5e45580788cfa62afea322e5676cf9e5f77d0a4
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Fri May 17 15:01:14 EDT 2019
merge
--- a/sys/src/9/bcm64/dat.h
+++ b/sys/src/9/bcm64/dat.h
@@ -115,7 +115,7 @@
*/
struct MMMU
{
- PTE* mmul1; /* l1 for this processor */
+ PTE* mmutop; /* first level user page table */
};
/*
@@ -245,8 +245,6 @@
uintptr busdram;
uintptr busio;
uintptr armlocal;
- u32int l1ptedramattrs;
- u32int l2ptedramattrs;
};
extern Soc soc;
--- a/sys/src/9/bcm64/l.s
+++ b/sys/src/9/bcm64/l.s
@@ -195,8 +195,8 @@
/* T0SZ */ | (64-EVASHIFT)<<0 )
MOV $TCRINIT, R1
MRS ID_AA64MMFR0_EL1, R2
- ANDW $0xF, R2 // IPS
- ADD R2<<32, R1
+ ANDW $0x7, R2 // PARange
+ ADD R2<<32, R1 // IPS
MSR R1, TCR_EL1
ISB $SY
@@ -331,8 +331,7 @@
MSR R0, TTBR0_EL1
DSB $ISH
ISB $SY
-
- B cacheiinv(SB)
+ RETURN
/*
* TLB maintenance operations.
--- a/sys/src/9/bcm64/mem.h
+++ b/sys/src/9/bcm64/mem.h
@@ -17,11 +17,11 @@
* 16K 32M 64G 128T
* 64K 512M 4T -
*/
-#define PGSHIFT 12 /* log(BY2PG) */
+#define PGSHIFT 16 /* log(BY2PG) */
#define BY2PG (1ULL<<PGSHIFT) /* bytes per page */
/* effective virtual address space */
-#define EVASHIFT 36
+#define EVASHIFT 33
#define EVAMASK ((1ULL<<EVASHIFT)-1)
#define PTSHIFT (PGSHIFT-3)
@@ -31,8 +31,8 @@
#define PTL1X(v, l) (L1TABLEX(v, l) | PTLX(v, l))
#define L1TABLEX(v, l) (L1TABLE(v, l) << PTSHIFT)
-#define L1TABLES HOWMANY(-KZERO, PGLSZ(2))
-#define L1TABLE(v, l) (L1TABLES-1 - ((PTLX(v, 2) % L1TABLES) >> (((l)-1)*PTSHIFT)) + (l)-1)
+#define L1TABLES HOWMANY(-KSEG0, PGLSZ(2))
+#define L1TABLE(v, l) (L1TABLES - ((PTLX(v, 2) % L1TABLES) >> (((l)-1)*PTSHIFT)) + (l)-1)
#define L1TOPSIZE (1ULL << (EVASHIFT - PTLEVELS*PTSHIFT))
#define MAXMACH 4 /* max # cpus system can run */
@@ -42,15 +42,13 @@
#define STACKALIGN(sp) ((sp) & ~7) /* bug: assure with alloc */
#define TRAPFRAMESIZE (38*8)
-/*
- * Address spaces.
- * KTZERO is used by kprof and dumpstack (if any).
- *
- * KZERO is mapped to physical 0 (start of ram).
- */
+#define KSEG0 (0xFFFFFFFF00000000ULL)
+#define VIRTIO (0xFFFFFFFF3F000000ULL) /* i/o registers */
+#define ARMLOCAL (0xFFFFFFFF40000000ULL)
+#define KZERO (0xFFFFFFFF80000000ULL) /* kernel address space */
+#define FRAMEBUFFER (0xFFFFFFFFC0000000ULL|PTEWT)
+#define VGPIO 0 /* virtual gpio for pi3 ACT LED */
-#define KZERO 0xFFFFFFFF80000000ULL /* kernel address space */
-
#define SPINTABLE (KZERO+0xd8)
#define CONFADDR (KZERO+0x100)
#define REBOOTADDR (0x1c00) /* reboot code - physical address */
@@ -57,16 +55,12 @@
#define VCBUFFER (KZERO+0x3400) /* videocore mailbox buffer */
#define L1 (L1TOP-L1SIZE)
-#define L1SIZE ((L1TABLES+PTLEVELS-3)*BY2PG)
+#define L1SIZE ((L1TABLES+PTLEVELS-2)*BY2PG)
#define L1TOP ((MACHADDR(MAXMACH-1)-L1TOPSIZE)&-BY2PG)
#define MACHADDR(n) (KTZERO-((n)+1)*MACHSIZE)
#define KTZERO (KZERO+0x80000) /* kernel text start */
-#define FRAMEBUFFER (0xFFFFFFFFC0000000ULL | PTEWT)
-#define VIRTIO 0xFFFFFFFFE0000000ULL /* i/o registers */
-#define ARMLOCAL (VIRTIO+IOSIZE)
-#define VGPIO 0 /* virtual gpio for pi3 ACT LED */
#define UZERO 0ULL /* user segment */
#define UTZERO (UZERO+0x10000) /* user text start */
--- a/sys/src/9/bcm64/mkfile
+++ b/sys/src/9/bcm64/mkfile
@@ -71,11 +71,11 @@
$p$CONF:DQ: $CONF.c $OBJ $LIB mkfile
$CC $CFLAGS '-DKERNDATE='`{date -n} $CONF.c
echo '# linking raw kernel' # H6: no headers, data segment aligned
- $LD -l -o $target -H6 -R4096 -T$loadaddr $OBJ $CONF.$O $LIB
+ $LD -l -o $target -H6 -R0x10000 -T$loadaddr $OBJ $CONF.$O $LIB
s$p$CONF:DQ: $CONF.$O $OBJ $LIB
echo '# linking kernel with symbols'
- $LD -l -o $target -R4096 -T$loadaddr $OBJ $CONF.$O $LIB
+ $LD -l -o $target -R0x10000 -T$loadaddr $OBJ $CONF.$O $LIB
size $target
$p$CONF.gz:D: $p$CONF
--- a/sys/src/9/bcm64/mmu.c
+++ b/sys/src/9/bcm64/mmu.c
@@ -8,44 +8,64 @@
void
mmu0init(uintptr *l1)
{
- uintptr va, pa, pe;
+ uintptr va, pa, pe, attr;
- /* 0 identity map */
+ /* KZERO */
+ attr = PTEWRITE | PTEAF | PTEKERNEL | PTESH(SHARE_INNER);
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);
+ for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1)){
+ if(pe - pa < PGLSZ(1)){
+ l1[PTL1X(va, 1)] = (uintptr)l1 | PTEVALID | PTETABLE;
+ l1[PTL1X(pa, 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;
+ l1[PTL1X(pa, 1)] = pa | PTEVALID | PTEBLOCK | attr;
+ }
+ pe = (uintptr)-KZERO; /* populate top levels for mmukmap() */
if(PTLEVELS > 2)
- for(pa = PHYSDRAM; pa < pe; pa += PGLSZ(2))
+ for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(2), va += PGLSZ(2)){
+ l1[PTL1X(va, 2)] = (uintptr)&l1[L1TABLEX(va, 1)] | PTEVALID | PTETABLE;
l1[PTL1X(pa, 2)] = (uintptr)&l1[L1TABLEX(pa, 1)] | PTEVALID | PTETABLE;
+ }
if(PTLEVELS > 3)
- for(pa = PHYSDRAM; pa < pe; pa += PGLSZ(3))
+ for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(3), va += PGLSZ(3)){
+ l1[PTL1X(va, 3)] = (uintptr)&l1[L1TABLEX(va, 2)] | PTEVALID | PTETABLE;
l1[PTL1X(pa, 3)] = (uintptr)&l1[L1TABLEX(pa, 2)] | PTEVALID | PTETABLE;
+ }
- /* KZERO */
- for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1))
- l1[PTL1X(va, 1)] = pa | PTEVALID | PTEBLOCK | PTEWRITE | PTEAF
- | PTEKERNEL | PTESH(SHARE_INNER);
+ /* VIRTIO */
+ attr = PTEWRITE | PTEAF | PTEKERNEL | PTESH(SHARE_OUTER) | PTEDEVICE;
+ pe = soc.physio + IOSIZE;
+ for(pa = soc.physio, va = VIRTIO; 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 = KZERO; pa < pe; pa += PGLSZ(2), va += PGLSZ(2))
+ for(pa = soc.physio, va = VIRTIO; 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 = KZERO; pa < pe; pa += PGLSZ(3), va += PGLSZ(3))
+ for(pa = soc.physio, va = VIRTIO; pa < pe; pa += PGLSZ(3), va += PGLSZ(3))
l1[PTL1X(va, 3)] = (uintptr)&l1[L1TABLEX(va, 2)] | PTEVALID | PTETABLE;
- /* VIRTIO */
- pe = -VIRTIO + soc.physio;
- for(pa = soc.physio, va = VIRTIO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1))
- l1[PTL1X(va, 1)] = pa | PTEVALID | PTEBLOCK | PTEWRITE | PTEAF
- | PTEKERNEL | PTESH(SHARE_OUTER) | PTEDEVICE;
+ /* ARMLOCAL */
+ pe = soc.armlocal + MB;
+ for(pa = soc.armlocal, va = ARMLOCAL; pa < pe; pa += PGLSZ(1), va += PGLSZ(1))
+ l1[PTL1X(va, 1)] = pa | PTEVALID | PTEBLOCK | attr;
if(PTLEVELS > 2)
- for(pa = soc.physio, va = VIRTIO; pa < pe; pa += PGLSZ(2), va += PGLSZ(2))
+ for(pa = soc.armlocal, va = ARMLOCAL; pa < pe; pa += PGLSZ(2), va += PGLSZ(2))
l1[PTL1X(va, 2)] = (uintptr)&l1[L1TABLEX(va, 1)] | PTEVALID | PTETABLE;
if(PTLEVELS > 3)
- for(pa = soc.physio, va = VIRTIO; pa < pe; pa += PGLSZ(3), va += PGLSZ(3))
+ for(pa = soc.armlocal, va = ARMLOCAL; pa < pe; pa += PGLSZ(3), va += PGLSZ(3))
l1[PTL1X(va, 3)] = (uintptr)&l1[L1TABLEX(va, 2)] | PTEVALID | PTETABLE;
}
@@ -57,21 +77,17 @@
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))
l1[PTL1X(pa, 1)] = 0;
- }
if(PTLEVELS > 2)
- for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(2), va += PGLSZ(2)){
+ for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(2), va += PGLSZ(2))
if(PTL1X(pa, 2) != PTL1X(va, 2))
l1[PTL1X(pa, 2)] = 0;
- }
if(PTLEVELS > 3)
- for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(3), va += PGLSZ(3)){
+ for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(3), va += PGLSZ(3))
if(PTL1X(pa, 3) != PTL1X(va, 3))
l1[PTL1X(pa, 3)] = 0;
- }
}
void
@@ -79,28 +95,17 @@
{
uintptr va, pa, pe;
- mmuswitch(nil);
- 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))
- l1[PTL1X(pa, 1)] = pa | PTEVALID | PTEBLOCK | PTEWRITE | PTEAF
- | PTEKERNEL | PTESH(SHARE_INNER);
- }
+ for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1))
+ l1[PTL1X(pa, 1)] = l1[PTL1X(va, 1)];
if(PTLEVELS > 2)
- for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(2), va += PGLSZ(2)){
- if(PTL1X(pa, 2) != PTL1X(va, 2))
- l1[PTL1X(pa, 2)] = PADDR(&l1[L1TABLEX(pa, 1)]) | PTEVALID | PTETABLE;
- }
+ for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(2), va += PGLSZ(2))
+ l1[PTL1X(pa, 2)] = l1[PTL1X(va, 2)];
if(PTLEVELS > 3)
- for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(3), va += PGLSZ(3)){
- if(PTL1X(pa, 3) != PTL1X(va, 3))
- l1[PTL1X(pa, 3)] = PADDR(&l1[L1TABLEX(pa, 2)]) | PTEVALID | PTETABLE;
- }
+ for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(3), va += PGLSZ(3))
+ l1[PTL1X(pa, 3)] = l1[PTL1X(va, 3)];
setttbr(PADDR(&l1[L1TABLEX(0, PTLEVELS-1)]));
}
@@ -107,10 +112,10 @@
void
mmu1init(void)
{
- m->mmul1 = mallocalign(L1SIZE+L1TOPSIZE, BY2PG, L1SIZE, 0);
- if(m->mmul1 == nil)
- panic("mmu1init: no memory for mmul1");
- memset(m->mmul1, 0, L1SIZE+L1TOPSIZE);
+ m->mmutop = mallocalign(L1TOPSIZE, BY2PG, 0, 0);
+ if(m->mmutop == nil)
+ panic("mmu1init: no memory for mmutop");
+ memset(m->mmutop, 0, L1TOPSIZE);
mmuswitch(nil);
}
@@ -187,7 +192,7 @@
int i, x;
x = PTLX(va, PTLEVELS-1);
- table = &m->mmul1[L1TABLEX(va, PTLEVELS-1)];
+ table = m->mmutop;
for(i = PTLEVELS-2; i >= level; i--){
pte = table[x];
if(pte & PTEVALID) {
@@ -262,12 +267,12 @@
{
/*
* Prevent the following scenario:
- * pX sleeps on cpuA, leaving its page tables in mmul1
+ * pX sleeps on cpuA, leaving its page tables in mmutop
* pX wakes up on cpuB, and exits, freeing its page tables
* pY on cpuB allocates a freed page table page and overwrites with data
* cpuA takes an interrupt, and is now running with bad page tables
* In theory this shouldn't hurt because only user address space tables
- * are affected, and mmuswitch will clear mmul1 before a user process is
+ * are affected, and mmuswitch will clear mmutop before a user process is
* dispatched. But empirically it correlates with weird problems, eg
* resetting of the core clock at 0x4000001C which confuses local timers.
*/
@@ -287,7 +292,6 @@
s = splhi();
while((pte = mmuwalk(va, 0)) == nil){
spllo();
- assert(up->mmufree == nil);
up->mmufree = newpage(0, nil, 0);
splhi();
}
@@ -330,10 +334,10 @@
Page *t;
for(va = UZERO; va < USTKTOP; va += PGLSZ(PTLEVELS-1))
- m->mmul1[PTL1X(va, PTLEVELS-1)] = 0;
+ m->mmutop[PTLX(va, PTLEVELS-1)] = 0;
if(p == nil){
- setttbr(PADDR(&m->mmul1[L1TABLEX(0, PTLEVELS-1)]));
+ setttbr(PADDR(m->mmutop));
return;
}
@@ -344,13 +348,13 @@
for(t = p->mmuhead[PTLEVELS-1]; t != nil; t = t->next){
va = t->va;
- m->mmul1[PTL1X(va, PTLEVELS-1)] = t->pa | PTEVALID | PTETABLE;
+ m->mmutop[PTLX(va, PTLEVELS-1)] = t->pa | PTEVALID | PTETABLE;
}
if(allocasid(p))
flushasid((uvlong)p->asid<<48);
- setttbr((uvlong)p->asid<<48 | PADDR(&m->mmul1[L1TABLEX(0, PTLEVELS-1)]));
+ setttbr((uvlong)p->asid<<48 | PADDR(m->mmutop));
}
void
--- a/sys/src/9/port/rebootcmd.c
+++ b/sys/src/9/port/rebootcmd.c
@@ -37,7 +37,7 @@
{
Chan *c;
Exec exec;
- ulong magic, text, rtext, entry, data, size;
+ ulong magic, text, rtext, entry, data, size, align;
uchar *p;
if(argc == 0)
@@ -68,8 +68,17 @@
if(magic & HDR_MAGIC)
readn(c, &exec, 8);
+ switch(magic){
+ case R_MAGIC:
+ align = 0x10000; /* 64k segment alignment for arm64 */
+ break;
+ default:
+ align = BY2PG;
+ break;
+ }
+
/* round text out to page boundary */
- rtext = PGROUND(entry+text)-entry;
+ rtext = ROUND(entry+text, align)-entry;
size = rtext + data;
p = malloc(size);
if(p == nil)
--- a/sys/src/cmd/7l/asm.c
+++ b/sys/src/cmd/7l/asm.c
@@ -100,7 +100,7 @@
seek(cout, OFFSET, 0);
break;
case 6: /* no header, padded segments */
- OFFSET = rnd(HEADR+textsize, 4096);
+ OFFSET = rnd(HEADR+textsize, INITRND);
seek(cout, OFFSET, 0);
break;
}
@@ -132,7 +132,7 @@
seek(cout, OFFSET, 0);
break;
case 6: /* no header, padded segments */
- OFFSET += rnd(datsize, 4096);
+ OFFSET += rnd(datsize, INITRND);
seek(cout, OFFSET, 0);
break;
case 7:
--- a/sys/src/cmd/7l/obj.c
+++ b/sys/src/cmd/7l/obj.c
@@ -35,8 +35,8 @@
/*
* -H0 no header
- * -H2 -T0x100028 -R0x100000 is plan9 format
- * -H6 -R4096 no header with segments padded to pages
+ * -H2 -T0x100028 -R0x100000 is plan9 format
+ * -H6 -R0x10000 no header with segments padded to pages
* -H7 is elf
*/