source: rtems/cpukit/score/cpu/riscv/riscv-context-switch.S @ e755782

5
Last change on this file since e755782 was e755782, checked in by Sebastian Huber <sebastian.huber@…>, on 07/03/18 at 07:54:47

riscv: Clear reservations

See also RISC-V User-Level ISA V2.3, comment in section 8.2
"Load-Reserved/Store?-Conditional Instructions".

Update #3433.

  • Property mode set to 100644
File size: 4.9 KB
Line 
1/*
2 * Copyright (c) 2018 embedded brains GmbH
3 *
4 * Copyright (c) 2015 University of York.
5 * Hesham ALmatary <hesham@alumni.york.ac.uk>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include <rtems/asm.h>
34#include <rtems/score/percpu.h>
35
36        .section        .text, "ax", @progbits
37        .align  2
38
39PUBLIC(_CPU_Context_switch)
40PUBLIC(_CPU_Context_restore)
41
42SYM(_CPU_Context_switch):
43        GET_SELF_CPU_CONTROL    a2
44        lw      a3, PER_CPU_ISR_DISPATCH_DISABLE(a2)
45
46#if __riscv_flen > 0
47        frcsr   a4
48#endif
49
50        SREG    ra, RISCV_CONTEXT_RA(a0)
51        SREG    sp, RISCV_CONTEXT_SP(a0)
52        SREG    s0, RISCV_CONTEXT_S0(a0)
53        SREG    s1, RISCV_CONTEXT_S1(a0)
54        SREG    s2, RISCV_CONTEXT_S2(a0)
55        SREG    s3, RISCV_CONTEXT_S3(a0)
56        SREG    s4, RISCV_CONTEXT_S4(a0)
57        SREG    s5, RISCV_CONTEXT_S5(a0)
58        SREG    s6, RISCV_CONTEXT_S6(a0)
59        SREG    s7, RISCV_CONTEXT_S7(a0)
60        SREG    s8, RISCV_CONTEXT_S8(a0)
61        SREG    s9, RISCV_CONTEXT_S9(a0)
62        SREG    s10, RISCV_CONTEXT_S10(a0)
63        SREG    s11, RISCV_CONTEXT_S11(a0)
64
65#if __riscv_flen > 0
66        sw      a4, RISCV_CONTEXT_FCSR(a0)
67        FSREG   fs0, RISCV_CONTEXT_FS0(a0)
68        FSREG   fs1, RISCV_CONTEXT_FS1(a0)
69        FSREG   fs2, RISCV_CONTEXT_FS2(a0)
70        FSREG   fs3, RISCV_CONTEXT_FS3(a0)
71        FSREG   fs4, RISCV_CONTEXT_FS4(a0)
72        FSREG   fs5, RISCV_CONTEXT_FS5(a0)
73        FSREG   fs6, RISCV_CONTEXT_FS6(a0)
74        FSREG   fs7, RISCV_CONTEXT_FS7(a0)
75        FSREG   fs8, RISCV_CONTEXT_FS8(a0)
76        FSREG   fs9, RISCV_CONTEXT_FS9(a0)
77        FSREG   fs10, RISCV_CONTEXT_FS10(a0)
78        FSREG   fs11, RISCV_CONTEXT_FS11(a0)
79#endif
80
81        sw      a3, RISCV_CONTEXT_ISR_DISPATCH_DISABLE(a0)
82
83#ifdef RTEMS_SMP
84        /*
85         * The executing thread no longer executes on this processor.  Switch
86         * the stack to the temporary interrupt stack of this processor.  Mark
87         * the context of the executing thread as not executing.
88         */
89        addi    sp, a2, PER_CPU_INTERRUPT_FRAME_AREA + CPU_INTERRUPT_FRAME_SIZE
90        amoswap.w.rl    zero, zero, RISCV_CONTEXT_IS_EXECUTING(a0)
91
92.Ltry_update_is_executing:
93
94        /* Try to update the is executing indicator of the heir context */
95        li      a3, 1
96        amoswap.w.aq    a3, a3, RISCV_CONTEXT_IS_EXECUTING(a1)
97        bnez    a3, .Lcheck_is_executing
98#endif
99
100.Lrestore:
101
102        lw      a3, RISCV_CONTEXT_ISR_DISPATCH_DISABLE(a1)
103
104        LREG    ra, RISCV_CONTEXT_RA(a1)
105        LREG    sp, RISCV_CONTEXT_SP(a1)
106        LREG    tp, RISCV_CONTEXT_TP(a1)
107        LREG    s0, RISCV_CONTEXT_S0(a1)
108        LREG    s1, RISCV_CONTEXT_S1(a1)
109        LREG    s2, RISCV_CONTEXT_S2(a1)
110        LREG    s3, RISCV_CONTEXT_S3(a1)
111        LREG    s4, RISCV_CONTEXT_S4(a1)
112        LREG    s5, RISCV_CONTEXT_S5(a1)
113        LREG    s6, RISCV_CONTEXT_S6(a1)
114        LREG    s7, RISCV_CONTEXT_S7(a1)
115        LREG    s8, RISCV_CONTEXT_S8(a1)
116        LREG    s9, RISCV_CONTEXT_S9(a1)
117        LREG    s10, RISCV_CONTEXT_S10(a1)
118        LREG    s11, RISCV_CONTEXT_S11(a1)
119
120#if __riscv_flen > 0
121        lw      a4, RISCV_CONTEXT_FCSR(a1)
122        FLREG   fs0, RISCV_CONTEXT_FS0(a1)
123        FLREG   fs1, RISCV_CONTEXT_FS1(a1)
124        FLREG   fs2, RISCV_CONTEXT_FS2(a1)
125        FLREG   fs3, RISCV_CONTEXT_FS3(a1)
126        FLREG   fs4, RISCV_CONTEXT_FS4(a1)
127        FLREG   fs5, RISCV_CONTEXT_FS5(a1)
128        FLREG   fs6, RISCV_CONTEXT_FS6(a1)
129        FLREG   fs7, RISCV_CONTEXT_FS7(a1)
130        FLREG   fs8, RISCV_CONTEXT_FS8(a1)
131        FLREG   fs9, RISCV_CONTEXT_FS9(a1)
132        FLREG   fs10, RISCV_CONTEXT_FS10(a1)
133        FLREG   fs11, RISCV_CONTEXT_FS11(a1)
134        fscsr   a4
135#endif
136
137        sw      a3, PER_CPU_ISR_DISPATCH_DISABLE(a2)
138
139        CLEAR_RESERVATIONS      a2
140
141        ret
142
143SYM(_CPU_Context_restore):
144        mv      a1, a0
145        GET_SELF_CPU_CONTROL    a2
146        j       .Lrestore
147
148#ifdef RTEMS_SMP
149.Lcheck_is_executing:
150
151        /* Check the is executing indicator of the heir context */
152        lw      a3, RISCV_CONTEXT_IS_EXECUTING(a1)
153        beqz    a3, .Ltry_update_is_executing
154
155        /* We may have a new heir */
156
157        /* Read the executing and heir */
158        LREG    a4, PER_CPU_OFFSET_EXECUTING(a2)
159        LREG    a5, PER_CPU_OFFSET_HEIR(a2)
160
161        /*
162         * Update the executing only if necessary to avoid cache line
163         * monopolization.
164         */
165        beq     a4, a5, .Ltry_update_is_executing
166
167        /* Calculate the heir context pointer */
168        sub     a4, a1, a4
169        add     a1, a5, a4
170
171        /* Update the executing */
172        sw      a5, PER_CPU_OFFSET_EXECUTING(a2)
173
174        j       .Ltry_update_is_executing
175#endif
Note: See TracBrowser for help on using the repository browser.