ref: a3b5e3994f7f2897ab1b5bb20b91224d145c1fc1
parent: 3b36daa2bb8c0f4169455baf829b9695b520c5fc
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon May 13 15:20:21 EDT 2019
bcm64: implement reboot support
--- a/sys/src/9/bcm64/archbcm3.c
+++ b/sys/src/9/bcm64/archbcm3.c
@@ -17,7 +17,7 @@
#define POWERREGS (VIRTIO+0x100000)
Soc soc = {
- .dramsize = GiB,
+ .dramsize = 0x3F000000,
.physio = 0x3F000000,
.busdram = 0xC0000000,
.busio = 0x7E000000,
@@ -164,5 +164,5 @@
void
archbcm3link(void)
{
-// addclock0link(wdogfeed, HZ);
+ addclock0link(wdogfeed, HZ);
}
--- a/sys/src/9/bcm64/dat.h
+++ b/sys/src/9/bcm64/dat.h
@@ -194,7 +194,6 @@
extern register Mach* m; /* R27 */
extern register Proc* up; /* R26 */
extern int normalprint;
-extern ulong memsize;
/*
* a parsed plan9.ini line
--- a/sys/src/9/bcm64/fns.h
+++ b/sys/src/9/bcm64/fns.h
@@ -33,6 +33,9 @@
extern void flushtlb(void);
extern void tlbivmalle1(void);
+extern void flushlocaltlb(void);
+extern void tlbivmalle1(void);
+
/* cache */
extern ulong cachesize(int level);
@@ -68,6 +71,7 @@
extern void mmu0init(uintptr*);
extern void mmu0clear(uintptr*);
+extern void mmuidmap(uintptr*);
extern void mmu1init(void);
extern void putasid(Proc*);
@@ -76,6 +80,7 @@
extern void clockinit(void);
extern void synccycles(void);
extern void armtimerset(int);
+extern void clockshutdown(void);
/* fpu */
extern void fpuinit(void);
@@ -127,6 +132,7 @@
extern void gpiomeminit(void);
/* arch */
+extern void archreboot(void);
extern char *cputype2name(char*, int);
extern void cpuidprint(void);
extern void uartconsinit(void);
@@ -134,6 +140,7 @@
extern int getncpus(void);
extern int startcpu(uint);
extern void okay(int);
+extern void wdogoff(void);
/* dma */
extern uintptr dmaaddr(void*);
--- a/sys/src/9/bcm64/l.s
+++ b/sys/src/9/bcm64/l.s
@@ -50,8 +50,6 @@
MOV $(L1-KZERO), R0
BL mmu0init(SB)
- BL cachedwbinv(SB)
- BL l2cacheuwbinv(SB)
SEVL
_startup:
WFE
@@ -162,7 +160,6 @@
ORR $KZERO, LR
MOV LR, -16(RSP)!
- BL cachedwbinv(SB)
BL flushlocaltlb(SB)
/* memory attributes */
--- a/sys/src/9/bcm64/main.c
+++ b/sys/src/9/bcm64/main.c
@@ -8,12 +8,12 @@
#include "io.h"
#include "init.h"
#include "sysreg.h"
+#include "reboot.h"
#include <pool.h>
#include <libsec.h>
Conf conf;
-ulong memsize = GiB;
/*
* starting place for first process
@@ -122,7 +122,7 @@
pg = newpage(1, 0, UTZERO);
pg->txtflush = ~0;
segpage(s, pg);
- k = kmap(s->map[0]->pages[0]);
+ k = kmap(pg);
memmove((void*)VA(k), initcode, sizeof initcode);
kunmap(k);
@@ -133,7 +133,7 @@
confinit(void)
{
int i, userpcnt;
- ulong kpages;
+ ulong kpages, memsize = 0;
uintptr pa;
char *p;
@@ -149,12 +149,10 @@
else
userpcnt = 0;
- if((p = getconf("*maxmem")) != nil){
+ if(p = getconf("*maxmem"))
memsize = strtoul(p, 0, 0) - PHYSDRAM;
- if (memsize < 16*MB) /* sanity */
- memsize = 16*MB;
- }
-
+ if (memsize < 16*MB) /* sanity */
+ memsize = 16*MB;
getramsize(&conf.mem[0]);
if(conf.mem[0].limit == 0){
conf.mem[0].base = PHYSDRAM;
@@ -247,7 +245,7 @@
for(i = 1; i < conf.nmach; i++)
MACHP(i)->machno = i;
- cachedwbinv();
+ coherence();
for(i = 1; i < conf.nmach; i++)
((uintptr*)SPINTABLE)[i] = PADDR(_start);
@@ -257,6 +255,9 @@
delay(100);
sev();
synccycles();
+
+ for(i = 0; i < MAXMACH; i++)
+ ((uintptr*)SPINTABLE)[i] = 0;
}
void
@@ -276,12 +277,11 @@
schedinit();
return;
}
+ quotefmtinstall();
bootargsinit();
confinit();
xinit();
printinit();
- fmtinstall('H', encodefmt);
- quotefmtinstall();
uartconsinit();
screeninit();
print("\nPlan 9\n");
@@ -308,17 +308,64 @@
schedinit();
}
+static void
+rebootjump(void *entry, void *code, ulong size)
+{
+ void (*f)(void*, void*, ulong);
+
+ intrsoff();
+ intrcpushutdown();
+
+ /* redo identity map */
+ mmuidmap((uintptr*)L1);
+
+ /* setup reboot trampoline function */
+ f = (void*)REBOOTADDR;
+ memmove(f, rebootcode, sizeof(rebootcode));
+ cachedwbinvse(f, sizeof(rebootcode));
+ cacheiinvse(f, sizeof(rebootcode));
+
+ (*f)(entry, code, size);
+
+ for(;;);
+}
+
void
exit(int)
{
cpushutdown();
- for(;;);
+ splfhi();
+ if(m->machno == 0)
+ archreboot();
+ rebootjump(0, 0, 0);
}
void
-reboot(void*, void*, ulong)
+reboot(void *entry, void *code, ulong size)
{
- error(Egreg);
+ writeconf();
+ while(m->machno != 0){
+ procwired(up, 0);
+ sched();
+ }
+
+ cpushutdown();
+ delay(2000);
+
+ splfhi();
+
+ /* turn off buffered serial console */
+ serialoq = nil;
+
+ /* shutdown devices */
+ chandevshutdown();
+
+ /* stop the clock (and watchdog if any) */
+ clockshutdown();
+ wdogoff();
+
+ /* off we go - never to return */
+ rebootjump(entry, code, size);
}
/*
--- a/sys/src/9/bcm64/mkfile
+++ b/sys/src/9/bcm64/mkfile
@@ -1,6 +1,5 @@
CONF=pi3
CONFLIST=pi3
-EXTRACOPIES=
loadaddr=0xffffffff80080000
@@ -8,8 +7,6 @@
</$objtype/mkfile
p=9
-OS=7
-
DEVS=`{rc ../port/mkdevlist $CONF}
PORT=\
@@ -89,12 +86,7 @@
install:V: /$objtype/$p$CONF
/$objtype/$p$CONF:D: $p$CONF s$p$CONF
- cp -x $p$CONF s$p$CONF /$objtype/ &
- for(i in $EXTRACOPIES)
- { 9fs $i && cp $p$CONF s$p$CONF /n/$i/$objtype && echo -n $i... & }
- wait
- echo
- touch $target
+ cp -x $p$CONF s$p$CONF /$objtype/
REPCC=`{../port/mkfilelist ../bcm}
@@ -108,8 +100,9 @@
arch.$O clock.$O fpiarm.$O main.$O mmu.$O screen.$O syscall.$O trap.$O: \
/$objtype/include/ureg.h
-l.$O cache.v8.$O lexception.$O lproc.$O mmu.$O: mem.h
+l.$O cache.v8.$O mmu.$O: mem.h
l.$O cache.v8.$O archbcm3.$O clock.$O fpu.$O trap.$O mmu.$O: sysreg.h
+main.$O: reboot.h
devmouse.$O mouse.$O screen.$O: screen.h
usbdwc.$O: dwcotg.h ../port/usb.h
@@ -130,14 +123,14 @@
sed -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
echo '};'} > init.h
-#reboot.h:D: rebootcode.s arm.s arm.h mem.h
-# $AS rebootcode.s
-# # -T arg is REBOOTADDR
-# $LD -l -s -T0x1c00 -R4 -o reboot.out rebootcode.$O
-# {echo 'uchar rebootcode[]={'
-# xd -1x reboot.out |
-# sed -e '1,2d' -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
-# echo '};'} > reboot.h
+reboot.h:D: rebootcode.s cache.v8.$O mem.h sysreg.h
+ $AS rebootcode.s
+ # -T arg is REBOOTADDR
+ $LD -l -o reboot.out -H6 -R1 -T0x1c00 rebootcode.$O cache.v8.$O
+ {echo 'uchar rebootcode[]={'
+ xd -1x reboot.out |
+ sed -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
+ echo '};'} > reboot.h
errstr.h:D: ../port/mkerrstr ../port/error.h
rc ../port/mkerrstr > errstr.h
--- a/sys/src/9/bcm64/mmu.c
+++ b/sys/src/9/bcm64/mmu.c
@@ -54,9 +54,9 @@
pe = PHYSDRAM + soc.dramsize;
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)] = 0;
+ 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)){
@@ -63,10 +63,38 @@
if(PTL1X(pa, 2) != PTL1X(va, 2))
l1[PTL1X(pa, 2)] = 0;
}
+ 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
+mmuidmap(uintptr *l1)
+{
+ uintptr va, pa, pe;
+
+ mmuswitch(nil);
+ flushtlb();
+
+ pe = PHYSDRAM + soc.dramsize;
+
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;
+ l1[PTL1X(pa, 1)] = pa | PTEVALID | PTEBLOCK | PTEWRITE | PTEAF
+ | PTEKERNEL | PTESH(SHARE_INNER);
}
+ 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;
+ }
+ 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;
+ }
+ setttbr(PADDR(&l1[L1TABLEX(0, PTLEVELS-1)]));
}
void
@@ -264,7 +292,6 @@
uintptr *pte, old;
int s;
-// iprint("cpu%d: putmmu va %#p asid %d proc %lud %s\n", m->machno, va, up->asid, up->pid, up->text);
s = splhi();
while((pte = mmuwalk(va, 0)) == nil){
spllo();
@@ -345,7 +372,6 @@
if(allocasid(p))
flushasid((uvlong)p->asid<<48);
-// iprint("cpu%d: mmuswitch asid %d proc %lud %s\n", m->machno, p->asid, p->pid, p->text);
setttbr((uvlong)p->asid<<48 | PADDR(&m->mmul1[L1TABLEX(0, PTLEVELS-1)]));
}
--- /dev/null
+++ b/sys/src/9/bcm64/rebootcode.s
@@ -1,0 +1,51 @@
+#include "mem.h"
+#include "sysreg.h"
+
+#undef SYSREG
+#define SYSREG(op0,op1,Cn,Cm,op2) SPR(((op0)<<19|(op1)<<16|(Cn)<<12|(Cm)<<8|(op2)<<5))
+
+TEXT _start(SB), 1, $-4
+ MOV $setSB(SB), R28
+
+ MRS MPIDR_EL1, R27
+ ANDW $(MAXMACH-1), R27
+ LSL $3, R27
+ ADD $(SPINTABLE-KZERO), R27
+
+ CBZ R0, _mmuoff
+ MOV R0, (R27)
+ MOV code+8(FP), R1
+ MOVWU size+16(FP), R2
+ BIC $3, R2
+ ADD R1, R2, R3
+
+_copy:
+ MOVW (R1)4!, R4
+ MOVW R4, (R0)4!
+ CMP R1, R3
+ BNE _copy
+
+ BL cachedwbinv(SB)
+ BL l2cacheuwbinv(SB)
+ SEVL
+
+_mmuoff:
+ ISB $SY
+ MRS SCTLR_EL1, R0
+ BIC $(1<<0 | 1<<2 | 1<<12), R0
+ ISB $SY
+ MSR R0, SCTLR_EL1
+ ISB $SY
+
+ DSB $NSHST
+ TLBI R0, 0,8,7,0 /* VMALLE1 */
+ DSB $NSH
+ ISB $SY
+
+ BL cachedwbinv(SB)
+ BL cacheiinv(SB)
+_wait:
+ WFE
+ MOV (R27), LR
+ CBZ LR, _wait
+ RETURN