]> git.ipfire.org Git - people/ms/u-boot.git/blob - cpu/arm926ejs/start.S
* Patch by Rahul Shanbhag, 19 Feb 2004:
[people/ms/u-boot.git] / cpu / arm926ejs / start.S
1 /*
2 * armboot - Startup Code for ARM926EJS CPU-core
3 *
4 * Copyright (c) 2003 Texas Instruments
5 *
6 * ----- Adapted for OMAP1610 from ARM925t code ------
7 *
8 * Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
9 * Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
10 * Copyright (c) 2002 Gary Jennejohn <gj@denx.de>
11 * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
12 * Copyright (c) 2003 Kshitij <kshitij@ti.com>
13 *
14 * See file CREDITS for list of people who contributed to this
15 * project.
16 *
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License as
19 * published by the Free Software Foundation; either version 2 of
20 * the License, or (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
30 * MA 02111-1307 USA
31 */
32
33
34 #include <config.h>
35 #include <version.h>
36
37 #if defined(CONFIG_OMAP1610)
38 #include <./configs/omap1510.h>
39 #endif
40
41 /*
42 *************************************************************************
43 *
44 * Jump vector table as in table 3.1 in [1]
45 *
46 *************************************************************************
47 */
48
49
50 .globl _start
51 _start:
52 b reset
53 ldr pc, _undefined_instruction
54 ldr pc, _software_interrupt
55 ldr pc, _prefetch_abort
56 ldr pc, _data_abort
57 ldr pc, _not_used
58 ldr pc, _irq
59 ldr pc, _fiq
60
61 _undefined_instruction:
62 .word undefined_instruction
63 _software_interrupt:
64 .word software_interrupt
65 _prefetch_abort:
66 .word prefetch_abort
67 _data_abort:
68 .word data_abort
69 _not_used:
70 .word not_used
71 _irq:
72 .word irq
73 _fiq:
74 .word fiq
75
76 .balignl 16,0xdeadbeef
77
78
79 /*
80 *************************************************************************
81 *
82 * Startup Code (reset vector)
83 *
84 * do important init only if we don't start from memory!
85 * setup Memory and board specific bits prior to relocation.
86 * relocate armboot to ram
87 * setup stack
88 *
89 *************************************************************************
90 */
91
92 _TEXT_BASE:
93 .word TEXT_BASE
94
95 .globl _armboot_start
96 _armboot_start:
97 .word _start
98
99 /*
100 * These are defined in the board-specific linker script.
101 */
102 .globl _bss_start
103 _bss_start:
104 .word __bss_start
105
106 .globl _bss_end
107 _bss_end:
108 .word _end
109
110 #ifdef CONFIG_USE_IRQ
111 /* IRQ stack memory (calculated at run-time) */
112 .globl IRQ_STACK_START
113 IRQ_STACK_START:
114 .word 0x0badc0de
115
116 /* IRQ stack memory (calculated at run-time) */
117 .globl FIQ_STACK_START
118 FIQ_STACK_START:
119 .word 0x0badc0de
120 #endif
121
122
123 /*
124 * the actual reset code
125 */
126
127 reset:
128 /*
129 * set the cpu to SVC32 mode
130 */
131 mrs r0,cpsr
132 bic r0,r0,#0x1f
133 orr r0,r0,#0xd3
134 msr cpsr,r0
135
136 /*
137 * we do sys-critical inits only at reboot,
138 * not when booting from ram!
139 */
140 #ifdef CONFIG_INIT_CRITICAL
141 bl cpu_init_crit
142 #endif
143
144 relocate: /* relocate U-Boot to RAM */
145 adr r0, _start /* r0 <- current position of code */
146 ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
147 cmp r0, r1 /* don't reloc during debug */
148 beq stack_setup
149
150 ldr r2, _armboot_start
151 ldr r3, _bss_start
152 sub r2, r3, r2 /* r2 <- size of armboot */
153 add r2, r0, r2 /* r2 <- source end address */
154
155 copy_loop:
156 ldmia r0!, {r3-r10} /* copy from source address [r0] */
157 stmia r1!, {r3-r10} /* copy to target address [r1] */
158 cmp r0, r2 /* until source end addreee [r2] */
159 ble copy_loop
160
161 /* Set up the stack */
162 stack_setup:
163 ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
164 sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
165 sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
166 #ifdef CONFIG_USE_IRQ
167 sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
168 #endif
169 sub sp, r0, #12 /* leave 3 words for abort-stack */
170
171 clear_bss:
172 ldr r0, _bss_start /* find start of bss segment */
173 add r0, r0, #4 /* start at first byte of bss */
174 ldr r1, _bss_end /* stop here */
175 mov r2, #0x00000000 /* clear */
176
177 clbss_l:str r2, [r0] /* clear loop... */
178 add r0, r0, #4
179 cmp r0, r1
180 bne clbss_l
181
182 ldr pc, _start_armboot
183
184 _start_armboot:
185 .word start_armboot
186
187
188 /*
189 *************************************************************************
190 *
191 * CPU_init_critical registers
192 *
193 * setup important registers
194 * setup memory timing
195 *
196 *************************************************************************
197 */
198
199
200 cpu_init_crit:
201 /*
202 * flush v4 I/D caches
203 */
204 mov r0, #0
205 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
206 mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
207
208 /*
209 * disable MMU stuff and caches
210 */
211 mrc p15, 0, r0, c1, c0, 0
212 bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */
213 bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */
214 orr r0, r0, #0x00000002 /* set bit 2 (A) Align */
215 orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
216 mcr p15, 0, r0, c1, c0, 0
217
218 /*
219 * Go setup Memory and board specific bits prior to relocation.
220 */
221 mov ip, lr /* perserve link reg across call */
222 bl platformsetup /* go setup pll,mux,memory */
223 mov lr, ip /* restore link */
224 mov pc, lr /* back to my caller */
225 /*
226 *************************************************************************
227 *
228 * Interrupt handling
229 *
230 *************************************************************************
231 */
232
233 @
234 @ IRQ stack frame.
235 @
236 #define S_FRAME_SIZE 72
237
238 #define S_OLD_R0 68
239 #define S_PSR 64
240 #define S_PC 60
241 #define S_LR 56
242 #define S_SP 52
243
244 #define S_IP 48
245 #define S_FP 44
246 #define S_R10 40
247 #define S_R9 36
248 #define S_R8 32
249 #define S_R7 28
250 #define S_R6 24
251 #define S_R5 20
252 #define S_R4 16
253 #define S_R3 12
254 #define S_R2 8
255 #define S_R1 4
256 #define S_R0 0
257
258 #define MODE_SVC 0x13
259 #define I_BIT 0x80
260
261 /*
262 * use bad_save_user_regs for abort/prefetch/undef/swi ...
263 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
264 */
265
266 .macro bad_save_user_regs
267 @ carve out a frame on current user stack
268 sub sp, sp, #S_FRAME_SIZE
269 stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
270
271 ldr r2, _armboot_start
272 sub r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
273 sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
274 @ get values for "aborted" pc and cpsr (into parm regs)
275 ldmia r2, {r2 - r3}
276 add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
277 add r5, sp, #S_SP
278 mov r1, lr
279 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
280 mov r0, sp @ save current stack into r0 (param register)
281 .endm
282
283 .macro irq_save_user_regs
284 sub sp, sp, #S_FRAME_SIZE
285 stmia sp, {r0 - r12} @ Calling r0-r12
286 @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
287 add r8, sp, #S_PC
288 stmdb r8, {sp, lr}^ @ Calling SP, LR
289 str lr, [r8, #0] @ Save calling PC
290 mrs r6, spsr
291 str r6, [r8, #4] @ Save CPSR
292 str r0, [r8, #8] @ Save OLD_R0
293 mov r0, sp
294 .endm
295
296 .macro irq_restore_user_regs
297 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
298 mov r0, r0
299 ldr lr, [sp, #S_PC] @ Get PC
300 add sp, sp, #S_FRAME_SIZE
301 subs pc, lr, #4 @ return & move spsr_svc into cpsr
302 .endm
303
304 .macro get_bad_stack
305 ldr r13, _armboot_start @ setup our mode stack
306 sub r13, r13, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
307 sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack
308
309 str lr, [r13] @ save caller lr in position 0 of saved stack
310 mrs lr, spsr @ get the spsr
311 str lr, [r13, #4] @ save spsr in position 1 of saved stack
312 mov r13, #MODE_SVC @ prepare SVC-Mode
313 @ msr spsr_c, r13
314 msr spsr, r13 @ switch modes, make sure moves will execute
315 mov lr, pc @ capture return pc
316 movs pc, lr @ jump to next instruction & switch modes.
317 .endm
318
319 .macro get_irq_stack @ setup IRQ stack
320 ldr sp, IRQ_STACK_START
321 .endm
322
323 .macro get_fiq_stack @ setup FIQ stack
324 ldr sp, FIQ_STACK_START
325 .endm
326
327 /*
328 * exception handlers
329 */
330 .align 5
331 undefined_instruction:
332 get_bad_stack
333 bad_save_user_regs
334 bl do_undefined_instruction
335
336 .align 5
337 software_interrupt:
338 get_bad_stack
339 bad_save_user_regs
340 bl do_software_interrupt
341
342 .align 5
343 prefetch_abort:
344 get_bad_stack
345 bad_save_user_regs
346 bl do_prefetch_abort
347
348 .align 5
349 data_abort:
350 get_bad_stack
351 bad_save_user_regs
352 bl do_data_abort
353
354 .align 5
355 not_used:
356 get_bad_stack
357 bad_save_user_regs
358 bl do_not_used
359
360 #ifdef CONFIG_USE_IRQ
361
362 .align 5
363 irq:
364 get_irq_stack
365 irq_save_user_regs
366 bl do_irq
367 irq_restore_user_regs
368
369 .align 5
370 fiq:
371 get_fiq_stack
372 /* someone ought to write a more effiction fiq_save_user_regs */
373 irq_save_user_regs
374 bl do_fiq
375 irq_restore_user_regs
376
377 #else
378
379 .align 5
380 irq:
381 get_bad_stack
382 bad_save_user_regs
383 bl do_irq
384
385 .align 5
386 fiq:
387 get_bad_stack
388 bad_save_user_regs
389 bl do_fiq
390
391 #endif
392
393 .align 5
394 .globl reset_cpu
395 reset_cpu:
396 ldr r1, rstctl1 /* get clkm1 reset ctl */
397 mov r3, #0x0
398 strh r3, [r1] /* clear it */
399 mov r3, #0x8
400 strh r3, [r1] /* force dsp+arm reset */
401 _loop_forever:
402 b _loop_forever
403
404
405 rstctl1:
406 .word 0xfffece10