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

4.115
Last change on this file since 8ae37323 was 8ae37323, checked in by Sebastian Huber <sebastian.huber@…>, on 08/10/14 at 16:36:30

arm: Add support for FPv4-SP floating point unit

This floating point unit is available in Cortex-M4 processors and
defined by ARMv7-M. This adds basic support for other VFP-D16 variants.

  • Property mode set to 100644
File size: 3.5 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup ScoreCPU
5 *
6 * @brief ARM architecture support implementation.
7 */
8
9/*
10 *  This file contains all assembly code for the ARM implementation
11 *  of RTEMS.
12 *
13 *  Copyright (c) 2007 by Ray Xu, <Rayx.cn@gmail.com>
14 *          Thumb support added.
15 *
16 *  Copyright (c) 2002 by Advent Networks, Inc.
17 *          Jay Monkman <jmonkman@adventnetworks.com>
18 *
19 *  COPYRIGHT (c) 2000 Canon Research Centre France SA.
20 *  Emmanuel Raguet, mailto:raguet@crf.canon.fr
21 *
22 *  Copyright (c) 2013-2014 embedded brains GmbH
23 *
24 *  The license and distribution terms for this file may be
25 *  found in the file LICENSE in this distribution or at
26 *  http://www.rtems.org/license/LICENSE.
27 *
28 */
29
30#ifdef HAVE_CONFIG_H
31#include "config.h"
32#endif
33
34#include <rtems/asm.h>
35
36#ifdef ARM_MULTILIB_ARCH_V4
37
38        .text
39
40/*
41 *  void _CPU_Context_switch( run_context, heir_context )
42 *  void _CPU_Context_restore( run_context, heir_context )
43 *
44 *  This routine performs a normal non-FP context.
45 *
46 *  R0 = run_context    R1 = heir_context
47 *
48 *  This function copies the current registers to where r0 points, then
49 *  restores the ones from where r1 points.
50 *
51 *  Using the ldm/stm opcodes save 2-3 us on 100 MHz ARM9TDMI with
52 *  a 16 bit data bus.
53 *
54 */
55
56DEFINE_FUNCTION_ARM(_CPU_Context_switch)
57/* Start saving context */
58        mrs     r2, CPSR
59        stmia   r0,  {r2, r4, r5, r6, r7, r8, r9, r10, r11, r13, r14}
60
61#ifdef ARM_MULTILIB_VFP
62        add     r3, r0, #ARM_CONTEXT_CONTROL_D8_OFFSET
63        vstm    r3, {d8-d15}
64#endif
65
66#ifdef ARM_MULTILIB_HAS_THREAD_ID_REGISTER
67        mrc     p15, 0, r3, c13, c0, 3
68        str     r3, [r0, #ARM_CONTEXT_CONTROL_THREAD_ID_OFFSET]
69#endif
70
71#ifdef RTEMS_SMP
72        /* The executing context no longer executes on this processor */
73        dmb
74        mov     r3, #0
75        strb    r3, [r0, #ARM_CONTEXT_CONTROL_IS_EXECUTING_OFFSET]
76
77.L_check_is_executing:
78
79        /* Check the is executing indicator of the heir context */
80        add     r3, r1, #ARM_CONTEXT_CONTROL_IS_EXECUTING_OFFSET
81        ldrexb  r4, [r3]
82        cmp     r4, #0
83        bne     .L_check_thread_dispatch_necessary
84
85        /* Try to update the is executing indicator of the heir context */
86        mov     r4, #1
87        strexb  r5, r4, [r3]
88        cmp     r5, #0
89        bne     .L_check_thread_dispatch_necessary
90        dmb
91#endif
92
93/* Start restoring context */
94.L_restore:
95#if !defined(RTEMS_SMP) && defined(ARM_MULTILIB_HAS_LOAD_STORE_EXCLUSIVE)
96        clrex
97#endif
98
99#ifdef ARM_MULTILIB_HAS_THREAD_ID_REGISTER
100        ldr     r3, [r1, #ARM_CONTEXT_CONTROL_THREAD_ID_OFFSET]
101        mcr     p15, 0, r3, c13, c0, 3
102#endif
103
104#ifdef ARM_MULTILIB_VFP
105        add     r3, r1, #ARM_CONTEXT_CONTROL_D8_OFFSET
106        vldm    r3, {d8-d15}
107#endif
108
109        ldmia   r1,  {r2, r4, r5, r6, r7, r8, r9, r10, r11, r13, r14}
110        msr     CPSR_fsxc, r2
111#ifdef __thumb__
112        bx      lr
113        nop
114#else
115        mov     pc, lr
116#endif
117/*
118 *  void _CPU_Context_restore( new_context )
119 *
120 *  This function copies the restores the registers from where r0 points.
121 *  It must match _CPU_Context_switch()
122 *
123 */
124DEFINE_FUNCTION_ARM(_CPU_Context_restore)
125        mov     r1, r0
126        b       .L_restore
127
128#ifdef RTEMS_SMP
129.L_check_thread_dispatch_necessary:
130
131        GET_SELF_CPU_CONTROL    r2, r3
132
133        /* Check if a thread dispatch is necessary */
134        ldrb    r4, [r2, #PER_CPU_DISPATCH_NEEDED]
135        cmp     r4, #0
136        beq     .L_check_is_executing
137
138        /* We have a new heir */
139
140        /* Clear the thread dispatch necessary flag */
141        mov     r4, #0
142        strb    r4, [r2, #PER_CPU_DISPATCH_NEEDED]
143        dmb
144
145        /* Read the executing and heir */
146        ldr     r4, [r2, #PER_CPU_OFFSET_EXECUTING]
147        ldr     r5, [r2, #PER_CPU_OFFSET_HEIR]
148
149        /* Calculate the heir context pointer */
150        sub     r4, r1, r4
151        add     r1, r5, r4
152
153        /* Update the executing */
154        str     r5, [r2, #PER_CPU_OFFSET_EXECUTING]
155
156        b       .L_check_is_executing
157#endif
158
159#endif /* ARM_MULTILIB_ARCH_V4 */
Note: See TracBrowser for help on using the repository browser.