]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - cpu/arm926ejs/start.S
Support new configuration of TRAB board with more memory
[karo-tx-uboot.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