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
front
cinap_lenrek 2018-10-28 06:16:10 +01:00
parent 0fc2adb43d
commit b715c39bfa
9 changed files with 71 additions and 101 deletions

View File

@ -237,7 +237,7 @@ cpustart(int cpu)
mb->clr[cpu].doorbell = 1;
trapinit();
clockinit();
mmuinit1();
mmuinit1(0);
timersinit();
cpuidprint();
archreset();

View File

@ -40,8 +40,6 @@
MOVW $0x10000,R3; \
MOVW R3,(R2)
#define PUTC(s)
/*
* get cpu id, or zero if armv6
*/

View File

@ -45,17 +45,6 @@ TEXT armstart(SB), 1, $-4
MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
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
@ -67,6 +56,17 @@ _ramZ:
MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
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

View File

@ -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);

View File

@ -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

View File

@ -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...
*/

View File

@ -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'

View File

@ -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

View File

@ -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