source: rtems/cpukit/score/cpu/arm/arm_exc_interrupt.S @ 9b2e7143

4.115
Last change on this file since 9b2e7143 was c5ed148, checked in by Sebastian Huber <sebastian.huber@…>, on 09/24/11 at 12:56:51

2011-09-24 Sebastian Huber <sebastian.huber@…>

  • rtems/score/armv7m.h, armv7m-context-initialize.c, armv7m-context-restore.c, armv7m-context-switch.c, armv7m-exception-handler-get.c, armv7m-exception-handler-set.c, armv7m-exception-priority-get.c, armv7m-exception-priority-set.c, armv7m-initialize.c, armv7m-isr-dispatch.c, armv7m-isr-enter-leave.c, armv7m-isr-level-get.c, armv7m-isr-level-set.c, armv7m-isr-vector-install.c, armv7m-multitasking-start-stop.c: New files.
  • Makefile.am, preinstall.am: Reflect changes above.
  • rtems/score/arm.h: Define ARM_MULTILIB_ARCH_V4 and ARM_MULTILIB_ARCH_V7M.
  • rtems/score/cpu.h, cpu_asm.S, cpu.c, arm_exc_abort.S, arm_exc_handler_high.c, arm_exc_handler_low.S, arm_exc_interrupt.S: Define CPU_HAS_HARDWARE_INTERRUPT_STACK to FALSE. Use ARM_MULTILIB_ARCH_V4 and ARM_MULTILIB_ARCH_V7M.
  • Property mode set to 100644
File size: 3.9 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup ScoreCPU
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#include <rtems/score/percpu.h>
34
35#ifdef ARM_MULTILIB_ARCH_V4
36
37#define EXCHANGE_LR r4
38#define EXCHANGE_SPSR r5
39#define EXCHANGE_CPSR r6
40#define EXCHANGE_INT_SP r7
41
42#define EXCHANGE_LIST {EXCHANGE_LR, EXCHANGE_SPSR, EXCHANGE_CPSR, EXCHANGE_INT_SP}
43#define EXCHANGE_SIZE 16
44
45#define CONTEXT_LIST {r0, r1, r2, r3, EXCHANGE_LR, EXCHANGE_SPSR, r12}
46#define CONTEXT_SIZE 28
47
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, =DISPATCH_NEEDED
128        ldrb    r1, [r0]
129        cmp     r1, #0
130        beq     thread_dispatch_done
131
132        /* This aligns thread_dispatch_done on a 4 byte boundary */
133#ifdef __thumb__
134        nop
135#endif /* __thumb__ */
136
137do_thread_dispatch:
138
139        /* Thread dispatch */
140        bl      _Thread_Dispatch
141
142thread_dispatch_done:
143
144        /* Switch to ARM instructions if necessary */
145        SWITCH_FROM_THUMB_TO_ARM
146
147        /* Restore link register */
148        ldmia   sp!, {lr}
149
150        /*
151         * XXX: Remember and restore stack pointer.  The data on the stack is
152         * still in use.  So the stack is now in an inconsistent state.  The
153         * FIQ handler implementation must not use this area.
154         */
155        mov     r0, sp
156        add     sp, #CONTEXT_SIZE
157
158        /* Get INT mode program status register */
159        mrs     r1, cpsr
160        bic     r1, r1, #0x1
161
162        /* Switch to INT mode */
163        msr     cpsr, r1
164
165        /* Save EXCHANGE_LR and EXCHANGE_SPSR registers to exchange area */
166        stmdb   sp!, {EXCHANGE_LR, EXCHANGE_SPSR}
167
168        /* Restore context */
169        ldmia   r0, CONTEXT_LIST
170
171        /* Set return address and program status */
172        mov     lr, EXCHANGE_LR
173        msr     spsr, EXCHANGE_SPSR
174
175        /* Restore EXCHANGE_LR and EXCHANGE_SPSR registers from exchange area */
176        ldmia   sp!, {EXCHANGE_LR, EXCHANGE_SPSR}
177
178        /* Return from interrupt */
179        subs    pc, lr, #4
180
181#endif /* ARM_MULTILIB_ARCH_V4 */
Note: See TracBrowser for help on using the repository browser.