]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/ixp/start.S
ARM: use the same branch insn on all architectures
[karo-tx-uboot.git] / arch / arm / cpu / ixp / start.S
1 /* vi: set ts=8 sw=8 noet: */
2 /*
3  *  u-boot - Startup Code for XScale IXP
4  *
5  * Copyright (C) 2003   Kyle Harris <kharris@nexus-tech.net>
6  *
7  * Based on startup code example contained in the
8  * Intel IXP4xx Programmer's Guide and past u-boot Start.S
9  * samples.
10  *
11  * See file CREDITS for list of people who contributed to this
12  * project.
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License as
16  * published by the Free Software Foundation; either version 2 of
17  * the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27  * MA 02111-1307 USA
28  */
29
30 #include <asm-offsets.h>
31 #include <config.h>
32 #include <version.h>
33 #include <asm/arch/ixp425.h>
34
35 #define MMU_Control_M  0x001    /* Enable MMU */
36 #define MMU_Control_A  0x002    /* Enable address alignment faults */
37 #define MMU_Control_C  0x004    /* Enable cache */
38 #define MMU_Control_W  0x008    /* Enable write-buffer */
39 #define MMU_Control_P  0x010    /* Compatability: 32 bit code */
40 #define MMU_Control_D  0x020    /* Compatability: 32 bit data */
41 #define MMU_Control_L  0x040    /* Compatability: */
42 #define MMU_Control_B  0x080    /* Enable Big-Endian */
43 #define MMU_Control_S  0x100    /* Enable system protection */
44 #define MMU_Control_R  0x200    /* Enable ROM protection */
45 #define MMU_Control_I  0x1000   /* Enable Instruction cache */
46 #define MMU_Control_X  0x2000   /* Set interrupt vectors at 0xFFFF0000 */
47 #define MMU_Control_Init (MMU_Control_P|MMU_Control_D|MMU_Control_L)
48
49
50 /*
51  * Macro definitions
52  */
53         /* Delay a bit */
54         .macro DELAY_FOR cycles, reg0
55         ldr     \reg0, =\cycles
56         subs    \reg0, \reg0, #1
57         subne   pc,  pc, #0xc
58         .endm
59
60         /* wait for coprocessor write complete */
61         .macro CPWAIT reg
62         mrc  p15,0,\reg,c2,c0,0
63         mov  \reg,\reg
64         sub  pc,pc,#4
65         .endm
66
67 .globl _start
68 _start: b       reset
69         ldr     pc, _undefined_instruction
70         ldr     pc, _software_interrupt
71         ldr     pc, _prefetch_abort
72         ldr     pc, _data_abort
73         ldr     pc, _not_used
74         ldr     pc, _irq
75         ldr     pc, _fiq
76
77 _undefined_instruction: .word undefined_instruction
78 _software_interrupt:    .word software_interrupt
79 _prefetch_abort:        .word prefetch_abort
80 _data_abort:            .word data_abort
81 _not_used:              .word not_used
82 _irq:                   .word irq
83 _fiq:                   .word fiq
84
85         .balignl 16,0xdeadbeef
86
87
88 /*
89  * Startup Code (reset vector)
90  *
91  * do important init only if we don't start from memory!
92  * - relocate armboot to ram
93  * - setup stack
94  * - jump to second stage
95  */
96
97 .globl _TEXT_BASE
98 _TEXT_BASE:
99         .word   CONFIG_SYS_TEXT_BASE
100
101 #if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
102 .globl _armboot_start
103 _armboot_start:
104         .word _start
105 #endif
106
107 /*
108  * These are defined in the board-specific linker script.
109  */
110 .globl _bss_start
111 _bss_start:
112         .word __bss_start
113
114 .globl _bss_end
115 _bss_end:
116         .word _end
117
118 #ifdef CONFIG_USE_IRQ
119 /* IRQ stack memory (calculated at run-time) */
120 .globl IRQ_STACK_START
121 IRQ_STACK_START:
122         .word   0x0badc0de
123
124 /* IRQ stack memory (calculated at run-time) */
125 .globl FIQ_STACK_START
126 FIQ_STACK_START:
127         .word 0x0badc0de
128 #endif
129
130 #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
131 /* IRQ stack memory (calculated at run-time) + 8 bytes */
132 .globl IRQ_STACK_START_IN
133 IRQ_STACK_START_IN:
134         .word   0x0badc0de
135
136 .globl _datarel_start
137 _datarel_start:
138         .word __datarel_start
139
140 .globl _datarelrolocal_start
141 _datarelrolocal_start:
142         .word __datarelrolocal_start
143
144 .globl _datarellocal_start
145 _datarellocal_start:
146         .word __datarellocal_start
147
148 .globl _datarelro_start
149 _datarelro_start:
150         .word __datarelro_start
151
152 .globl _got_start
153 _got_start:
154         .word __got_start
155
156 .globl _got_end
157 _got_end:
158         .word __got_end
159
160 /*
161  * the actual reset code
162  */
163
164 reset:
165         /* disable mmu, set big-endian */
166         mov     r0, #0xf8
167         mcr     p15, 0, r0, c1, c0, 0
168         CPWAIT  r0
169
170         /* invalidate I & D caches & BTB */
171         mcr     p15, 0, r0, c7, c7, 0
172         CPWAIT  r0
173
174         /* invalidate I & Data TLB */
175         mcr     p15, 0, r0, c8, c7, 0
176         CPWAIT r0
177
178         /* drain write and fill buffers */
179         mcr     p15, 0, r0, c7, c10, 4
180         CPWAIT  r0
181
182         /* disable write buffer coalescing */
183         mrc     p15, 0, r0, c1, c0, 1
184         orr     r0, r0, #1
185         mcr     p15, 0, r0, c1, c0, 1
186         CPWAIT  r0
187
188         /* set EXP CS0 to the optimum timing */
189         ldr     r1, =CONFIG_SYS_EXP_CS0
190         ldr     r2, =IXP425_EXP_CS0
191         str     r1, [r2]
192
193         /* make sure flash is visible at 0 */
194 #if 0
195         ldr     r2, =IXP425_EXP_CFG0
196         ldr     r1, [r2]
197         orr     r1, r1, #0x80000000
198         str     r1, [r2]
199 #endif
200         mov     r1, #CONFIG_SYS_SDR_CONFIG
201         ldr     r2, =IXP425_SDR_CONFIG
202         str     r1, [r2]
203
204         /* disable refresh cycles */
205         mov     r1, #0
206         ldr     r3, =IXP425_SDR_REFRESH
207         str     r1, [r3]
208
209         /* send nop command */
210         mov     r1, #3
211         ldr     r4, =IXP425_SDR_IR
212         str     r1, [r4]
213         DELAY_FOR 0x4000, r0
214
215         /* set SDRAM internal refresh val */
216         ldr     r1, =CONFIG_SYS_SDRAM_REFRESH_CNT
217         str     r1, [r3]
218         DELAY_FOR 0x4000, r0
219
220         /* send precharge-all command to close all open banks */
221         mov     r1, #2
222         str     r1, [r4]
223         DELAY_FOR 0x4000, r0
224
225         /* provide 8 auto-refresh cycles */
226         mov     r1, #4
227         mov     r5, #8
228 111:    str     r1, [r4]
229         DELAY_FOR 0x100, r0
230         subs    r5, r5, #1
231         bne     111b
232
233         /* set mode register in sdram */
234         mov     r1, #CONFIG_SYS_SDR_MODE_CONFIG
235         str     r1, [r4]
236         DELAY_FOR 0x4000, r0
237
238         /* send normal operation command */
239         mov     r1, #6
240         str     r1, [r4]
241         DELAY_FOR 0x4000, r0
242
243         /* copy */
244         mov     r0, #0
245         mov     r4, r0
246         add     r2, r0, #CONFIG_SYS_MONITOR_LEN
247         mov     r1, #0x10000000
248         mov     r5, r1
249
250     30:
251         ldr     r3, [r0], #4
252         str     r3, [r1], #4
253         cmp     r0, r2
254         bne     30b
255
256         /* invalidate I & D caches & BTB */
257         mcr     p15, 0, r0, c7, c7, 0
258         CPWAIT  r0
259
260         /* invalidate I & Data TLB */
261         mcr     p15, 0, r0, c8, c7, 0
262         CPWAIT r0
263
264         /* drain write and fill buffers */
265         mcr     p15, 0, r0, c7, c10, 4
266         CPWAIT  r0
267
268         /* move flash to 0x50000000 */
269         ldr     r2, =IXP425_EXP_CFG0
270         ldr     r1, [r2]
271         bic     r1, r1, #0x80000000
272         str     r1, [r2]
273
274         nop
275         nop
276         nop
277         nop
278         nop
279         nop
280
281         /* invalidate I & Data TLB */
282         mcr     p15, 0, r0, c8, c7, 0
283         CPWAIT r0
284
285         /* enable I cache */
286         mrc     p15, 0, r0, c1, c0, 0
287         orr     r0, r0, #MMU_Control_I
288         mcr     p15, 0, r0, c1, c0, 0
289         CPWAIT  r0
290
291         mrs     r0,cpsr                 /* set the cpu to SVC32 mode        */
292         bic     r0,r0,#0x1f             /* (superviser mode, M=10011)       */
293         orr     r0,r0,#0x13
294         msr     cpsr,r0
295
296 /* Set stackpointer in internal RAM to call board_init_f */
297 call_board_init_f:
298         ldr     sp, =(CONFIG_SYS_INIT_SP_ADDR)
299         ldr     r0,=0x00000000
300         bl      board_init_f
301
302 /*------------------------------------------------------------------------------*/
303
304 /*
305  * void relocate_code (addr_sp, gd, addr_moni)
306  *
307  * This "function" does not return, instead it continues in RAM
308  * after relocating the monitor code.
309  *
310  */
311         .globl  relocate_code
312 relocate_code:
313         mov     r4, r0  /* save addr_sp */
314         mov     r5, r1  /* save addr of gd */
315         mov     r6, r2  /* save addr of destination */
316         mov     r7, r2  /* save addr of destination */
317
318         /* Set up the stack                                                 */
319 stack_setup:
320         mov     sp, r4
321
322         adr     r0, _start
323         ldr     r2, _TEXT_BASE
324         ldr     r3, _bss_start
325         sub     r2, r3, r2              /* r2 <- size of armboot            */
326         add     r2, r0, r2              /* r2 <- source end address         */
327         cmp     r0, r6
328         beq     clear_bss
329
330 #ifndef CONFIG_SKIP_RELOCATE_UBOOT
331 copy_loop:
332         ldmia   r0!, {r9-r10}           /* copy from source address [r0]    */
333         stmia   r6!, {r9-r10}           /* copy to   target address [r1]    */
334         cmp     r0, r2                  /* until source end address [r2]    */
335         blo     copy_loop
336
337 #ifndef CONFIG_PRELOADER
338         /* fix got entries */
339         ldr     r1, _TEXT_BASE          /* Text base */
340         mov     r0, r7                  /* reloc addr */
341         ldr     r2, _got_start          /* addr in Flash */
342         ldr     r3, _got_end            /* addr in Flash */
343         sub     r3, r3, r1
344         add     r3, r3, r0
345         sub     r2, r2, r1
346         add     r2, r2, r0
347
348 fixloop:
349         ldr     r4, [r2]
350         sub     r4, r4, r1
351         add     r4, r4, r0
352         str     r4, [r2]
353         add     r2, r2, #4
354         cmp     r2, r3
355         blo     fixloop
356 #endif
357 #endif  /* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */
358
359 clear_bss:
360 #ifndef CONFIG_PRELOADER
361         ldr     r0, _bss_start
362         ldr     r1, _bss_end
363         ldr     r3, _TEXT_BASE          /* Text base */
364         mov     r4, r7                  /* reloc addr */
365         sub     r0, r0, r3
366         add     r0, r0, r4
367         sub     r1, r1, r3
368         add     r1, r1, r4
369         mov     r2, #0x00000000         /* clear                            */
370
371 clbss_l:str     r2, [r0]                /* clear loop...                    */
372         add     r0, r0, #4
373         cmp     r0, r1
374         bne     clbss_l
375
376         bl coloured_LED_init
377         bl red_LED_on
378 #endif
379
380 /*
381  * We are done. Do not return, instead branch to second part of board
382  * initialization, now running from RAM.
383  */
384         ldr     r0, _TEXT_BASE
385         ldr     r2, _board_init_r
386         sub     r2, r2, r0
387         add     r2, r2, r7      /* position from board_init_r in RAM */
388         /* setup parameters for board_init_r */
389         mov     r0, r5          /* gd_t */
390         mov     r1, r7          /* dest_addr */
391         /* jump to it ... */
392         mov     lr, r2
393         mov     pc, lr
394
395 _board_init_r: .word board_init_r
396
397 #else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
398 /****************************************************************************/
399 /*                                                                          */
400 /* the actual reset code                                                    */
401 /*                                                                          */
402 /****************************************************************************/
403
404 reset:
405         /* disable mmu, set big-endian */
406         mov     r0, #0xf8
407         mcr     p15, 0, r0, c1, c0, 0
408         CPWAIT  r0
409
410         /* invalidate I & D caches & BTB */
411         mcr     p15, 0, r0, c7, c7, 0
412         CPWAIT  r0
413
414         /* invalidate I & Data TLB */
415         mcr     p15, 0, r0, c8, c7, 0
416         CPWAIT r0
417
418         /* drain write and fill buffers */
419         mcr     p15, 0, r0, c7, c10, 4
420         CPWAIT  r0
421
422         /* disable write buffer coalescing */
423         mrc     p15, 0, r0, c1, c0, 1
424         orr     r0, r0, #1
425         mcr     p15, 0, r0, c1, c0, 1
426         CPWAIT  r0
427
428         /* set EXP CS0 to the optimum timing */
429         ldr     r1, =CONFIG_SYS_EXP_CS0
430         ldr     r2, =IXP425_EXP_CS0
431         str     r1, [r2]
432
433         /* make sure flash is visible at 0 */
434 #if 0
435         ldr     r2, =IXP425_EXP_CFG0
436         ldr     r1, [r2]
437         orr     r1, r1, #0x80000000
438         str     r1, [r2]
439 #endif
440         mov     r1, #CONFIG_SYS_SDR_CONFIG
441         ldr     r2, =IXP425_SDR_CONFIG
442         str     r1, [r2]
443
444         /* disable refresh cycles */
445         mov     r1, #0
446         ldr     r3, =IXP425_SDR_REFRESH
447         str     r1, [r3]
448
449         /* send nop command */
450         mov     r1, #3
451         ldr     r4, =IXP425_SDR_IR
452         str     r1, [r4]
453         DELAY_FOR 0x4000, r0
454
455         /* set SDRAM internal refresh val */
456         ldr     r1, =CONFIG_SYS_SDRAM_REFRESH_CNT
457         str     r1, [r3]
458         DELAY_FOR 0x4000, r0
459
460         /* send precharge-all command to close all open banks */
461         mov     r1, #2
462         str     r1, [r4]
463         DELAY_FOR 0x4000, r0
464
465         /* provide 8 auto-refresh cycles */
466         mov     r1, #4
467         mov     r5, #8
468 111:    str     r1, [r4]
469         DELAY_FOR 0x100, r0
470         subs    r5, r5, #1
471         bne     111b
472
473         /* set mode register in sdram */
474         mov     r1, #CONFIG_SYS_SDR_MODE_CONFIG
475         str     r1, [r4]
476         DELAY_FOR 0x4000, r0
477
478         /* send normal operation command */
479         mov     r1, #6
480         str     r1, [r4]
481         DELAY_FOR 0x4000, r0
482
483         /* copy */
484         mov     r0, #0
485         mov     r4, r0
486         add     r2, r0, #CONFIG_SYS_MONITOR_LEN
487         mov     r1, #0x10000000
488         mov     r5, r1
489
490     30:
491         ldr     r3, [r0], #4
492         str     r3, [r1], #4
493         cmp     r0, r2
494         bne     30b
495
496         /* invalidate I & D caches & BTB */
497         mcr     p15, 0, r0, c7, c7, 0
498         CPWAIT  r0
499
500         /* invalidate I & Data TLB */
501         mcr     p15, 0, r0, c8, c7, 0
502         CPWAIT r0
503
504         /* drain write and fill buffers */
505         mcr     p15, 0, r0, c7, c10, 4
506         CPWAIT  r0
507
508         /* move flash to 0x50000000 */
509         ldr     r2, =IXP425_EXP_CFG0
510         ldr     r1, [r2]
511         bic     r1, r1, #0x80000000
512         str     r1, [r2]
513
514         nop
515         nop
516         nop
517         nop
518         nop
519         nop
520
521         /* invalidate I & Data TLB */
522         mcr     p15, 0, r0, c8, c7, 0
523         CPWAIT r0
524
525         /* enable I cache */
526         mrc     p15, 0, r0, c1, c0, 0
527         orr     r0, r0, #MMU_Control_I
528         mcr     p15, 0, r0, c1, c0, 0
529         CPWAIT  r0
530
531         mrs     r0,cpsr                 /* set the cpu to SVC32 mode        */
532         bic     r0,r0,#0x1f             /* (superviser mode, M=10011)       */
533         orr     r0,r0,#0x13
534         msr     cpsr,r0
535
536 #ifndef CONFIG_SKIP_RELOCATE_UBOOT
537 relocate:                               /* relocate U-Boot to RAM           */
538         adr     r0, _start              /* r0 <- current position of code   */
539         ldr     r1, _TEXT_BASE          /* test if we run from flash or RAM */
540         cmp     r0, r1                  /* don't reloc during debug         */
541         beq     stack_setup
542
543         ldr     r2, _armboot_start
544         ldr     r3, _bss_start
545         sub     r2, r3, r2              /* r2 <- size of armboot            */
546         add     r2, r0, r2              /* r2 <- source end address         */
547
548 copy_loop:
549         ldmia   r0!, {r3-r10}           /* copy from source address [r0]    */
550         stmia   r1!, {r3-r10}           /* copy to   target address [r1]    */
551         cmp     r0, r2                  /* until source end address [r2]    */
552         blo     copy_loop
553 #endif  /* CONFIG_SKIP_RELOCATE_UBOOT */
554
555         /* Set up the stack                                                 */
556 stack_setup:
557         ldr     r0, _TEXT_BASE          /* upper 128 KiB: relocated uboot   */
558         sub     r0, r0, #CONFIG_SYS_MALLOC_LEN  /* malloc area                      */
559         sub     r0, r0, #GENERATED_GBL_DATA_SIZE /* bdinfo                        */
560 #ifdef CONFIG_USE_IRQ
561         sub     r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
562 #endif
563         sub     sp, r0, #12             /* leave 3 words for abort-stack    */
564         bic     sp, sp, #7              /* 8-byte alignment for ABI compliance */
565
566 clear_bss:
567         ldr     r0, _bss_start          /* find start of bss segment        */
568         ldr     r1, _bss_end            /* stop here                        */
569         mov     r2, #0x00000000         /* clear                            */
570
571 clbss_l:str     r2, [r0]                /* clear loop...                    */
572         add     r0, r0, #4
573         cmp     r0, r1
574         blo     clbss_l
575
576         ldr     pc, _start_armboot
577
578 _start_armboot: .word start_armboot
579 #endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
580
581
582 /****************************************************************************/
583 /*                                                                          */
584 /* Interrupt handling                                                       */
585 /*                                                                          */
586 /****************************************************************************/
587
588 /* IRQ stack frame                                                          */
589
590 #define S_FRAME_SIZE    72
591
592 #define S_OLD_R0        68
593 #define S_PSR           64
594 #define S_PC            60
595 #define S_LR            56
596 #define S_SP            52
597
598 #define S_IP            48
599 #define S_FP            44
600 #define S_R10           40
601 #define S_R9            36
602 #define S_R8            32
603 #define S_R7            28
604 #define S_R6            24
605 #define S_R5            20
606 #define S_R4            16
607 #define S_R3            12
608 #define S_R2            8
609 #define S_R1            4
610 #define S_R0            0
611
612 #define MODE_SVC 0x13
613
614         /* use bad_save_user_regs for abort/prefetch/undef/swi ...          */
615
616         .macro  bad_save_user_regs
617         sub     sp, sp, #S_FRAME_SIZE
618         stmia   sp, {r0 - r12}                  /* Calling r0-r12           */
619         add     r8, sp, #S_PC
620
621 #if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
622         ldr     r2, _armboot_start
623         sub     r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
624         sub     r2, r2, #(GENERATED_GBL_DATA_SIZE+8)  @ set base 2 words into abort stack
625 #else
626         ldr     r2, IRQ_STACK_START_IN
627 #endif
628         ldmia   r2, {r2 - r4}                   /* get pc, cpsr, old_r0     */
629         add     r0, sp, #S_FRAME_SIZE           /* restore sp_SVC           */
630
631         add     r5, sp, #S_SP
632         mov     r1, lr
633         stmia   r5, {r0 - r4}                   /* save sp_SVC, lr_SVC, pc, cpsr, old_r */
634         mov     r0, sp
635         .endm
636
637
638         /* use irq_save_user_regs / irq_restore_user_regs for                */
639         /* IRQ/FIQ handling                                                  */
640
641         .macro  irq_save_user_regs
642         sub     sp, sp, #S_FRAME_SIZE
643         stmia   sp, {r0 - r12}                  /* Calling r0-r12            */
644         add     r8, sp, #S_PC
645         stmdb   r8, {sp, lr}^                   /* Calling SP, LR            */
646         str     lr, [r8, #0]                    /* Save calling PC           */
647         mrs     r6, spsr
648         str     r6, [r8, #4]                    /* Save CPSR                 */
649         str     r0, [r8, #8]                    /* Save OLD_R0               */
650         mov     r0, sp
651         .endm
652
653         .macro  irq_restore_user_regs
654         ldmia   sp, {r0 - lr}^                  @ Calling r0 - lr
655         mov     r0, r0
656         ldr     lr, [sp, #S_PC]                 @ Get PC
657         add     sp, sp, #S_FRAME_SIZE
658         subs    pc, lr, #4                      @ return & move spsr_svc into cpsr
659         .endm
660
661         .macro get_bad_stack
662 #if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
663         ldr     r13, _armboot_start             @ setup our mode stack
664         sub     r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
665         sub     r13, r13, #(GENERATED_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack
666 #else
667         ldr     r13, IRQ_STACK_START_IN         @ setup our mode stack
668 #endif
669
670         str     lr, [r13]                       @ save caller lr / spsr
671         mrs     lr, spsr
672         str     lr, [r13, #4]
673
674         mov     r13, #MODE_SVC                  @ prepare SVC-Mode
675         msr     spsr_c, r13
676         mov     lr, pc
677         movs    pc, lr
678         .endm
679
680         .macro get_irq_stack                    @ setup IRQ stack
681         ldr     sp, IRQ_STACK_START
682         .endm
683
684         .macro get_fiq_stack                    @ setup FIQ stack
685         ldr     sp, FIQ_STACK_START
686         .endm
687
688
689 /****************************************************************************/
690 /*                                                                          */
691 /* exception handlers                                                       */
692 /*                                                                          */
693 /****************************************************************************/
694
695         .align  5
696 undefined_instruction:
697         get_bad_stack
698         bad_save_user_regs
699         bl      do_undefined_instruction
700
701         .align  5
702 software_interrupt:
703         get_bad_stack
704         bad_save_user_regs
705         bl      do_software_interrupt
706
707         .align  5
708 prefetch_abort:
709         get_bad_stack
710         bad_save_user_regs
711         bl      do_prefetch_abort
712
713         .align  5
714 data_abort:
715         get_bad_stack
716         bad_save_user_regs
717         bl      do_data_abort
718
719         .align  5
720 not_used:
721         get_bad_stack
722         bad_save_user_regs
723         bl      do_not_used
724
725 #ifdef CONFIG_USE_IRQ
726
727         .align  5
728 irq:
729         get_irq_stack
730         irq_save_user_regs
731         bl      do_irq
732         irq_restore_user_regs
733
734         .align  5
735 fiq:
736         get_fiq_stack
737         irq_save_user_regs              /* someone ought to write a more    */
738         bl      do_fiq                  /* effiction fiq_save_user_regs     */
739         irq_restore_user_regs
740
741 #else
742
743         .align  5
744 irq:
745         get_bad_stack
746         bad_save_user_regs
747         bl      do_irq
748
749         .align  5
750 fiq:
751         get_bad_stack
752         bad_save_user_regs
753         bl      do_fiq
754
755 #endif
756
757 /****************************************************************************/
758 /*                                                                          */
759 /* Reset function: Use Watchdog to reset                                    */
760 /*                                                                          */
761 /****************************************************************************/
762
763         .align  5
764 .globl reset_cpu
765
766 reset_cpu:
767         ldr     r1, =0x482e
768         ldr     r2, =IXP425_OSWK
769         str     r1, [r2]
770         ldr     r1, =0x0fff
771         ldr     r2, =IXP425_OSWT
772         str     r1, [r2]
773         ldr     r1, =0x5
774         ldr     r2, =IXP425_OSWE
775         str     r1, [r2]
776         b       reset_endless
777
778
779 reset_endless:
780
781         b       reset_endless
782
783 #ifdef CONFIG_USE_IRQ
784
785 .LC0:           .word   loops_per_jiffy
786
787 /*
788  * 0 <= r0 <= 2000
789  */
790 .globl __udelay
791 __udelay:
792         mov     r2,     #0x6800
793         orr     r2, r2, #0x00db
794         mul     r0, r2, r0
795         ldr     r2, .LC0
796         ldr     r2, [r2]                @ max = 0x0fffffff
797         mov     r0, r0, lsr #11         @ max = 0x00003fff
798         mov     r2, r2, lsr #11         @ max = 0x0003ffff
799         mul     r0, r2, r0              @ max = 2^32-1
800         movs    r0, r0, lsr #6
801
802 delay_loop:
803         subs    r0, r0, #1
804         bne     delay_loop
805         mov     pc, lr
806
807 #endif /* CONFIG_USE_IRQ */