diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-05-13 19:20:21 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-05-13 19:20:21 +0200 |
commit | a3b5e3994f7f2897ab1b5bb20b91224d145c1fc1 (patch) | |
tree | ceea2105303a45715bb44151be9b9420aad179bb | |
parent | 3b36daa2bb8c0f4169455baf829b9695b520c5fc (diff) |
bcm64: implement reboot support
-rw-r--r-- | sys/src/9/bcm64/archbcm3.c | 4 | ||||
-rw-r--r-- | sys/src/9/bcm64/dat.h | 1 | ||||
-rw-r--r-- | sys/src/9/bcm64/fns.h | 7 | ||||
-rw-r--r-- | sys/src/9/bcm64/l.s | 3 | ||||
-rw-r--r-- | sys/src/9/bcm64/main.c | 75 | ||||
-rw-r--r-- | sys/src/9/bcm64/mkfile | 29 | ||||
-rw-r--r-- | sys/src/9/bcm64/mmu.c | 38 | ||||
-rw-r--r-- | sys/src/9/bcm64/rebootcode.s | 51 |
8 files changed, 164 insertions, 44 deletions
diff --git a/sys/src/9/bcm64/archbcm3.c b/sys/src/9/bcm64/archbcm3.c index eb5e5b5f5..33dcc46ed 100644 --- a/sys/src/9/bcm64/archbcm3.c +++ b/sys/src/9/bcm64/archbcm3.c @@ -17,7 +17,7 @@ typedef struct Mboxes Mboxes; #define POWERREGS (VIRTIO+0x100000) Soc soc = { - .dramsize = GiB, + .dramsize = 0x3F000000, .physio = 0x3F000000, .busdram = 0xC0000000, .busio = 0x7E000000, @@ -164,5 +164,5 @@ wakecpu(uint cpu) void archbcm3link(void) { -// addclock0link(wdogfeed, HZ); + addclock0link(wdogfeed, HZ); } diff --git a/sys/src/9/bcm64/dat.h b/sys/src/9/bcm64/dat.h index d41ff3f4f..89336b4cd 100644 --- a/sys/src/9/bcm64/dat.h +++ b/sys/src/9/bcm64/dat.h @@ -194,7 +194,6 @@ struct extern register Mach* m; /* R27 */ extern register Proc* up; /* R26 */ extern int normalprint; -extern ulong memsize; /* * a parsed plan9.ini line diff --git a/sys/src/9/bcm64/fns.h b/sys/src/9/bcm64/fns.h index 779fc7686..25345043a 100644 --- a/sys/src/9/bcm64/fns.h +++ b/sys/src/9/bcm64/fns.h @@ -33,6 +33,9 @@ extern void tlbiaside1is(uintptr asid); 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 uintptr mmukmap(uintptr, uintptr, usize); 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 putasid(Proc*); 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 int gpiogetevent(uint); 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 void links(void); extern int getncpus(void); extern int startcpu(uint); extern void okay(int); +extern void wdogoff(void); /* dma */ extern uintptr dmaaddr(void*); diff --git a/sys/src/9/bcm64/l.s b/sys/src/9/bcm64/l.s index 69e9c3924..2270fbb8d 100644 --- a/sys/src/9/bcm64/l.s +++ b/sys/src/9/bcm64/l.s @@ -50,8 +50,6 @@ _zerobss: MOV $(L1-KZERO), R0 BL mmu0init(SB) - BL cachedwbinv(SB) - BL l2cacheuwbinv(SB) SEVL _startup: WFE @@ -162,7 +160,6 @@ TEXT mmuenable<>(SB), 1, $-4 ORR $KZERO, LR MOV LR, -16(RSP)! - BL cachedwbinv(SB) BL flushlocaltlb(SB) /* memory attributes */ diff --git a/sys/src/9/bcm64/main.c b/sys/src/9/bcm64/main.c index f82ca0f61..eab88466b 100644 --- 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 @@ userinit(void) 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 @@ void confinit(void) { int i, userpcnt; - ulong kpages; + ulong kpages, memsize = 0; uintptr pa; char *p; @@ -149,12 +149,10 @@ confinit(void) 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 @@ mpinit(void) 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 @@ mpinit(void) delay(100); sev(); synccycles(); + + for(i = 0; i < MAXMACH; i++) + ((uintptr*)SPINTABLE)[i] = 0; } void @@ -276,12 +277,11 @@ main(void) schedinit(); return; } + quotefmtinstall(); bootargsinit(); confinit(); xinit(); printinit(); - fmtinstall('H', encodefmt); - quotefmtinstall(); uartconsinit(); screeninit(); print("\nPlan 9\n"); @@ -308,17 +308,64 @@ main(void) 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); } /* diff --git a/sys/src/9/bcm64/mkfile b/sys/src/9/bcm64/mkfile index 2dbbe02b3..ad216131e 100644 --- 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=arm64 </$objtype/mkfile p=9 -OS=7 - DEVS=`{rc ../port/mkdevlist $CONF} PORT=\ @@ -89,12 +86,7 @@ $OBJ: $HFILES 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 @@ REPCC=`{../port/mkfilelist ../bcm} 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 @@ init.h:D: ../port/initcode.c init9.s 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 diff --git a/sys/src/9/bcm64/mmu.c b/sys/src/9/bcm64/mmu.c index 112b99a80..34c5d82bb 100644 --- a/sys/src/9/bcm64/mmu.c +++ b/sys/src/9/bcm64/mmu.c @@ -54,19 +54,47 @@ mmu0clear(uintptr *l1) 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)){ 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 @@ putmmu(uintptr va, uintptr pa, Page *pg) 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 @@ mmuswitch(Proc *p) 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)])); } diff --git a/sys/src/9/bcm64/rebootcode.s b/sys/src/9/bcm64/rebootcode.s new file mode 100644 index 000000000..b3eb307ac --- /dev/null +++ b/sys/src/9/bcm64/rebootcode.s @@ -0,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 |