xref: /plan9-contrib/sys/src/9/omap/rebootcode.s (revision bb9c7457bbc95323d3ebe779d2114080683da0b8)
18e32b400SDavid du Colombier/*
28e32b400SDavid du Colombier * omap3530 reboot code
38e32b400SDavid du Colombier *
48e32b400SDavid du Colombier * must fit in 11K to avoid stepping on PTEs; see mem.h.
58e32b400SDavid du Colombier *
68e32b400SDavid du Colombier * R11 is used by the loader as a temporary, so avoid it.
78e32b400SDavid du Colombier */
88e32b400SDavid du Colombier#include "arm.s"
98e32b400SDavid du Colombier
108e32b400SDavid du Colombier/*
118e32b400SDavid du Colombier * Turn off MMU, then copy the new kernel to its correct location
128e32b400SDavid du Colombier * in physical memory.  Then jump to the start of the kernel.
138e32b400SDavid du Colombier */
148e32b400SDavid du Colombier
158e32b400SDavid du Colombier/* main(PADDR(entry), PADDR(code), size); */
168e32b400SDavid du ColombierTEXT	main(SB), 1, $-4
178e32b400SDavid du Colombier	MOVW	$setR12(SB), R12
188e32b400SDavid du Colombier
198e32b400SDavid du Colombier	MOVW	R0, p1+0(FP)		/* destination, passed in R0 */
208e32b400SDavid du Colombier
218e32b400SDavid du Colombier	MOVW	CPSR, R0
228e32b400SDavid du Colombier	ORR	$(PsrDirq|PsrDfiq), R0
238e32b400SDavid du Colombier	MOVW	R0, CPSR		/* splhi */
248e32b400SDavid du Colombier	BARRIERS
258e32b400SDavid du Colombier
26*bb9c7457SDavid du ColombierPUTC('R')
278e32b400SDavid du Colombier	MRC	CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
288e32b400SDavid du Colombier	BIC	$CpACasa, R1	/* no speculative I access forwarding to mem */
298e32b400SDavid du Colombier	/* slow down */
308e32b400SDavid du Colombier	ORR	$(CpACcachenopipe|CpACcp15serial|CpACcp15waitidle|CpACcp15pipeflush), R1
318e32b400SDavid du Colombier	MCR	CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
328e32b400SDavid du Colombier	BARRIERS
338e32b400SDavid du Colombier
348e32b400SDavid du Colombier	BL	cachesoff(SB)
358e32b400SDavid du Colombier	/* now back in 29- or 26-bit addressing, mainly for SB */
368e32b400SDavid du Colombier	/* double mapping of PHYSDRAM & KZERO now in effect */
378e32b400SDavid du Colombier
388e32b400SDavid du Colombier	/*
398e32b400SDavid du Colombier	 * turn the MMU off
408e32b400SDavid du Colombier	 */
418e32b400SDavid du Colombier
42*bb9c7457SDavid du ColombierPUTC('e')
438e32b400SDavid du Colombier	/* first switch to PHYSDRAM-based addresses */
448e32b400SDavid du Colombier	DMB
458e32b400SDavid du Colombier
468e32b400SDavid du Colombier	MOVW	$KSEGM, R7		/* clear segment bits */
478e32b400SDavid du Colombier	MOVW	$PHYSDRAM, R0		/* set dram base bits */
488e32b400SDavid du Colombier	BIC	R7, R12			/* adjust SB */
498e32b400SDavid du Colombier	ORR	R0, R12
508e32b400SDavid du Colombier
518e32b400SDavid du Colombier	BL	_r15warp(SB)
528e32b400SDavid du Colombier	/* don't care about saving R14; we're not returning */
538e32b400SDavid du Colombier
548e32b400SDavid du Colombier	/*
558e32b400SDavid du Colombier	 * now running in PHYSDRAM segment, not KZERO.
568e32b400SDavid du Colombier	 */
578e32b400SDavid du Colombier
58*bb9c7457SDavid du ColombierPUTC('b')
598e32b400SDavid du Colombier	SUB	$12, SP				/* paranoia */
608e32b400SDavid du Colombier	BL	cacheuwbinv(SB)
618e32b400SDavid du Colombier	ADD	$12, SP				/* paranoia */
628e32b400SDavid du Colombier
638e32b400SDavid du Colombier	/* invalidate mmu mappings */
648e32b400SDavid du Colombier	MOVW	$KZERO, R0			/* some valid virtual address */
658e32b400SDavid du Colombier	MCR	CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
668e32b400SDavid du Colombier	BARRIERS
678e32b400SDavid du Colombier
68*bb9c7457SDavid du ColombierPUTC('o')
698e32b400SDavid du Colombier	MRC	CpSC, 0, R0, C(CpCONTROL), C(0)
708e32b400SDavid du Colombier	BIC	$(CpCmmu|CpCdcache|CpCicache), R0
718e32b400SDavid du Colombier	MCR     CpSC, 0, R0, C(CpCONTROL), C(0)	/* mmu off */
728e32b400SDavid du Colombier	BARRIERS
738e32b400SDavid du Colombier
74*bb9c7457SDavid du ColombierPUTC('o')
758e32b400SDavid du Colombier	/* copy in arguments from stack frame before moving stack */
768e32b400SDavid du Colombier	MOVW	p2+4(FP), R4		/* phys source */
778e32b400SDavid du Colombier	MOVW	n+8(FP), R5		/* byte count */
788e32b400SDavid du Colombier	MOVW	p1+0(FP), R6		/* phys destination */
798e32b400SDavid du Colombier
808e32b400SDavid du Colombier	/* set up a new stack for local vars and memmove args */
818e32b400SDavid du Colombier	MOVW	R6, SP			/* tiny trampoline stack */
828e32b400SDavid du Colombier	SUB	$(0x20 + 4), SP		/* back up before a.out header */
838e32b400SDavid du Colombier
848e32b400SDavid du Colombier//	MOVW	R14, -48(SP)		/* store return addr */
858e32b400SDavid du Colombier	SUB	$48, SP			/* allocate stack frame */
868e32b400SDavid du Colombier
878e32b400SDavid du Colombier	MOVW	R5, 40(SP)		/* save count */
888e32b400SDavid du Colombier	MOVW	R6, 44(SP)		/* save dest/entry */
898e32b400SDavid du Colombier
908e32b400SDavid du Colombier	DELAY(printloop2, 2)
91*bb9c7457SDavid du ColombierPUTC('t')
928e32b400SDavid du Colombier
938e32b400SDavid du Colombier	MOVW	40(SP), R5		/* restore count */
948e32b400SDavid du Colombier	MOVW	44(SP), R6		/* restore dest/entry */
958e32b400SDavid du Colombier	MOVW	R6, 0(SP)		/* normally saved LR goes here */
968e32b400SDavid du Colombier	MOVW	R6, 4(SP)		/* push dest */
978e32b400SDavid du Colombier	MOVW	R6, R0
988e32b400SDavid du Colombier	MOVW	R4, 8(SP)		/* push src */
998e32b400SDavid du Colombier	MOVW	R5, 12(SP)		/* push size */
1008e32b400SDavid du Colombier	BL	memmove(SB)
1018e32b400SDavid du Colombier
102*bb9c7457SDavid du ColombierPUTC('-')
1038e32b400SDavid du Colombier	/*
1048e32b400SDavid du Colombier	 * flush caches
1058e32b400SDavid du Colombier	 */
1068e32b400SDavid du Colombier	BL	cacheuwbinv(SB)
1078e32b400SDavid du Colombier
108*bb9c7457SDavid du ColombierPUTC('>')
1098e32b400SDavid du Colombier	DELAY(printloopret, 1)
110*bb9c7457SDavid du ColombierPUTC('\r')
1118e32b400SDavid du Colombier	DELAY(printloopnl, 1)
112*bb9c7457SDavid du ColombierPUTC('\n')
1138e32b400SDavid du Colombier/*
1148e32b400SDavid du Colombier * jump to kernel entry point.  Note the true kernel entry point is
1158e32b400SDavid du Colombier * the virtual address KZERO|R6, but this must wait until
1168e32b400SDavid du Colombier * the MMU is enabled by the kernel in l.s
1178e32b400SDavid du Colombier */
1188e32b400SDavid du Colombier	MOVW	44(SP), R6		/* restore R6 (dest/entry) */
1198e32b400SDavid du Colombier	ORR	R6, R6			/* NOP: avoid link bug */
1208e32b400SDavid du Colombier	B	(R6)
121*bb9c7457SDavid du ColombierPUTC('?')
1228e32b400SDavid du Colombier	B	0(PC)
1238e32b400SDavid du Colombier
1248e32b400SDavid du Colombier/*
1258e32b400SDavid du Colombier * turn the caches off, double map PHYSDRAM & KZERO, invalidate TLBs, revert
1268e32b400SDavid du Colombier * to tiny addresses.  upon return, it will be safe to turn off the mmu.
1278e32b400SDavid du Colombier */
1288e32b400SDavid du ColombierTEXT cachesoff(SB), 1, $-4
1298e32b400SDavid du Colombier	MOVM.DB.W [R14,R1-R10], (R13)		/* save regs on stack */
1308e32b400SDavid du Colombier	MOVW	CPSR, R0
1318e32b400SDavid du Colombier	ORR	$(PsrDirq|PsrDfiq), R0
1328e32b400SDavid du Colombier	MOVW	R0, CPSR
1338e32b400SDavid du Colombier	BARRIERS
1348e32b400SDavid du Colombier
1358e32b400SDavid du Colombier	SUB	$12, SP				/* paranoia */
1368e32b400SDavid du Colombier	BL	cacheuwbinv(SB)
1378e32b400SDavid du Colombier	ADD	$12, SP				/* paranoia */
1388e32b400SDavid du Colombier
1398e32b400SDavid du Colombier	MRC	CpSC, 0, R0, C(CpCONTROL), C(0)
1408e32b400SDavid du Colombier	BIC	$(CpCicache|CpCdcache), R0
1418e32b400SDavid du Colombier	MCR     CpSC, 0, R0, C(CpCONTROL), C(0)	/* caches off */
1428e32b400SDavid du Colombier	BARRIERS
1438e32b400SDavid du Colombier
1448e32b400SDavid du Colombier	/*
1458e32b400SDavid du Colombier	 * caches are off
1468e32b400SDavid du Colombier	 */
1478e32b400SDavid du Colombier
1488e32b400SDavid du Colombier	/* invalidate stale TLBs before changing them */
1498e32b400SDavid du Colombier	MOVW	$KZERO, R0			/* some valid virtual address */
1508e32b400SDavid du Colombier	MCR	CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
1518e32b400SDavid du Colombier	BARRIERS
1528e32b400SDavid du Colombier
1538e32b400SDavid du Colombier	/* redo double map of PHYSDRAM, KZERO */
1548e32b400SDavid du Colombier	MOVW	$PHYSDRAM, R3
1558e32b400SDavid du Colombier	CMP	$KZERO, R3
1568e32b400SDavid du Colombier	BEQ	noun2map
1578e32b400SDavid du Colombier	MOVW	$(L1+L1X(PHYSDRAM)), R4		/* address of PHYSDRAM's PTE */
1588e32b400SDavid du Colombier	MOVW	$PTEDRAM, R2			/* PTE bits */
1598e32b400SDavid du Colombier	MOVW	$DOUBLEMAPMBS, R5
1608e32b400SDavid du Colombier_ptrdbl:
1618e32b400SDavid du Colombier	ORR	R3, R2, R1		/* first identity-map 0 to 0, etc. */
1628e32b400SDavid du Colombier	MOVW	R1, (R4)
1638e32b400SDavid du Colombier	ADD	$4, R4				/* bump PTE address */
1648e32b400SDavid du Colombier	ADD	$MiB, R3			/* bump pa */
1658e32b400SDavid du Colombier	SUB.S	$1, R5
1668e32b400SDavid du Colombier	BNE	_ptrdbl
1678e32b400SDavid du Colombiernoun2map:
1688e32b400SDavid du Colombier
1698e32b400SDavid du Colombier	/*
1708e32b400SDavid du Colombier	 * flush stale TLB entries
1718e32b400SDavid du Colombier	 */
1728e32b400SDavid du Colombier
1738e32b400SDavid du Colombier	BARRIERS
1748e32b400SDavid du Colombier	MOVW	$KZERO, R0			/* some valid virtual address */
1758e32b400SDavid du Colombier	MCR	CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
1768e32b400SDavid du Colombier	BARRIERS
1778e32b400SDavid du Colombier
1788e32b400SDavid du Colombier	/* switch back to PHYSDRAM addressing, mainly for SB */
1798e32b400SDavid du Colombier	MOVW	$KSEGM, R7		/* clear segment bits */
1808e32b400SDavid du Colombier	MOVW	$PHYSDRAM, R0		/* set dram base bits */
1818e32b400SDavid du Colombier	BIC	R7, R12			/* adjust SB */
1828e32b400SDavid du Colombier	ORR	R0, R12
1838e32b400SDavid du Colombier	BIC	R7, SP
1848e32b400SDavid du Colombier	ORR	R0, SP
1858e32b400SDavid du Colombier
1868e32b400SDavid du Colombier	MOVM.IA.W (R13), [R14,R1-R10]		/* restore regs from stack */
1878e32b400SDavid du Colombier
1888e32b400SDavid du Colombier	MOVW	$KSEGM, R0		/* clear segment bits */
1898e32b400SDavid du Colombier	BIC	R0, R14			/* adjust link */
1908e32b400SDavid du Colombier	MOVW	$PHYSDRAM, R0		/* set dram base bits */
1918e32b400SDavid du Colombier	ORR	R0, R14
1928e32b400SDavid du Colombier
1938e32b400SDavid du Colombier	RET
1948e32b400SDavid du Colombier
1958e32b400SDavid du ColombierTEXT _r15warp(SB), 1, $-4
1968e32b400SDavid du Colombier	BIC	R7, R14			/* link */
1978e32b400SDavid du Colombier	ORR	R0, R14
1988e32b400SDavid du Colombier
1998e32b400SDavid du Colombier	BIC	R7, R13			/* SP */
2008e32b400SDavid du Colombier	ORR	R0, R13
2018e32b400SDavid du Colombier	RET
2028e32b400SDavid du Colombier
2038e32b400SDavid du ColombierTEXT panic(SB), 1, $-4		/* stub */
204*bb9c7457SDavid du ColombierPUTC('?')
2058e32b400SDavid du Colombier	RET
2068e32b400SDavid du ColombierTEXT pczeroseg(SB), 1, $-4	/* stub */
2078e32b400SDavid du Colombier	RET
2088e32b400SDavid du Colombier
2098e32b400SDavid du Colombier#include "cache.v7.s"
210