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

5
Last change on this file since 258ad71 was 258ad71, checked in by Sebastian Huber <sebastian.huber@…>, on 09/25/15 at 12:34:24

SMP: Fix and optimize thread dispatching

According to the C11 and C++11 memory models only a read-modify-write
operation guarantees that we read the last value written in modification
order. Avoid the sequential consistent thread fence and instead use the
inter-processor interrupt to set the thread dispatch necessary
indicator.

  • Property mode set to 100644
File size: 3.4 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-2015 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_get_potential_new_heir
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_get_potential_new_heir
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_get_potential_new_heir:
130
131        GET_SELF_CPU_CONTROL    r2, r3
132
133        /* We may have a new heir */
134
135        /* Read the executing and heir */
136        ldr     r4, [r2, #PER_CPU_OFFSET_EXECUTING]
137        ldr     r5, [r2, #PER_CPU_OFFSET_HEIR]
138
139        /*
140         * Update the executing only if necessary to avoid cache line
141         * monopolization.
142         */
143        cmp     r4, r5
144        beq     .L_check_is_executing
145
146        /* Calculate the heir context pointer */
147        sub     r4, r1, r4
148        add     r1, r5, r4
149
150        /* Update the executing */
151        str     r5, [r2, #PER_CPU_OFFSET_EXECUTING]
152
153        b       .L_check_is_executing
154#endif
155
156#endif /* ARM_MULTILIB_ARCH_V4 */
Note: See TracBrowser for help on using the repository browser.