source: rtems/c/src/lib/libbsp/arm/gba/irq/irq_asm.S @ 92ce6ac

4.9
Last change on this file since 92ce6ac was 92ce6ac, checked in by Joel Sherrill <joel.sherrill@…>, on 03/12/09 at 14:17:29

2009-03-12 Joel Sherrill <joel.sherrill@…>

PR 1385/cpukit

  • irq/irq_asm.S: When the type rtems_boolean was switched to the C99 bool, the size changed from 4 bytes to 1 byte. The interrupt dispatching code accesses two boolean variables for scheduling purposes and the assembly implementations of this code did not get updated.
  • Property mode set to 100644
File size: 5.9 KB
Line 
1/**
2 *  @file irq_asm.S
3 *
4 *  This file contains the implementation of the IRQ handler.
5 */
6/*
7 *  RTEMS GBA BSP
8 *
9 *  Copyright (c) 2002 Advent Networks, Inc.
10 *      Jay Monkman <jmonkman@adventnetworks.com>
11 *
12 *  Copyright (C) 2000 Canon Research France SA.
13 *      Emmanuel Raguet,  mailto:raguet@crf.canon.fr
14 *
15 *  Modified Andy Dachs <a.dachs@sstl.co.uk>
16 *  Copyright (c) 2001 Surrey Satellite Technolgy Limited
17 *
18 *  Modified Markku Puro <markku.puro@kopteri.net>
19 *      Copyright (c) 2004
20 *
21 *  The license and distribution terms for this file may be
22 *  found in found in the file LICENSE in this distribution or at
23 *  http://www.rtems.com/license/LICENSE.
24 *
25 *  $Id$
26 */
27
28#define __asm__
29#include <rtems/asm.h>
30#include <asm_macros.h>
31#include <arm_mode_bits.h>
32/* @cond  INCLUDE_ASM */
33
34/**
35 *  Interrupt handler
36 *  function void _ISR_Handler(void)
37 *
38 */
39    .align
40/*    .section  .iwram */
41
42PUBLIC_ARM_FUNCTION(_ISR_Handler)
43        stmdb   sp!, {r0, r1, r2, r3, r12}  /* save regs on INT stack   */
44        stmdb   sp!, {lr}                   /* now safe to call C funcs */
45
46
47/* one nest level deeper */
48        ldr     r0, =_ISR_Nest_level
49        ldr     r1, [r0]
50        add     r1, r1,#1
51        str     r1, [r0]
52
53/* disable multitasking */
54        ldr     r0, =_Thread_Dispatch_disable_level
55        ldr     r1, [r0]
56        add     r1, r1,#1
57        str     r1, [r0]
58
59/* BSP specific function to INT handler */
60        bl      ExecuteITHandler
61
62/* one less nest level  */
63        ldr     r0, =_ISR_Nest_level
64        ldr     r1, [r0]
65        sub     r1, r1,#1
66        str     r1, [r0]
67
68/* unnest multitasking */
69        ldr     r0, =_Thread_Dispatch_disable_level
70        ldr     r1, [r0]
71        sub     r1, r1,#1
72        str     r1, [r0]
73
74/* check to see if we interrupted (no FIQ in GBA) */
75        mrs   r0, spsr
76        and   r0, r0, #Mode_Bits
77        cmp   r0, #Mode_IRQ       /* is it INT mode? */
78        beq   exitit
79
80/* If thread dispatching is disabled, exit */
81        cmp     r1, #0
82        bne     exitit
83
84/* If a task switch is necessary, call scheduler */
85        ldr     r0, =_Context_Switch_necessary
86        ldrb    r1, [r0]
87        cmp     r1, #0
88
89        /* since bframe is going to clear _ISR_Signals_to_thread_executing, */
90        /*    we need to load it here */
91        ldr     r0, =_ISR_Signals_to_thread_executing
92        ldrb    r1, [r0]
93        bne     bframe
94
95/* If a signals to be sent (_ISR_Signals_to_thread_executing != 0),        */
96/*  call scheduler */
97        cmp     r1, #0
98        beq     exitit
99
100/* _ISR_Signals_to_thread_executing = FALSE */
101        mov     r1, #0
102        strb    r1, [r0]
103
104bframe:
105/* Now we need to set up the return from this ISR to be _ISR_Dispatch */
106/* To do that, we need to save the current lr_int and spsr_int on the */
107/* SVC stack                                                          */
108        mrs     r0, spsr
109        ldmia   sp!, {r1}         /* get lr off stack */
110        stmdb   sp!, {r1}
111        mrs     r2, cpsr
112        bic     r3, r2, #Mode_Bits
113        orr     r3, r3, #ModePriv /* change to SVC mode */
114        msr     cpsr_c, r3
115
116        /* now in SVC mode */
117        stmdb   sp!, {r0, r1}   /* put spsr_int and lr_int on SVC stack */
118        msr     cpsr_c, r2      /* change back to INT mode */
119
120        /* now in INT mode */
121
122        /* replace lr with address of _ISR_Dispatch */
123        ldr     lr, =_ISR_Dispatch_p_4    /* On entry to an ISR, the lr is */
124                                          /*    the return address + 4, so */
125                                          /*    we have to emulate that    */
126        ldmia   sp!, {r1}                 /* out with the old          */
127        stmdb   sp!, {lr}                 /*    in with the new (lr) */
128
129
130        orr     r0, r0, #Int_Bits
131        msr     spsr, r0
132
133exitit:
134        ldmia   sp!, {lr}                     /* restore regs from INT stack */
135        ldmia   sp!, {r0, r1, r2, r3, r12}    /* restore regs from INT stack */
136        subs    pc, lr , #4                   /* return */
137LABEL_END(_ISR_Handler)
138
139        /* on entry to _ISR_Dispatch, we're in SVC mode */
140PUBLIC_ARM_FUNCTION(_ISR_Dispatch)
141        stmdb   sp!, {r0-r3, r12,lr}      /* save regs on SVC stack */
142                                          /*    (now safe to call C funcs) */
143                                          /*    we don't save lr, since  */
144                                          /*    it's just going to get   */
145                                          /*    overwritten              */
146_ISR_Dispatch_p_4:
147        bl      _Thread_Dispatch
148        ldmia   sp!, {r0-r3, r12, lr}
149
150        stmdb   sp!, {r0-r2}
151        /* Now we have to screw with the stack */
152        mov     r0, sp                  /* copy the SVC stack pointer */
153
154        mrs     r1, cpsr
155        bic     r2, r1, #Mode_Bits              /* clear mode bits    */
156        orr     r2, r2, #(Mode_IRQ | Int_Bits)  /* change to INT mode */
157        msr     cpsr_c, r2                      /* disable interrupts */
158
159        /* now in INT mode */
160        stmdb   sp!, {r4, r5, r6}   /* save temp vars on INT stack */
161        ldmia   r0!, {r4, r5, r6}   /* Get r0-r3 from SVC stack */
162        stmdb   sp!, {r4, r5, r6}   /*    and save them on INT stack */
163
164        ldmia   r0!, {r4, r5}           /* get saved values from SVC stack */
165                                        /*      r4=spsr, r5=lr */
166        mov     lr,   r5                /* restore lr_int */
167        msr     spsr, r4                /* restore spsr_int */
168
169        /* switch to SVC mode, update sp, then return to INT mode */
170        msr     cpsr_c, r1              /* switch to SVC mode */
171        mov     sp, r0                  /* update sp_svc */
172        msr     cpsr_c, r2              /* switch back to INT mode */
173
174        /* pop all the registers from the stack */
175        ldmia   sp!, {r0, r1, r2}
176        ldmia   sp!, {r4, r5, r6}
177
178        /* Finally, we can return to the interrupted task */
179        subs    pc, lr, #4
180
181LABEL_END(_ISR_Dispatch)
182/* @endcond */
183
Note: See TracBrowser for help on using the repository browser.