]> git.ipfire.org Git - people/ms/u-boot.git/blob - cpu/arm926ejs/start.S
Support new configuration of TRAB board with more memory
[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
35 #include <config.h>
36 #include <version.h>
37
38 #if defined(CONFIG_OMAP1610)
39 #include <./configs/omap1510.h>
40 #endif
41
42 /*
43 *************************************************************************
44 *
45 * Jump vector table as in table 3.1 in [1]
46 *
47 *************************************************************************
48 */
49
50
51 .globl _start
52 _start:
53 b reset
54 ldr pc, _undefined_instruction
55 ldr pc, _software_interrupt
56 ldr pc, _prefetch_abort
57 ldr pc, _data_abort
58 ldr pc, _not_used
59 ldr pc, _irq
60 ldr pc, _fiq
61
62 _undefined_instruction:
63 .word undefined_instruction
64 _software_interrupt:
65 .word software_interrupt
66 _prefetch_abort:
67 .word prefetch_abort
68 _data_abort:
69 .word data_abort
70 _not_used:
71 .word not_used
72 _irq:
73 .word irq
74 _fiq:
75 .word fiq
76
77 .balignl 16,0xdeadbeef
78
79
80 /*
81 *************************************************************************
82 *
83 * Startup Code (reset vector)
84 *
85 * do important init only if we don't start from memory!
86 * setup Memory and board specific bits prior to relocation.
87 * relocate armboot to ram
88 * setup stack
89 *
90 *************************************************************************
91 */
92
93 _TEXT_BASE:
94 .word TEXT_BASE
95
96 .globl _armboot_start
97 _armboot_start:
98 .word _start
99
100 /*
101 * Note: _armboot_end_data and _armboot_end are defined
102 * by the (board-dependent) linker script.
103 * _armboot_end_data is the first usable FLASH address after armboot
104 */
105 .globl _armboot_end_data
106 _armboot_end_data:
107 .word armboot_end_data
108 .globl _armboot_end
109 _armboot_end:
110 .word armboot_end
111
112 /*
113 * _armboot_real_end is the first usable RAM address behind armboot
114 * and the various stacks
115 */
116 .globl _armboot_real_end
117 _armboot_real_end:
118 .word 0x0badc0de
119
120 #ifdef CONFIG_USE_IRQ
121 /* IRQ stack memory (calculated at run-time) */
122 .globl IRQ_STACK_START
123 IRQ_STACK_START:
124 .word 0x0badc0de
125
126 /* IRQ stack memory (calculated at run-time) */
127 .globl FIQ_STACK_START
128 FIQ_STACK_START:
129 .word 0x0badc0de
130 #endif
131
132
133 /*
134 * the actual reset code
135 */
136
137 reset:
138 /*
139 * set the cpu to SVC32 mode
140 */
141 mrs r0,cpsr
142 bic r0,r0,#0x1f
143 orr r0,r0,#0xd3
144 msr cpsr,r0
145
146
147 /*
148 * turn off the watchdog, unlock/diable sequence
149 */
150 mov r1, #0xF5
151 ldr r0, =WDTIM_MODE
152 strh r1, [r0]
153 mov r1, #0xA0
154 strh r1, [r0]
155
156
157
158
159
160 /*
161 * mask all IRQs by setting all bits in the INTMR - default
162 */
163
164 mov r1, #0xffffffff
165 ldr r0, =REG_IHL1_MIR
166 str r1, [r0]
167 ldr r0, =REG_IHL2_MIR
168 str r1, [r0]
169 bl cpu_init_crit
170
171 relocate:
172 /*
173 * relocate armboot to RAM
174 */
175 adr r0, _start /* r0 <- current position of code */
176 ldr r2, _armboot_start
177 ldr r3, _armboot_end
178 sub r2, r3, r2 /* r2 <- size of armboot */
179 ldr r1, _TEXT_BASE /* r1 <- destination address */
180 add r2, r0, r2 /* r2 <- source end address */
181
182 /*
183 * r0 = source address
184 * r1 = target address
185 * r2 = source end address
186 */
187 copy_loop:
188 ldmia r0!, {r3-r10}
189 stmia r1!, {r3-r10}
190 cmp r0, r2
191 ble copy_loop
192
193 /* set up the stack */
194 ldr r0, _armboot_end
195 add r0, r0, #CONFIG_STACKSIZE
196 sub sp, r0, #12 /* leave 3 words for abort-stack */
197
198 ldr pc, _start_armboot
199
200 _start_armboot:
201 .word start_armboot
202
203
204 /*
205 *************************************************************************
206 *
207 * CPU_init_critical registers
208 *
209 * setup important registers
210 * setup memory timing
211 *
212 *************************************************************************
213 */
214
215
216 cpu_init_crit:
217 /*
218 * flush v4 I/D caches
219 */
220 mov r0, #0
221 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
222 mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
223
224 /*
225 * disable MMU stuff and caches
226 */
227 mrc p15, 0, r0, c1, c0, 0
228 bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */
229 bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */
230 orr r0, r0, #0x00000002 /* set bit 2 (A) Align */
231 orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
232 mcr p15, 0, r0, c1, c0, 0
233
234 /*
235 * Go setup Memory and board specific bits prior to relocation.
236 */
237 mov ip, lr /* perserve link reg across call */
238 bl platformsetup /* go setup pll,mux,memory */
239 mov lr, ip /* restore link */
240 mov pc, lr /* back to my caller */
241 /*
242 *************************************************************************
243 *
244 * Interrupt handling
245 *
246 *************************************************************************
247 */
248
249 @
250 @ IRQ stack frame.
251 @
252 #define S_FRAME_SIZE 72
253
254 #define S_OLD_R0 68
255 #define S_PSR 64
256 #define S_PC 60
257 #define S_LR 56
258 #define S_SP 52
259
260 #define S_IP 48
261 #define S_FP 44
262 #define S_R10 40
263 #define S_R9 36
264 #define S_R8 32
265 #define S_R7 28
266 #define S_R6 24
267 #define S_R5 20
268 #define S_R4 16
269 #define S_R3 12
270 #define S_R2 8
271 #define S_R1 4
272 #define S_R0 0
273
274 #define MODE_SVC 0x13
275 #define I_BIT 0x80
276
277 /*
278 * use bad_save_user_regs for abort/prefetch/undef/swi ...
279 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
280 */
281
282 .macro bad_save_user_regs
283 @ carve out a frame on current user stack
284 sub sp, sp, #S_FRAME_SIZE
285 stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
286 ldr r2, _armboot_end @ find top of stack
287 add r2, r2, #CONFIG_STACKSIZE @ find base of normal stack
288 sub r2, r2, #8 @ set base 2 words into abort stack
289 @ get values for "aborted" pc and cpsr (into parm regs)
290 ldmia r2, {r2 - r3}
291 add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
292 add r5, sp, #S_SP
293 mov r1, lr
294 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
295 mov r0, sp @ save current stack into r0 (param register)
296 .endm
297
298 .macro irq_save_user_regs
299 sub sp, sp, #S_FRAME_SIZE
300 stmia sp, {r0 - r12} @ Calling r0-r12
301 @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
302 add r8, sp, #S_PC
303 stmdb r8, {sp, lr}^ @ Calling SP, LR
304 str lr, [r8, #0] @ Save calling PC
305 mrs r6, spsr
306 str r6, [r8, #4] @ Save CPSR
307 str r0, [r8, #8] @ Save OLD_R0
308 mov r0, sp
309 .endm
310
311 .macro irq_restore_user_regs
312 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
313 mov r0, r0
314 ldr lr, [sp, #S_PC] @ Get PC
315 add sp, sp, #S_FRAME_SIZE
316 subs pc, lr, #4 @ return & move spsr_svc into cpsr
317 .endm
318
319 .macro get_bad_stack
320 @ get bottom of stack (into sp by by user stack pointer).
321 ldr r13, _armboot_end
322 @ head to reserved words at the top of the stack
323 add r13, r13, #CONFIG_STACKSIZE
324 sub r13, r13, #8 @ reserved a couple spots in abort stack
325
326 str lr, [r13] @ save caller lr in position 0 of saved stack
327 mrs lr, spsr @ get the spsr
328 str lr, [r13, #4] @ save spsr in position 1 of saved stack
329 mov r13, #MODE_SVC @ prepare SVC-Mode
330 @ msr spsr_c, r13
331 msr spsr, r13 @ switch modes, make sure moves will execute
332 mov lr, pc @ capture return pc
333 movs pc, lr @ jump to next instruction & switch modes.
334 .endm
335
336 .macro get_irq_stack @ setup IRQ stack
337 ldr sp, IRQ_STACK_START
338 .endm
339
340 .macro get_fiq_stack @ setup FIQ stack
341 ldr sp, FIQ_STACK_START
342 .endm
343
344 /*
345 * exception handlers
346 */
347 .align 5
348 undefined_instruction:
349 get_bad_stack
350 bad_save_user_regs
351 bl do_undefined_instruction
352
353 .align 5
354 software_interrupt:
355 get_bad_stack
356 bad_save_user_regs
357 bl do_software_interrupt
358
359 .align 5
360 prefetch_abort:
361 get_bad_stack
362 bad_save_user_regs
363 bl do_prefetch_abort
364
365 .align 5
366 data_abort:
367 get_bad_stack
368 bad_save_user_regs
369 bl do_data_abort
370
371 .align 5
372 not_used:
373 get_bad_stack
374 bad_save_user_regs
375 bl do_not_used
376
377 #ifdef CONFIG_USE_IRQ
378
379 .align 5
380 irq:
381 get_irq_stack
382 irq_save_user_regs
383 bl do_irq
384 irq_restore_user_regs
385
386 .align 5
387 fiq:
388 get_fiq_stack
389 /* someone ought to write a more effiction fiq_save_user_regs */
390 irq_save_user_regs
391 bl do_fiq
392 irq_restore_user_regs
393
394 #else
395
396 .align 5
397 irq:
398 get_bad_stack
399 bad_save_user_regs
400 bl do_irq
401
402 .align 5
403 fiq:
404 get_bad_stack
405 bad_save_user_regs
406 bl do_fiq
407
408 #endif
409
410 .align 5
411 .globl reset_cpu
412 reset_cpu:
413 ldr r1, rstctl1 /* get clkm1 reset ctl */
414 mov r3, #0x0
415 strh r3, [r1] /* clear it */
416 mov r3, #0x8
417 strh r3, [r1] /* force dsp+arm reset */
418 _loop_forever:
419 b _loop_forever
420
421
422 rstctl1:
423 .word 0xfffece10