entry.S revision 1.4 1 /* $NetBSD: entry.S,v 1.4 2011/10/30 20:42:09 phx Exp $ */
2
3 #include <powerpc/psl.h>
4 #include <powerpc/spr.h>
5 #include <powerpc/oea/spr.h>
6 #include <powerpc/oea/bat.h>
7 #include <powerpc/oea/hid.h>
8
9 .text
10 .globl _start
11 _start:
12 /*
13 * Save possible argc and argv values from the firmware, usually
14 * passed in r3 and r4.
15 * When started with "bootm", as a Linux kernel module, r6 and r7
16 * point to the start and end address of the bootargs.
17 */
18 mr 30,3
19 mr 31,4
20 mr 28,6
21 mr 29,7
22
23 /* Disable interrupts and everything except the MMU. */
24 mfmsr 3
25 andi. 3,3,PSL_DR|PSL_IR
26 mtmsr 3
27 isync
28
29 /*
30 * U-Boot/PPCBoot forgets to flush the cache when using the "bootm"
31 * command, so we have to do that now.
32 */
33 lis 11,_start@ha
34 addi 11,11,_start@l
35 li 10,-32
36 and 11,11,10
37 lis 12,(_edata+31)@ha
38 addi 12,12,(_edata+31)@l
39 bl syncicache
40
41 mfspr 11,SPR_HID0
42 andi. 0,11,HID0_DCE
43 ori 11,11,HID0_ICE
44 ori 8,11,HID0_ICFI
45 bne 1f /* don't invalidate the D-cache */
46 ori 8,8,HID0_DCFI /* unless it wasn't enabled */
47 1:
48 mfmsr 0
49 andi. 0,0,PSL_DR
50 beq 2f
51 lis 5,0xfec00000@ha /* CONFIG_ADDR of PCI */
52 lis 6,0xfee00000@ha /* CONFIG_DATA of PCI */
53 mfspr 3,SPR_DBAT0U
54 mfspr 4,SPR_DBAT0L
55 bl dbat_sanity_check
56 beq 3f
57 mfspr 3,SPR_DBAT1U
58 mfspr 4,SPR_DBAT1L
59 bl dbat_sanity_check
60 beq 3f
61 mfspr 3,SPR_DBAT2U
62 mfspr 4,SPR_DBAT2L
63 bl dbat_sanity_check
64 beq 3f
65 mfspr 3,SPR_DBAT3U
66 mfspr 4,SPR_DBAT3L
67 bl dbat_sanity_check
68 beq 3f
69
70 2: /* Disable D-cache */
71 li 0,HID0_DCE
72 andc 11,11,0
73 b 4f
74
75 3: /* Enable D-cache */
76 ori 11,11,HID0_DCE
77
78 4:
79 lis 1,BAT123@ha
80 addi 1,1,BAT123@l
81 lwz 3,0(1)
82 lwz 4,4(1)
83 mtdbatl 1,3
84 mtdbatu 1,4
85 lwz 3,8(1)
86 lwz 4,12(1)
87 mtdbatl 2,3
88 mtdbatu 2,4
89 lwz 3,16(1)
90 lwz 4,20(1)
91 mtdbatl 3,3
92 mtdbatu 3,4
93
94 sync
95 mtspr SPR_HID0,8 /* enable and invalidate caches */
96 sync
97 mtspr SPR_HID0,11 /* enable caches */
98 sync
99 isync
100
101 /* make sure .bss gets zeroed. */
102 li 0,0
103 lis 8,edata@ha
104 addi 8,8,edata@l
105 lis 9,end@ha
106 addi 9,9,end@l
107 5: cmpw 0,8,9 /* edata & end are >= word aligned */
108 bge 6f
109 stw 0,0(8)
110 addi 8,8,4
111 b 5b
112
113 6:
114 /* prepare stack at +1MB from _start, 16-byte aligned */
115 lis 1,_start@ha
116 addi 1,1,_start@l
117 addis 1,1,0x100000@ha
118 li 10,-16
119 and 1,1,10
120 stw 0,0(1)
121
122 bl brdsetup
123 #ifdef DEBUG
124 bl init_vectors
125 #endif
126 mr 3,30
127 mr 4,31
128 mr 5,28
129 mr 6,29
130 bl main
131
132 hang: b hang
133 /* NOTREACHED */
134
135 dbat_sanity_check:
136 andi. 0,3,BAT_Vs
137 beq 2f
138 andi. 0,4,BAT_I|BAT_PP_RW
139 cmpwi 0,0,BAT_I|BAT_PP_RW
140 bnelr
141 rlwinm 0,3,15,4,14
142 andis. 3,3,0xfffe0000@ha /* BAT_EPI */
143 andis. 4,4,BAT_RPN@ha
144 cmplw 0,3,4
145 bnelr
146 add 4,4,0
147 oris 4,4,0x0001ffff@ha
148 ori 4,4,0x0001ffff@l
149 cmplw 0,3,5
150 bgt 1f
151 cmplw 0,5,4
152 bgt 1f
153 li 5,0
154 1: cmplw 0,3,6
155 bgt 2f
156 cmplw 0,6,4
157 bgt 2f
158 li 6,0
159 2: cmplw 0,5,6
160 blr
161
162 /*
163 * run(startsym, endsym, howto, bootinfo, entry)
164 */
165 .globl run
166 run:
167 mtctr 7 /* hat trick jump to entry point */
168 bctr
169
170 /*
171 * newaltboot(argc, argv, altboot_base, altboot_len)
172 * To be executed in a safe memory region. Copies the new altboot from
173 * altboot_base to 0x1000000 and starts it there.
174 */
175 .globl newaltboot
176 newaltboot:
177 lis 7,0x1000000@h
178 mr 11,7
179 subi 7,7,4
180 subi 5,5,4
181 add 12,11,6
182 addi 6,6,3
183 srawi 6,6,2
184 mtctr 6
185 1: lwzu 8,4(5)
186 stwu 8,4(7)
187 bdnz+ 1b
188 mtctr 11
189 addi 12,12,31
190 bl syncicache
191 bctr
192 syncicache:
193 /* r11=start, r12=end, r10=scratch */
194 mr 10,11
195 2: dcbst 0,10
196 addi 10,10,32
197 cmplw 10,12
198 ble 2b
199 sync
200 3: icbi 0,11
201 addi 11,11,32
202 cmplw 11,12
203 ble 3b
204 sync
205 isync
206 blr
207 .globl newaltboot_end
208 newaltboot_end:
209
210 /*
211 * reverse endian access to mimic outw/outl/inw/inl
212 */
213 .globl out16rb
214 .globl iohtole16
215 out16rb:
216 iohtole16:
217 sthbrx 4,0,3
218 eieio
219 blr
220
221 .globl out32rb
222 .globl iohtole32
223 out32rb:
224 iohtole32:
225 stwbrx 4,0,3
226 eieio
227 blr
228
229 .globl in16rb
230 .globl iole16toh
231 in16rb:
232 iole16toh:
233 lhbrx 3,0,3
234 eieio
235 blr
236
237 .globl in32rb
238 .globl iole32toh
239 in32rb:
240 iole32toh:
241 lwbrx 3,0,3
242 eieio
243 blr
244
245 #ifdef DEBUG
246 /*
247 * Call an exception handler, which prints out all information
248 * about the type of exception, cpu registers, stack frame
249 * backtrace, etc.
250 * Use a new stack at 0x2000 and make room for 32 GPRs, and 15
251 * special registers. The layout will be:
252 * 0x00: link area
253 * 0x10: R0
254 * ...
255 * 0x8c: R31
256 * 0x90: CR, XER, LR, CTR
257 * 0xa0: SRR0, SRR1, DAR, DSISR
258 * 0xb0: DMISS, DCMP, HASH1, HASH2
259 * 0xc0: IMISS, ICMP, RPA
260 *
261 */
262 .globl trap
263 trap:
264 mtsprg1 1
265 mfmsr 1
266 andis. 1,1,PSL_TGPR@h
267 beq 1f
268 andi. 1,1,0xffff /* make sure TGPR is disabled */
269 mtmsr 1
270 isync
271 mtsprg1 1 /* and save the real r1 again */
272 1: li 1,0x2000-16-(32*4+15*4)
273 stmw 2,24(1) /* save r2..r31 */
274 stw 0,16(1) /* save r0 */
275 mfsprg1 3
276 stw 3,20(1) /* and finally r1 */
277 mfcr 3
278 stw 3,0x90(1)
279 mfxer 3
280 stw 3,0x94(1)
281 mflr 3
282 stw 3,0x98(1)
283 mfctr 3
284 stw 3,0x9c(1)
285 mfsrr0 3
286 stw 3,0xa0(1)
287 mfsrr1 3
288 stw 3,0xa4(1)
289 mfdar 3
290 stw 3,0xa8(1)
291 mfdsisr 3
292 stw 3,0xac(1)
293 mfspr 3,976
294 stw 3,0xb0(1)
295 mfspr 3,977
296 stw 3,0xb4(1)
297 mfspr 3,978
298 stw 3,0xb8(1)
299 mfspr 3,979
300 stw 3,0xbc(1)
301 mfspr 3,980
302 stw 3,0xc0(1)
303 mfspr 3,981
304 stw 3,0xc4(1)
305 mfspr 3,982
306 stw 3,0xc8(1)
307 bl call_handler
308 call_handler:
309 lis 11,exception_handler@ha
310 addi 11,11,exception_handler@l
311 mtsrr0 11
312 li 0,PSL_DR|PSL_IR
313 mtsrr1 0
314 mflr 3
315 subi 3,3,call_handler-trap
316 addi 4,1,16
317 rfi
318 .globl trap_end
319 trap_end:
320 #endif
321
322 .data
323 #define xBATL(pa, wimg, pp) \
324 ((pa) | (wimg) | (pp))
325 #define xBATU(va, len, v) \
326 ((va) | ((len) & BAT_BL) | ((v) & BAT_V))
327 BAT123:
328 .long xBATL(0x80000000, BAT_I|BAT_G, BAT_PP_RW)
329 .long xBATU(0x80000000, BAT_BL_256M, BAT_Vs)
330 .long xBATL(0xfc000000, BAT_I|BAT_G, BAT_PP_RW)
331 .long xBATU(0xfc000000, BAT_BL_64M, BAT_Vs)
332 .long 0
333 .long 0
334