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