ref: 7aa8c6d47ede0a8d419ba0c9695933f67f01ffda
parent: cac30a565ebcd596c83f78c07da5d1a35f67f6b6
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun May 8 16:26:56 EDT 2022
imx8: implement psci calls for system reset and multicore startup
--- a/sys/src/9/imx8/fns.h
+++ b/sys/src/9/imx8/fns.h
@@ -16,6 +16,7 @@
extern void returnto(void*);
extern void fpsaveregs(void*);
extern void fploadregs(void*);
+extern void smccall(Ureg*);
extern void setttbr(uintptr pa);
extern uintptr getfar(void);
@@ -136,4 +137,4 @@
extern void writeconf(void);
extern int isaconfig(char*, int, ISAConf*);
-extern void links(void);
\ No newline at end of file
+extern void links(void);
--- a/sys/src/9/imx8/gic.c
+++ b/sys/src/9/imx8/gic.c
@@ -139,7 +139,6 @@
/* clear all interrupts */
n = ((dregs[GICD_TYPER] & 0x1F)+1) << 5;
-print("nirq %d\n", n);
for(i = 32; i < n; i += 32){
dregs[GICD_IGROUPR0 + (i/32)] = -1;
@@ -146,11 +145,9 @@
dregs[GICD_ISENABLER0 + (i/32)] = -1;
while(dregs[GICD_CTLR]&(1<<31))
;
-print("%d: distributor stuck disabled: %.8ux\n", i, ~dregs[GICD_ISENABLER0 + (i/32)]);
dregs[GICD_ICENABLER0 + (i/32)] = -1;
while(dregs[GICD_CTLR]&(1<<31))
;
-print("%d: distributor stuck enabled: %.8ux\n", i, dregs[GICD_ISENABLER0 + (i/32)]);
dregs[GICD_ICACTIVER0 + (i/32)] = -1;
}
for(i = 0; i < n; i += 4){
@@ -174,11 +171,9 @@
rregs[GICR_ISENABLER0 + (i/32)] = -1;
while(rregs[GICR_CTLR]&(1<<3))
;
-print("%d: re-distributor stuck disabled: %.8ux\n", i, ~rregs[GICR_ISENABLER0 + (i/32)]);
rregs[GICR_ICENABLER0 + (i/32)] = -1;
while(dregs[GICD_CTLR]&(1<<31))
;
-print("%d: re-distributor stuck enabled: %.8ux\n", i, rregs[GICR_ISENABLER0 + (i/32)]);
rregs[GICR_ICACTIVER0 + (i/32)] = -1;
}
for(i = 0; i < n; i += 4){
--- a/sys/src/9/imx8/l.s
+++ b/sys/src/9/imx8/l.s
@@ -679,3 +679,34 @@
SUBS $1, R0
BNE _peekloop
RETURN
+
+TEXT smccall(SB), 1, $32
+ /* save extern registers */
+ MOVP R26, R27, (RSP)
+
+ /* R0 = Ureg */
+ MOV R0, R8
+
+ /* save ureg pointer */
+ MOV R8, 16(RSP)
+
+ MOVP 0(R8), R0, R1
+ MOVP 16(R8), R2, R3
+ MOVP 32(R8), R4, R5
+ MOVP 48(R8), R6, R7
+
+ SMC
+
+ /* restore ureg pointer */
+ MOV 16(RSP), R8
+
+ MOVP R0, R1, 0(R8)
+ MOVP R2, R3, 16(R8)
+
+ /* restore extern registers */
+ MOVP (RSP), R26, R27
+
+ RETURN
+
+
+
--- a/sys/src/9/imx8/main.c
+++ b/sys/src/9/imx8/main.c
@@ -8,6 +8,7 @@
#include "pool.h"
#include "io.h"
#include "sysreg.h"
+#include "ureg.h"
Conf conf;
@@ -46,7 +47,7 @@
char *p;
int i;
- conf.nmach = 1;
+ conf.nmach = MAXMACH;
if(p = getconf("service")){
if(strcmp(p, "cpu") == 0)
@@ -117,6 +118,29 @@
}
void
+mpinit(void)
+{
+ extern void _start(void);
+ int i;
+
+ splhi();
+ for(i = 1; i < conf.nmach; i++){
+ Ureg u = {0};
+
+ MACHP(i)->machno = i;
+ cachedwbinvse(MACHP(i), MACHSIZE);
+
+ u.r0 = 0x84000003;
+ u.r1 = (sysrd(MPIDR_EL1) & ~0xFF) | i;
+ u.r2 = PADDR(_start);
+ u.r3 = i;
+ smccall(&u);
+ }
+ synccycles();
+ spllo();
+}
+
+void
main(void)
{
machinit();
@@ -125,7 +149,7 @@
fpuinit();
intrinit();
clockinit();
- // cpuidprint();
+ print("cpu%d: UP!\n", m->machno);
synccycles();
timersinit();
flushtlb();
@@ -152,7 +176,7 @@
links();
chandevreset();
userinit();
-// mpinit();
+ mpinit();
mmu0clear((uintptr*)L1);
flushtlb();
mmu1init();
@@ -162,9 +186,13 @@
void
exit(int)
{
+ Ureg u = { .r0 = 0x84000009 };
+
cpushutdown();
splfhi();
- for(;;);
+
+ /* system reset */
+ smccall(&u);
}
int