]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/arm1176/start.S
Merge branch 'elf_reloc'
[karo-tx-uboot.git] / arch / arm / cpu / arm1176 / start.S
1 /*
2  *  armboot - Startup Code for ARM1176 CPU-core
3  *
4  * Copyright (c) 2007   Samsung Electronics
5  *
6  * Copyright (C) 2008
7  * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
8  *
9  * See file CREDITS for list of people who contributed to this
10  * project.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License as
14  * published by the Free Software Foundation; either version 2 of
15  * the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25  * MA 02111-1307 USA
26  *
27  * 2007-09-21 - Restructured codes by jsgood (jsgood.yang@samsung.com)
28  * 2007-09-21 - Added MoviNAND and OneNAND boot codes by
29  * jsgood (jsgood.yang@samsung.com)
30  * Base codes by scsuh (sc.suh)
31  */
32
33 #include <config.h>
34 #include <version.h>
35 #ifdef CONFIG_ENABLE_MMU
36 #include <asm/proc/domain.h>
37 #endif
38
39 #if !defined(CONFIG_ENABLE_MMU) && !defined(CONFIG_SYS_PHY_UBOOT_BASE)
40 #define CONFIG_SYS_PHY_UBOOT_BASE       CONFIG_SYS_UBOOT_BASE
41 #endif
42
43 /*
44  *************************************************************************
45  *
46  * Jump vector table as in table 3.1 in [1]
47  *
48  *************************************************************************
49  */
50
51 .globl _start
52 _start: b       reset
53 #ifndef CONFIG_NAND_SPL
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 _pad:
77         .word 0x12345678 /* now 16*4=64 */
78 #else
79         . = _start + 64
80 #endif
81
82 .global _end_vect
83 _end_vect:
84         .balignl 16,0xdeadbeef
85 /*
86  *************************************************************************
87  *
88  * Startup Code (reset vector)
89  *
90  * do important init only if we don't start from memory!
91  * setup Memory and board specific bits prior to relocation.
92  * relocate armboot to ram
93  * setup stack
94  *
95  *************************************************************************
96  */
97
98 .globl _TEXT_BASE
99 _TEXT_BASE:
100         .word   CONFIG_SYS_TEXT_BASE
101
102 /*
103  * Below variable is very important because we use MMU in U-Boot.
104  * Without it, we cannot run code correctly before MMU is ON.
105  * by scsuh.
106  */
107 _TEXT_PHY_BASE:
108         .word   CONFIG_SYS_PHY_UBOOT_BASE
109
110 #if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
111 .globl _armboot_start
112 _armboot_start:
113         .word _start
114 #endif
115
116 /*
117  * These are defined in the board-specific linker script.
118  */
119 .globl _bss_start
120 _bss_start:
121         .word __bss_start
122
123 .globl _bss_end
124 _bss_end:
125         .word _end
126
127 #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
128 /* IRQ stack memory (calculated at run-time) + 8 bytes */
129 .globl IRQ_STACK_START_IN
130 IRQ_STACK_START_IN:
131         .word   0x0badc0de
132
133 .globl _datarel_start
134 _datarel_start:
135         .word __datarel_start
136
137 .globl _datarelrolocal_start
138 _datarelrolocal_start:
139         .word __datarelrolocal_start
140
141 .globl _datarellocal_start
142 _datarellocal_start:
143         .word __datarellocal_start
144
145 .globl _datarelro_start
146 _datarelro_start:
147         .word __datarelro_start
148
149 .globl _got_start
150 _got_start:
151         .word __got_start
152
153 .globl _got_end
154 _got_end:
155         .word __got_end
156
157 /*
158  * the actual reset code
159  */
160
161 reset:
162         /*
163          * set the cpu to SVC32 mode
164          */
165         mrs     r0, cpsr
166         bic     r0, r0, #0x3f
167         orr     r0, r0, #0xd3
168         msr     cpsr, r0
169
170 /*
171  *************************************************************************
172  *
173  * CPU_init_critical registers
174  *
175  * setup important registers
176  * setup memory timing
177  *
178  *************************************************************************
179  */
180         /*
181          * we do sys-critical inits only at reboot,
182          * not when booting from ram!
183          */
184 cpu_init_crit:
185         /*
186          * When booting from NAND - it has definitely been a reset, so, no need
187          * to flush caches and disable the MMU
188          */
189 #ifndef CONFIG_NAND_SPL
190         /*
191          * flush v4 I/D caches
192          */
193         mov     r0, #0
194         mcr     p15, 0, r0, c7, c7, 0   /* flush v3/v4 cache */
195         mcr     p15, 0, r0, c8, c7, 0   /* flush v4 TLB */
196
197         /*
198          * disable MMU stuff and caches
199          */
200         mrc     p15, 0, r0, c1, c0, 0
201         bic     r0, r0, #0x00002300     @ clear bits 13, 9:8 (--V- --RS)
202         bic     r0, r0, #0x00000087     @ clear bits 7, 2:0 (B--- -CAM)
203         orr     r0, r0, #0x00000002     @ set bit 2 (A) Align
204         orr     r0, r0, #0x00001000     @ set bit 12 (I) I-Cache
205
206         /* Prepare to disable the MMU */
207         adr     r2, mmu_disable_phys
208         sub     r2, r2, #(CONFIG_SYS_PHY_UBOOT_BASE - CONFIG_SYS_TEXT_BASE)
209         b       mmu_disable
210
211         .align 5
212         /* Run in a single cache-line */
213 mmu_disable:
214         mcr     p15, 0, r0, c1, c0, 0
215         nop
216         nop
217         mov     pc, r2
218 mmu_disable_phys:
219
220 #ifdef CONFIG_DISABLE_TCM
221         /*
222          * Disable the TCMs
223          */
224         mrc     p15, 0, r0, c0, c0, 2   /* Return TCM details */
225         cmp     r0, #0
226         beq     skip_tcmdisable
227         mov     r1, #0
228         mov     r2, #1
229         tst     r0, r2
230         mcrne   p15, 0, r1, c9, c1, 1   /* Disable Instruction TCM if present*/
231         tst     r0, r2, LSL #16
232         mcrne   p15, 0, r1, c9, c1, 0   /* Disable Data TCM if present*/
233 skip_tcmdisable:
234 #endif
235 #endif
236
237 #ifdef CONFIG_PERIPORT_REMAP
238         /* Peri port setup */
239         ldr     r0, =CONFIG_PERIPORT_BASE
240         orr     r0, r0, #CONFIG_PERIPORT_SIZE
241         mcr     p15,0,r0,c15,c2,4
242 #endif
243
244         /*
245          * Go setup Memory and board specific bits prior to relocation.
246          */
247         bl      lowlevel_init           /* go setup pll,mux,memory */
248
249 /* Set stackpointer in internal RAM to call board_init_f */
250 call_board_init_f:
251         ldr     sp, =(CONFIG_SYS_INIT_SP_ADDR)
252         ldr     r0,=0x00000000
253         bl      board_init_f
254
255 /*------------------------------------------------------------------------------*/
256
257 /*
258  * void relocate_code (addr_sp, gd, addr_moni)
259  *
260  * This "function" does not return, instead it continues in RAM
261  * after relocating the monitor code.
262  *
263  */
264         .globl  relocate_code
265 relocate_code:
266         mov     r4, r0  /* save addr_sp */
267         mov     r5, r1  /* save addr of gd */
268         mov     r6, r2  /* save addr of destination */
269         mov     r7, r2  /* save addr of destination */
270
271         /* Set up the stack                                                 */
272 stack_setup:
273         mov     sp, r4
274
275         adr     r0, _start
276         ldr     r2, _TEXT_BASE
277         ldr     r3, _bss_start
278         sub     r2, r3, r2              /* r2 <- size of armboot            */
279         add     r2, r0, r2              /* r2 <- source end address         */
280         cmp     r0, r6
281         beq     clear_bss
282
283 #ifndef CONFIG_SKIP_RELOCATE_UBOOT
284 copy_loop:
285         ldmia   r0!, {r9-r10}           /* copy from source address [r0]    */
286         stmia   r6!, {r9-r10}           /* copy to   target address [r1]    */
287         cmp     r0, r2                  /* until source end address [r2]    */
288         blo     copy_loop
289
290 #ifndef CONFIG_PRELOADER
291         /* fix got entries */
292         ldr     r1, _TEXT_BASE          /* Text base */
293         mov     r0, r7                  /* reloc addr */
294         ldr     r2, _got_start          /* addr in Flash */
295         ldr     r3, _got_end            /* addr in Flash */
296         sub     r3, r3, r1
297         add     r3, r3, r0
298         sub     r2, r2, r1
299         add     r2, r2, r0
300
301 fixloop:
302         ldr     r4, [r2]
303         sub     r4, r4, r1
304         add     r4, r4, r0
305         str     r4, [r2]
306         add     r2, r2, #4
307         cmp     r2, r3
308         bne     fixloop
309 #endif
310 #endif  /* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */
311
312 #ifdef CONFIG_ENABLE_MMU
313 enable_mmu:
314         /* enable domain access */
315         ldr     r5, =0x0000ffff
316         mcr     p15, 0, r5, c3, c0, 0   /* load domain access register */
317
318         /* Set the TTB register */
319         ldr     r0, _mmu_table_base
320         ldr     r1, =CONFIG_SYS_PHY_UBOOT_BASE
321         ldr     r2, =0xfff00000
322         bic     r0, r0, r2
323         orr     r1, r0, r1
324         mcr     p15, 0, r1, c2, c0, 0
325
326         /* Enable the MMU */
327         mrc     p15, 0, r0, c1, c0, 0
328         orr     r0, r0, #1              /* Set CR_M to enable MMU */
329
330         /* Prepare to enable the MMU */
331         adr     r1, skip_hw_init
332         and     r1, r1, #0x3fc
333         ldr     r2, _TEXT_BASE
334         ldr     r3, =0xfff00000
335         and     r2, r2, r3
336         orr     r2, r2, r1
337         b       mmu_enable
338
339         .align 5
340         /* Run in a single cache-line */
341 mmu_enable:
342
343         mcr     p15, 0, r0, c1, c0, 0
344         nop
345         nop
346         mov     pc, r2
347 skip_hw_init:
348 #endif
349
350 clear_bss:
351 #ifndef CONFIG_PRELOADER
352         ldr     r0, _bss_start
353         ldr     r1, _bss_end
354         ldr     r3, _TEXT_BASE          /* Text base */
355         mov     r4, r7                  /* reloc addr */
356         sub     r0, r0, r3
357         add     r0, r0, r4
358         sub     r1, r1, r3
359         add     r1, r1, r4
360         mov     r2, #0x00000000         /* clear                            */
361
362 clbss_l:str     r2, [r0]                /* clear loop...                    */
363         add     r0, r0, #4
364         cmp     r0, r1
365         bne     clbss_l
366
367         bl coloured_LED_init
368         bl red_LED_on
369 #endif
370
371 /*
372  * We are done. Do not return, instead branch to second part of board
373  * initialization, now running from RAM.
374  */
375 #ifdef CONFIG_NAND_SPL
376         ldr     pc, _nand_boot
377
378 _nand_boot: .word nand_boot
379 #else
380         ldr     r0, _TEXT_BASE
381         ldr     r2, _board_init_r
382         sub     r2, r2, r0
383         add     r2, r2, r7      /* position from board_init_r in RAM */
384         /* setup parameters for board_init_r */
385         mov     r0, r5          /* gd_t */
386         mov     r1, r7          /* dest_addr */
387         /* jump to it ... */
388         mov     lr, r2
389         mov     pc, lr
390
391 _board_init_r: .word board_init_r
392 #endif
393
394 #else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
395
396 /*
397  * the actual reset code
398  */
399
400 reset:
401         /*
402          * set the cpu to SVC32 mode
403          */
404         mrs     r0, cpsr
405         bic     r0, r0, #0x3f
406         orr     r0, r0, #0xd3
407         msr     cpsr, r0
408
409 /*
410  *************************************************************************
411  *
412  * CPU_init_critical registers
413  *
414  * setup important registers
415  * setup memory timing
416  *
417  *************************************************************************
418  */
419         /*
420          * we do sys-critical inits only at reboot,
421          * not when booting from ram!
422          */
423 cpu_init_crit:
424         /*
425          * When booting from NAND - it has definitely been a reset, so, no need
426          * to flush caches and disable the MMU
427          */
428 #ifndef CONFIG_NAND_SPL
429         /*
430          * flush v4 I/D caches
431          */
432         mov     r0, #0
433         mcr     p15, 0, r0, c7, c7, 0   /* flush v3/v4 cache */
434         mcr     p15, 0, r0, c8, c7, 0   /* flush v4 TLB */
435
436         /*
437          * disable MMU stuff and caches
438          */
439         mrc     p15, 0, r0, c1, c0, 0
440         bic     r0, r0, #0x00002300     @ clear bits 13, 9:8 (--V- --RS)
441         bic     r0, r0, #0x00000087     @ clear bits 7, 2:0 (B--- -CAM)
442         orr     r0, r0, #0x00000002     @ set bit 2 (A) Align
443         orr     r0, r0, #0x00001000     @ set bit 12 (I) I-Cache
444
445         /* Prepare to disable the MMU */
446         adr     r2, mmu_disable_phys
447         sub     r2, r2, #(CONFIG_SYS_PHY_UBOOT_BASE - CONFIG_SYS_TEXT_BASE)
448         b       mmu_disable
449
450         .align 5
451         /* Run in a single cache-line */
452 mmu_disable:
453         mcr     p15, 0, r0, c1, c0, 0
454         nop
455         nop
456         mov     pc, r2
457 mmu_disable_phys:
458
459 #ifdef CONFIG_DISABLE_TCM
460         /*
461          * Disable the TCMs
462          */
463         mrc     p15, 0, r0, c0, c0, 2   /* Return TCM details */
464         cmp     r0, #0
465         beq     skip_tcmdisable
466         mov     r1, #0
467         mov     r2, #1
468         tst     r0, r2
469         mcrne   p15, 0, r1, c9, c1, 1   /* Disable Instruction TCM if present*/
470         tst     r0, r2, LSL #16
471         mcrne   p15, 0, r1, c9, c1, 0   /* Disable Data TCM if present*/
472 skip_tcmdisable:
473 #endif
474 #endif
475
476 #ifdef CONFIG_PERIPORT_REMAP
477         /* Peri port setup */
478         ldr     r0, =CONFIG_PERIPORT_BASE
479         orr     r0, r0, #CONFIG_PERIPORT_SIZE
480         mcr     p15,0,r0,c15,c2,4
481 #endif
482
483         /*
484          * Go setup Memory and board specific bits prior to relocation.
485          */
486         bl      lowlevel_init           /* go setup pll,mux,memory */
487
488 #ifndef CONFIG_SKIP_RELOCATE_UBOOT
489 relocate:                               /* relocate U-Boot to RAM           */
490         adr     r0, _start              /* r0 <- current position of code   */
491         ldr     r1, _TEXT_BASE          /* test if we run from flash or RAM */
492         cmp     r0, r1                  /* don't reloc during debug         */
493         beq     stack_setup
494
495         ldr     r2, _armboot_start
496         ldr     r3, _bss_start
497         sub     r2, r3, r2              /* r2 <- size of armboot            */
498         add     r2, r0, r2              /* r2 <- source end address         */
499
500 copy_loop:
501         ldmia   r0!, {r3-r10}           /* copy from source address [r0]    */
502         stmia   r1!, {r3-r10}           /* copy to   target address [r1]    */
503         cmp     r0, r2                  /* until source end address [r2]    */
504         blo     copy_loop
505 #endif  /* CONFIG_SKIP_RELOCATE_UBOOT */
506
507 #ifdef CONFIG_ENABLE_MMU
508 enable_mmu:
509         /* enable domain access */
510         ldr     r5, =0x0000ffff
511         mcr     p15, 0, r5, c3, c0, 0   /* load domain access register */
512
513         /* Set the TTB register */
514         ldr     r0, _mmu_table_base
515         ldr     r1, =CONFIG_SYS_PHY_UBOOT_BASE
516         ldr     r2, =0xfff00000
517         bic     r0, r0, r2
518         orr     r1, r0, r1
519         mcr     p15, 0, r1, c2, c0, 0
520
521         /* Enable the MMU */
522         mrc     p15, 0, r0, c1, c0, 0
523         orr     r0, r0, #1              /* Set CR_M to enable MMU */
524
525         /* Prepare to enable the MMU */
526         adr     r1, skip_hw_init
527         and     r1, r1, #0x3fc
528         ldr     r2, _TEXT_BASE
529         ldr     r3, =0xfff00000
530         and     r2, r2, r3
531         orr     r2, r2, r1
532         b       mmu_enable
533
534         .align 5
535         /* Run in a single cache-line */
536 mmu_enable:
537
538         mcr     p15, 0, r0, c1, c0, 0
539         nop
540         nop
541         mov     pc, r2
542 skip_hw_init:
543 #endif
544
545         /* Set up the stack                                                 */
546 stack_setup:
547         ldr     r0, =CONFIG_SYS_UBOOT_BASE      /* base of copy in DRAM     */
548         sub     r0, r0, #CONFIG_SYS_MALLOC_LEN  /* malloc area                      */
549         sub     r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo                        */
550         sub     sp, r0, #12             /* leave 3 words for abort-stack    */
551         bic     sp, sp, #7              /* 8-byte alignment for ABI compliance */
552
553 clear_bss:
554         ldr     r0, _bss_start          /* find start of bss segment        */
555         ldr     r1, _bss_end            /* stop here                        */
556         mov     r2, #0                  /* clear                            */
557
558 clbss_l:
559         str     r2, [r0]                /* clear loop...                    */
560         add     r0, r0, #4
561         cmp     r0, r1
562         blo     clbss_l
563
564 #ifndef CONFIG_NAND_SPL
565         ldr     pc, _start_armboot
566
567 _start_armboot:
568         .word start_armboot
569 #else
570         b       nand_boot
571 /*      .word nand_boot*/
572 #endif
573
574 #endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
575
576 #ifdef CONFIG_ENABLE_MMU
577 _mmu_table_base:
578         .word mmu_table
579 #endif
580
581 #ifndef CONFIG_NAND_SPL
582 /*
583  * we assume that cache operation is done before. (eg. cleanup_before_linux())
584  * actually, we don't need to do anything about cache if not use d-cache in
585  * U-Boot. So, in this function we clean only MMU. by scsuh
586  *
587  * void theLastJump(void *kernel, int arch_num, uint boot_params);
588  */
589 #ifdef CONFIG_ENABLE_MMU
590         .globl theLastJump
591 theLastJump:
592         mov     r9, r0
593         ldr     r3, =0xfff00000
594         ldr     r4, _TEXT_PHY_BASE
595         adr     r5, phy_last_jump
596         bic     r5, r5, r3
597         orr     r5, r5, r4
598         mov     pc, r5
599 phy_last_jump:
600         /*
601          * disable MMU stuff
602          */
603         mrc     p15, 0, r0, c1, c0, 0
604         bic     r0, r0, #0x00002300     /* clear bits 13, 9:8 (--V- --RS) */
605         bic     r0, r0, #0x00000087     /* clear bits 7, 2:0 (B--- -CAM) */
606         orr     r0, r0, #0x00000002     /* set bit 2 (A) Align */
607         orr     r0, r0, #0x00001000     /* set bit 12 (I) I-Cache */
608         mcr     p15, 0, r0, c1, c0, 0
609
610         mcr     p15, 0, r0, c8, c7, 0   /* flush v4 TLB */
611
612         mov     r0, #0
613         mov     pc, r9
614 #endif
615
616
617 /*
618  *************************************************************************
619  *
620  * Interrupt handling
621  *
622  *************************************************************************
623  */
624 @
625 @ IRQ stack frame.
626 @
627 #define S_FRAME_SIZE    72
628
629 #define S_OLD_R0        68
630 #define S_PSR           64
631 #define S_PC            60
632 #define S_LR            56
633 #define S_SP            52
634
635 #define S_IP            48
636 #define S_FP            44
637 #define S_R10           40
638 #define S_R9            36
639 #define S_R8            32
640 #define S_R7            28
641 #define S_R6            24
642 #define S_R5            20
643 #define S_R4            16
644 #define S_R3            12
645 #define S_R2            8
646 #define S_R1            4
647 #define S_R0            0
648
649 #define MODE_SVC 0x13
650 #define I_BIT    0x80
651
652 /*
653  * use bad_save_user_regs for abort/prefetch/undef/swi ...
654  */
655
656         .macro  bad_save_user_regs
657         /* carve out a frame on current user stack */
658         sub     sp, sp, #S_FRAME_SIZE
659         /* Save user registers (now in svc mode) r0-r12 */
660         stmia   sp, {r0 - r12}
661
662 #if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
663         ldr     r2, _armboot_start
664         sub     r2, r2, #(CONFIG_SYS_MALLOC_LEN)
665         /* set base 2 words into abort stack */
666         sub     r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8)
667 #else
668         ldr     r2, IRQ_STACK_START_IN
669 #endif
670         /* get values for "aborted" pc and cpsr (into parm regs) */
671         ldmia   r2, {r2 - r3}
672         /* grab pointer to old stack */
673         add     r0, sp, #S_FRAME_SIZE
674
675         add     r5, sp, #S_SP
676         mov     r1, lr
677         /* save sp_SVC, lr_SVC, pc, cpsr */
678         stmia   r5, {r0 - r3}
679         /* save current stack into r0 (param register) */
680         mov     r0, sp
681         .endm
682
683         .macro get_bad_stack
684 #if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
685         /* setup our mode stack (enter in banked mode) */
686         ldr     r13, _armboot_start
687         /* move past malloc pool */
688         sub     r13, r13, #(CONFIG_SYS_MALLOC_LEN)
689         /* move to reserved a couple spots for abort stack */
690         sub     r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE + 8)
691 #else
692         ldr     r13, IRQ_STACK_START_IN         @ setup our mode stack
693 #endif
694
695         /* save caller lr in position 0 of saved stack */
696         str     lr, [r13]
697         /* get the spsr */
698         mrs     lr, spsr
699         /* save spsr in position 1 of saved stack */
700         str     lr, [r13, #4]
701
702         /* prepare SVC-Mode */
703         mov     r13, #MODE_SVC
704         @ msr   spsr_c, r13
705         /* switch modes, make sure moves will execute */
706         msr     spsr, r13
707         /* capture return pc */
708         mov     lr, pc
709         /* jump to next instruction & switch modes. */
710         movs    pc, lr
711         .endm
712
713         .macro get_bad_stack_swi
714         /* space on current stack for scratch reg. */
715         sub     r13, r13, #4
716         /* save R0's value. */
717         str     r0, [r13]
718 #if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
719         /* get data regions start */
720         ldr     r0, _armboot_start
721         /* move past malloc pool */
722         sub     r0, r0, #(CONFIG_SYS_MALLOC_LEN)
723         /* move past gbl and a couple spots for abort stack */
724         sub     r0, r0, #(CONFIG_SYS_GBL_DATA_SIZE + 8)
725 #else
726         ldr     r13, IRQ_STACK_START_IN         @ setup our mode stack
727 #endif
728         /* save caller lr in position 0 of saved stack */
729         str     lr, [r0]
730         /* get the spsr */
731         mrs     r0, spsr
732         /* save spsr in position 1 of saved stack */
733         str     lr, [r0, #4]
734         /* restore r0 */
735         ldr     r0, [r13]
736         /* pop stack entry */
737         add     r13, r13, #4
738         .endm
739
740 /*
741  * exception handlers
742  */
743         .align  5
744 undefined_instruction:
745         get_bad_stack
746         bad_save_user_regs
747         bl      do_undefined_instruction
748
749         .align  5
750 software_interrupt:
751         get_bad_stack_swi
752         bad_save_user_regs
753         bl      do_software_interrupt
754
755         .align  5
756 prefetch_abort:
757         get_bad_stack
758         bad_save_user_regs
759         bl      do_prefetch_abort
760
761         .align  5
762 data_abort:
763         get_bad_stack
764         bad_save_user_regs
765         bl      do_data_abort
766
767         .align  5
768 not_used:
769         get_bad_stack
770         bad_save_user_regs
771         bl      do_not_used
772
773         .align  5
774 irq:
775         get_bad_stack
776         bad_save_user_regs
777         bl      do_irq
778
779         .align  5
780 fiq:
781         get_bad_stack
782         bad_save_user_regs
783         bl      do_fiq
784 #endif /* CONFIG_NAND_SPL */