imx8: implement /dev/reboot support

This commit is contained in:
cinap_lenrek 2022-07-10 11:35:58 +00:00
parent 414cefcb0b
commit 32183b1abf
5 changed files with 130 additions and 6 deletions

View File

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

View File

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

View File

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

View File

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

View 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