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

Last change on this file was bcef89f2, checked in by Sebastian Huber <sebastian.huber@…>, on 05/19/23 at 06:18:25

Update company name

The embedded brains GmbH & Co. KG is the legal successor of embedded
brains GmbH.

  • Property mode set to 100644
File size: 5.4 KB
Line 
1/*
2 * Copyright (c) 2018 embedded brains GmbH & Co. KG
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        .option arch, +zicsr
39
40PUBLIC(_CPU_Context_switch)
41PUBLIC(_CPU_Context_switch_no_return)
42PUBLIC(_CPU_Context_restore)
43#ifdef RTEMS_SMP
44PUBLIC(_RISCV_Start_multitasking)
45#endif
46
47SYM(_CPU_Context_switch):
48SYM(_CPU_Context_switch_no_return):
49        GET_SELF_CPU_CONTROL    a2
50        lw      a3, PER_CPU_ISR_DISPATCH_DISABLE(a2)
51
52#if __riscv_flen > 0
53        frcsr   a4
54#endif
55
56        SREG    ra, RISCV_CONTEXT_RA(a0)
57        SREG    sp, RISCV_CONTEXT_SP(a0)
58        SREG    s0, RISCV_CONTEXT_S0(a0)
59        SREG    s1, RISCV_CONTEXT_S1(a0)
60        SREG    s2, RISCV_CONTEXT_S2(a0)
61        SREG    s3, RISCV_CONTEXT_S3(a0)
62        SREG    s4, RISCV_CONTEXT_S4(a0)
63        SREG    s5, RISCV_CONTEXT_S5(a0)
64        SREG    s6, RISCV_CONTEXT_S6(a0)
65        SREG    s7, RISCV_CONTEXT_S7(a0)
66        SREG    s8, RISCV_CONTEXT_S8(a0)
67        SREG    s9, RISCV_CONTEXT_S9(a0)
68        SREG    s10, RISCV_CONTEXT_S10(a0)
69        SREG    s11, RISCV_CONTEXT_S11(a0)
70
71#if __riscv_flen > 0
72        sw      a4, RISCV_CONTEXT_FCSR(a0)
73        FSREG   fs0, RISCV_CONTEXT_FS0(a0)
74        FSREG   fs1, RISCV_CONTEXT_FS1(a0)
75        FSREG   fs2, RISCV_CONTEXT_FS2(a0)
76        FSREG   fs3, RISCV_CONTEXT_FS3(a0)
77        FSREG   fs4, RISCV_CONTEXT_FS4(a0)
78        FSREG   fs5, RISCV_CONTEXT_FS5(a0)
79        FSREG   fs6, RISCV_CONTEXT_FS6(a0)
80        FSREG   fs7, RISCV_CONTEXT_FS7(a0)
81        FSREG   fs8, RISCV_CONTEXT_FS8(a0)
82        FSREG   fs9, RISCV_CONTEXT_FS9(a0)
83        FSREG   fs10, RISCV_CONTEXT_FS10(a0)
84        FSREG   fs11, RISCV_CONTEXT_FS11(a0)
85#endif
86
87        sw      a3, RISCV_CONTEXT_ISR_DISPATCH_DISABLE(a0)
88
89#ifdef RTEMS_SMP
90        /*
91         * The executing thread no longer executes on this processor.  Switch
92         * the stack to the temporary interrupt stack of this processor.  Mark
93         * the context of the executing thread as not executing.
94         */
95        addi    sp, a2, PER_CPU_INTERRUPT_FRAME_AREA + CPU_INTERRUPT_FRAME_SIZE
96        amoswap.w.rl    zero, zero, RISCV_CONTEXT_IS_EXECUTING(a0)
97
98.Ltry_update_is_executing:
99
100        /* Try to update the is executing indicator of the heir context */
101        li      a3, 1
102        amoswap.w.aq    a3, a3, RISCV_CONTEXT_IS_EXECUTING(a1)
103        bnez    a3, .Lcheck_is_executing
104#endif
105
106.Lrestore:
107
108        lw      a3, RISCV_CONTEXT_ISR_DISPATCH_DISABLE(a1)
109
110        LREG    ra, RISCV_CONTEXT_RA(a1)
111        LREG    sp, RISCV_CONTEXT_SP(a1)
112        LREG    tp, RISCV_CONTEXT_TP(a1)
113        LREG    s0, RISCV_CONTEXT_S0(a1)
114        LREG    s1, RISCV_CONTEXT_S1(a1)
115        LREG    s2, RISCV_CONTEXT_S2(a1)
116        LREG    s3, RISCV_CONTEXT_S3(a1)
117        LREG    s4, RISCV_CONTEXT_S4(a1)
118        LREG    s5, RISCV_CONTEXT_S5(a1)
119        LREG    s6, RISCV_CONTEXT_S6(a1)
120        LREG    s7, RISCV_CONTEXT_S7(a1)
121        LREG    s8, RISCV_CONTEXT_S8(a1)
122        LREG    s9, RISCV_CONTEXT_S9(a1)
123        LREG    s10, RISCV_CONTEXT_S10(a1)
124        LREG    s11, RISCV_CONTEXT_S11(a1)
125
126#if __riscv_flen > 0
127        lw      a4, RISCV_CONTEXT_FCSR(a1)
128        FLREG   fs0, RISCV_CONTEXT_FS0(a1)
129        FLREG   fs1, RISCV_CONTEXT_FS1(a1)
130        FLREG   fs2, RISCV_CONTEXT_FS2(a1)
131        FLREG   fs3, RISCV_CONTEXT_FS3(a1)
132        FLREG   fs4, RISCV_CONTEXT_FS4(a1)
133        FLREG   fs5, RISCV_CONTEXT_FS5(a1)
134        FLREG   fs6, RISCV_CONTEXT_FS6(a1)
135        FLREG   fs7, RISCV_CONTEXT_FS7(a1)
136        FLREG   fs8, RISCV_CONTEXT_FS8(a1)
137        FLREG   fs9, RISCV_CONTEXT_FS9(a1)
138        FLREG   fs10, RISCV_CONTEXT_FS10(a1)
139        FLREG   fs11, RISCV_CONTEXT_FS11(a1)
140        fscsr   a4
141#endif
142
143        sw      a3, PER_CPU_ISR_DISPATCH_DISABLE(a2)
144
145        CLEAR_RESERVATIONS      a2
146
147        ret
148
149SYM(_CPU_Context_restore):
150        mv      a1, a0
151        GET_SELF_CPU_CONTROL    a2
152        j       .Lrestore
153
154#ifdef RTEMS_SMP
155.Lcheck_is_executing:
156
157        /* Check the is executing indicator of the heir context */
158        lw      a3, RISCV_CONTEXT_IS_EXECUTING(a1)
159        beqz    a3, .Ltry_update_is_executing
160
161        /* We may have a new heir */
162
163        /* Read the executing and heir */
164        LREG    a4, PER_CPU_OFFSET_EXECUTING(a2)
165        LREG    a5, PER_CPU_OFFSET_HEIR(a2)
166
167        /*
168         * Update the executing only if necessary to avoid cache line
169         * monopolization.
170         */
171        beq     a4, a5, .Ltry_update_is_executing
172
173        /* Calculate the heir context pointer */
174        sub     a4, a1, a4
175        add     a1, a5, a4
176
177        /* Update the executing */
178        sw      a5, PER_CPU_OFFSET_EXECUTING(a2)
179
180        j       .Ltry_update_is_executing
181
182SYM(_RISCV_Start_multitasking):
183        mv      a1, a0
184        GET_SELF_CPU_CONTROL    a2
185
186        /* Switch the stack to the temporary interrupt stack of this processor */
187        addi    sp, a2, PER_CPU_INTERRUPT_FRAME_AREA + CPU_INTERRUPT_FRAME_SIZE
188
189        /* Enable interrupts */
190        csrrs   zero, mstatus, RISCV_MSTATUS_MIE
191
192        j       .Ltry_update_is_executing
193#endif
Note: See TracBrowser for help on using the repository browser.