1/*
2 * BK Id: SCCS/s.head.S 1.13 01/11/02 10:46:07 trini
3 */
4
5#include <asm/ppc_asm.h>
6#include <asm/processor.h>
7#include <asm/cache.h>
8
9	.text
10
11/*
12 * Boot loader philosophy:
13 *      ROM loads us to some arbitrary location
14 *      Move the boot code to the link address (8M)
15 *      Call decompress_kernel()
16 *         Relocate the initrd, zimage and residual data to 8M
17 *         Decompress the kernel to 0
18 *      Jump to the kernel entry
19 *            -- Cort
20 */
21	.globl	start
22start:
23	bl	start_
24start_:
25
26        /* Enable, invalidate, Disable L1 icache/dcache */
27	li	r8, 0
28	ori	r8, r8, (HID0_ICE|HID0_DCE|HID0_ICFI|HID0_DCI)
29	mfspr	r11,HID0
30	or	r11,r11,r8
31	andc	r10,r11,r8
32	isync
33	mtspr	HID0,r8
34	sync
35	isync
36	mtspr	HID0,r10
37	sync
38	isync
39
40	mr	r11,r3		/* Save pointer to residual/board data */
41	mr      r25,r5		/* Save OFW pointer */
42
43	/* Save the original MSR value */
44	mfmsr	r26
45
46	/* Establish default MSR value */
47	li	r3,MSR_IP|MSR_FP
48	mtmsr	r3
49
50	/* compute the size of the whole image in words. */
51	lis	r4,start@h
52	ori	r4,r4,start@l
53	lis	r5,end@h
54	ori	r5,r5,end@l
55	addi	r5,r5,3		/* round up */
56	sub	r5,r5,r4	/* end - start */
57	srwi	r5,r5,2
58	mr	r7,r5		/* Save for later use. */
59
60	/* check if we need to relocate ourselves to the link addr or were
61	 * we loaded there to begin with -- Cort */
62	mflr	r3
63	subi	r3,r3,4		/* we get the nip, not the ip of the branch */
64	mr	r8,r3
65	cmp	0,r3,r4
66	beq	start_ldr	/* If 0, we don't need to relocate */
67/*
68 * no matter where we're loaded, move ourselves to -Ttext address
69 */
70relocate:
71	mflr	r3		/* Compute code bias */
72	subi	r3,r3,4
73	mr	r8,r3
74	lis	r4,start@h
75	ori	r4,r4,start@l
76	mr	r5,r7		/* Get the # of longwords again */
77	mtctr	r5		/* Setup for loop */
78	li	r6,0
79	subi	r3,r3,4
80	subi	r4,r4,4
8100:	lwzu	r5,4(r3)
82	stwu	r5,4(r4)
83	xor	r6,r6,r5
84	bdnz	00b
85  	lis	r3,start_ldr@h
86	ori	r3,r3,start_ldr@l
87	mtlr	r3		/* Easiest way to do an absolute jump */
88	blr
89
90start_ldr:
91/* Some boards don't boot up with the I-cache enabled.  Do that
92 * now because the decompress runs much faster that way.
93 * As a side effect, we have to ensure the data cache is not enabled
94 * so we can access the serial I/O without trouble.
95 */
96	bl	flush_instruction_cache
97
98/* Clear all of BSS */
99	lis	r3,edata@h
100	ori	r3,r3,edata@l
101	lis	r4,end@h
102	ori	r4,r4,end@l
103	subi	r3,r3,4
104	subi	r4,r4,4
105	li	r0,0
10650:	stwu	r0,4(r3)
107	cmp	0,r3,r4
108	bne	50b
10990:	mr	r9,r1			/* Save old stack pointer (in case it matters) */
110	lis	r1,.stack@h
111	ori	r1,r1,.stack@l
112	addi	r1,r1,4096*2
113	subi	r1,r1,256
114	li	r2,0x000F		/* Mask pointer to 16-byte boundary */
115	andc	r1,r1,r2
116
117	/* Store the original MSR into 'orig_MSR' */
118	lis	r3,orig_MSR@h
119	ori	r3,r3,orig_MSR@l
120	stw	r26,0(r3)
121
122/* Run loader */
123	mr	r3,r8			/* Load point */
124	mr	r4,r7			/* Program length */
125	mr	r5,r6			/* Checksum */
126	mr	r6,r11			/* Residual data */
127	mr      r7,r25                  /* OFW interfaces */
128	bl	decompress_kernel
129
130	/*
131	 * We have to do this after decompress_kernel, just to make
132	 * sure we don't wipe out things mapped in BATs which we need.
133	 * -- Tom
134	 */
135	li      r6,0
136	/* Test for a 601 */
137	mfspr	r9,PVR
138	srwi	r9,r9,16
139	cmpi	0,r9,1          /* 601 ? */
140	beq	.clearbats_601
141
142	/* Clear BATS */
143	mtspr   DBAT0U,r6
144	mtspr	DBAT0L,r6
145	mtspr   DBAT1U,r6
146	mtspr	DBAT1L,r6
147	mtspr   DBAT2U,r6
148	mtspr	DBAT2L,r6
149	mtspr   DBAT3U,r6
150	mtspr	DBAT3L,r6
151.clearbats_601:
152	mtspr   IBAT0U,r6
153	mtspr	IBAT0L,r6
154	mtspr   IBAT1U,r6
155	mtspr	IBAT1L,r6
156	mtspr	IBAT2U,r6
157	mtspr   IBAT2L,r6
158	mtspr   IBAT3U,r6
159	mtspr	IBAT3L,r6
160	isync
161	sync
162	sync
163
164	/* Set segment registers */
165	li	r6,16		/* load up segment register values */
166	mtctr	r6		/* for context 0 */
167	lis	r6,0x2000	/* Ku = 1, VSID = 0 */
168	li	r10,0
1693:	mtsrin	r6,r10
170	addi	r6,r6,0x111	/* increment VSID */
171	addis	r10,r10,0x1000	/* address of next segment */
172	bdnz	3b
173
174	/* tell kernel we're prep, by putting 0xdeadc0de at KERNELLOAD,
175	 * and tell the kernel to start on the 4th instruction since we
176	 * overwrite the first 3 sometimes (which are 'nop').
177	 */
178	li	r9,0xc
179	mtlr	r9
180	lis	r10,0xdeadc0de@h
181	ori	r10,r10,0xdeadc0de@l
182	li	r9,0
183	stw	r10,0(r9)
184	blr
185
186	.comm	.stack,4096*2,4
187