xref: /plan9-contrib/sys/src/9/vt4/rebootcode.s (revision d6dfd9ef91cf0fa8514a249d5f2a550978c19369)
1*d6dfd9efSDavid du Colombier/* virtex4 ppc405 reboot code */
2*d6dfd9efSDavid du Colombier#include "mem.h"
3*d6dfd9efSDavid du Colombier
4*d6dfd9efSDavid du Colombier#define SPR_SRR0	26		/* Save/Restore Register 0 */
5*d6dfd9efSDavid du Colombier#define SPR_SRR1	27		/* Save/Restore Register 1 */
6*d6dfd9efSDavid du Colombier#define SPR_DCWR	954		/* Data Cache Write-through Register */
7*d6dfd9efSDavid du Colombier#define SPR_DCCR	1018		/* Data Cache Cachability Register */
8*d6dfd9efSDavid du Colombier#define SPR_ICCR	1019		/* Instruction Cache Cachability Register */
9*d6dfd9efSDavid du Colombier
10*d6dfd9efSDavid du Colombier/* special instruction definitions */
11*d6dfd9efSDavid du Colombier#define	BDNZ	BC	16,0,
12*d6dfd9efSDavid du Colombier#define	BDNE	BC	0,2,
13*d6dfd9efSDavid du Colombier
14*d6dfd9efSDavid du Colombier#define	ICCCI(a,b)	WORD	$((31<<26)|((a)<<16)|((b)<<11)|(966<<1))
15*d6dfd9efSDavid du Colombier#define	DCCCI(a,b)	WORD	$((31<<26)|((a)<<16)|((b)<<11)|(454<<1))
16*d6dfd9efSDavid du Colombier
17*d6dfd9efSDavid du Colombier/* on the 400 series, the prefetcher madly fetches across RFI, sys call, and others; use BR 0(PC) to stop */
18*d6dfd9efSDavid du Colombier#define	RFI	WORD $((19<<26)|(50<<1)); BR 0(PC)
19*d6dfd9efSDavid du Colombier#define	RFCI	WORD $((19<<26)|(51<<1)); BR 0(PC)
20*d6dfd9efSDavid du Colombier
21*d6dfd9efSDavid du Colombier/* print progress character.  steps on R7 and R8, needs SB set. */
22*d6dfd9efSDavid du Colombier#define PROG(c)	MOVW $(Uartlite+4), R7; MOVW $(c), R8; MOVW	R8, 0(R7); SYNC
23*d6dfd9efSDavid du Colombier
24*d6dfd9efSDavid du Colombier/*
25*d6dfd9efSDavid du Colombier * Turn off MMU, then copy the new kernel to its correct location
26*d6dfd9efSDavid du Colombier * in physical memory.  Then jump to the start of the kernel.
27*d6dfd9efSDavid du Colombier */
28*d6dfd9efSDavid du Colombier
29*d6dfd9efSDavid du Colombier	NOSCHED
30*d6dfd9efSDavid du Colombier
31*d6dfd9efSDavid du ColombierTEXT	main(SB),1,$-4
32*d6dfd9efSDavid du Colombier	MOVW	$setSB+KZERO(SB), R2
33*d6dfd9efSDavid du Colombier
34*d6dfd9efSDavid du ColombierPROG('*')
35*d6dfd9efSDavid du Colombier	MOVW	R3, p1+0(FP)		/* destination, passed in R3 */
36*d6dfd9efSDavid du Colombier	MOVW	R3, R6			/* entry point */
37*d6dfd9efSDavid du Colombier	MOVW	p2+4(FP), R4		/* source */
38*d6dfd9efSDavid du Colombier	MOVW	n+8(FP), R5		/* byte count */
39*d6dfd9efSDavid du Colombier
40*d6dfd9efSDavid du Colombier	BL	mmuoff(SB)
41*d6dfd9efSDavid du Colombier	MOVW	$setSB(SB), R2
42*d6dfd9efSDavid du Colombier
43*d6dfd9efSDavid du Colombier//	BL	resetcaches(SB)
44*d6dfd9efSDavid du Colombier
45*d6dfd9efSDavid du ColombierPROG('*')
46*d6dfd9efSDavid du Colombier	MOVW	R3, R1			/* tiny trampoline stack */
47*d6dfd9efSDavid du Colombier	SUB	$0x20, R1		/* bypass a.out header */
48*d6dfd9efSDavid du Colombier
49*d6dfd9efSDavid du Colombier	MOVWU	R0, -48(R1)		/* allocate stack frame */
50*d6dfd9efSDavid du Colombier	MOVW	R3, 44(R1)		/* save dest */
51*d6dfd9efSDavid du Colombier	MOVW	R5, 40(R1)		/* save count */
52*d6dfd9efSDavid du Colombier	MOVW	R3, 0(R1)
53*d6dfd9efSDavid du Colombier	MOVW	R3, 4(R1)		/* push dest */
54*d6dfd9efSDavid du Colombier	MOVW	R4, 8(R1)		/* push src */
55*d6dfd9efSDavid du Colombier	MOVW	R5, 12(R1)		/* push size */
56*d6dfd9efSDavid du Colombier	BL	memmove(SB)
57*d6dfd9efSDavid du Colombier	SYNC
58*d6dfd9efSDavid du Colombier	MOVW	44(R1), R6		/* restore R6 (dest) */
59*d6dfd9efSDavid du Colombier	MOVW	40(R1), R5		/* restore R5 (count) */
60*d6dfd9efSDavid du ColombierPROG('-')
61*d6dfd9efSDavid du Colombier	/*
62*d6dfd9efSDavid du Colombier	 * flush data cache
63*d6dfd9efSDavid du Colombier	 */
64*d6dfd9efSDavid du Colombier	MOVW	R6, R3			/* virtaddr */
65*d6dfd9efSDavid du Colombier	MOVW	R5, R4			/* count */
66*d6dfd9efSDavid du Colombier	RLWNM	$0, R3, $~(DCACHELINESZ-1), R5
67*d6dfd9efSDavid du Colombier	CMP	R4, $0
68*d6dfd9efSDavid du Colombier	BLE	dcf1
69*d6dfd9efSDavid du Colombier	SUB	R5, R3
70*d6dfd9efSDavid du Colombier	ADD	R3, R4
71*d6dfd9efSDavid du Colombier	ADD	$(DCACHELINESZ-1), R4
72*d6dfd9efSDavid du Colombier	SRAW	$DCACHELINELOG, R4
73*d6dfd9efSDavid du Colombier	MOVW	R4, CTR
74*d6dfd9efSDavid du Colombierdcf0:	DCBF	(R5)
75*d6dfd9efSDavid du Colombier	ADD	$DCACHELINESZ, R5
76*d6dfd9efSDavid du Colombier	BDNZ	dcf0
77*d6dfd9efSDavid du Colombierdcf1:
78*d6dfd9efSDavid du Colombier	SYNC
79*d6dfd9efSDavid du Colombier
80*d6dfd9efSDavid du Colombier	/* be sure icache is cleared */
81*d6dfd9efSDavid du Colombier	BL	resetcaches(SB)
82*d6dfd9efSDavid du Colombier
83*d6dfd9efSDavid du Colombier/*
84*d6dfd9efSDavid du Colombier * jump to kernel entry point.  Note the true kernel entry point is
85*d6dfd9efSDavid du Colombier * the virtual address KZERO|R6, but this must wait until
86*d6dfd9efSDavid du Colombier * the MMU is enabled by the kernel in l.s
87*d6dfd9efSDavid du Colombier */
88*d6dfd9efSDavid du Colombier	OR	R6, R6		/* NOP: avoid link bug */
89*d6dfd9efSDavid du Colombier	MOVW	R6, LR
90*d6dfd9efSDavid du ColombierPROG('>')
91*d6dfd9efSDavid du ColombierPROG('\r');
92*d6dfd9efSDavid du ColombierPROG('\n');
93*d6dfd9efSDavid du Colombier	BL	(LR)
94*d6dfd9efSDavid du Colombier	BR	0(PC)
95*d6dfd9efSDavid du Colombier
96*d6dfd9efSDavid du ColombierTEXT	mmuoff(SB), 1, $-4
97*d6dfd9efSDavid du Colombier	MOVW	LR, R7
98*d6dfd9efSDavid du Colombier	RLWNM	$0, R7, $~KZERO, R7	/* new PC */
99*d6dfd9efSDavid du Colombier	MOVW	R7, SPR(SPR_SRR0)
100*d6dfd9efSDavid du Colombier
101*d6dfd9efSDavid du Colombier	RLWNM	$0, R1, $~KZERO, R1	/* make stack pointer physical */
102*d6dfd9efSDavid du Colombier
103*d6dfd9efSDavid du Colombier	/*
104*d6dfd9efSDavid du Colombier	 * turn off interrupts & MMU
105*d6dfd9efSDavid du Colombier	 * disable machine check
106*d6dfd9efSDavid du Colombier	 */
107*d6dfd9efSDavid du Colombier	MOVW	MSR, R7
108*d6dfd9efSDavid du Colombier	RLWNM	$0, R7, $~(MSR_EE), R7
109*d6dfd9efSDavid du Colombier	RLWNM	$0, R7, $~(MSR_ME), R7
110*d6dfd9efSDavid du Colombier	RLWNM	$0, R7, $~(MSR_IR|MSR_DR), R7
111*d6dfd9efSDavid du Colombier	MOVW	R7, SPR(SPR_SRR1)
112*d6dfd9efSDavid du Colombier/*	ISYNC		/* no ISYNC here as we have no TLB entry for the PC */
113*d6dfd9efSDavid du Colombier	SYNC		/* fix 405 errata cpu_210 */
114*d6dfd9efSDavid du Colombier	RFI		/* resume in kernel mode in caller */
115*d6dfd9efSDavid du Colombier
116*d6dfd9efSDavid du Colombier/* clobbers R7 */
117*d6dfd9efSDavid du ColombierTEXT	resetcaches(SB),1,$-4
118*d6dfd9efSDavid du Colombier	/*
119*d6dfd9efSDavid du Colombier	 * reset the caches and disable them
120*d6dfd9efSDavid du Colombier	 */
121*d6dfd9efSDavid du Colombier	MOVW	R0, SPR(SPR_ICCR)
122*d6dfd9efSDavid du Colombier	ICCCI(0, 2)  /* errata cpu_121 reveals that EA is used; we'll use SB */
123*d6dfd9efSDavid du Colombier	ISYNC
124*d6dfd9efSDavid du Colombier	DCCCI(0, 0)
125*d6dfd9efSDavid du Colombier	SYNC; ISYNC
126*d6dfd9efSDavid du Colombier
127*d6dfd9efSDavid du Colombier	MOVW	$((DCACHEWAYSIZE/DCACHELINESZ)-1), R7
128*d6dfd9efSDavid du Colombier	MOVW	R7, CTR
129*d6dfd9efSDavid du Colombier	MOVW	R0, R7
130*d6dfd9efSDavid du Colombierdcinv:
131*d6dfd9efSDavid du Colombier	DCCCI(0,7)
132*d6dfd9efSDavid du Colombier	ADD	$32, R7
133*d6dfd9efSDavid du Colombier	BDNZ	dcinv
134*d6dfd9efSDavid du Colombier
135*d6dfd9efSDavid du Colombier	/* cache is copy-back, disabled */
136*d6dfd9efSDavid du Colombier	MOVW	R0, SPR(SPR_DCWR)
137*d6dfd9efSDavid du Colombier	MOVW	R0, SPR(SPR_DCCR)
138*d6dfd9efSDavid du Colombier	MOVW	R0, SPR(SPR_ICCR)
139*d6dfd9efSDavid du Colombier	ISYNC
140*d6dfd9efSDavid du Colombier	SYNC
141*d6dfd9efSDavid du Colombier	BR	(LR)
142