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