]> git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arm/cpu/arm925t/start.S
Replace CONFIG_SYS_GBL_DATA_SIZE by auto-generated value
[people/ms/u-boot.git] / arch / arm / cpu / arm925t / start.S
1 /*
2 * armboot - Startup Code for ARM925 CPU-core
3 *
4 * Copyright (c) 2003 Texas Instruments
5 *
6 * ----- Adapted for OMAP1510 from ARM920 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 <garyj@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 #include <asm-offsets.h>
34 #include <config.h>
35 #include <version.h>
36
37 #if defined(CONFIG_OMAP1510)
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: b reset
52 ldr pc, _undefined_instruction
53 ldr pc, _software_interrupt
54 ldr pc, _prefetch_abort
55 ldr pc, _data_abort
56 ldr pc, _not_used
57 ldr pc, _irq
58 ldr pc, _fiq
59
60 _undefined_instruction: .word undefined_instruction
61 _software_interrupt: .word software_interrupt
62 _prefetch_abort: .word prefetch_abort
63 _data_abort: .word data_abort
64 _not_used: .word not_used
65 _irq: .word irq
66 _fiq: .word fiq
67
68 .balignl 16,0xdeadbeef
69
70
71 /*
72 *************************************************************************
73 *
74 * Startup Code (reset vector)
75 *
76 * do important init only if we don't start from memory!
77 * setup Memory and board specific bits prior to relocation.
78 * relocate armboot to ram
79 * setup stack
80 *
81 *************************************************************************
82 */
83
84 .globl _TEXT_BASE
85 _TEXT_BASE:
86 .word CONFIG_SYS_TEXT_BASE
87
88 #if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
89 .globl _armboot_start
90 _armboot_start:
91 .word _start
92 #endif
93
94 /*
95 * These are defined in the board-specific linker script.
96 */
97 .globl _bss_start
98 _bss_start:
99 .word __bss_start
100
101 .globl _bss_end
102 _bss_end:
103 .word _end
104
105 #ifdef CONFIG_USE_IRQ
106 /* IRQ stack memory (calculated at run-time) */
107 .globl IRQ_STACK_START
108 IRQ_STACK_START:
109 .word 0x0badc0de
110
111 /* IRQ stack memory (calculated at run-time) */
112 .globl FIQ_STACK_START
113 FIQ_STACK_START:
114 .word 0x0badc0de
115 #endif
116
117 #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
118 /* IRQ stack memory (calculated at run-time) + 8 bytes */
119 .globl IRQ_STACK_START_IN
120 IRQ_STACK_START_IN:
121 .word 0x0badc0de
122
123 .globl _datarel_start
124 _datarel_start:
125 .word __datarel_start
126
127 .globl _datarelrolocal_start
128 _datarelrolocal_start:
129 .word __datarelrolocal_start
130
131 .globl _datarellocal_start
132 _datarellocal_start:
133 .word __datarellocal_start
134
135 .globl _datarelro_start
136 _datarelro_start:
137 .word __datarelro_start
138
139 .globl _got_start
140 _got_start:
141 .word __got_start
142
143 .globl _got_end
144 _got_end:
145 .word __got_end
146
147 /*
148 * the actual reset code
149 */
150
151 reset:
152 /*
153 * set the cpu to SVC32 mode
154 */
155 mrs r0,cpsr
156 bic r0,r0,#0x1f
157 orr r0,r0,#0xd3
158 msr cpsr,r0
159
160 /*
161 * Set up 925T mode
162 */
163 mov r1, #0x81 /* Set ARM925T configuration. */
164 mcr p15, 0, r1, c15, c1, 0 /* Write ARM925T configuration register. */
165
166 /*
167 * turn off the watchdog, unlock/diable sequence
168 */
169 mov r1, #0xF5
170 ldr r0, =WDTIM_MODE
171 strh r1, [r0]
172 mov r1, #0xA0
173 strh r1, [r0]
174
175 /*
176 * mask all IRQs by setting all bits in the INTMR - default
177 */
178 mov r1, #0xffffffff
179 ldr r0, =REG_IHL1_MIR
180 str r1, [r0]
181 ldr r0, =REG_IHL2_MIR
182 str r1, [r0]
183
184 /*
185 * wait for dpll to lock
186 */
187 ldr r0, =CK_DPLL1
188 mov r1, #0x10
189 strh r1, [r0]
190 poll1:
191 ldrh r1, [r0]
192 ands r1, r1, #0x01
193 beq poll1
194
195 /*
196 * we do sys-critical inits only at reboot,
197 * not when booting from ram!
198 */
199 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
200 bl cpu_init_crit
201 #endif
202
203 /* Set stackpointer in internal RAM to call board_init_f */
204 call_board_init_f:
205 ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
206 ldr r0,=0x00000000
207 bl board_init_f
208
209 /*------------------------------------------------------------------------------*/
210
211 /*
212 * void relocate_code (addr_sp, gd, addr_moni)
213 *
214 * This "function" does not return, instead it continues in RAM
215 * after relocating the monitor code.
216 *
217 */
218 .globl relocate_code
219 relocate_code:
220 mov r4, r0 /* save addr_sp */
221 mov r5, r1 /* save addr of gd */
222 mov r6, r2 /* save addr of destination */
223 mov r7, r2 /* save addr of destination */
224
225 /* Set up the stack */
226 stack_setup:
227 mov sp, r4
228
229 adr r0, _start
230 ldr r2, _TEXT_BASE
231 ldr r3, _bss_start
232 sub r2, r3, r2 /* r2 <- size of armboot */
233 add r2, r0, r2 /* r2 <- source end address */
234 cmp r0, r6
235 beq clear_bss
236
237 #ifndef CONFIG_SKIP_RELOCATE_UBOOT
238 copy_loop:
239 ldmia r0!, {r9-r10} /* copy from source address [r0] */
240 stmia r6!, {r9-r10} /* copy to target address [r1] */
241 cmp r0, r2 /* until source end address [r2] */
242 blo copy_loop
243
244 #ifndef CONFIG_PRELOADER
245 /* fix got entries */
246 ldr r1, _TEXT_BASE /* Text base */
247 mov r0, r7 /* reloc addr */
248 ldr r2, _got_start /* addr in Flash */
249 ldr r3, _got_end /* addr in Flash */
250 sub r3, r3, r1
251 add r3, r3, r0
252 sub r2, r2, r1
253 add r2, r2, r0
254
255 fixloop:
256 ldr r4, [r2]
257 sub r4, r4, r1
258 add r4, r4, r0
259 str r4, [r2]
260 add r2, r2, #4
261 cmp r2, r3
262 bne fixloop
263 #endif
264 #endif /* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */
265
266 clear_bss:
267 #ifndef CONFIG_PRELOADER
268 ldr r0, _bss_start
269 ldr r1, _bss_end
270 ldr r3, _TEXT_BASE /* Text base */
271 mov r4, r7 /* reloc addr */
272 sub r0, r0, r3
273 add r0, r0, r4
274 sub r1, r1, r3
275 add r1, r1, r4
276 mov r2, #0x00000000 /* clear */
277
278 clbss_l:str r2, [r0] /* clear loop... */
279 add r0, r0, #4
280 cmp r0, r1
281 bne clbss_l
282
283 #endif
284
285 /*
286 * We are done. Do not return, instead branch to second part of board
287 * initialization, now running from RAM.
288 */
289 #ifdef CONFIG_NAND_SPL
290 ldr pc, _nand_boot
291
292 _nand_boot: .word nand_boot
293 #else
294 ldr r0, _TEXT_BASE
295 ldr r2, _board_init_r
296 sub r2, r2, r0
297 add r2, r2, r7 /* position from board_init_r in RAM */
298 /* setup parameters for board_init_r */
299 mov r0, r5 /* gd_t */
300 mov r1, r7 /* dest_addr */
301 /* jump to it ... */
302 mov lr, r2
303 mov pc, lr
304
305 _board_init_r: .word board_init_r
306 #endif
307
308 #else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
309 /*
310 * the actual reset code
311 */
312
313 reset:
314 /*
315 * set the cpu to SVC32 mode
316 */
317 mrs r0,cpsr
318 bic r0,r0,#0x1f
319 orr r0,r0,#0xd3
320 msr cpsr,r0
321
322 /*
323 * Set up 925T mode
324 */
325 mov r1, #0x81 /* Set ARM925T configuration. */
326 mcr p15, 0, r1, c15, c1, 0 /* Write ARM925T configuration register. */
327
328 /*
329 * turn off the watchdog, unlock/diable sequence
330 */
331 mov r1, #0xF5
332 ldr r0, =WDTIM_MODE
333 strh r1, [r0]
334 mov r1, #0xA0
335 strh r1, [r0]
336
337 /*
338 * mask all IRQs by setting all bits in the INTMR - default
339 */
340 mov r1, #0xffffffff
341 ldr r0, =REG_IHL1_MIR
342 str r1, [r0]
343 ldr r0, =REG_IHL2_MIR
344 str r1, [r0]
345
346 /*
347 * wait for dpll to lock
348 */
349 ldr r0, =CK_DPLL1
350 mov r1, #0x10
351 strh r1, [r0]
352 poll1:
353 ldrh r1, [r0]
354 ands r1, r1, #0x01
355 beq poll1
356
357 /*
358 * we do sys-critical inits only at reboot,
359 * not when booting from ram!
360 */
361 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
362 bl cpu_init_crit
363 #endif
364
365 #ifndef CONFIG_SKIP_RELOCATE_UBOOT
366 relocate: /* relocate U-Boot to RAM */
367 adr r0, _start /* r0 <- current position of code */
368 ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
369 cmp r0, r1 /* don't reloc during debug */
370 beq stack_setup
371
372 ldr r2, _armboot_start
373 ldr r3, _bss_start
374 sub r2, r3, r2 /* r2 <- size of armboot */
375 add r2, r0, r2 /* r2 <- source end address */
376
377 copy_loop:
378 ldmia r0!, {r3-r10} /* copy from source address [r0] */
379 stmia r1!, {r3-r10} /* copy to target address [r1] */
380 cmp r0, r2 /* until source end address [r2] */
381 blo copy_loop
382 #endif /* CONFIG_SKIP_RELOCATE_UBOOT */
383
384 /* Set up the stack */
385 stack_setup:
386 ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
387 sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */
388 sub r0, r0, #GENERATED_GBL_DATA_SIZE /* bdinfo */
389 #ifdef CONFIG_USE_IRQ
390 sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
391 #endif
392 sub sp, r0, #12 /* leave 3 words for abort-stack */
393 bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
394
395 clear_bss:
396 ldr r0, _bss_start /* find start of bss segment */
397 ldr r1, _bss_end /* stop here */
398 mov r2, #0x00000000 /* clear */
399
400 clbss_l:str r2, [r0] /* clear loop... */
401 add r0, r0, #4
402 cmp r0, r1
403 blo clbss_l
404
405 ldr pc, _start_armboot
406
407 _start_armboot: .word start_armboot
408 #endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
409
410 /*
411 *************************************************************************
412 *
413 * CPU_init_critical registers
414 *
415 * setup important registers
416 * setup memory timing
417 *
418 *************************************************************************
419 */
420
421
422 cpu_init_crit:
423 /*
424 * flush v4 I/D caches
425 */
426 mov r0, #0
427 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
428 mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
429
430 /*
431 * disable MMU stuff and caches
432 */
433 mrc p15, 0, r0, c1, c0, 0
434 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
435 bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
436 orr r0, r0, #0x00000002 @ set bit 2 (A) Align
437 orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
438 mcr p15, 0, r0, c1, c0, 0
439
440 /*
441 * Go setup Memory and board specific bits prior to relocation.
442 */
443 mov ip, lr /* perserve link reg across call */
444 bl lowlevel_init /* go setup pll,mux,memory */
445 mov lr, ip /* restore link */
446 mov pc, lr /* back to my caller */
447 /*
448 *************************************************************************
449 *
450 * Interrupt handling
451 *
452 *************************************************************************
453 */
454
455 @
456 @ IRQ stack frame.
457 @
458 #define S_FRAME_SIZE 72
459
460 #define S_OLD_R0 68
461 #define S_PSR 64
462 #define S_PC 60
463 #define S_LR 56
464 #define S_SP 52
465
466 #define S_IP 48
467 #define S_FP 44
468 #define S_R10 40
469 #define S_R9 36
470 #define S_R8 32
471 #define S_R7 28
472 #define S_R6 24
473 #define S_R5 20
474 #define S_R4 16
475 #define S_R3 12
476 #define S_R2 8
477 #define S_R1 4
478 #define S_R0 0
479
480 #define MODE_SVC 0x13
481 #define I_BIT 0x80
482
483 /*
484 * use bad_save_user_regs for abort/prefetch/undef/swi ...
485 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
486 */
487
488 .macro bad_save_user_regs
489 sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current user stack
490 stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
491
492 #if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
493 ldr r2, _armboot_start
494 sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
495 sub r2, r2, #(GENERATED_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
496 #else
497 ldr r2, IRQ_STACK_START_IN
498 #endif
499 ldmia r2, {r2 - r3} @ get values for "aborted" pc and cpsr (into parm regs)
500 add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
501
502 add r5, sp, #S_SP
503 mov r1, lr
504 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
505 mov r0, sp @ save current stack into r0 (param register)
506 .endm
507
508 .macro irq_save_user_regs
509 sub sp, sp, #S_FRAME_SIZE
510 stmia sp, {r0 - r12} @ Calling r0-r12
511 add r8, sp, #S_PC @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
512 stmdb r8, {sp, lr}^ @ Calling SP, LR
513 str lr, [r8, #0] @ Save calling PC
514 mrs r6, spsr
515 str r6, [r8, #4] @ Save CPSR
516 str r0, [r8, #8] @ Save OLD_R0
517 mov r0, sp
518 .endm
519
520 .macro irq_restore_user_regs
521 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
522 mov r0, r0
523 ldr lr, [sp, #S_PC] @ Get PC
524 add sp, sp, #S_FRAME_SIZE
525 subs pc, lr, #4 @ return & move spsr_svc into cpsr
526 .endm
527
528 .macro get_bad_stack
529 #if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
530 ldr r13, _armboot_start @ setup our mode stack
531 sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
532 sub r13, r13, #(GENERATED_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack
533 #else
534 ldr r13, IRQ_STACK_START_IN
535 #endif
536
537 str lr, [r13] @ save caller lr in position 0 of saved stack
538 mrs lr, spsr @ get the spsr
539 str lr, [r13, #4] @ save spsr in position 1 of saved stack
540
541 mov r13, #MODE_SVC @ prepare SVC-Mode
542 @ msr spsr_c, r13
543 msr spsr, r13 @ switch modes, make sure moves will execute
544 mov lr, pc @ capture return pc
545 movs pc, lr @ jump to next instruction & switch modes.
546 .endm
547
548 .macro get_irq_stack @ setup IRQ stack
549 ldr sp, IRQ_STACK_START
550 .endm
551
552 .macro get_fiq_stack @ setup FIQ stack
553 ldr sp, FIQ_STACK_START
554 .endm
555
556 /*
557 * exception handlers
558 */
559 .align 5
560 undefined_instruction:
561 get_bad_stack
562 bad_save_user_regs
563 bl do_undefined_instruction
564
565 .align 5
566 software_interrupt:
567 get_bad_stack
568 bad_save_user_regs
569 bl do_software_interrupt
570
571 .align 5
572 prefetch_abort:
573 get_bad_stack
574 bad_save_user_regs
575 bl do_prefetch_abort
576
577 .align 5
578 data_abort:
579 get_bad_stack
580 bad_save_user_regs
581 bl do_data_abort
582
583 .align 5
584 not_used:
585 get_bad_stack
586 bad_save_user_regs
587 bl do_not_used
588
589 #ifdef CONFIG_USE_IRQ
590
591 .align 5
592 irq:
593 get_irq_stack
594 irq_save_user_regs
595 bl do_irq
596 irq_restore_user_regs
597
598 .align 5
599 fiq:
600 get_fiq_stack
601 /* someone ought to write a more effiction fiq_save_user_regs */
602 irq_save_user_regs
603 bl do_fiq
604 irq_restore_user_regs
605
606 #else
607
608 .align 5
609 irq:
610 get_bad_stack
611 bad_save_user_regs
612 bl do_irq
613
614 .align 5
615 fiq:
616 get_bad_stack
617 bad_save_user_regs
618 bl do_fiq
619
620 #endif
621
622 .align 5
623 .globl reset_cpu
624 reset_cpu:
625 ldr r1, rstctl1 /* get clkm1 reset ctl */
626 mov r3, #0x3 /* dsp_en + arm_rst = global reset */
627 strh r3, [r1] /* force reset */
628 mov r0, r0
629 _loop_forever:
630 b _loop_forever
631 rstctl1:
632 .word 0xfffece10