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

4.104.114.95
Last change on this file since 661e5de4 was 661e5de4, checked in by Joel Sherrill <joel.sherrill@…>, on 11/06/07 at 22:51:08

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

  • cpu.c, cpu_asm.S, score/cpu.h : add support for ARM<->THUMB veneer thumb new dir to controll CPSR/SPRS in thumb mode

2007-05-09 Ray Xu <rayx.cn@…>

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