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

Last change on this file since faaffbd9 was faaffbd9, checked in by Sebastian Huber <sebastian.huber@…>, on 02/25/22 at 16:45:06

riscv: Use zicsr architecture extension

This is required for ISA 2.0 support, see chapter

"Zicsr", Control and Status Register (CSR) Instructions, Version 2.0

in

RISC-V Instruction Set Manual, Volume I: RISC-V User-Level ISA

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