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 "sysreg.h"
|
||||||
#include "ureg.h"
|
#include "ureg.h"
|
||||||
|
|
||||||
|
#include "rebootcode.i"
|
||||||
|
|
||||||
Conf conf;
|
Conf conf;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -124,7 +126,7 @@ mpinit(void)
|
||||||
MACHP(i)->machno = i;
|
MACHP(i)->machno = i;
|
||||||
cachedwbinvse(MACHP(i), MACHSIZE);
|
cachedwbinvse(MACHP(i), MACHSIZE);
|
||||||
|
|
||||||
u.r0 = 0x84000003;
|
u.r0 = 0x84000003; /* CPU_ON */
|
||||||
u.r1 = (sysrd(MPIDR_EL1) & ~0xFF) | i;
|
u.r1 = (sysrd(MPIDR_EL1) & ~0xFF) | i;
|
||||||
u.r2 = PADDR(_start);
|
u.r2 = PADDR(_start);
|
||||||
u.r3 = i;
|
u.r3 = i;
|
||||||
|
@ -188,12 +190,13 @@ main(void)
|
||||||
void
|
void
|
||||||
exit(int)
|
exit(int)
|
||||||
{
|
{
|
||||||
Ureg u = { .r0 = 0x84000009 };
|
Ureg u = { .r0 = 0x84000002 }; /* CPU_OFF */
|
||||||
|
|
||||||
cpushutdown();
|
cpushutdown();
|
||||||
splfhi();
|
splfhi();
|
||||||
|
|
||||||
/* system reset */
|
if(m->machno == 0)
|
||||||
|
u.r0 = 0x84000009; /* SYSTEM RESET */
|
||||||
smccall(&u);
|
smccall(&u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,9 +217,54 @@ writeconf(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
reboot(void *, void *, ulong)
|
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
|
void
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
#define UCRAMSIZE (8*MiB)
|
#define UCRAMSIZE (8*MiB)
|
||||||
|
|
||||||
#define VDRAM (0xFFFFFFFFC0000000ULL) /* 0x40000000 - 0x80000000 */
|
#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 ARMLOCAL (0xFFFFFFFFB1000000ULL) /* 0x31000000 */
|
||||||
#define VIRTIO (0xFFFFFFFFB0000000ULL) /* 0x30000000 */
|
#define VIRTIO (0xFFFFFFFFB0000000ULL) /* 0x30000000 */
|
||||||
|
@ -64,6 +64,9 @@
|
||||||
|
|
||||||
#define MACHADDR(n) (KTZERO-((n)+1)*MACHSIZE)
|
#define MACHADDR(n) (KTZERO-((n)+1)*MACHSIZE)
|
||||||
|
|
||||||
|
#define CONFADDR (VDRAM + 0x10000) /* 0x40010000 */
|
||||||
|
#define REBOOTADDR (0x40020000) /* 0x40020000 */
|
||||||
|
|
||||||
#define UZERO 0ULL /* user segment */
|
#define UZERO 0ULL /* user segment */
|
||||||
#define UTZERO (UZERO+0x10000) /* user text start */
|
#define UTZERO (UZERO+0x10000) /* user text start */
|
||||||
#define USTKTOP ((EVAMASK>>1)-0xFFFF) /* user segment end +1 */
|
#define USTKTOP ((EVAMASK>>1)-0xFFFF) /* user segment end +1 */
|
||||||
|
|
|
@ -87,8 +87,15 @@ install:V: /$objtype/$p$CONF
|
||||||
<../port/portmkfile
|
<../port/portmkfile
|
||||||
<|../port/mkbootrules $CONF
|
<|../port/mkbootrules $CONF
|
||||||
|
|
||||||
|
main.$O: rebootcode.i
|
||||||
|
|
||||||
|
pciimx.$O: ../port/pci.h
|
||||||
|
|
||||||
initcode.out: init9.$O initcode.$O /$objtype/lib/libc.a
|
initcode.out: init9.$O initcode.$O /$objtype/lib/libc.a
|
||||||
$LD -l -R1 -s -o $target $prereq
|
$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:
|
$CONF.clean:
|
||||||
rm -rf $p$CONF $p$CONF.u errstr.h $CONF.c boot$CONF.c
|
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;
|
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
|
void
|
||||||
mmu1init(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