diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2018-10-28 06:16:10 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2018-10-28 06:16:10 +0100 |
commit | b715c39bfa1e2169f450f719ba8a7643c7b39b68 (patch) | |
tree | dc5becbf9c6826e8e17b34fe84723630e8410ad5 /sys/src | |
parent | 0fc2adb43dc8be67b6eca49e3e28339367a01246 (diff) |
bcm: simplify reboot code
- synchronize rebootcode installation
- handle the 1MB identity map in mmu.c (mmuinit1())
- do not overlap CONFADDR with rebootcode, the non boot
processors are parked there.
- make REBOOTADDR physical address
Diffstat (limited to 'sys/src')
-rw-r--r-- | sys/src/9/bcm/archbcm2.c | 2 | ||||
-rw-r--r-- | sys/src/9/bcm/arm.s | 2 | ||||
-rw-r--r-- | sys/src/9/bcm/armv7.s | 23 | ||||
-rw-r--r-- | sys/src/9/bcm/fns.h | 2 | ||||
-rw-r--r-- | sys/src/9/bcm/main.c | 60 | ||||
-rw-r--r-- | sys/src/9/bcm/mem.h | 4 | ||||
-rw-r--r-- | sys/src/9/bcm/mkfile | 4 | ||||
-rw-r--r-- | sys/src/9/bcm/mmu.c | 15 | ||||
-rw-r--r-- | sys/src/9/bcm/rebootcode.s | 60 |
9 files changed, 71 insertions, 101 deletions
diff --git a/sys/src/9/bcm/archbcm2.c b/sys/src/9/bcm/archbcm2.c index 03836ca51..abde129d0 100644 --- a/sys/src/9/bcm/archbcm2.c +++ b/sys/src/9/bcm/archbcm2.c @@ -237,7 +237,7 @@ cpustart(int cpu) mb->clr[cpu].doorbell = 1; trapinit(); clockinit(); - mmuinit1(); + mmuinit1(0); timersinit(); cpuidprint(); archreset(); diff --git a/sys/src/9/bcm/arm.s b/sys/src/9/bcm/arm.s index 661b7136f..dd500ca5f 100644 --- a/sys/src/9/bcm/arm.s +++ b/sys/src/9/bcm/arm.s @@ -40,8 +40,6 @@ MOVW $0x10000,R3; \ MOVW R3,(R2) -#define PUTC(s) - /* * get cpu id, or zero if armv6 */ diff --git a/sys/src/9/bcm/armv7.s b/sys/src/9/bcm/armv7.s index 27f2e49c8..6f5390aa5 100644 --- a/sys/src/9/bcm/armv7.s +++ b/sys/src/9/bcm/armv7.s @@ -46,17 +46,6 @@ TEXT armstart(SB), 1, $-4 BARRIERS /* - * clear mach and page tables - */ - MOVW $PADDR(MACHADDR), R1 - MOVW $PADDR(KTZERO), R2 -_ramZ: - MOVW R0, (R1) - ADD $4, R1 - CMP R1, R2 - BNE _ramZ - - /* * turn SMP on * invalidate tlb */ @@ -68,6 +57,17 @@ _ramZ: BARRIERS /* + * clear mach and page tables + */ + MOVW $PADDR(MACHADDR), R1 + MOVW $PADDR(KTZERO), R2 +_ramZ: + MOVW R0, (R1) + ADD $4, R1 + CMP R1, R2 + BNE _ramZ + + /* * start stack at top of mach (physical addr) * set up page tables for kernel */ @@ -96,7 +96,6 @@ _ramZ: /* * enable caches, mmu, and high vectors */ - MRC CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl ORR $(CpChv|CpCdcache|CpCicache|CpCmmu), R0 MCR CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl diff --git a/sys/src/9/bcm/fns.h b/sys/src/9/bcm/fns.h index eb9c09eb5..56ce4085d 100644 --- a/sys/src/9/bcm/fns.h +++ b/sys/src/9/bcm/fns.h @@ -66,7 +66,7 @@ extern int isaconfig(char*, int, ISAConf*); extern void l2cacheuwbinv(void); extern void links(void); extern void mmuinit(void*); -extern void mmuinit1(void); +extern void mmuinit1(int); extern void mmuinvalidate(void); extern void mmuinvalidateaddr(u32int); extern uintptr mmukmap(uintptr, uintptr, usize); diff --git a/sys/src/9/bcm/main.c b/sys/src/9/bcm/main.c index 54956a3d0..9bf02215a 100644 --- a/sys/src/9/bcm/main.c +++ b/sys/src/9/bcm/main.c @@ -19,7 +19,7 @@ * Where configuration info is left for the loaded programme. */ #define BOOTARGS ((char*)CONFADDR) -#define BOOTARGSLEN (MACHADDR-CONFADDR) +#define BOOTARGSLEN (REBOOTADDR-PADDR(CONFADDR)) #define MAXCONF 64 #define MAXCONFLINE 160 @@ -301,7 +301,7 @@ main(void) pageinit(); userinit(); launchinit(); - mmuinit1(); + mmuinit1(0); schedinit(); assert(0); /* shouldn't have returned */ } @@ -550,6 +550,35 @@ confinit(void) } +static void +rebootjump(ulong entry, ulong code, ulong size) +{ + static void (*f)(ulong, ulong, ulong); + static Lock lk; + + intrsoff(); + intrcpushutdown(); + + /* redo identity map */ + mmuinit1(1); + + lock(&lk); + if(f == nil){ + /* setup reboot trampoline function */ + f = (void*)REBOOTADDR; + memmove(f, rebootcode, sizeof(rebootcode)); + cachedwbse(f, sizeof(rebootcode)); + } + unlock(&lk); + + cacheuwbinv(); + l2cacheuwbinv(); + + (*f)(entry, code, size); + + for(;;); +} + /* * exit kernel either on a panic or user request */ @@ -558,14 +587,8 @@ exit(int) { cpushutdown(); splfhi(); - if(m->machno != 0){ - void (*f)(ulong, ulong, ulong) = (void*)REBOOTADDR; - intrsoff(); - intrcpushutdown(); - cacheuwbinv(); - (*f)(0, 0, 0); - for(;;); - } + if(m->machno != 0) + rebootjump(0, 0, 0); archreboot(); } @@ -585,21 +608,14 @@ isaconfig(char *, int, ISAConf *) void reboot(void *entry, void *code, ulong size) { - void (*f)(ulong, ulong, ulong); - writeconf(); if (m->machno != 0) { procwired(up, 0); sched(); } - /* setup reboot trampoline function */ - f = (void*)REBOOTADDR; - memmove(f, rebootcode, sizeof(rebootcode)); - cachedwbse(f, sizeof(rebootcode)); - cpushutdown(); - delay(500); + delay(1000); splfhi(); @@ -611,14 +627,10 @@ reboot(void *entry, void *code, ulong size) /* stop the clock (and watchdog if any) */ clockshutdown(); - intrsoff(); - intrcpushutdown(); - - cacheuwbinv(); - l2cacheuwbinv(); + wdogoff(); /* off we go - never to return */ - (*f)(PADDR(entry), PADDR(code), size); + rebootjump(PADDR(entry), PADDR(code), size); } void diff --git a/sys/src/9/bcm/mem.h b/sys/src/9/bcm/mem.h index f9b6af838..baed39050 100644 --- a/sys/src/9/bcm/mem.h +++ b/sys/src/9/bcm/mem.h @@ -44,6 +44,7 @@ #define KSEGM 0xC0000000 #define KZERO KSEG0 /* kernel address space */ #define CONFADDR (KZERO+0x100) /* unparsed plan9.ini */ +#define REBOOTADDR (0x1c00) /* reboot code - physical address */ #define MACHADDR (KZERO+0x2000) /* Mach structure */ #define L2 (KZERO+0x3000) /* L2 ptes for vectors etc */ #define VCBUFFER (KZERO+0x3400) /* videocore mailbox buffer */ @@ -62,9 +63,6 @@ #define TSTKTOP (USTKTOP-USTKSIZE) /* sysexec temporary stack */ #define TSTKSIZ 256 -/* address at which to copy and execute rebootcode */ -#define REBOOTADDR (KZERO+0x1800) - /* * Legacy... */ diff --git a/sys/src/9/bcm/mkfile b/sys/src/9/bcm/mkfile index a9673a7ce..e9823a982 100644 --- a/sys/src/9/bcm/mkfile +++ b/sys/src/9/bcm/mkfile @@ -123,8 +123,8 @@ init.h:D: ../port/initcode.c init9.s reboot.h:D: rebootcode.s arm.s arm.h mem.h $AS rebootcode.s - # -lc is only for memmove. -T arg is PADDR(REBOOTADDR) - $LD -l -s -T0x1800 -R4 -o reboot.out rebootcode.$O -lc + # -lc is only for memmove. -T arg is REBOOTADDR + $LD -l -s -T0x1c00 -R4 -o reboot.out rebootcode.$O -lc {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' diff --git a/sys/src/9/bcm/mmu.c b/sys/src/9/bcm/mmu.c index af647285f..431c2bff9 100644 --- a/sys/src/9/bcm/mmu.c +++ b/sys/src/9/bcm/mmu.c @@ -12,6 +12,7 @@ #define L2AP(ap) l2ap(ap) #define L1ptedramattrs soc.l1ptedramattrs #define L2ptedramattrs soc.l2ptedramattrs +#define PTEDRAM (PHYSDRAM|Dom0|L1AP(Krw)|Section|L1ptedramattrs) enum { L1lo = UZERO/MiB, /* L1X(UZERO)? */ @@ -43,7 +44,7 @@ mmuinit(void *a) /* * identity map first MB of ram so mmu can be enabled */ - l1[L1X(PHYSDRAM)] = PHYSDRAM|Dom0|L1AP(Krw)|Section|L1ptedramattrs; + l1[L1X(PHYSDRAM)] = PTEDRAM; /* * map i/o registers @@ -65,19 +66,19 @@ mmuinit(void *a) l2[L2X(va)] = PHYSDRAM|L2AP(Krw)|Small|L2ptedramattrs; } +/* + * enable/disable identity map of first MB of ram + */ void -mmuinit1() +mmuinit1(int on) { PTE *l1; l1 = m->mmul1; - - /* - * undo identity map of first MB of ram - */ - l1[L1X(PHYSDRAM)] = 0; + l1[L1X(PHYSDRAM)] = on? PTEDRAM: Fault; cachedwbtlb(&l1[L1X(PHYSDRAM)], sizeof(PTE)); mmuinvalidateaddr(PHYSDRAM); + mmuinvalidate(); } static void diff --git a/sys/src/9/bcm/rebootcode.s b/sys/src/9/bcm/rebootcode.s index a685debb3..c2a91f0bd 100644 --- a/sys/src/9/bcm/rebootcode.s +++ b/sys/src/9/bcm/rebootcode.s @@ -3,8 +3,6 @@ */ #include "arm.s" -#define PTEDRAM (Dom0|L1AP(Krw)|Section) - #define WFI WORD $0xe320f003 /* wait for interrupt */ #define WFE WORD $0xe320f002 /* wait for event */ @@ -26,8 +24,16 @@ TEXT main(SB), 1, $-4 MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R1 MOVW R1, CPSR - /* prepare to turn off mmu */ - BL cachesoff(SB) + /* turn caches off */ + MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl + BIC $(CpCdcache|CpCicache|CpCpredict), R1 + MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl + BARRIERS + + /* invalidate icache */ + MOVW $0, R0 + MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall + BARRIERS /* turn off mmu */ MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl @@ -49,7 +55,7 @@ dowfi: MOVW $0x40000060, R1 ADD R2<<2, R1 MOVW 0(R1), R0 - AND $0x10, R0 + AND $0x10, R0 BEQ dowfi MOVW $0x8000, R1 BL (R1) @@ -72,47 +78,3 @@ bootcpu: ORR R8,R8 B (R8) B 0(PC) - -/* - * turn the caches off, double map PHYSDRAM & KZERO, invalidate TLBs, revert - * to tiny addresses. upon return, it will be safe to turn off the mmu. - * clobbers R0-R2, and returns with SP invalid. - */ -TEXT cachesoff(SB), 1, $-4 - MOVM.DB.W [R14,R1-R10], (R13) /* save regs on stack */ - - /* turn caches off, invalidate icache */ - MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl - BIC $(CpCdcache|CpCicache|CpCpredict), R1 - MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl - MOVW $0, R0 - MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall - - /* invalidate stale TLBs before changing them */ - BARRIERS - MOVW $0, R0 - MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv - BARRIERS - - /* redo double map of first MiB PHYSDRAM = KZERO */ - MOVW 12(R(MACH)), R2 /* m->mmul1 (virtual addr) */ - MOVW $PTEDRAM, R1 /* PTE bits */ - MOVW R1, (R2) - DSB - MCR CpSC, 0, R2, C(CpCACHE), C(CpCACHEwb), CpCACHEse - - /* invalidate stale TLBs again */ - BARRIERS - MOVW $0, R0 - MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv - BARRIERS - - /* relocate SB and return address to PHYSDRAM addressing */ - MOVW $KSEGM, R1 /* clear segment bits */ - BIC R1, R12 /* adjust SB */ - MOVM.IA.W (R13), [R14,R1-R10] /* restore regs from stack */ - - MOVW $KSEGM, R1 /* clear segment bits */ - BIC R1, R14 /* adjust return address */ - - RET |