imx8: implement /dev/reboot support
This commit is contained in:
parent
414cefcb0b
commit
32183b1abf
5 changed files with 130 additions and 6 deletions
|
@ -10,6 +10,8 @@
|
|||
#include "sysreg.h"
|
||||
#include "ureg.h"
|
||||
|
||||
#include "rebootcode.i"
|
||||
|
||||
Conf conf;
|
||||
|
||||
/*
|
||||
|
@ -124,7 +126,7 @@ mpinit(void)
|
|||
MACHP(i)->machno = i;
|
||||
cachedwbinvse(MACHP(i), MACHSIZE);
|
||||
|
||||
u.r0 = 0x84000003;
|
||||
u.r0 = 0x84000003; /* CPU_ON */
|
||||
u.r1 = (sysrd(MPIDR_EL1) & ~0xFF) | i;
|
||||
u.r2 = PADDR(_start);
|
||||
u.r3 = i;
|
||||
|
@ -188,12 +190,13 @@ main(void)
|
|||
void
|
||||
exit(int)
|
||||
{
|
||||
Ureg u = { .r0 = 0x84000009 };
|
||||
Ureg u = { .r0 = 0x84000002 }; /* CPU_OFF */
|
||||
|
||||
cpushutdown();
|
||||
splfhi();
|
||||
|
||||
/* system reset */
|
||||
if(m->machno == 0)
|
||||
u.r0 = 0x84000009; /* SYSTEM RESET */
|
||||
smccall(&u);
|
||||
}
|
||||
|
||||
|
@ -214,9 +217,54 @@ writeconf(void)
|
|||
{
|
||||
}
|
||||
|
||||
void
|
||||
reboot(void *, void *, ulong)
|
||||
static void
|
||||
rebootjump(void *entry, void *code, ulong size)
|
||||
{
|
||||
void (*f)(void*, void*, ulong);
|
||||
|
||||
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
|
||||
reboot(void*, void *code, ulong size)
|
||||
{
|
||||
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 */
|
||||
clockshutdown();
|
||||
intrsoff();
|
||||
|
||||
/* off we go - never to return */
|
||||
rebootjump((void*)(KTZERO-KZERO), code, size);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#define UCRAMSIZE (8*MiB)
|
||||
|
||||
#define VDRAM (0xFFFFFFFFC0000000ULL) /* 0x40000000 - 0x80000000 */
|
||||
#define KTZERO (VDRAM + 0x100000) /* kernel text start */
|
||||
#define KTZERO (VDRAM + 0x100000) /* 0x40100000 - kernel text start */
|
||||
|
||||
#define ARMLOCAL (0xFFFFFFFFB1000000ULL) /* 0x31000000 */
|
||||
#define VIRTIO (0xFFFFFFFFB0000000ULL) /* 0x30000000 */
|
||||
|
@ -64,6 +64,9 @@
|
|||
|
||||
#define MACHADDR(n) (KTZERO-((n)+1)*MACHSIZE)
|
||||
|
||||
#define CONFADDR (VDRAM + 0x10000) /* 0x40010000 */
|
||||
#define REBOOTADDR (0x40020000) /* 0x40020000 */
|
||||
|
||||
#define UZERO 0ULL /* user segment */
|
||||
#define UTZERO (UZERO+0x10000) /* user text start */
|
||||
#define USTKTOP ((EVAMASK>>1)-0xFFFF) /* user segment end +1 */
|
||||
|
|
|
@ -87,8 +87,15 @@ install:V: /$objtype/$p$CONF
|
|||
<../port/portmkfile
|
||||
<|../port/mkbootrules $CONF
|
||||
|
||||
main.$O: rebootcode.i
|
||||
|
||||
pciimx.$O: ../port/pci.h
|
||||
|
||||
initcode.out: init9.$O initcode.$O /$objtype/lib/libc.a
|
||||
$LD -l -R1 -s -o $target $prereq
|
||||
|
||||
rebootcode.out: rebootcode.$O cache.v8.$O
|
||||
$LD -l -H6 -R1 -T0x40020000 -s -o $target $prereq
|
||||
|
||||
$CONF.clean:
|
||||
rm -rf $p$CONF $p$CONF.u errstr.h $CONF.c boot$CONF.c
|
||||
|
|
|
@ -60,6 +60,24 @@ mmu0clear(uintptr *l1)
|
|||
l1[PTL1X(pa, 3)] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
mmuidmap(uintptr *l1)
|
||||
{
|
||||
uintptr va, pa, pe;
|
||||
|
||||
pe = -VDRAM;
|
||||
for(pa = VDRAM - KZERO, va = VDRAM; pa < pe; pa += PGLSZ(1), va += PGLSZ(1))
|
||||
l1[PTL1X(pa, 1)] = l1[PTL1X(va, 1)];
|
||||
if(PTLEVELS > 2)
|
||||
for(pa = VDRAM - KZERO, va = VDRAM; pa < pe; pa += PGLSZ(2), va += PGLSZ(2))
|
||||
l1[PTL1X(pa, 2)] = l1[PTL1X(va, 2)];
|
||||
if(PTLEVELS > 3)
|
||||
for(pa = VDRAM - KZERO, va = VDRAM; pa < pe; pa += PGLSZ(3), va += PGLSZ(3))
|
||||
l1[PTL1X(pa, 3)] = l1[PTL1X(va, 3)];
|
||||
setttbr(PADDR(&l1[L1TABLEX(0, PTLEVELS-1)]));
|
||||
flushtlb();
|
||||
}
|
||||
|
||||
void
|
||||
mmu1init(void)
|
||||
{
|
||||
|
|
48
sys/src/9/imx8/rebootcode.s
Normal file
48
sys/src/9/imx8/rebootcode.s
Normal file
|
@ -0,0 +1,48 @@
|
|||
#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
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
MOVWU $0, R0
|
||||
MOVWU $0, R1
|
||||
MOVWU $0, R2
|
||||
MOVWU $0, R3
|
||||
|
||||
MOV R27, LR
|
||||
|
||||
RETURN
|
Loading…
Reference in a new issue