entry.S revision 1.6 1 /* $NetBSD: entry.S,v 1.6 2012/01/14 20:03:12 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 /* 8-bit i/o access */
212 .globl out8
213 out8:
214 stb 4,0(3)
215 eieio
216 blr
217
218 .globl in8
219 in8:
220 lbz 3,0(3)
221 eieio
222 blr
223
224 /*
225 * reverse endian access to mimic outw/outl/inw/inl
226 */
227 .globl out16rb
228 .globl iohtole16
229 out16rb:
230 iohtole16:
231 sthbrx 4,0,3
232 eieio
233 blr
234
235 .globl out32rb
236 .globl iohtole32
237 out32rb:
238 iohtole32:
239 stwbrx 4,0,3
240 eieio
241 blr
242
243 .globl in16rb
244 .globl iole16toh
245 in16rb:
246 iole16toh:
247 lhbrx 3,0,3
248 eieio
249 blr
250
251 .globl in32rb
252 .globl iole32toh
253 in32rb:
254 iole32toh:
255 lwbrx 3,0,3
256 eieio
257 blr
258
259 #ifdef DEBUG
260 /*
261 * Call an exception handler, which prints out all information
262 * about the type of exception, cpu registers, stack frame
263 * backtrace, etc.
264 * Use a new stack at 0x2000 and make room for 32 GPRs, and 15
265 * special registers. The layout will be:
266 * 0x00: link area
267 * 0x10: R0
268 * ...
269 * 0x8c: R31
270 * 0x90: CR, XER, LR, CTR
271 * 0xa0: SRR0, SRR1, DAR, DSISR
272 * 0xb0: DMISS, DCMP, HASH1, HASH2
273 * 0xc0: IMISS, ICMP, RPA
274 *
275 */
276 .globl trap
277 trap:
278 mtsprg1 1
279 mfmsr 1
280 andis. 1,1,PSL_TGPR@h
281 beq 1f
282 andi. 1,1,0xffff /* make sure TGPR is disabled */
283 mtmsr 1
284 isync
285 mtsprg1 1 /* and save the real r1 again */
286 1: li 1,0x2000-16-(32*4+15*4)
287 stmw 2,24(1) /* save r2..r31 */
288 stw 0,16(1) /* save r0 */
289 mfsprg1 3
290 stw 3,20(1) /* and finally r1 */
291 mfcr 3
292 stw 3,0x90(1)
293 mfxer 3
294 stw 3,0x94(1)
295 mflr 3
296 stw 3,0x98(1)
297 mfctr 3
298 stw 3,0x9c(1)
299 mfsrr0 3
300 stw 3,0xa0(1)
301 mfsrr1 3
302 stw 3,0xa4(1)
303 mfdar 3
304 stw 3,0xa8(1)
305 mfdsisr 3
306 stw 3,0xac(1)
307 mfspr 3,976
308 stw 3,0xb0(1)
309 mfspr 3,977
310 stw 3,0xb4(1)
311 mfspr 3,978
312 stw 3,0xb8(1)
313 mfspr 3,979
314 stw 3,0xbc(1)
315 mfspr 3,980
316 stw 3,0xc0(1)
317 mfspr 3,981
318 stw 3,0xc4(1)
319 mfspr 3,982
320 stw 3,0xc8(1)
321 bl call_handler
322 call_handler:
323 lis 11,exception_handler@ha
324 addi 11,11,exception_handler@l
325 mtsrr0 11
326 li 0,PSL_DR|PSL_IR
327 mtsrr1 0
328 mflr 3
329 subi 3,3,call_handler-trap
330 addi 4,1,16
331 rfi
332 .globl trap_end
333 trap_end:
334 #endif
335
336 .data
337 #define xBATL(pa, wimg, pp) \
338 ((pa) | (wimg) | (pp))
339 #define xBATU(va, len, v) \
340 ((va) | ((len) & BAT_BL) | ((v) & BAT_V))
341 BAT123:
342 .long xBATL(0x80000000, BAT_I|BAT_G, BAT_PP_RW)
343 .long xBATU(0x80000000, BAT_BL_256M, BAT_Vs)
344 .long xBATL(0xfc000000, BAT_I|BAT_G, BAT_PP_RW)
345 .long xBATU(0xfc000000, BAT_BL_64M, BAT_Vs)
346 .long xBATL(0x70000000, BAT_I|BAT_G, BAT_PP_RW)
347 .long xBATU(0x70000000, BAT_BL_128K, BAT_Vs)
348