source: rtems/cpukit/score/cpu/arm/arm_exc_interrupt.S @ 199041aa

4.104.115
Last change on this file since 199041aa was 0acc9af3, checked in by Joel Sherrill <joel.sherrill@…>, on 03/27/10 at 15:01:19

2010-03-27 Joel Sherrill <joel.sherrill@…>

  • arm_exc_abort.S, arm_exc_handler_high.c, arm_exc_handler_low.S, arm_exc_interrupt.S, cpu.c, cpu_asm.S: Add include of config.h
  • Property mode set to 100644
File size: 4.1 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup arm
5 *
6 * @brief ARM interrupt exception prologue and epilogue.
7 */
8
9/*
10 * Copyright (c) 2009
11 * embedded brains GmbH
12 * Obere Lagerstr. 30
13 * D-82178 Puchheim
14 * Germany
15 * <rtems@embedded-brains.de>
16 *
17 * The license and distribution terms for this file may be
18 * found in the file LICENSE in this distribution or at
19 * http://www.rtems.com/license/LICENSE.
20 */
21
22/*
23 * The upper EXCHANGE_SIZE bytes of the INT stack area are used for data
24 * exchange between INT and SVC mode.  Below of this is the actual INT stack.
25 * The exchange area is only accessed if INT is disabled.
26 */
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <rtems/asm.h>
33
34#define EXCHANGE_LR r4
35#define EXCHANGE_SPSR r5
36#define EXCHANGE_CPSR r6
37#define EXCHANGE_INT_SP r7
38
39#define EXCHANGE_LIST {EXCHANGE_LR, EXCHANGE_SPSR, EXCHANGE_CPSR, EXCHANGE_INT_SP}
40#define EXCHANGE_SIZE 16
41
42#define CONTEXT_LIST {r0, r1, r2, r3, EXCHANGE_LR, EXCHANGE_SPSR, r12}
43#define CONTEXT_SIZE 28
44
45.extern _ISR_Nest_level
46.extern _ISR_Signals_to_thread_executing
47.extern _ISR_Thread_dispatch
48.extern _Thread_Dispatch_disable_level
49
50.extern bsp_interrupt_dispatch
51
52.arm
53.globl arm_exc_interrupt
54arm_exc_interrupt:
55
56        /* Save exchange registers to exchange area */
57        stmdb   sp, EXCHANGE_LIST
58
59        /* Set exchange registers */
60        mov     EXCHANGE_LR, lr
61        mrs     EXCHANGE_SPSR, spsr
62        mrs     EXCHANGE_CPSR, cpsr
63        sub     EXCHANGE_INT_SP, sp, #EXCHANGE_SIZE
64
65        /* Switch to SVC mode */
66        orr     EXCHANGE_CPSR, EXCHANGE_CPSR, #0x1
67        msr     cpsr, EXCHANGE_CPSR
68
69        /*
70         * Save context.  We save the LR separately because it has to be
71         * restored in SVC mode.  The other registers can be restored in INT
72         * mode.
73         */
74        stmdb   sp!, CONTEXT_LIST
75        stmdb   sp!, {lr}
76
77        /* Remember INT stack pointer */
78        mov     r1, EXCHANGE_INT_SP
79
80        /* Restore exchange registers from exchange area */
81        ldmia   r1, EXCHANGE_LIST
82
83        /* Get interrupt nest level */
84        ldr     r0, =_ISR_Nest_level
85        ldr     r2, [r0]
86
87        /* Switch stack if necessary and save original stack pointer */
88        mov     r3, sp
89        cmp     r2, #0
90        moveq   sp, r1
91        stmdb   sp!, {r3}
92
93        /* Switch to THUMB instructions if necessary */
94        SWITCH_FROM_ARM_TO_THUMB        r1
95
96        /* Increment interrupt nest and thread dispatch disable level */
97        ldr     r1, =_Thread_Dispatch_disable_level
98        ldr     r3, [r1]
99        add     r2, #1
100        add     r3, #1
101        str     r2, [r0]
102        str     r3, [r1]
103
104        /* Call BSP dependent interrupt dispatcher */
105        bl      bsp_interrupt_dispatch
106
107        /* Decrement interrupt nest and thread dispatch disable level */
108        ldr     r0, =_ISR_Nest_level
109        ldr     r1, =_Thread_Dispatch_disable_level
110        ldr     r2, [r0]
111        ldr     r3, [r1]
112        sub     r2, #1
113        sub     r3, #1
114        str     r2, [r0]
115        str     r3, [r1]
116
117        /* Restore stack pointer */
118        SWITCH_FROM_THUMB_TO_ARM
119        ldr     sp, [sp]
120        SWITCH_FROM_ARM_TO_THUMB        r0
121
122        /* Check thread dispatch disable level */
123        cmp     r3, #0
124        bne     thread_dispatch_done
125
126        /* Check context switch necessary */
127        ldr     r0, =_Context_Switch_necessary
128        ldrb    r1, [r0]
129        ldr     r0, =_ISR_Signals_to_thread_executing
130        cmp     r1, #0
131        bne     do_thread_dispatch
132
133        /* Check ISR signals to thread executing */
134        ldrb    r1, [r0]
135        cmp     r1, #0
136        beq     thread_dispatch_done
137
138        /* This aligns thread_dispatch_done on a 4 byte boundary */
139#ifdef __thumb__
140        nop
141#endif /* __thumb__ */
142
143do_thread_dispatch:
144
145        /* Clear ISR signals to thread executing */
146        strb    r3, [r0]
147
148        /* Thread dispatch */
149        bl      _Thread_Dispatch
150
151thread_dispatch_done:
152
153        /* Switch to ARM instructions if necessary */
154        SWITCH_FROM_THUMB_TO_ARM
155
156        /* Restore link register */
157        ldmia   sp!, {lr}
158
159        /*
160         * XXX: Remember and restore stack pointer.  The data on the stack is
161         * still in use.  So the stack is now in an inconsistent state.  The
162         * FIQ handler implementation must not use this area.
163         */
164        mov     r0, sp
165        add     sp, #CONTEXT_SIZE
166
167        /* Get INT mode program status register */
168        mrs     r1, cpsr
169        bic     r1, r1, #0x1
170
171        /* Switch to INT mode */
172        msr     cpsr, r1
173
174        /* Save EXCHANGE_LR and EXCHANGE_SPSR registers to exchange area */
175        stmdb   sp!, {EXCHANGE_LR, EXCHANGE_SPSR}
176
177        /* Restore context */
178        ldmia   r0, CONTEXT_LIST
179
180        /* Set return address and program status */
181        mov     lr, EXCHANGE_LR
182        msr     spsr, EXCHANGE_SPSR
183
184        /* Restore EXCHANGE_LR and EXCHANGE_SPSR registers from exchange area */
185        ldmia   sp!, {EXCHANGE_LR, EXCHANGE_SPSR}
186
187        /* Return from interrupt */
188        subs    pc, lr, #4
Note: See TracBrowser for help on using the repository browser.