source: rtems/cpukit/score/cpu/arm/arm_exc_handler_low.S @ 13c5cea

4.104.115
Last change on this file since 13c5cea was 5e61c80, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on 09/18/09 at 08:07:23
  • rtems/score/cpu.h: Fix for inline asm in _CPU_Fatal_halt().
  • rtems/asm.h: Added macro to define ARM functions.
  • cpu_asm.S, arm_exc_handler_low.S: Use macro from above.
  • Property mode set to 100644
File size: 4.1 KB
Line 
1/**
2 * @file
3 *
4 * ARM exception support code.
5 */
6
7/*
8 *  $Id$
9 *
10 *  Copyright (c) 2007 by Ray Xu, <Rayx.cn@gmail.com>
11 *          Thumb support added.
12 *
13 *  Copyright (c) 2002 by Advent Networks, Inc.
14 *          Jay Monkman <jmonkman@adventnetworks.com>
15 *
16 *  COPYRIGHT (c) 2000 Canon Research Centre France SA.
17 *  Emmanuel Raguet, mailto:raguet@crf.canon.fr
18 *
19 *  The license and distribution terms for this file may be
20 *  found in the file LICENSE in this distribution or at
21 *  http://www.rtems.com/license/LICENSE.
22 *
23 *  Moved from file 'cpukit/score/cpu/arm/cpu_asm.S'.
24 *
25 */
26
27#include <rtems/asm.h>
28#include <rtems/score/cpu_asm.h>
29
30        .text
31
32/* FIXME:       _Exception_Handler_Undef_Swi is untested */
33DEFINE_FUNCTION_ARM(_Exception_Handler_Undef_Swi)
34/* FIXME: This should use load and store multiple instructions */
35        sub     r13,r13,#SIZE_REGS
36        str     r4,  [r13, #REG_R4]
37        str     r5,  [r13, #REG_R5]
38        str     r6,  [r13, #REG_R6]
39        str     r7,  [r13, #REG_R7]
40        str     r8,  [r13, #REG_R8]
41        str     r9,  [r13, #REG_R9]
42        str     r10, [r13, #REG_R10]
43        str     r11, [r13, #REG_R11]
44        str     sp,  [r13, #REG_SP]
45        str     lr,  [r13, #REG_LR]
46        mrs     r0,  cpsr               /* read the status */
47        and     r0,  r0,#0x1f           /* we keep the mode as exception number */
48        str     r0,  [r13, #REG_PC]     /* we store it in a free place */
49        mov     r0,  r13                /* put frame address in r0 (C arg 1) */
50
51        ldr     r1, =SWI_Handler
52        ldr     lr, =_go_back_1
53        ldr     pc,[r1]                         /* call handler  */
54_go_back_1:
55        ldr     r4,  [r13, #REG_R4]
56        ldr     r5,  [r13, #REG_R5]
57        ldr     r6,  [r13, #REG_R6]
58        ldr     r7,  [r13, #REG_R7]
59        ldr     r8,  [r13, #REG_R8]
60        ldr     r9,  [r13, #REG_R9]
61        ldr     r10, [r13, #REG_R10]
62        ldr     r11, [r13, #REG_R11]
63        ldr     sp,  [r13, #REG_SP]
64        ldr     lr,  [r13, #REG_LR]
65        add     r13,r13,#SIZE_REGS
66        movs    pc,r14                  /* return  */
67       
68/* FIXME:       _Exception_Handler_Abort is untested */
69DEFINE_FUNCTION_ARM(_Exception_Handler_Abort)
70/* FIXME: This should use load and store multiple instructions */
71        sub     r13,r13,#SIZE_REGS
72        str     r4,  [r13, #REG_R4]
73        str     r5,  [r13, #REG_R5]
74        str     r6,  [r13, #REG_R6]
75        str     r7,  [r13, #REG_R7]
76        str     r8,  [r13, #REG_R8]
77        str     r9,  [r13, #REG_R9]
78        str     sp,  [r13, #REG_R11]
79        str     lr,  [r13, #REG_SP]
80        str     lr,  [r13, #REG_LR]
81        mrs     r0,  cpsr               /* read the status */
82        and     r0,  r0,#0x1f           /* we keep the mode as exception number */
83        str     r0,  [r13, #REG_PC]     /* we store it in a free place */
84        mov     r0,  r13                /* put frame address in ro (C arg 1) */
85       
86        ldr     r1, =_currentExcHandler
87        ldr     lr, =_go_back_2
88        ldr     pc,[r1]                         /* call handler  */
89_go_back_2:
90        ldr     r4,  [r13, #REG_R4]
91        ldr     r5,  [r13, #REG_R5]
92        ldr     r6,  [r13, #REG_R6]
93        ldr     r7,  [r13, #REG_R7]
94        ldr     r8,  [r13, #REG_R8]
95        ldr     r9,  [r13, #REG_R9]
96        ldr     r10, [r13, #REG_R10]
97        ldr     sp,  [r13, #REG_R11]
98        ldr     lr,  [r13, #REG_SP]
99        ldr     lr,  [r13, #REG_LR]
100        add     r13,r13,#SIZE_REGS
101#ifdef  __thumb__
102        subs    r11, r14,#4
103        bx      r11
104        nop
105#else
106        subs    pc,r14,#4                       /* return */
107#endif
108
109#define ABORT_REGS_OFFS 32-REG_R4
110#define ABORT_SIZE_REGS SIZE_REGS+ABORT_REGS_OFFS
111       
112DEFINE_FUNCTION_ARM(_exc_data_abort)
113        sub     sp, sp, #ABORT_SIZE_REGS        /* reserve register frame */
114        stmia   sp, {r0-r11}
115        add     sp, sp, #ABORT_REGS_OFFS        /* the Context_Control structure starts by CPSR, R4, ... */
116
117        str     ip, [sp, #REG_PC]               /* store R12 (ip) somewhere, oh hackery, hackery, hack */
118        str     lr, [sp, #REG_LR]
119
120        mov     r1, lr
121        ldr     r0, [r1, #-8]                   /* r0 = bad instruction */
122        mrs     r1, spsr                        /* r1 = spsr */
123        mov     r2, r13                         /* r2 = exception frame of Context_Control type */
124#if defined(__thumb__)
125        .code 32
126        /*arm to thumb*/
127        adr     r5, to_thumb + 1
128        bx      r5
129        .code 16
130to_thumb:       
131#endif 
132        bl      do_data_abort
133#if defined(__thumb__)
134/*back to arm*/         
135        .code 16
136thumb_to_arm:
137        .align 2
138        adr r5, arm_code
139        bx      r5
140        nop
141        .code 32
142arm_code:
143#endif
144       
145        ldr     lr, [sp, #REG_LR]
146        ldr     ip, [sp, #REG_PC]               /* restore R12 (ip) */
147
148        sub     sp, sp, #ABORT_REGS_OFFS
149        ldmia   sp, {r0-r11}
150        add     sp, sp, #ABORT_SIZE_REGS
151#ifdef  __thumb__
152        subs    r11, r14, #4                    /* return to the instruction */
153        bx      r11
154        nop
155#else
156        subs    pc, r14, #4
157#endif
158                                                /* _AFTER_ the aborted one */
Note: See TracBrowser for help on using the repository browser.