xref: /plan9/sys/src/9/kw/rebootcode.s (revision bb9c7457bbc95323d3ebe779d2114080683da0b8)
1154abd99SDavid du Colombier/*
2154abd99SDavid du Colombier * sheevaplug reboot code
3154abd99SDavid du Colombier *
4154abd99SDavid du Colombier * R11 is used by the loader as a temporary, so avoid it.
5154abd99SDavid du Colombier */
6154abd99SDavid du Colombier#include "arm.s"
7154abd99SDavid du Colombier
8154abd99SDavid du Colombier/*
9154abd99SDavid du Colombier * Turn off MMU, then copy the new kernel to its correct location
10154abd99SDavid du Colombier * in physical memory.  Then jump to the start of the kernel.
11154abd99SDavid du Colombier */
12154abd99SDavid du Colombier
13154abd99SDavid du Colombier/* main(PADDR(entry), PADDR(code), size); */
14154abd99SDavid du ColombierTEXT	main(SB), 1, $-4
15154abd99SDavid du Colombier	MOVW	$setR12(SB), R12
16154abd99SDavid du Colombier
17154abd99SDavid du Colombier	MOVW	R0, p1+0(FP)		/* destination, passed in R0 */
18154abd99SDavid du Colombier
19154abd99SDavid du Colombier	/* copy in arguments from frame */
20154abd99SDavid du Colombier	MOVW	R0, R8			/* entry point */
21154abd99SDavid du Colombier	MOVW	p2+4(FP), R9		/* source */
22154abd99SDavid du Colombier	MOVW	n+8(FP), R10		/* byte count */
23154abd99SDavid du Colombier
24*bb9c7457SDavid du ColombierPUTC('R')
25154abd99SDavid du Colombier	BL	cachesoff(SB)
26154abd99SDavid du Colombier	/* now back in 29- or 26-bit addressing, mainly for SB */
27154abd99SDavid du Colombier
28154abd99SDavid du Colombier	/* turn the MMU off */
29*bb9c7457SDavid du ColombierPUTC('e')
30154abd99SDavid du Colombier	MOVW	$KSEGM, R7
31154abd99SDavid du Colombier	MOVW	$PHYSDRAM, R0
32154abd99SDavid du Colombier	BL	_r15warp(SB)
33154abd99SDavid du Colombier
34154abd99SDavid du Colombier	BIC	R7, R12			/* SB */
35154abd99SDavid du Colombier	BIC	R7, R13			/* SP */
36154abd99SDavid du Colombier	/* don't care about R14 */
37154abd99SDavid du Colombier
38*bb9c7457SDavid du ColombierPUTC('b')
39154abd99SDavid du Colombier	BL	mmuinvalidate(SB)
40*bb9c7457SDavid du ColombierPUTC('o')
41154abd99SDavid du Colombier	BL	mmudisable(SB)
42154abd99SDavid du Colombier
43*bb9c7457SDavid du ColombierPUTC('o')
44154abd99SDavid du Colombier	MOVW	R9, R4			/* restore regs across function calls */
45154abd99SDavid du Colombier	MOVW	R10, R5
46154abd99SDavid du Colombier	MOVW	R8, R6
47154abd99SDavid du Colombier
48154abd99SDavid du Colombier	/* set up a new stack for local vars and memmove args */
49154abd99SDavid du Colombier	MOVW	R6, SP			/* tiny trampoline stack */
50154abd99SDavid du Colombier	SUB	$(0x20 + 4), SP		/* back up before a.out header */
51154abd99SDavid du Colombier
52154abd99SDavid du Colombier	MOVW	R14, -48(SP)		/* store return addr */
53154abd99SDavid du Colombier	SUB	$48, SP			/* allocate stack frame */
54154abd99SDavid du Colombier
55154abd99SDavid du Colombier	MOVW	R6, 44(SP)		/* save dest/entry */
56154abd99SDavid du Colombier	MOVW	R5, 40(SP)		/* save count */
57154abd99SDavid du Colombier
58*bb9c7457SDavid du ColombierPUTC('t')
59154abd99SDavid du Colombier
60154abd99SDavid du Colombier	MOVW	R6, 0(SP)
61154abd99SDavid du Colombier	MOVW	R6, 4(SP)		/* push dest */
62154abd99SDavid du Colombier	MOVW	R6, R0
63154abd99SDavid du Colombier	MOVW	R4, 8(SP)		/* push src */
64154abd99SDavid du Colombier	MOVW	R5, 12(SP)		/* push size */
65154abd99SDavid du Colombier	BL	memmove(SB)
66154abd99SDavid du Colombier
67154abd99SDavid du Colombier	MOVW	44(SP), R6		/* restore R6 (dest/entry) */
68154abd99SDavid du Colombier	MOVW	40(SP), R5		/* restore R5 (count) */
69*bb9c7457SDavid du ColombierPUTC('-')
70154abd99SDavid du Colombier	/*
71154abd99SDavid du Colombier	 * flush caches
72154abd99SDavid du Colombier	 */
73154abd99SDavid du Colombier	BL	cacheuwbinv(SB)
74154abd99SDavid du Colombier
75*bb9c7457SDavid du ColombierPUTC('>')
76*bb9c7457SDavid du ColombierPUTC('\r');
77*bb9c7457SDavid du ColombierPUTC('\n');
78154abd99SDavid du Colombier/*
79154abd99SDavid du Colombier * jump to kernel entry point.  Note the true kernel entry point is
80154abd99SDavid du Colombier * the virtual address KZERO|R6, but this must wait until
81154abd99SDavid du Colombier * the MMU is enabled by the kernel in l.s
82154abd99SDavid du Colombier */
83154abd99SDavid du Colombier	ORR	R6, R6			/* NOP: avoid link bug */
84154abd99SDavid du Colombier	B	(R6)
85154abd99SDavid du Colombier
86154abd99SDavid du Colombier/*
87154abd99SDavid du Colombier * turn the caches off, double map 0 & KZERO, invalidate TLBs, revert to
88154abd99SDavid du Colombier * tiny addresses.  upon return, it will be safe to turn off the mmu.
89154abd99SDavid du Colombier */
90154abd99SDavid du ColombierTEXT cachesoff(SB), 1, $-4
91154abd99SDavid du Colombier	MOVW	$(PsrDirq|PsrDfiq|PsrMsvc), R0
92154abd99SDavid du Colombier	MOVW	R0, CPSR
93154abd99SDavid du Colombier	MOVW	$KADDR(0x100-4), R7		/* just before this code */
94154abd99SDavid du Colombier	MOVW	R14, (R7)			/* save link */
95154abd99SDavid du Colombier
96154abd99SDavid du Colombier	BL	cacheuwbinv(SB)
97154abd99SDavid du Colombier
98154abd99SDavid du Colombier	MRC	CpSC, 0, R0, C(CpCONTROL), C(0)
99154abd99SDavid du Colombier	BIC	$(CpCwb|CpCicache|CpCdcache|CpCalign), R0
100154abd99SDavid du Colombier	MCR     CpSC, 0, R0, C(CpCONTROL), C(0)
101154abd99SDavid du Colombier	BARRIERS
102154abd99SDavid du Colombier
103154abd99SDavid du Colombier	/* redo double map of 0, KZERO */
104154abd99SDavid du Colombier	MOVW	$(L1+L1X(PHYSDRAM)), R4		/* address of PTE for 0 */
105154abd99SDavid du Colombier	MOVW	$PTEDRAM, R2			/* PTE bits */
106154abd99SDavid du Colombier//	MOVW	$PTEIO, R2			/* PTE bits */
107154abd99SDavid du Colombier	MOVW	$PHYSDRAM, R3
108154abd99SDavid du Colombier	MOVW	$512, R5
109154abd99SDavid du Colombier_ptrdbl:
110154abd99SDavid du Colombier	ORR	R3, R2, R1		/* first identity-map 0 to 0, etc. */
111154abd99SDavid du Colombier	MOVW	R1, (R4)
112154abd99SDavid du Colombier	ADD	$4, R4				/* bump PTE address */
113154abd99SDavid du Colombier	ADD	$MiB, R3			/* bump pa */
114154abd99SDavid du Colombier	SUB.S	$1, R5
115154abd99SDavid du Colombier	BNE	_ptrdbl
116154abd99SDavid du Colombier
117154abd99SDavid du Colombier	BARRIERS
118154abd99SDavid du Colombier	MOVW	$0, R0
119154abd99SDavid du Colombier	MCR	CpSC, 0, R0, C(CpTLB), C(CpTLBinvd), CpTLBinv
120154abd99SDavid du Colombier	MCR	CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
121154abd99SDavid du Colombier	BARRIERS
122154abd99SDavid du Colombier
123154abd99SDavid du Colombier	/* back to 29- or 26-bit addressing, mainly for SB */
124154abd99SDavid du Colombier	MRC	CpSC, 0, R0, C(CpCONTROL), C(0)
125154abd99SDavid du Colombier	BIC	$(CpCd32|CpCi32), R0
126154abd99SDavid du Colombier	MCR     CpSC, 0, R0, C(CpCONTROL), C(0)
127154abd99SDavid du Colombier	BARRIERS
128154abd99SDavid du Colombier
129154abd99SDavid du Colombier	MOVW	$KADDR(0x100-4), R7		/* just before this code */
130154abd99SDavid du Colombier	MOVW	(R7), R14			/* restore link */
131154abd99SDavid du Colombier	RET
132154abd99SDavid du Colombier
133154abd99SDavid du ColombierTEXT _r15warp(SB), 1, $-4
13433cde4a6SDavid du Colombier	BIC	$KSEGM, R14
135154abd99SDavid du Colombier	ORR	R0, R14
136154abd99SDavid du Colombier	RET
137154abd99SDavid du Colombier
138154abd99SDavid du ColombierTEXT mmudisable(SB), 1, $-4
139154abd99SDavid du Colombier	MRC	CpSC, 0, R0, C(CpCONTROL), C(0)
140154abd99SDavid du Colombier	BIC	$(CpChv|CpCmmu|CpCdcache|CpCicache|CpCwb), R0
141154abd99SDavid du Colombier	MCR     CpSC, 0, R0, C(CpCONTROL), C(0)
142154abd99SDavid du Colombier	BARRIERS
143154abd99SDavid du Colombier	RET
144154abd99SDavid du Colombier
145154abd99SDavid du ColombierTEXT mmuinvalidate(SB), 1, $-4			/* invalidate all */
146154abd99SDavid du Colombier	MOVW	$0, R0
147154abd99SDavid du Colombier	MCR	CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
148154abd99SDavid du Colombier	BARRIERS
149154abd99SDavid du Colombier	RET
150154abd99SDavid du Colombier
151154abd99SDavid du ColombierTEXT cacheuwbinv(SB), 1, $-4			/* D+I writeback+invalidate */
152154abd99SDavid du Colombier	BARRIERS
153154abd99SDavid du Colombier	MOVW	CPSR, R3			/* splhi */
154154abd99SDavid du Colombier	ORR	$(PsrDirq), R3, R1
155154abd99SDavid du Colombier	MOVW	R1, CPSR
156154abd99SDavid du Colombier
157154abd99SDavid du Colombier_uwbinv:					/* D writeback+invalidate */
158154abd99SDavid du Colombier	MRC	CpSC, 0, PC, C(CpCACHE), C(CpCACHEwbi), CpCACHEtest
159154abd99SDavid du Colombier	BNE	_uwbinv
160154abd99SDavid du Colombier
16133cde4a6SDavid du Colombier	MOVW	$0, R0				/* I invalidate */
16233cde4a6SDavid du Colombier	MCR	CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall
163b72bcbbfSDavid du Colombier	/* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
16433cde4a6SDavid du Colombier	BARRIERS
16533cde4a6SDavid du Colombier
166b72bcbbfSDavid du Colombier	MCR	CpSC, CpL2, R0, C(CpTESTCFG), C(CpTCl2flush), CpTCl2all
16733cde4a6SDavid du Colombier	BARRIERS
168b72bcbbfSDavid du Colombier	MCR	CpSC, CpL2, R0, C(CpTESTCFG), C(CpTCl2inv), CpTCl2all
169154abd99SDavid du Colombier	BARRIERS
170154abd99SDavid du Colombier
171154abd99SDavid du Colombier	MOVW	R3, CPSR			/* splx */
172154abd99SDavid du Colombier	RET
173