changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: bcm64: implement reboot support

changeset 7235: b1dc95374307
parent 7234: fc141b91ed8a
child 7236: 0a1134e2909d
author: cinap_lenrek@felloff.net
date: Mon, 13 May 2019 19:20:21 +0200
files: sys/src/9/bcm64/archbcm3.c sys/src/9/bcm64/dat.h sys/src/9/bcm64/fns.h sys/src/9/bcm64/l.s sys/src/9/bcm64/main.c sys/src/9/bcm64/mkfile sys/src/9/bcm64/mmu.c sys/src/9/bcm64/rebootcode.s
description: bcm64: implement reboot support
     1.1--- a/sys/src/9/bcm64/archbcm3.c
     1.2+++ b/sys/src/9/bcm64/archbcm3.c
     1.3@@ -17,7 +17,7 @@ typedef struct Mboxes Mboxes;
     1.4 #define	POWERREGS	(VIRTIO+0x100000)
     1.5 
     1.6 Soc soc = {
     1.7-	.dramsize	= GiB,
     1.8+	.dramsize	= 0x3F000000,
     1.9 	.physio		= 0x3F000000,
    1.10 	.busdram	= 0xC0000000,
    1.11 	.busio		= 0x7E000000,
    1.12@@ -164,5 +164,5 @@ wakecpu(uint cpu)
    1.13 void
    1.14 archbcm3link(void)
    1.15 {
    1.16-//	addclock0link(wdogfeed, HZ);
    1.17+	addclock0link(wdogfeed, HZ);
    1.18 }
     2.1--- a/sys/src/9/bcm64/dat.h
     2.2+++ b/sys/src/9/bcm64/dat.h
     2.3@@ -194,7 +194,6 @@ struct
     2.4 extern register Mach* m;			/* R27 */
     2.5 extern register Proc* up;			/* R26 */
     2.6 extern int normalprint;
     2.7-extern ulong memsize;
     2.8 
     2.9 /*
    2.10  *  a parsed plan9.ini line
     3.1--- a/sys/src/9/bcm64/fns.h
     3.2+++ b/sys/src/9/bcm64/fns.h
     3.3@@ -33,6 +33,9 @@ extern void tlbiaside1is(uintptr asid);
     3.4 extern void flushtlb(void);
     3.5 extern void tlbivmalle1(void);
     3.6 
     3.7+extern void flushlocaltlb(void);
     3.8+extern void tlbivmalle1(void);
     3.9+
    3.10 /* cache */
    3.11 extern ulong cachesize(int level);
    3.12 
    3.13@@ -68,6 +71,7 @@ extern uintptr mmukmap(uintptr, uintptr,
    3.14 
    3.15 extern void mmu0init(uintptr*);
    3.16 extern void mmu0clear(uintptr*);
    3.17+extern void mmuidmap(uintptr*);
    3.18 extern void mmu1init(void);
    3.19 
    3.20 extern void putasid(Proc*);
    3.21@@ -76,6 +80,7 @@ extern void putasid(Proc*);
    3.22 extern void clockinit(void);
    3.23 extern void synccycles(void);
    3.24 extern void armtimerset(int);
    3.25+extern void clockshutdown(void);
    3.26 
    3.27 /* fpu */
    3.28 extern void fpuinit(void);
    3.29@@ -127,6 +132,7 @@ extern int gpiogetevent(uint);
    3.30 extern void gpiomeminit(void);
    3.31 
    3.32 /* arch */
    3.33+extern void archreboot(void);
    3.34 extern char *cputype2name(char*, int);
    3.35 extern void cpuidprint(void);
    3.36 extern void uartconsinit(void);
    3.37@@ -134,6 +140,7 @@ extern void links(void);
    3.38 extern int getncpus(void);
    3.39 extern int startcpu(uint);
    3.40 extern void okay(int);
    3.41+extern void wdogoff(void);
    3.42 
    3.43 /* dma */
    3.44 extern uintptr dmaaddr(void*);
     4.1--- a/sys/src/9/bcm64/l.s
     4.2+++ b/sys/src/9/bcm64/l.s
     4.3@@ -50,8 +50,6 @@ TEXT _start(SB), 1, $-4
     4.4 	MOV	$(L1-KZERO), R0
     4.5 	BL	mmu0init(SB)
     4.6 
     4.7-	BL	cachedwbinv(SB)
     4.8-	BL	l2cacheuwbinv(SB)
     4.9 	SEVL
    4.10 _startup:
    4.11 	WFE
    4.12@@ -162,7 +160,6 @@ TEXT mmuenable<>(SB), 1, $-4
    4.13 	ORR	$KZERO, LR
    4.14 	MOV	LR, -16(RSP)!
    4.15 
    4.16-	BL	cachedwbinv(SB)
    4.17 	BL	flushlocaltlb(SB)
    4.18 
    4.19 	/* memory attributes */
     5.1--- a/sys/src/9/bcm64/main.c
     5.2+++ b/sys/src/9/bcm64/main.c
     5.3@@ -8,12 +8,12 @@
     5.4 #include "io.h"
     5.5 #include "init.h"
     5.6 #include "sysreg.h"
     5.7+#include "reboot.h"
     5.8 
     5.9 #include <pool.h>
    5.10 #include <libsec.h>
    5.11 
    5.12 Conf conf;
    5.13-ulong memsize = GiB;
    5.14 
    5.15 /*
    5.16  *  starting place for first process
    5.17@@ -122,7 +122,7 @@ userinit(void)
    5.18 	pg = newpage(1, 0, UTZERO);
    5.19 	pg->txtflush = ~0;
    5.20 	segpage(s, pg);
    5.21-	k = kmap(s->map[0]->pages[0]);
    5.22+	k = kmap(pg);
    5.23 	memmove((void*)VA(k), initcode, sizeof initcode);
    5.24 	kunmap(k);
    5.25 
    5.26@@ -133,7 +133,7 @@ void
    5.27 confinit(void)
    5.28 {
    5.29 	int i, userpcnt;
    5.30-	ulong kpages;
    5.31+	ulong kpages, memsize = 0;
    5.32 	uintptr pa;
    5.33 	char *p;
    5.34 
    5.35@@ -149,12 +149,10 @@ confinit(void)
    5.36 	else
    5.37 		userpcnt = 0;
    5.38 
    5.39-	if((p = getconf("*maxmem")) != nil){
    5.40+	if(p = getconf("*maxmem"))
    5.41 		memsize = strtoul(p, 0, 0) - PHYSDRAM;
    5.42-		if (memsize < 16*MB)		/* sanity */
    5.43-			memsize = 16*MB;
    5.44-	}
    5.45-
    5.46+	if (memsize < 16*MB)		/* sanity */
    5.47+		memsize = 16*MB;
    5.48 	getramsize(&conf.mem[0]);
    5.49 	if(conf.mem[0].limit == 0){
    5.50 		conf.mem[0].base = PHYSDRAM;
    5.51@@ -247,7 +245,7 @@ mpinit(void)
    5.52 	for(i = 1; i < conf.nmach; i++)
    5.53 		MACHP(i)->machno = i;
    5.54 
    5.55-	cachedwbinv();
    5.56+	coherence();
    5.57 
    5.58 	for(i = 1; i < conf.nmach; i++)
    5.59 		((uintptr*)SPINTABLE)[i] = PADDR(_start);
    5.60@@ -257,6 +255,9 @@ mpinit(void)
    5.61 	delay(100);
    5.62 	sev();
    5.63 	synccycles();
    5.64+
    5.65+	for(i = 0; i < MAXMACH; i++)
    5.66+		((uintptr*)SPINTABLE)[i] = 0;
    5.67 }
    5.68 
    5.69 void
    5.70@@ -276,12 +277,11 @@ main(void)
    5.71 		schedinit();
    5.72 		return;
    5.73 	}
    5.74+	quotefmtinstall();
    5.75 	bootargsinit();
    5.76 	confinit();
    5.77 	xinit();
    5.78 	printinit();
    5.79-	fmtinstall('H', encodefmt);
    5.80-	quotefmtinstall();
    5.81 	uartconsinit();
    5.82 	screeninit();
    5.83 	print("\nPlan 9\n");
    5.84@@ -308,17 +308,64 @@ main(void)
    5.85 	schedinit();
    5.86 }
    5.87 
    5.88+static void
    5.89+rebootjump(void *entry, void *code, ulong size)
    5.90+{
    5.91+	void (*f)(void*, void*, ulong);
    5.92+
    5.93+	intrsoff();
    5.94+	intrcpushutdown();
    5.95+
    5.96+	/* redo identity map */
    5.97+	mmuidmap((uintptr*)L1);
    5.98+
    5.99+	/* setup reboot trampoline function */
   5.100+	f = (void*)REBOOTADDR;
   5.101+	memmove(f, rebootcode, sizeof(rebootcode));
   5.102+	cachedwbinvse(f, sizeof(rebootcode));
   5.103+	cacheiinvse(f, sizeof(rebootcode));
   5.104+
   5.105+	(*f)(entry, code, size);
   5.106+
   5.107+	for(;;);
   5.108+}
   5.109+
   5.110 void
   5.111 exit(int)
   5.112 {
   5.113 	cpushutdown();
   5.114-	for(;;);
   5.115+	splfhi();
   5.116+	if(m->machno == 0)
   5.117+		archreboot();
   5.118+	rebootjump(0, 0, 0);
   5.119 }
   5.120 
   5.121 void
   5.122-reboot(void*, void*, ulong)
   5.123+reboot(void *entry, void *code, ulong size)
   5.124 {
   5.125-	error(Egreg);
   5.126+	writeconf();
   5.127+	while(m->machno != 0){
   5.128+		procwired(up, 0);
   5.129+		sched();
   5.130+	}
   5.131+
   5.132+	cpushutdown();
   5.133+	delay(2000);
   5.134+
   5.135+	splfhi();
   5.136+
   5.137+	/* turn off buffered serial console */
   5.138+	serialoq = nil;
   5.139+
   5.140+	/* shutdown devices */
   5.141+	chandevshutdown();
   5.142+
   5.143+	/* stop the clock (and watchdog if any) */
   5.144+	clockshutdown();
   5.145+	wdogoff();
   5.146+
   5.147+	/* off we go - never to return */
   5.148+	rebootjump(entry, code, size);
   5.149 }
   5.150 
   5.151 /*
     6.1--- a/sys/src/9/bcm64/mkfile
     6.2+++ b/sys/src/9/bcm64/mkfile
     6.3@@ -1,6 +1,5 @@
     6.4 CONF=pi3
     6.5 CONFLIST=pi3
     6.6-EXTRACOPIES=
     6.7 
     6.8 loadaddr=0xffffffff80080000
     6.9 
    6.10@@ -8,8 +7,6 @@ objtype=arm64
    6.11 </$objtype/mkfile
    6.12 p=9
    6.13 
    6.14-OS=7
    6.15-
    6.16 DEVS=`{rc ../port/mkdevlist $CONF}
    6.17 
    6.18 PORT=\
    6.19@@ -89,12 +86,7 @@ s$p$CONF:DQ:	$CONF.$O $OBJ $LIB
    6.20 install:V: /$objtype/$p$CONF
    6.21 
    6.22 /$objtype/$p$CONF:D: $p$CONF s$p$CONF
    6.23-	cp -x $p$CONF s$p$CONF /$objtype/ &
    6.24-	for(i in $EXTRACOPIES)
    6.25-		{ 9fs $i && cp $p$CONF s$p$CONF /n/$i/$objtype && echo -n $i... & }
    6.26-	wait
    6.27-	echo
    6.28-	touch $target
    6.29+	cp -x $p$CONF s$p$CONF /$objtype/
    6.30 
    6.31 
    6.32 REPCC=`{../port/mkfilelist ../bcm}
    6.33@@ -108,8 +100,9 @@ REPCC=`{../port/mkfilelist ../bcm}
    6.34 arch.$O clock.$O fpiarm.$O main.$O mmu.$O screen.$O syscall.$O trap.$O: \
    6.35 	/$objtype/include/ureg.h
    6.36 
    6.37-l.$O cache.v8.$O lexception.$O lproc.$O mmu.$O: mem.h
    6.38+l.$O cache.v8.$O mmu.$O: mem.h
    6.39 l.$O cache.v8.$O archbcm3.$O clock.$O fpu.$O trap.$O mmu.$O: sysreg.h
    6.40+main.$O: reboot.h
    6.41 
    6.42 devmouse.$O mouse.$O screen.$O: screen.h
    6.43 usbdwc.$O: dwcotg.h ../port/usb.h
    6.44@@ -130,14 +123,14 @@ init.h:D:	../port/initcode.c init9.s
    6.45 		sed -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
    6.46 	 echo '};'} > init.h
    6.47 
    6.48-#reboot.h:D:	rebootcode.s arm.s arm.h mem.h
    6.49-#	$AS rebootcode.s
    6.50-#	# -T arg is REBOOTADDR
    6.51-#	$LD -l -s -T0x1c00 -R4 -o reboot.out rebootcode.$O
    6.52-#	{echo 'uchar rebootcode[]={'
    6.53-#	 xd -1x reboot.out |
    6.54-#		sed -e '1,2d' -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
    6.55-#	 echo '};'} > reboot.h
    6.56+reboot.h:D:	rebootcode.s cache.v8.$O mem.h sysreg.h
    6.57+	$AS rebootcode.s
    6.58+	# -T arg is REBOOTADDR
    6.59+	$LD -l -o reboot.out -H6 -R1 -T0x1c00 rebootcode.$O cache.v8.$O
    6.60+	{echo 'uchar rebootcode[]={'
    6.61+	 xd -1x reboot.out |
    6.62+		sed -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
    6.63+	 echo '};'} > reboot.h
    6.64 
    6.65 errstr.h:D:	../port/mkerrstr ../port/error.h
    6.66 	rc ../port/mkerrstr > errstr.h
     7.1--- a/sys/src/9/bcm64/mmu.c
     7.2+++ b/sys/src/9/bcm64/mmu.c
     7.3@@ -54,19 +54,47 @@ mmu0clear(uintptr *l1)
     7.4 	pe = PHYSDRAM + soc.dramsize;
     7.5 
     7.6 	if(PTLEVELS > 3)
     7.7-	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(3), va += PGLSZ(3)){
     7.8-		if(PTL1X(pa, 3) != PTL1X(va, 3))
     7.9-			l1[PTL1X(pa, 3)] = 0;
    7.10+	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1)){
    7.11+		if(PTL1X(pa, 1) != PTL1X(va, 1))
    7.12+			l1[PTL1X(pa, 1)] = 0;
    7.13 	}
    7.14 	if(PTLEVELS > 2)
    7.15 	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(2), va += PGLSZ(2)){
    7.16 		if(PTL1X(pa, 2) != PTL1X(va, 2))
    7.17 			l1[PTL1X(pa, 2)] = 0;
    7.18 	}
    7.19+	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(3), va += PGLSZ(3)){
    7.20+		if(PTL1X(pa, 3) != PTL1X(va, 3))
    7.21+			l1[PTL1X(pa, 3)] = 0;
    7.22+	}
    7.23+}
    7.24+
    7.25+void
    7.26+mmuidmap(uintptr *l1)
    7.27+{
    7.28+	uintptr va, pa, pe;
    7.29+
    7.30+	mmuswitch(nil);
    7.31+	flushtlb();
    7.32+
    7.33+	pe = PHYSDRAM + soc.dramsize;
    7.34+
    7.35 	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1)){
    7.36 		if(PTL1X(pa, 1) != PTL1X(va, 1))
    7.37-			l1[PTL1X(pa, 1)] = 0;
    7.38+			l1[PTL1X(pa, 1)] = pa | PTEVALID | PTEBLOCK | PTEWRITE | PTEAF
    7.39+				 | PTEKERNEL | PTESH(SHARE_INNER);
    7.40 	}
    7.41+	if(PTLEVELS > 2)
    7.42+	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(2), va += PGLSZ(2)){
    7.43+		if(PTL1X(pa, 2) != PTL1X(va, 2))
    7.44+			l1[PTL1X(pa, 2)] = PADDR(&l1[L1TABLEX(pa, 1)]) | PTEVALID | PTETABLE;
    7.45+	}
    7.46+	if(PTLEVELS > 3)
    7.47+	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(3), va += PGLSZ(3)){
    7.48+		if(PTL1X(pa, 3) != PTL1X(va, 3))
    7.49+			l1[PTL1X(pa, 3)] = PADDR(&l1[L1TABLEX(pa, 2)]) | PTEVALID | PTETABLE;
    7.50+	}
    7.51+	setttbr(PADDR(&l1[L1TABLEX(0, PTLEVELS-1)]));
    7.52 }
    7.53 
    7.54 void
    7.55@@ -264,7 +292,6 @@ putmmu(uintptr va, uintptr pa, Page *pg)
    7.56 	uintptr *pte, old;
    7.57 	int s;
    7.58 
    7.59-// iprint("cpu%d: putmmu va %#p asid %d proc %lud %s\n", m->machno, va, up->asid, up->pid, up->text);
    7.60 	s = splhi();
    7.61 	while((pte = mmuwalk(va, 0)) == nil){
    7.62 		spllo();
    7.63@@ -345,7 +372,6 @@ mmuswitch(Proc *p)
    7.64 	if(allocasid(p))
    7.65 		flushasid((uvlong)p->asid<<48);
    7.66 
    7.67-// iprint("cpu%d: mmuswitch asid %d proc %lud %s\n", m->machno, p->asid, p->pid, p->text);
    7.68 	setttbr((uvlong)p->asid<<48 | PADDR(&m->mmul1[L1TABLEX(0, PTLEVELS-1)]));
    7.69 }
    7.70 
     8.1new file mode 100644
     8.2--- /dev/null
     8.3+++ b/sys/src/9/bcm64/rebootcode.s
     8.4@@ -0,0 +1,51 @@
     8.5+#include "mem.h"
     8.6+#include "sysreg.h"
     8.7+
     8.8+#undef	SYSREG
     8.9+#define	SYSREG(op0,op1,Cn,Cm,op2)	SPR(((op0)<<19|(op1)<<16|(Cn)<<12|(Cm)<<8|(op2)<<5))
    8.10+
    8.11+TEXT _start(SB), 1, $-4
    8.12+	MOV	$setSB(SB), R28
    8.13+
    8.14+	MRS	MPIDR_EL1, R27
    8.15+	ANDW	$(MAXMACH-1), R27
    8.16+	LSL	$3, R27
    8.17+	ADD	$(SPINTABLE-KZERO), R27
    8.18+
    8.19+	CBZ	R0, _mmuoff
    8.20+	MOV	R0, (R27)
    8.21+	MOV	code+8(FP), R1
    8.22+	MOVWU	size+16(FP), R2
    8.23+	BIC	$3, R2
    8.24+	ADD	R1, R2, R3
    8.25+
    8.26+_copy:
    8.27+	MOVW	(R1)4!, R4
    8.28+	MOVW	R4, (R0)4!
    8.29+	CMP	R1, R3
    8.30+	BNE	_copy
    8.31+
    8.32+	BL	cachedwbinv(SB)
    8.33+	BL	l2cacheuwbinv(SB)
    8.34+	SEVL
    8.35+
    8.36+_mmuoff:
    8.37+	ISB	$SY
    8.38+	MRS	SCTLR_EL1, R0
    8.39+	BIC	$(1<<0 | 1<<2 | 1<<12), R0
    8.40+	ISB	$SY
    8.41+	MSR	R0, SCTLR_EL1
    8.42+	ISB	$SY
    8.43+
    8.44+	DSB	$NSHST
    8.45+	TLBI	R0, 0,8,7,0	/* VMALLE1 */
    8.46+	DSB	$NSH
    8.47+	ISB	$SY
    8.48+
    8.49+	BL	cachedwbinv(SB)
    8.50+	BL	cacheiinv(SB)
    8.51+_wait:
    8.52+	WFE
    8.53+	MOV	(R27), LR
    8.54+	CBZ	LR, _wait
    8.55+	RETURN