xref: /plan9-contrib/sys/src/9/bcm/rebootcode.s (revision 5c47fe09a0cc86dfb02c0ea4a2b6aec7eda2361f)
15d9de2d3SDavid du Colombier/*
2*5c47fe09SDavid du Colombier * armv6/armv7 reboot code
35d9de2d3SDavid du Colombier */
45d9de2d3SDavid du Colombier#include "arm.s"
55d9de2d3SDavid du Colombier
6*5c47fe09SDavid du Colombier#define PTEDRAM		(Dom0|L1AP(Krw)|Section)
7*5c47fe09SDavid du Colombier
8*5c47fe09SDavid du Colombier#define WFI	WORD	$0xe320f003	/* wait for interrupt */
9*5c47fe09SDavid du Colombier#define WFE	WORD	$0xe320f002	/* wait for event */
10*5c47fe09SDavid du Colombier
115d9de2d3SDavid du Colombier/*
12*5c47fe09SDavid du Colombier * CPU0:
13*5c47fe09SDavid du Colombier *   main(PADDR(entry), PADDR(code), size);
14*5c47fe09SDavid du Colombier * Copy the new kernel to its correct location in virtual memory.
15*5c47fe09SDavid du Colombier * Then turn off the mmu and jump to the start of the kernel.
16*5c47fe09SDavid du Colombier *
17*5c47fe09SDavid du Colombier * Other CPUs:
18*5c47fe09SDavid du Colombier *   main(0, soc.armlocal, 0);
19*5c47fe09SDavid du Colombier * Turn off the mmu, wait for a restart address from CPU0, and jump to it.
205d9de2d3SDavid du Colombier */
215d9de2d3SDavid du Colombier
22*5c47fe09SDavid du Colombier/* */
235d9de2d3SDavid du ColombierTEXT	main(SB), 1, $-4
245d9de2d3SDavid du Colombier	MOVW	$setR12(SB), R12
255d9de2d3SDavid du Colombier
265d9de2d3SDavid du Colombier	/* copy in arguments before stack gets unmapped */
275d9de2d3SDavid du Colombier	MOVW	R0, R8			/* entry point */
28*5c47fe09SDavid du Colombier	MOVW	p2+4(FP), R7		/* source */
29*5c47fe09SDavid du Colombier	MOVW	n+8(FP), R6		/* byte count */
305d9de2d3SDavid du Colombier
31*5c47fe09SDavid du Colombier	/* redo double map of first MiB PHYSDRAM = KZERO */
32*5c47fe09SDavid du Colombier	MOVW	12(R(MACH)), R2		/* m->mmul1 (virtual addr) */
33*5c47fe09SDavid du Colombier	MOVW	$PTEDRAM, R1		/* PTE bits */
34*5c47fe09SDavid du Colombier	MOVW	R1, (R2)
35*5c47fe09SDavid du Colombier	DSB
36*5c47fe09SDavid du Colombier	MCR	CpSC, 0, R2, C(CpCACHE), C(CpCACHEwb), CpCACHEse
375d9de2d3SDavid du Colombier
38*5c47fe09SDavid du Colombier	/* invalidate stale TLBs */
39*5c47fe09SDavid du Colombier	BARRIERS
40*5c47fe09SDavid du Colombier	MOVW	$0, R0
41*5c47fe09SDavid du Colombier	MCR	CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
42*5c47fe09SDavid du Colombier	BARRIERS
435d9de2d3SDavid du Colombier
44*5c47fe09SDavid du Colombier	/* relocate PC to physical addressing */
45*5c47fe09SDavid du Colombier	MOVW	$_reloc(SB), R15
46*5c47fe09SDavid du Colombier
47*5c47fe09SDavid du ColombierTEXT _reloc(SB), $-4
48*5c47fe09SDavid du Colombier
49*5c47fe09SDavid du Colombier	/* continue with reboot only on cpu0 */
50*5c47fe09SDavid du Colombier	CPUID(R2)
51*5c47fe09SDavid du Colombier	BEQ	bootcpu
52*5c47fe09SDavid du Colombier
53*5c47fe09SDavid du Colombier	/* other cpus wait for inter processor interrupt from cpu0 */
54*5c47fe09SDavid du Colombier
55*5c47fe09SDavid du Colombier	/* turn caches off, invalidate icache */
56*5c47fe09SDavid du Colombier	MRC	CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
57*5c47fe09SDavid du Colombier	BIC	$(CpCdcache|CpCicache), R1
58*5c47fe09SDavid du Colombier	MCR	CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
59*5c47fe09SDavid du Colombier	MOVW	$0, R0
60*5c47fe09SDavid du Colombier	MCR	CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall
615d9de2d3SDavid du Colombier 	/* turn off mmu */
625d9de2d3SDavid du Colombier	MRC	CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
635d9de2d3SDavid du Colombier	BIC	$CpCmmu, R1
645d9de2d3SDavid du Colombier	MCR	CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
65*5c47fe09SDavid du Colombier	/* turn off SMP cache snooping */
66*5c47fe09SDavid du Colombier	MRC	CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
67*5c47fe09SDavid du Colombier	BIC	$CpACsmp, R1
68*5c47fe09SDavid du Colombier	MCR	CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
69*5c47fe09SDavid du Colombier	ISB
70*5c47fe09SDavid du Colombier	DSB
71*5c47fe09SDavid du Colombier	/* turn icache back on */
72*5c47fe09SDavid du Colombier	MRC	CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
73*5c47fe09SDavid du Colombier	ORR	$(CpCicache), R1
74*5c47fe09SDavid du Colombier	MCR	CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
75*5c47fe09SDavid du Colombier	BARRIERS
765d9de2d3SDavid du Colombier
77*5c47fe09SDavid du Colombierdowfi:
78*5c47fe09SDavid du Colombier	WFE			/* wait for event signal */
79*5c47fe09SDavid du Colombier	MOVW	$0xCC(R7), R1	/* inter-core .startcpu mailboxes */
80*5c47fe09SDavid du Colombier	ADD	R2<<4, R1	/* mailbox for this core */
81*5c47fe09SDavid du Colombier	MOVW	0(R1), R8	/* content of mailbox */
82*5c47fe09SDavid du Colombier	CMP	$0, R8
83*5c47fe09SDavid du Colombier	BEQ	dowfi		/* if zero, wait again */
84*5c47fe09SDavid du Colombier	BL	(R8)		/* call received address */
85*5c47fe09SDavid du Colombier	B	dowfi		/* shouldn't return */
86*5c47fe09SDavid du Colombier
87*5c47fe09SDavid du Colombierbootcpu:
88*5c47fe09SDavid du Colombier	MOVW	$PADDR(MACHADDR+MACHSIZE-4), SP
895d9de2d3SDavid du Colombier
905d9de2d3SDavid du Colombier	/* copy the kernel to final destination */
91*5c47fe09SDavid du Colombier	MOVW	R8, R9		/* save physical entry point */
92*5c47fe09SDavid du Colombier	ADD	$KZERO, R8	/* relocate dest to virtual */
93*5c47fe09SDavid du Colombier	ADD	$KZERO, R7	/* relocate src to virtual */
94*5c47fe09SDavid du Colombier	ADD	$3, R6		/* round length to words */
95*5c47fe09SDavid du Colombier	BIC	$3, R6
96*5c47fe09SDavid du Colombiermemloop:
97*5c47fe09SDavid du Colombier	MOVM.IA.W	(R7), [R1]
98*5c47fe09SDavid du Colombier	MOVM.IA.W	[R1], (R8)
99*5c47fe09SDavid du Colombier	SUB.S	$4, R6
100*5c47fe09SDavid du Colombier	BNE	memloop
1015d9de2d3SDavid du Colombier
102*5c47fe09SDavid du Colombier	/* clean dcache using appropriate code for armv6 or armv7 */
103*5c47fe09SDavid du Colombier	MRC	CpSC, 0, R1, C(CpID), C(CpIDfeat), 7	/* Memory Model Feature Register 3 */
104*5c47fe09SDavid du Colombier	TST	$0xF, R1	/* hierarchical cache maintenance? */
105*5c47fe09SDavid du Colombier	BNE	l2wb
106*5c47fe09SDavid du Colombier	DSB
1075d9de2d3SDavid du Colombier	MOVW	$0, R0
108*5c47fe09SDavid du Colombier	MCR	CpSC, 0, R0, C(CpCACHE), C(CpCACHEwb), CpCACHEall
109*5c47fe09SDavid du Colombier	B	l2wbx
110*5c47fe09SDavid du Colombierl2wb:
111*5c47fe09SDavid du Colombier	BL		cachedwb(SB)
112*5c47fe09SDavid du Colombier	BL		l2cacheuwb(SB)
113*5c47fe09SDavid du Colombierl2wbx:
1145d9de2d3SDavid du Colombier
115*5c47fe09SDavid du Colombier	/* turn caches off, invalidate icache */
1165d9de2d3SDavid du Colombier	MRC	CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
1175d9de2d3SDavid du Colombier	BIC	$(CpCdcache|CpCicache|CpCpredict), R1
1185d9de2d3SDavid du Colombier	MCR	CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
119*5c47fe09SDavid du Colombier	DSB
120*5c47fe09SDavid du Colombier	MOVW	$0, R0
121*5c47fe09SDavid du Colombier	MCR	CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall
122*5c47fe09SDavid du Colombier	DSB
123*5c47fe09SDavid du Colombier 	/* turn off mmu */
124*5c47fe09SDavid du Colombier	MRC	CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
125*5c47fe09SDavid du Colombier	BIC	$CpCmmu, R1
126*5c47fe09SDavid du Colombier	MCR	CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
1275d9de2d3SDavid du Colombier	BARRIERS
128*5c47fe09SDavid du Colombier	/* turn off SMP cache snooping */
129*5c47fe09SDavid du Colombier	MRC	CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
130*5c47fe09SDavid du Colombier	BIC	$CpACsmp, R1
131*5c47fe09SDavid du Colombier	MCR	CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
1325d9de2d3SDavid du Colombier
133*5c47fe09SDavid du Colombier	/* invalidate dcache using appropriate code for armv6 or armv7 */
134*5c47fe09SDavid du Colombier	MRC	CpSC, 0, R1, C(CpID), C(CpIDfeat), 7	/* Memory Model Feature Register 3 */
135*5c47fe09SDavid du Colombier	TST	$0xF, R1	/* hierarchical cache maintenance */
136*5c47fe09SDavid du Colombier	BNE	l2inv
137*5c47fe09SDavid du Colombier	DSB
138*5c47fe09SDavid du Colombier	MOVW	$0, R0
139*5c47fe09SDavid du Colombier	MCR	CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvd), CpCACHEall
140*5c47fe09SDavid du Colombier	B	l2invx
141*5c47fe09SDavid du Colombierl2inv:
142*5c47fe09SDavid du Colombier	BL		cachedinv(SB)
143*5c47fe09SDavid du Colombier	BL		l2cacheuinv(SB)
144*5c47fe09SDavid du Colombierl2invx:
1455d9de2d3SDavid du Colombier
146*5c47fe09SDavid du Colombier	/* jump to restart entry point */
147*5c47fe09SDavid du Colombier	MOVW	R9, R8
148*5c47fe09SDavid du Colombier	MOVW	$0, R9
149*5c47fe09SDavid du Colombier	B	(R8)
1505d9de2d3SDavid du Colombier
151*5c47fe09SDavid du Colombier#define ICACHELINESZ	32
152*5c47fe09SDavid du Colombier#include "cache.v7.s"
153