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