changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: merge

changeset 7247: 78e735042ef6
parent 7242: 13cc4ad135d6
parent 7246: 424a0569af2c
child 7248: d702de816ecf
author: cinap_lenrek@felloff.net
date: Fri, 17 May 2019 19:01:14 +0200
files:
description: merge
     1.1--- a/sys/src/9/bcm64/dat.h
     1.2+++ b/sys/src/9/bcm64/dat.h
     1.3@@ -115,7 +115,7 @@ struct Conf
     1.4  */
     1.5 struct MMMU
     1.6 {
     1.7-	PTE*	mmul1;		/* l1 for this processor */
     1.8+	PTE*	mmutop;		/* first level user page table */
     1.9 };
    1.10 
    1.11 /*
    1.12@@ -245,8 +245,6 @@ struct Soc {			/* SoC dependent configur
    1.13 	uintptr	busdram;
    1.14 	uintptr	busio;
    1.15 	uintptr	armlocal;
    1.16-	u32int	l1ptedramattrs;
    1.17-	u32int	l2ptedramattrs;
    1.18 };
    1.19 extern Soc soc;
    1.20 
     2.1--- a/sys/src/9/bcm64/l.s
     2.2+++ b/sys/src/9/bcm64/l.s
     2.3@@ -195,8 +195,8 @@ TEXT mmuenable<>(SB), 1, $-4
     2.4 	/* T0SZ */	| (64-EVASHIFT)<<0 )
     2.5 	MOV	$TCRINIT, R1
     2.6 	MRS	ID_AA64MMFR0_EL1, R2
     2.7-	ANDW	$0xF, R2	// IPS
     2.8-	ADD	R2<<32, R1
     2.9+	ANDW	$0x7, R2	// PARange
    2.10+	ADD	R2<<32, R1	// IPS
    2.11 	MSR	R1, TCR_EL1
    2.12 	ISB	$SY
    2.13 
    2.14@@ -331,8 +331,7 @@ TEXT setttbr(SB), 1, $-4
    2.15 	MSR	R0, TTBR0_EL1
    2.16 	DSB	$ISH
    2.17 	ISB	$SY
    2.18-
    2.19-	B	cacheiinv(SB)
    2.20+	RETURN
    2.21 
    2.22 /*
    2.23  * TLB maintenance operations.
     3.1--- a/sys/src/9/bcm64/mem.h
     3.2+++ b/sys/src/9/bcm64/mem.h
     3.3@@ -17,11 +17,11 @@
     3.4  *	16K	32M	64G	128T
     3.5  *	64K	512M	4T	-
     3.6  */
     3.7-#define	PGSHIFT		12		/* log(BY2PG) */
     3.8+#define	PGSHIFT		16		/* log(BY2PG) */
     3.9 #define	BY2PG		(1ULL<<PGSHIFT)	/* bytes per page */
    3.10 
    3.11 /* effective virtual address space */
    3.12-#define EVASHIFT	36
    3.13+#define EVASHIFT	33
    3.14 #define EVAMASK		((1ULL<<EVASHIFT)-1)
    3.15 
    3.16 #define PTSHIFT		(PGSHIFT-3)
    3.17@@ -31,8 +31,8 @@
    3.18 
    3.19 #define PTL1X(v, l)	(L1TABLEX(v, l) | PTLX(v, l))
    3.20 #define L1TABLEX(v, l)	(L1TABLE(v, l) << PTSHIFT)
    3.21-#define L1TABLES	HOWMANY(-KZERO, PGLSZ(2))
    3.22-#define L1TABLE(v, l)	(L1TABLES-1 - ((PTLX(v, 2) % L1TABLES) >> (((l)-1)*PTSHIFT)) + (l)-1)
    3.23+#define L1TABLES	HOWMANY(-KSEG0, PGLSZ(2))
    3.24+#define L1TABLE(v, l)	(L1TABLES - ((PTLX(v, 2) % L1TABLES) >> (((l)-1)*PTSHIFT)) + (l)-1)
    3.25 #define L1TOPSIZE	(1ULL << (EVASHIFT - PTLEVELS*PTSHIFT))
    3.26 
    3.27 #define	MAXMACH		4			/* max # cpus system can run */
    3.28@@ -42,14 +42,12 @@
    3.29 #define STACKALIGN(sp)	((sp) & ~7)		/* bug: assure with alloc */
    3.30 #define TRAPFRAMESIZE	(38*8)
    3.31 
    3.32-/*
    3.33- * Address spaces.
    3.34- * KTZERO is used by kprof and dumpstack (if any).
    3.35- *
    3.36- * KZERO is mapped to physical 0 (start of ram).
    3.37- */
    3.38-
    3.39-#define	KZERO		0xFFFFFFFF80000000ULL	/* kernel address space */
    3.40+#define KSEG0		(0xFFFFFFFF00000000ULL)
    3.41+#define VIRTIO		(0xFFFFFFFF3F000000ULL)	/* i/o registers */
    3.42+#define	ARMLOCAL	(0xFFFFFFFF40000000ULL)
    3.43+#define	KZERO		(0xFFFFFFFF80000000ULL)	/* kernel address space */
    3.44+#define FRAMEBUFFER	(0xFFFFFFFFC0000000ULL|PTEWT)
    3.45+#define	VGPIO		0			/* virtual gpio for pi3 ACT LED */
    3.46 
    3.47 #define SPINTABLE	(KZERO+0xd8)
    3.48 #define CONFADDR	(KZERO+0x100)
    3.49@@ -57,16 +55,12 @@
    3.50 #define	VCBUFFER	(KZERO+0x3400)		/* videocore mailbox buffer */
    3.51 
    3.52 #define L1		(L1TOP-L1SIZE)
    3.53-#define L1SIZE		((L1TABLES+PTLEVELS-3)*BY2PG)
    3.54+#define L1SIZE		((L1TABLES+PTLEVELS-2)*BY2PG)
    3.55 #define L1TOP		((MACHADDR(MAXMACH-1)-L1TOPSIZE)&-BY2PG)
    3.56 
    3.57 #define MACHADDR(n)	(KTZERO-((n)+1)*MACHSIZE)
    3.58 
    3.59 #define	KTZERO		(KZERO+0x80000)		/* kernel text start */
    3.60-#define FRAMEBUFFER	(0xFFFFFFFFC0000000ULL | PTEWT)
    3.61-#define VIRTIO		0xFFFFFFFFE0000000ULL	/* i/o registers */
    3.62-#define	ARMLOCAL	(VIRTIO+IOSIZE)
    3.63-#define	VGPIO		0			/* virtual gpio for pi3 ACT LED */
    3.64 
    3.65 #define	UZERO		0ULL			/* user segment */
    3.66 #define	UTZERO		(UZERO+0x10000)		/* user text start */
     4.1--- a/sys/src/9/bcm64/mkfile
     4.2+++ b/sys/src/9/bcm64/mkfile
     4.3@@ -71,11 +71,11 @@ 9:V: $p$CONF s$p$CONF
     4.4 $p$CONF:DQ:	$CONF.c $OBJ $LIB mkfile
     4.5 	$CC $CFLAGS '-DKERNDATE='`{date -n} $CONF.c
     4.6 	echo '# linking raw kernel'	# H6: no headers, data segment aligned
     4.7-	$LD -l -o $target -H6 -R4096 -T$loadaddr $OBJ $CONF.$O $LIB
     4.8+	$LD -l -o $target -H6 -R0x10000 -T$loadaddr $OBJ $CONF.$O $LIB
     4.9 
    4.10 s$p$CONF:DQ:	$CONF.$O $OBJ $LIB
    4.11 	echo '# linking kernel with symbols'
    4.12-	$LD -l -o $target -R4096 -T$loadaddr $OBJ $CONF.$O $LIB
    4.13+	$LD -l -o $target -R0x10000 -T$loadaddr $OBJ $CONF.$O $LIB
    4.14 	size $target
    4.15 
    4.16 $p$CONF.gz:D:	$p$CONF
     5.1--- a/sys/src/9/bcm64/mmu.c
     5.2+++ b/sys/src/9/bcm64/mmu.c
     5.3@@ -8,45 +8,65 @@
     5.4 void
     5.5 mmu0init(uintptr *l1)
     5.6 {
     5.7-	uintptr va, pa, pe;
     5.8+	uintptr va, pa, pe, attr;
     5.9 
    5.10-	/* 0 identity map */
    5.11+	/* KZERO */
    5.12+	attr = PTEWRITE | PTEAF | PTEKERNEL | PTESH(SHARE_INNER);
    5.13 	pe = PHYSDRAM + soc.dramsize;
    5.14 	if(pe > (uintptr)-KZERO)
    5.15 		pe = (uintptr)-KZERO;
    5.16-
    5.17-	for(pa = PHYSDRAM; pa < pe; pa += PGLSZ(1))
    5.18-		l1[PTL1X(pa, 1)] = pa | PTEVALID | PTEBLOCK | PTEWRITE | PTEAF
    5.19-			 | PTEKERNEL | PTESH(SHARE_INNER);
    5.20+	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1)){
    5.21+		if(pe - pa < PGLSZ(1)){
    5.22+			l1[PTL1X(va, 1)] = (uintptr)l1 | PTEVALID | PTETABLE;
    5.23+			l1[PTL1X(pa, 1)] = (uintptr)l1 | PTEVALID | PTETABLE;
    5.24+			for(; pa < pe; pa += PGLSZ(0), va += PGLSZ(0))
    5.25+				l1[PTLX(va, 0)] = pa | PTEVALID | PTEPAGE | attr;
    5.26+			break;
    5.27+		}
    5.28+		l1[PTL1X(va, 1)] = pa | PTEVALID | PTEBLOCK | attr;
    5.29+		l1[PTL1X(pa, 1)] = pa | PTEVALID | PTEBLOCK | attr;
    5.30+	}
    5.31+	pe = (uintptr)-KZERO;	/* populate top levels for mmukmap() */
    5.32 	if(PTLEVELS > 2)
    5.33-	for(pa = PHYSDRAM; pa < pe; pa += PGLSZ(2))
    5.34+	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(2), va += PGLSZ(2)){
    5.35+		l1[PTL1X(va, 2)] = (uintptr)&l1[L1TABLEX(va, 1)] | PTEVALID | PTETABLE;
    5.36 		l1[PTL1X(pa, 2)] = (uintptr)&l1[L1TABLEX(pa, 1)] | PTEVALID | PTETABLE;
    5.37+	}
    5.38 	if(PTLEVELS > 3)
    5.39-	for(pa = PHYSDRAM; pa < pe; pa += PGLSZ(3))
    5.40+	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(3), va += PGLSZ(3)){
    5.41+		l1[PTL1X(va, 3)] = (uintptr)&l1[L1TABLEX(va, 2)] | PTEVALID | PTETABLE;
    5.42 		l1[PTL1X(pa, 3)] = (uintptr)&l1[L1TABLEX(pa, 2)] | PTEVALID | PTETABLE;
    5.43-
    5.44-	/* KZERO */
    5.45-	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1))
    5.46-		l1[PTL1X(va, 1)] = pa | PTEVALID | PTEBLOCK | PTEWRITE | PTEAF
    5.47-			| PTEKERNEL | PTESH(SHARE_INNER);
    5.48-	if(PTLEVELS > 2)
    5.49-	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(2), va += PGLSZ(2))
    5.50-		l1[PTL1X(va, 2)] = (uintptr)&l1[L1TABLEX(va, 1)] | PTEVALID | PTETABLE;
    5.51-	if(PTLEVELS > 3)
    5.52-	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(3), va += PGLSZ(3))
    5.53-		l1[PTL1X(va, 3)] = (uintptr)&l1[L1TABLEX(va, 2)] | PTEVALID | PTETABLE;
    5.54+	}
    5.55 
    5.56 	/* VIRTIO */
    5.57-	pe = -VIRTIO + soc.physio;
    5.58-	for(pa = soc.physio, va = VIRTIO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1))
    5.59-		l1[PTL1X(va, 1)] = pa | PTEVALID | PTEBLOCK | PTEWRITE | PTEAF
    5.60-			| PTEKERNEL | PTESH(SHARE_OUTER) | PTEDEVICE;
    5.61+	attr = PTEWRITE | PTEAF | PTEKERNEL | PTESH(SHARE_OUTER) | PTEDEVICE;
    5.62+	pe = soc.physio + IOSIZE;
    5.63+	for(pa = soc.physio, va = VIRTIO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1)){
    5.64+		if(pe - pa < PGLSZ(1)){
    5.65+			l1[PTL1X(va, 1)] = (uintptr)l1 | PTEVALID | PTETABLE;
    5.66+			for(; pa < pe; pa += PGLSZ(0), va += PGLSZ(0))
    5.67+				l1[PTLX(va, 0)] = pa | PTEVALID | PTEPAGE | attr;
    5.68+			break;
    5.69+		}
    5.70+		l1[PTL1X(va, 1)] = pa | PTEVALID | PTEBLOCK | attr;
    5.71+	}
    5.72 	if(PTLEVELS > 2)
    5.73 	for(pa = soc.physio, va = VIRTIO; pa < pe; pa += PGLSZ(2), va += PGLSZ(2))
    5.74 		l1[PTL1X(va, 2)] = (uintptr)&l1[L1TABLEX(va, 1)] | PTEVALID | PTETABLE;
    5.75 	if(PTLEVELS > 3)
    5.76 	for(pa = soc.physio, va = VIRTIO; pa < pe; pa += PGLSZ(3), va += PGLSZ(3))
    5.77 		l1[PTL1X(va, 3)] = (uintptr)&l1[L1TABLEX(va, 2)] | PTEVALID | PTETABLE;
    5.78+
    5.79+	/* ARMLOCAL */
    5.80+	pe = soc.armlocal + MB;
    5.81+	for(pa = soc.armlocal, va = ARMLOCAL; pa < pe; pa += PGLSZ(1), va += PGLSZ(1))
    5.82+		l1[PTL1X(va, 1)] = pa | PTEVALID | PTEBLOCK | attr;
    5.83+	if(PTLEVELS > 2)
    5.84+	for(pa = soc.armlocal, va = ARMLOCAL; pa < pe; pa += PGLSZ(2), va += PGLSZ(2))
    5.85+		l1[PTL1X(va, 2)] = (uintptr)&l1[L1TABLEX(va, 1)] | PTEVALID | PTETABLE;
    5.86+	if(PTLEVELS > 3)
    5.87+	for(pa = soc.armlocal, va = ARMLOCAL; pa < pe; pa += PGLSZ(3), va += PGLSZ(3))
    5.88+		l1[PTL1X(va, 3)] = (uintptr)&l1[L1TABLEX(va, 2)] | PTEVALID | PTETABLE;
    5.89 }
    5.90 
    5.91 void
    5.92@@ -57,21 +77,17 @@ mmu0clear(uintptr *l1)
    5.93 	pe = PHYSDRAM + soc.dramsize;
    5.94 	if(pe > (uintptr)-KZERO)
    5.95 		pe = (uintptr)-KZERO;
    5.96-
    5.97-	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1)){
    5.98+	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1))
    5.99 		if(PTL1X(pa, 1) != PTL1X(va, 1))
   5.100 			l1[PTL1X(pa, 1)] = 0;
   5.101-	}
   5.102 	if(PTLEVELS > 2)
   5.103-	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(2), va += PGLSZ(2)){
   5.104+	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(2), va += PGLSZ(2))
   5.105 		if(PTL1X(pa, 2) != PTL1X(va, 2))
   5.106 			l1[PTL1X(pa, 2)] = 0;
   5.107-	}
   5.108 	if(PTLEVELS > 3)
   5.109-	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(3), va += PGLSZ(3)){
   5.110+	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(3), va += PGLSZ(3))
   5.111 		if(PTL1X(pa, 3) != PTL1X(va, 3))
   5.112 			l1[PTL1X(pa, 3)] = 0;
   5.113-	}
   5.114 }
   5.115 
   5.116 void
   5.117@@ -79,38 +95,27 @@ mmuidmap(uintptr *l1)
   5.118 {
   5.119 	uintptr va, pa, pe;
   5.120 
   5.121-	mmuswitch(nil);
   5.122-	flushtlb();
   5.123-
   5.124 	pe = PHYSDRAM + soc.dramsize;
   5.125 	if(pe > (uintptr)-KZERO)
   5.126 		pe = (uintptr)-KZERO;
   5.127-
   5.128-	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1)){
   5.129-		if(PTL1X(pa, 1) != PTL1X(va, 1))
   5.130-			l1[PTL1X(pa, 1)] = pa | PTEVALID | PTEBLOCK | PTEWRITE | PTEAF
   5.131-				 | PTEKERNEL | PTESH(SHARE_INNER);
   5.132-	}
   5.133+	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1))
   5.134+		l1[PTL1X(pa, 1)] = l1[PTL1X(va, 1)];
   5.135 	if(PTLEVELS > 2)
   5.136-	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(2), va += PGLSZ(2)){
   5.137-		if(PTL1X(pa, 2) != PTL1X(va, 2))
   5.138-			l1[PTL1X(pa, 2)] = PADDR(&l1[L1TABLEX(pa, 1)]) | PTEVALID | PTETABLE;
   5.139-	}
   5.140+	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(2), va += PGLSZ(2))
   5.141+		l1[PTL1X(pa, 2)] = l1[PTL1X(va, 2)];
   5.142 	if(PTLEVELS > 3)
   5.143-	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(3), va += PGLSZ(3)){
   5.144-		if(PTL1X(pa, 3) != PTL1X(va, 3))
   5.145-			l1[PTL1X(pa, 3)] = PADDR(&l1[L1TABLEX(pa, 2)]) | PTEVALID | PTETABLE;
   5.146-	}
   5.147+	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(3), va += PGLSZ(3))
   5.148+		l1[PTL1X(pa, 3)] = l1[PTL1X(va, 3)];
   5.149 	setttbr(PADDR(&l1[L1TABLEX(0, PTLEVELS-1)]));
   5.150 }
   5.151 
   5.152 void
   5.153 mmu1init(void)
   5.154 {
   5.155-	m->mmul1 = mallocalign(L1SIZE+L1TOPSIZE, BY2PG, L1SIZE, 0);
   5.156-	if(m->mmul1 == nil)
   5.157-		panic("mmu1init: no memory for mmul1");
   5.158-	memset(m->mmul1, 0, L1SIZE+L1TOPSIZE);
   5.159+	m->mmutop = mallocalign(L1TOPSIZE, BY2PG, 0, 0);
   5.160+	if(m->mmutop == nil)
   5.161+		panic("mmu1init: no memory for mmutop");
   5.162+	memset(m->mmutop, 0, L1TOPSIZE);
   5.163 	mmuswitch(nil);
   5.164 }
   5.165 
   5.166@@ -187,7 +192,7 @@ mmuwalk(uintptr va, int level)
   5.167 	int i, x;
   5.168 
   5.169 	x = PTLX(va, PTLEVELS-1);
   5.170-	table = &m->mmul1[L1TABLEX(va, PTLEVELS-1)];
   5.171+	table = m->mmutop;
   5.172 	for(i = PTLEVELS-2; i >= level; i--){
   5.173 		pte = table[x];
   5.174 		if(pte & PTEVALID) {
   5.175@@ -262,12 +267,12 @@ putasid(Proc *p)
   5.176 {
   5.177 	/*
   5.178 	 * Prevent the following scenario:
   5.179-	 *	pX sleeps on cpuA, leaving its page tables in mmul1
   5.180+	 *	pX sleeps on cpuA, leaving its page tables in mmutop
   5.181 	 *	pX wakes up on cpuB, and exits, freeing its page tables
   5.182 	 *  pY on cpuB allocates a freed page table page and overwrites with data
   5.183 	 *  cpuA takes an interrupt, and is now running with bad page tables
   5.184 	 * In theory this shouldn't hurt because only user address space tables
   5.185-	 * are affected, and mmuswitch will clear mmul1 before a user process is
   5.186+	 * are affected, and mmuswitch will clear mmutop before a user process is
   5.187 	 * dispatched.  But empirically it correlates with weird problems, eg
   5.188 	 * resetting of the core clock at 0x4000001C which confuses local timers.
   5.189 	 */
   5.190@@ -287,7 +292,6 @@ putmmu(uintptr va, uintptr pa, Page *pg)
   5.191 	s = splhi();
   5.192 	while((pte = mmuwalk(va, 0)) == nil){
   5.193 		spllo();
   5.194-		assert(up->mmufree == nil);
   5.195 		up->mmufree = newpage(0, nil, 0);
   5.196 		splhi();
   5.197 	}
   5.198@@ -330,10 +334,10 @@ mmuswitch(Proc *p)
   5.199 	Page *t;
   5.200 
   5.201 	for(va = UZERO; va < USTKTOP; va += PGLSZ(PTLEVELS-1))
   5.202-		m->mmul1[PTL1X(va, PTLEVELS-1)] = 0;
   5.203+		m->mmutop[PTLX(va, PTLEVELS-1)] = 0;
   5.204 
   5.205 	if(p == nil){
   5.206-		setttbr(PADDR(&m->mmul1[L1TABLEX(0, PTLEVELS-1)]));
   5.207+		setttbr(PADDR(m->mmutop));
   5.208 		return;
   5.209 	}
   5.210 
   5.211@@ -344,13 +348,13 @@ mmuswitch(Proc *p)
   5.212 
   5.213 	for(t = p->mmuhead[PTLEVELS-1]; t != nil; t = t->next){
   5.214 		va = t->va;
   5.215-		m->mmul1[PTL1X(va, PTLEVELS-1)] = t->pa | PTEVALID | PTETABLE;
   5.216+		m->mmutop[PTLX(va, PTLEVELS-1)] = t->pa | PTEVALID | PTETABLE;
   5.217 	}
   5.218 
   5.219 	if(allocasid(p))
   5.220 		flushasid((uvlong)p->asid<<48);
   5.221 
   5.222-	setttbr((uvlong)p->asid<<48 | PADDR(&m->mmul1[L1TABLEX(0, PTLEVELS-1)]));
   5.223+	setttbr((uvlong)p->asid<<48 | PADDR(m->mmutop));
   5.224 }
   5.225 
   5.226 void
     6.1--- a/sys/src/9/port/rebootcmd.c
     6.2+++ b/sys/src/9/port/rebootcmd.c
     6.3@@ -37,7 +37,7 @@ rebootcmd(int argc, char *argv[])
     6.4 {
     6.5 	Chan *c;
     6.6 	Exec exec;
     6.7-	ulong magic, text, rtext, entry, data, size;
     6.8+	ulong magic, text, rtext, entry, data, size, align;
     6.9 	uchar *p;
    6.10 
    6.11 	if(argc == 0)
    6.12@@ -68,8 +68,17 @@ rebootcmd(int argc, char *argv[])
    6.13 	if(magic & HDR_MAGIC)
    6.14 		readn(c, &exec, 8);
    6.15 
    6.16+	switch(magic){
    6.17+	case R_MAGIC:
    6.18+		align = 0x10000;	/* 64k segment alignment for arm64 */
    6.19+		break;
    6.20+	default:
    6.21+		align = BY2PG;
    6.22+		break;
    6.23+	}
    6.24+
    6.25 	/* round text out to page boundary */
    6.26-	rtext = PGROUND(entry+text)-entry;
    6.27+	rtext = ROUND(entry+text, align)-entry;
    6.28 	size = rtext + data;
    6.29 	p = malloc(size);
    6.30 	if(p == nil)
     7.1--- a/sys/src/cmd/7l/asm.c
     7.2+++ b/sys/src/cmd/7l/asm.c
     7.3@@ -100,7 +100,7 @@ asmb(void)
     7.4 		seek(cout, OFFSET, 0);
     7.5 		break;
     7.6 	case 6:	/* no header, padded segments */
     7.7-		OFFSET = rnd(HEADR+textsize, 4096);
     7.8+		OFFSET = rnd(HEADR+textsize, INITRND);
     7.9 		seek(cout, OFFSET, 0);
    7.10 		break;
    7.11 	}
    7.12@@ -132,7 +132,7 @@ asmb(void)
    7.13 			seek(cout, OFFSET, 0);
    7.14 			break;
    7.15 		case 6:	/* no header, padded segments */
    7.16-			OFFSET += rnd(datsize, 4096);
    7.17+			OFFSET += rnd(datsize, INITRND);
    7.18 			seek(cout, OFFSET, 0);
    7.19 			break;
    7.20 		case 7:
     8.1--- a/sys/src/cmd/7l/obj.c
     8.2+++ b/sys/src/cmd/7l/obj.c
     8.3@@ -35,8 +35,8 @@ isobjfile(char *f)
     8.4 
     8.5 /*
     8.6  *	-H0				no header
     8.7- *	-H2 -T0x100028 -R0x100000		is plan9 format
     8.8- *	-H6 -R4096		no header with segments padded to pages
     8.9+ *	-H2 -T0x100028 -R0x100000	is plan9 format
    8.10+ *	-H6 -R0x10000			no header with segments padded to pages
    8.11  *	-H7				is elf
    8.12  */
    8.13