source: rtems/cpukit/score/cpu/arm/cpu_asm.S @ d0279f6e

4.9
Last change on this file since d0279f6e was a3ff693, checked in by Joel Sherrill <joel.sherrill@…>, on Nov 26, 2007 at 7:59:17 PM

2007-11-26 Ray Xu <rayx.cn@…>

  • cpu.c, score/cpu.h: Fix headers. Remove extra inline definition.
  • cpu_asm.S: Note origin of Thumb support.
  • Property mode set to 100644
File size: 5.5 KB
Line 
1/*
2 *  $Id$
3 *
4 *  This file contains all assembly code for the ARM implementation
5 *  of RTEMS.
6 *
7 *  Copyright (c) 2007 by Ray Xu, <Rayx.cn@gmail.com>
8 *          Thumb support added.
9 *
10 *  Copyright (c) 2002 by Advent Networks, Inc.
11 *          Jay Monkman <jmonkman@adventnetworks.com>
12 *
13 *  COPYRIGHT (c) 2000 Canon Research Centre France SA.
14 *  Emmanuel Raguet, mailto:raguet@crf.canon.fr
15 *
16 *  The license and distribution terms for this file may be
17 *  found in the file LICENSE in this distribution or at
18 *  http://www.rtems.com/license/LICENSE.
19 *
20 */
21
22#include <rtems/asm.h>
23#include <rtems/score/cpu_asm.h>
24
25/*
26 *  function declaration macro (start body in ARM mode)
27 */
28#ifdef __thumb__
29  #define FUNC_START_ARM(_name_)              \
30    .code   16                              ;\
31    .thumb_func                             ;\
32    .globl _name_                           ;\
33_name_:                                         ;\
34     bx      pc                              ;\
35     .code   32                              ;\
36_name_ ## _ARM:
37#else
38  #define FUNC_START_ARM(_name_) \
39     .globl _name_; \
40_name_:
41#endif
42
43        .text
44
45/*
46 *  void _CPU_Context_switch( run_context, heir_context )
47 *  void _CPU_Context_restore( run_context, heir_context )
48 *
49 *  This routine performs a normal non-FP context.
50 *
51 *  R0 = run_context    R1 = heir_context
52 *
53 *  This function copies the current registers to where r0 points, then
54 *  restores the ones from where r1 points.
55 *
56 *  Using the ldm/stm opcodes save 2-3 us on 100 MHz ARM9TDMI with
57 *  a 16 bit data bus.
58 *       
59 */
60 
61FUNC_START_ARM(_CPU_Context_switch)
62/* Start saving context */
63        mrs     r2, cpsr
64        stmia   r0,  {r2, r4, r5, r6, r7, r8, r9, r10, r11, r13, r14}
65
66
67/* Start restoring context */
68_restore:       
69        ldmia   r1,  {r2, r4, r5, r6, r7, r8, r9, r10, r11, r13, r14}
70        msr     cpsr, r2
71#ifdef __thumb__
72        bx      lr
73        nop
74#else
75        mov     pc, lr
76#endif
77/*
78 *  void _CPU_Context_restore( new_context )
79 *
80 *  This function copies the restores the registers from where r0 points.
81 *  It must match _CPU_Context_switch()
82 *
83 */
84FUNC_START_ARM(_CPU_Context_restore)
85        mov     r1, r0
86        b       _restore
87
88
89
90/* FIXME:       _Exception_Handler_Undef_Swi is untested */
91FUNC_START_ARM(_Exception_Handler_Undef_Swi)
92/* FIXME: This should use load and store multiple instructions */
93        sub     r13,r13,#SIZE_REGS
94        str     r4,  [r13, #REG_R4]
95        str     r5,  [r13, #REG_R5]
96        str     r6,  [r13, #REG_R6]
97        str     r7,  [r13, #REG_R7]
98        str     r8,  [r13, #REG_R8]
99        str     r9,  [r13, #REG_R9]
100        str     r10, [r13, #REG_R10]
101        str     r11, [r13, #REG_R11]
102        str     sp,  [r13, #REG_SP]
103        str     lr,  [r13, #REG_LR]
104        mrs     r0,  cpsr               /* read the status */
105        and     r0,  r0,#0x1f           /* we keep the mode as exception number */
106        str     r0,  [r13, #REG_PC]     /* we store it in a free place */
107        mov     r0,  r13                /* put frame address in r0 (C arg 1) */
108
109        ldr     r1, =SWI_Handler
110        ldr     lr, =_go_back_1
111        ldr     pc,[r1]                         /* call handler  */
112_go_back_1:
113        ldr     r4,  [r13, #REG_R4]
114        ldr     r5,  [r13, #REG_R5]
115        ldr     r6,  [r13, #REG_R6]
116        ldr     r7,  [r13, #REG_R7]
117        ldr     r8,  [r13, #REG_R8]
118        ldr     r9,  [r13, #REG_R9]
119        ldr     r10, [r13, #REG_R10]
120        ldr     r11, [r13, #REG_R11]
121        ldr     sp,  [r13, #REG_SP]
122        ldr     lr,  [r13, #REG_LR]
123        add     r13,r13,#SIZE_REGS
124        movs    pc,r14                  /* return  */
125       
126/* FIXME:       _Exception_Handler_Abort is untested */
127FUNC_START_ARM(_Exception_Handler_Abort)
128/* FIXME: This should use load and store multiple instructions */
129        sub     r13,r13,#SIZE_REGS
130        str     r4,  [r13, #REG_R4]
131        str     r5,  [r13, #REG_R5]
132        str     r6,  [r13, #REG_R6]
133        str     r7,  [r13, #REG_R7]
134        str     r8,  [r13, #REG_R8]
135        str     r9,  [r13, #REG_R9]
136        str     sp,  [r13, #REG_R11]
137        str     lr,  [r13, #REG_SP]
138        str     lr,  [r13, #REG_LR]
139        mrs     r0,  cpsr               /* read the status */
140        and     r0,  r0,#0x1f           /* we keep the mode as exception number */
141        str     r0,  [r13, #REG_PC]     /* we store it in a free place */
142        mov     r0,  r13                /* put frame address in ro (C arg 1) */
143       
144        ldr     r1, =_currentExcHandler
145        ldr     lr, =_go_back_2
146        ldr     pc,[r1]                         /* call handler  */
147_go_back_2:
148        ldr     r4,  [r13, #REG_R4]
149        ldr     r5,  [r13, #REG_R5]
150        ldr     r6,  [r13, #REG_R6]
151        ldr     r7,  [r13, #REG_R7]
152        ldr     r8,  [r13, #REG_R8]
153        ldr     r9,  [r13, #REG_R9]
154        ldr     r10, [r13, #REG_R10]
155        ldr     sp,  [r13, #REG_R11]
156        ldr     lr,  [r13, #REG_SP]
157        ldr     lr,  [r13, #REG_LR]
158        add     r13,r13,#SIZE_REGS
159#ifdef  __thumb__
160        subs    r11, r14,#4
161        bx      r11
162        nop
163#else
164        subs    pc,r14,#4                       /* return */
165#endif
166
167#define ABORT_REGS_OFFS 32-REG_R4
168#define ABORT_SIZE_REGS SIZE_REGS+ABORT_REGS_OFFS
169       
170FUNC_START_ARM(_exc_data_abort)
171        sub     sp, sp, #ABORT_SIZE_REGS        /* reserve register frame */
172        stmia   sp, {r0-r11}
173        add     sp, sp, #ABORT_REGS_OFFS        /* the Context_Control structure starts by CPSR, R4, ... */
174
175        str     ip, [sp, #REG_PC]               /* store R12 (ip) somewhere, oh hackery, hackery, hack */
176        str     lr, [sp, #REG_LR]
177
178        mov     r1, lr
179        ldr     r0, [r1, #-8]                   /* r0 = bad instruction */
180        mrs     r1, spsr                        /* r1 = spsr */
181        mov     r2, r13                         /* r2 = exception frame of Context_Control type */
182#if defined(__thumb__)
183        .code 32
184        /*arm to thumb*/
185        adr     r5, to_thumb + 1
186        bx      r5
187        .code 16
188to_thumb:       
189#endif 
190        bl      do_data_abort
191#if defined(__thumb__)
192/*back to arm*/         
193        .code 16
194thumb_to_arm:
195        .align 2
196        adr r5, arm_code
197        bx      r5
198        nop
199        .code 32
200arm_code:
201#endif
202       
203        ldr     lr, [sp, #REG_LR]
204        ldr     ip, [sp, #REG_PC]               /* restore R12 (ip) */
205
206        sub     sp, sp, #ABORT_REGS_OFFS
207        ldmia   sp, {r0-r11}
208        add     sp, sp, #ABORT_SIZE_REGS
209#ifdef  __thumb__
210        subs    r11, r14, #4                    /* return to the instruction */
211        bx      r11
212        nop
213#else
214        subs    pc, r14, #4
215#endif
216                                                /* _AFTER_ the aborted one */
Note: See TracBrowser for help on using the repository browser.