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

5
Last change on this file since cd3d747 was cd3d747, checked in by Sebastian Huber <sebastian.huber@…>, on 03/27/17 at 06:01:38

arm: Optimize context switch

Set CPU_ENABLE_ROBUST_THREAD_DISPATCH to TRUE. In this case the
interrupts are always enabled during a context switch even after
interrupt processing (see #2751). Remove the CPSR from the context
control since it contains only volatile bits.

Close #2954.

  • Property mode set to 100644
File size: 4.0 KB
RevLine 
[78623bce]1/**
2 * @file
3 *
4 * @ingroup ScoreCPU
5 *
6 * @brief ARM architecture support implementation.
7 */
8
[4f0b287]9/*
[08330bf]10 *  This file contains all assembly code for the ARM implementation
11 *  of RTEMS.
12 *
[a3ff693]13 *  Copyright (c) 2007 by Ray Xu, <Rayx.cn@gmail.com>
14 *          Thumb support added.
15 *
[4f0b287]16 *  Copyright (c) 2002 by Advent Networks, Inc.
17 *          Jay Monkman <jmonkman@adventnetworks.com>
18 *
[08330bf]19 *  COPYRIGHT (c) 2000 Canon Research Centre France SA.
20 *  Emmanuel Raguet, mailto:raguet@crf.canon.fr
21 *
[cd3d747]22 *  Copyright (c) 2013, 2017 embedded brains GmbH
[fbda4a8]23 *
[08330bf]24 *  The license and distribution terms for this file may be
25 *  found in the file LICENSE in this distribution or at
[c499856]26 *  http://www.rtems.org/license/LICENSE.
[08330bf]27 *
28 */
29
[0acc9af3]30#ifdef HAVE_CONFIG_H
31#include "config.h"
32#endif
33
[b49bcfc]34#include <rtems/asm.h>
[08330bf]35
[c5ed148]36#ifdef ARM_MULTILIB_ARCH_V4
37
[661e5de4]38        .text
[08330bf]39
40/*
41 *  void _CPU_Context_switch( run_context, heir_context )
[4f0b287]42 *  void _CPU_Context_restore( run_context, heir_context )
[08330bf]43 *
44 *  This routine performs a normal non-FP context.
45 *
[4f0b287]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 *
[fa237002]51 *  Using the ldm/stm opcodes save 2-3 us on 100 MHz ARM9TDMI with
52 *  a 16 bit data bus.
[5bb38e15]53 *
[08330bf]54 */
[5bb38e15]55
[5e61c80]56DEFINE_FUNCTION_ARM(_CPU_Context_switch)
[4f0b287]57/* Start saving context */
[d59585d]58        GET_SELF_CPU_CONTROL    r2
[cd3d747]59        stm     r0, {r4, r5, r6, r7, r8, r9, r10, r11, r13, r14}
60
61#ifdef ARM_MULTILIB_HAS_THREAD_ID_REGISTER
62        mrc     p15, 0, r3, c13, c0, 3
63#endif
64
[d59585d]65        ldr     r4, [r2, #PER_CPU_ISR_DISPATCH_DISABLE]
66
[8ae37323]67#ifdef ARM_MULTILIB_VFP
[cd3d747]68        add     r5, r0, #ARM_CONTEXT_CONTROL_D8_OFFSET
69        vstm    r5, {d8-d15}
[cfd8d7a]70#endif
[4f0b287]71
[022851a]72#ifdef ARM_MULTILIB_HAS_THREAD_ID_REGISTER
73        str     r3, [r0, #ARM_CONTEXT_CONTROL_THREAD_ID_OFFSET]
74#endif
75
[d59585d]76        str     r4, [r0, #ARM_CONTEXT_CONTROL_ISR_DISPATCH_DISABLE]
77
[38b59a6]78#ifdef RTEMS_SMP
[d5e073c]79        /*
80         * The executing thread no longer executes on this processor.  Switch
81         * the stack to the temporary interrupt stack of this processor.  Mark
82         * the context of the executing thread as not executing.
83         */
[38b59a6]84        dmb
[d5e073c]85        add     sp, r2, #(PER_CPU_INTERRUPT_FRAME_AREA + CPU_INTERRUPT_FRAME_SIZE)
[38b59a6]86        mov     r3, #0
87        strb    r3, [r0, #ARM_CONTEXT_CONTROL_IS_EXECUTING_OFFSET]
[cfd8d7a]88
[fbda4a8]89.L_check_is_executing:
90
91        /* Check the is executing indicator of the heir context */
92        add     r3, r1, #ARM_CONTEXT_CONTROL_IS_EXECUTING_OFFSET
93        ldrexb  r4, [r3]
94        cmp     r4, #0
[258ad71]95        bne     .L_get_potential_new_heir
[38b59a6]96
[fbda4a8]97        /* Try to update the is executing indicator of the heir context */
98        mov     r4, #1
99        strexb  r5, r4, [r3]
100        cmp     r5, #0
[258ad71]101        bne     .L_get_potential_new_heir
[38b59a6]102        dmb
103#endif
104
[11b05f1]105/* Start restoring context */
[f28f5c4]106.L_restore:
[fbda4a8]107#if !defined(RTEMS_SMP) && defined(ARM_MULTILIB_HAS_LOAD_STORE_EXCLUSIVE)
[11b05f1]108        clrex
109#endif
110
[022851a]111#ifdef ARM_MULTILIB_HAS_THREAD_ID_REGISTER
112        ldr     r3, [r1, #ARM_CONTEXT_CONTROL_THREAD_ID_OFFSET]
113#endif
114
[cd3d747]115        ldr     r4, [r1, #ARM_CONTEXT_CONTROL_ISR_DISPATCH_DISABLE]
116
[8ae37323]117#ifdef ARM_MULTILIB_VFP
[cd3d747]118        add     r5, r1, #ARM_CONTEXT_CONTROL_D8_OFFSET
119        vldm    r5, {d8-d15}
120#endif
121
122#ifdef ARM_MULTILIB_HAS_THREAD_ID_REGISTER
123        mcr     p15, 0, r3, c13, c0, 3
[cfd8d7a]124#endif
125
[d59585d]126        str     r4, [r2, #PER_CPU_ISR_DISPATCH_DISABLE]
127
[cd3d747]128        /* In ARMv5T and above the load of PC is an interworking branch */
129#if __ARM_ARCH >= 5
130        ldm     r1, {r4, r5, r6, r7, r8, r9, r10, r11, r13, pc}
[661e5de4]131#else
[cd3d747]132        ldm     r1, {r4, r5, r6, r7, r8, r9, r10, r11, r13, r14}
133        bx      lr
[661e5de4]134#endif
[cd3d747]135
[08330bf]136/*
137 *  void _CPU_Context_restore( new_context )
138 *
[4f0b287]139 *  This function copies the restores the registers from where r0 points.
140 *  It must match _CPU_Context_switch()
141 *
[08330bf]142 */
[5e61c80]143DEFINE_FUNCTION_ARM(_CPU_Context_restore)
[fa237002]144        mov     r1, r0
[d59585d]145        GET_SELF_CPU_CONTROL    r2
[f28f5c4]146        b       .L_restore
[c5ed148]147
[fbda4a8]148#ifdef RTEMS_SMP
[258ad71]149.L_get_potential_new_heir:
[fbda4a8]150
[258ad71]151        /* We may have a new heir */
[fbda4a8]152
153        /* Read the executing and heir */
154        ldr     r4, [r2, #PER_CPU_OFFSET_EXECUTING]
155        ldr     r5, [r2, #PER_CPU_OFFSET_HEIR]
156
[258ad71]157        /*
158         * Update the executing only if necessary to avoid cache line
159         * monopolization.
160         */
161        cmp     r4, r5
162        beq     .L_check_is_executing
163
[fbda4a8]164        /* Calculate the heir context pointer */
165        sub     r4, r1, r4
166        add     r1, r5, r4
167
168        /* Update the executing */
169        str     r5, [r2, #PER_CPU_OFFSET_EXECUTING]
170
171        b       .L_check_is_executing
172#endif
173
[c5ed148]174#endif /* ARM_MULTILIB_ARCH_V4 */
Note: See TracBrowser for help on using the repository browser.