Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:25

0001 /*
0002  * Copyright (c) 2018 embedded brains GmbH & Co. KG
0003  * Copyright (c) 2015 Hesham Almatary <hesham@alumni.york.ac.uk>
0004  *
0005  * Redistribution and use in source and binary forms, with or without
0006  * modification, are permitted provided that the following conditions
0007  * are met:
0008  * 1. Redistributions of source code must retain the above copyright
0009  *    notice, this list of conditions and the following disclaimer.
0010  * 2. Redistributions in binary form must reproduce the above copyright
0011  *    notice, this list of conditions and the following disclaimer in the
0012  *    documentation and/or other materials provided with the distribution.
0013  *
0014  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
0015  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0016  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0017  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
0018  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0019  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
0020  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
0021  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
0022  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
0023  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0024  * SUCH DAMAGE.
0025  */
0026 
0027 #ifdef HAVE_CONFIG_H
0028 #include "config.h"
0029 #endif
0030 
0031 #include <rtems/asm.h>
0032 #include <rtems/score/cpu.h>
0033 
0034 #define OFFSET(i) ((i) * CPU_SIZEOF_POINTER)
0035 
0036 #define RA_OFFSET OFFSET(0)
0037 #define T0_OFFSET OFFSET(1)
0038 #define T1_OFFSET OFFSET(2)
0039 #define T2_OFFSET OFFSET(3)
0040 #define S0_OFFSET OFFSET(4)
0041 #define S1_OFFSET OFFSET(5)
0042 #define A0_OFFSET OFFSET(6)
0043 #define A1_OFFSET OFFSET(7)
0044 #define A2_OFFSET OFFSET(8)
0045 #define A3_OFFSET OFFSET(9)
0046 #define A4_OFFSET OFFSET(10)
0047 #define A5_OFFSET OFFSET(11)
0048 #define A6_OFFSET OFFSET(12)
0049 #define A7_OFFSET OFFSET(13)
0050 #define S2_OFFSET OFFSET(14)
0051 #define S3_OFFSET OFFSET(15)
0052 #define S4_OFFSET OFFSET(16)
0053 #define S5_OFFSET OFFSET(17)
0054 #define S6_OFFSET OFFSET(18)
0055 #define S7_OFFSET OFFSET(19)
0056 #define S8_OFFSET OFFSET(20)
0057 #define S9_OFFSET OFFSET(21)
0058 #define S10_OFFSET OFFSET(22)
0059 #define S11_OFFSET OFFSET(23)
0060 #define T3_OFFSET OFFSET(24)
0061 #define T4_OFFSET OFFSET(25)
0062 #define T5_OFFSET OFFSET(26)
0063 #define T6_OFFSET OFFSET(27)
0064 #define TMP_OFFSET OFFSET(28)
0065 
0066 #if __riscv_flen == 32
0067 #define FOFFSET(i) (OFFSET(29) + (i) * 4)
0068 #elif __riscv_flen == 64
0069 #define FOFFSET(i) (OFFSET(30) + (i) * 8)
0070 #else
0071 #define FOFFSET(i) OFFSET(29)
0072 #endif /* __riscv_flen */
0073 
0074 #define FRAME_SIZE \
0075   ((FOFFSET(32) + CPU_STACK_ALIGNMENT - 1) & ~(CPU_STACK_ALIGNMENT - 1))
0076 
0077     .section    .text, "ax", @progbits
0078     .align  2
0079 
0080 PUBLIC(_CPU_Context_validate)
0081 SYM(_CPU_Context_validate):
0082     addi    sp, sp, -FRAME_SIZE
0083 
0084     /* Save */
0085 
0086     SREG    ra, RA_OFFSET(sp)
0087     SREG    t0, T0_OFFSET(sp)
0088     SREG    t1, T1_OFFSET(sp)
0089     SREG    t2, T2_OFFSET(sp)
0090     SREG    s0, S0_OFFSET(sp)
0091     SREG    s1, S1_OFFSET(sp)
0092     SREG    a0, A0_OFFSET(sp)
0093     SREG    a1, A1_OFFSET(sp)
0094     SREG    a2, A2_OFFSET(sp)
0095     SREG    a3, A3_OFFSET(sp)
0096     SREG    a4, A4_OFFSET(sp)
0097     SREG    a5, A5_OFFSET(sp)
0098     SREG    a6, A6_OFFSET(sp)
0099     SREG    a7, A7_OFFSET(sp)
0100     SREG    s2, S2_OFFSET(sp)
0101     SREG    s3, S3_OFFSET(sp)
0102     SREG    s4, S4_OFFSET(sp)
0103     SREG    s5, S5_OFFSET(sp)
0104     SREG    s6, S6_OFFSET(sp)
0105     SREG    s7, S7_OFFSET(sp)
0106     SREG    s8, S8_OFFSET(sp)
0107     SREG    s9, S9_OFFSET(sp)
0108     SREG    s10, S10_OFFSET(sp)
0109     SREG    s11, S11_OFFSET(sp)
0110     SREG    t3, T3_OFFSET(sp)
0111     SREG    t4, T4_OFFSET(sp)
0112     SREG    t5, T5_OFFSET(sp)
0113     SREG    t6, T6_OFFSET(sp)
0114 
0115 #if __riscv_flen > 0
0116     FSREG   f0, FOFFSET(0)(sp)
0117     FSREG   f1, FOFFSET(1)(sp)
0118     FSREG   f2, FOFFSET(2)(sp)
0119     FSREG   f3, FOFFSET(3)(sp)
0120     FSREG   f4, FOFFSET(4)(sp)
0121     FSREG   f5, FOFFSET(5)(sp)
0122     FSREG   f6, FOFFSET(6)(sp)
0123     FSREG   f7, FOFFSET(7)(sp)
0124     FSREG   f8, FOFFSET(8)(sp)
0125     FSREG   f9, FOFFSET(9)(sp)
0126     FSREG   f10, FOFFSET(10)(sp)
0127     FSREG   f11, FOFFSET(11)(sp)
0128     FSREG   f12, FOFFSET(12)(sp)
0129     FSREG   f13, FOFFSET(13)(sp)
0130     FSREG   f14, FOFFSET(14)(sp)
0131     FSREG   f15, FOFFSET(15)(sp)
0132     FSREG   f16, FOFFSET(16)(sp)
0133     FSREG   f17, FOFFSET(17)(sp)
0134     FSREG   f18, FOFFSET(18)(sp)
0135     FSREG   f19, FOFFSET(19)(sp)
0136     FSREG   f20, FOFFSET(20)(sp)
0137     FSREG   f21, FOFFSET(21)(sp)
0138     FSREG   f22, FOFFSET(22)(sp)
0139     FSREG   f23, FOFFSET(23)(sp)
0140     FSREG   f24, FOFFSET(24)(sp)
0141     FSREG   f25, FOFFSET(25)(sp)
0142     FSREG   f26, FOFFSET(26)(sp)
0143     FSREG   f27, FOFFSET(27)(sp)
0144     FSREG   f28, FOFFSET(28)(sp)
0145     FSREG   f29, FOFFSET(29)(sp)
0146     FSREG   f30, FOFFSET(30)(sp)
0147     FSREG   f31, FOFFSET(31)(sp)
0148 #endif /* __riscv_flen */
0149 
0150     /* Fill */
0151 
0152     addi    ra, a0, 1
0153     /* sp must remain as is */
0154     /* gp must remain as is */
0155     /* tp must remain as is */
0156     /* t0 is used for temporary values */
0157     addi    t1, a0, 2
0158     addi    t2, a0, 3
0159     addi    s0, a0, 4
0160     addi    s1, a0, 5
0161     /* a0 is the pattern */
0162     addi    a1, a0, 6
0163     addi    a2, a0, 7
0164     addi    a3, a0, 8
0165     addi    a4, a0, 9
0166     addi    a5, a0, 10
0167     addi    a6, a0, 11
0168     addi    a7, a0, 12
0169     addi    s2, a0, 13
0170     addi    s3, a0, 14
0171     addi    s4, a0, 15
0172     addi    s5, a0, 16
0173     addi    s6, a0, 17
0174     addi    s7, a0, 18
0175     addi    s8, a0, 19
0176     addi    s9, a0, 20
0177     addi    s10, a0, 21
0178     addi    s11, a0, 22
0179     addi    t3, a0, 23
0180 
0181     xor t4, sp, a0
0182     xor t5, gp, a0
0183     xor t6, tp, a0
0184 
0185 #if __riscv_flen > 0
0186     andi    t0, a0, 0x1f
0187     fsflags t0
0188 
0189     .macro  fill_f reg, inc
0190     addi    t0, a0, 24 + \inc
0191     FMVYX   \reg, t0
0192     .endm
0193 
0194     fill_f  f0, 0
0195     fill_f  f1, 1
0196     fill_f  f2, 2
0197     fill_f  f3, 3
0198     fill_f  f4, 4
0199     fill_f  f5, 5
0200     fill_f  f6, 6
0201     fill_f  f7, 7
0202     fill_f  f8, 8
0203     fill_f  f9, 9
0204     fill_f  f10, 10
0205     fill_f  f11, 11
0206     fill_f  f12, 12
0207     fill_f  f13, 13
0208     fill_f  f14, 14
0209     fill_f  f15, 15
0210     fill_f  f16, 16
0211     fill_f  f17, 17
0212     fill_f  f18, 18
0213     fill_f  f19, 19
0214     fill_f  f20, 20
0215     fill_f  f21, 21
0216     fill_f  f22, 22
0217     fill_f  f23, 23
0218     fill_f  f24, 24
0219     fill_f  f25, 25
0220     fill_f  f26, 26
0221     fill_f  f27, 27
0222     fill_f  f28, 28
0223     fill_f  f29, 29
0224     fill_f  f30, 30
0225     fill_f  f31, 31
0226 #endif /* __riscv_flen */
0227 
0228     /* Check */
0229 
0230 .Lcheck:
0231     .macro  check_register reg, inc
0232     addi    t0, a0, \inc
0233     bne \reg, t0, .Lrestore
0234     .endm
0235 
0236     check_register  ra, 1
0237     check_register  t1, 2
0238     check_register  t2, 3
0239     check_register  s0, 4
0240     check_register  s1, 5
0241     check_register  a1, 6
0242     check_register  a2, 7
0243     check_register  a3, 8
0244     check_register  a4, 9
0245     check_register  a5, 10
0246     check_register  a6, 11
0247     check_register  a7, 12
0248     check_register  s2, 13
0249     check_register  s3, 14
0250     check_register  s4, 15
0251     check_register  s5, 16
0252     check_register  s6, 17
0253     check_register  s7, 18
0254     check_register  s8, 19
0255     check_register  s9, 20
0256     check_register  s10, 21
0257     check_register  s11, 22
0258     check_register  t3, 23
0259 
0260     xor t0, sp, a0
0261     bne t4, t0, .Lrestore
0262 
0263     xor t0, gp, a0
0264     bne t5, t0, .Lrestore
0265 
0266     xor t0, tp, a0
0267     bne t6, t0, .Lrestore
0268 
0269 #if __riscv_flen > 0
0270     SREG    t1, TMP_OFFSET(sp)
0271     frflags t0
0272     andi    t1, a0, 0x1f
0273     xor t0, t1, t0
0274     LREG    t1, TMP_OFFSET(sp)
0275     bnez    t0, .Lrestore
0276 
0277 
0278     .macro  check_f reg, inc
0279     FMVXY   t0, \reg
0280     addi    t0, t0, -24 - \inc
0281     bne t0, a0, .Lrestore
0282     .endm
0283 
0284     check_f f0, 0
0285     check_f f1, 1
0286     check_f f2, 2
0287     check_f f3, 3
0288     check_f f4, 4
0289     check_f f5, 5
0290     check_f f6, 6
0291     check_f f7, 7
0292     check_f f8, 8
0293     check_f f9, 9
0294     check_f f10, 10
0295     check_f f11, 11
0296     check_f f12, 12
0297     check_f f13, 13
0298     check_f f14, 14
0299     check_f f15, 15
0300     check_f f16, 16
0301     check_f f17, 17
0302     check_f f18, 18
0303     check_f f19, 19
0304     check_f f20, 20
0305     check_f f21, 21
0306     check_f f22, 22
0307     check_f f23, 23
0308     check_f f24, 24
0309     check_f f25, 25
0310     check_f f26, 26
0311     check_f f27, 27
0312     check_f f28, 28
0313     check_f f29, 29
0314     check_f f30, 30
0315     check_f f31, 31
0316 #endif /* __riscv_flen */
0317 
0318     j   .Lcheck
0319 
0320     /* Restore */
0321 
0322 .Lrestore:
0323 
0324     LREG    ra, RA_OFFSET(sp)
0325     LREG    t0, T0_OFFSET(sp)
0326     LREG    t1, T1_OFFSET(sp)
0327     LREG    t2, T2_OFFSET(sp)
0328     LREG    s0, S0_OFFSET(sp)
0329     LREG    s1, S1_OFFSET(sp)
0330     LREG    a0, A0_OFFSET(sp)
0331     LREG    a1, A1_OFFSET(sp)
0332     LREG    a2, A2_OFFSET(sp)
0333     LREG    a3, A3_OFFSET(sp)
0334     LREG    a4, A4_OFFSET(sp)
0335     LREG    a5, A5_OFFSET(sp)
0336     LREG    a6, A6_OFFSET(sp)
0337     LREG    a7, A7_OFFSET(sp)
0338     LREG    s2, S2_OFFSET(sp)
0339     LREG    s3, S3_OFFSET(sp)
0340     LREG    s4, S4_OFFSET(sp)
0341     LREG    s5, S5_OFFSET(sp)
0342     LREG    s6, S6_OFFSET(sp)
0343     LREG    s7, S7_OFFSET(sp)
0344     LREG    s8, S8_OFFSET(sp)
0345     LREG    s9, S9_OFFSET(sp)
0346     LREG    s10, S10_OFFSET(sp)
0347     LREG    s11, S11_OFFSET(sp)
0348     LREG    t3, T3_OFFSET(sp)
0349     LREG    t4, T4_OFFSET(sp)
0350     LREG    t5, T5_OFFSET(sp)
0351     LREG    t6, T6_OFFSET(sp)
0352 
0353 #if __riscv_flen > 0
0354     FLREG   f0, FOFFSET(0)(sp)
0355     FLREG   f1, FOFFSET(1)(sp)
0356     FLREG   f2, FOFFSET(2)(sp)
0357     FLREG   f3, FOFFSET(3)(sp)
0358     FLREG   f4, FOFFSET(4)(sp)
0359     FLREG   f5, FOFFSET(5)(sp)
0360     FLREG   f6, FOFFSET(6)(sp)
0361     FLREG   f7, FOFFSET(7)(sp)
0362     FLREG   f8, FOFFSET(8)(sp)
0363     FLREG   f9, FOFFSET(9)(sp)
0364     FLREG   f10, FOFFSET(10)(sp)
0365     FLREG   f11, FOFFSET(11)(sp)
0366     FLREG   f12, FOFFSET(12)(sp)
0367     FLREG   f13, FOFFSET(13)(sp)
0368     FLREG   f14, FOFFSET(14)(sp)
0369     FLREG   f15, FOFFSET(15)(sp)
0370     FLREG   f16, FOFFSET(16)(sp)
0371     FLREG   f17, FOFFSET(17)(sp)
0372     FLREG   f18, FOFFSET(18)(sp)
0373     FLREG   f19, FOFFSET(19)(sp)
0374     FLREG   f20, FOFFSET(20)(sp)
0375     FLREG   f21, FOFFSET(21)(sp)
0376     FLREG   f22, FOFFSET(22)(sp)
0377     FLREG   f23, FOFFSET(23)(sp)
0378     FLREG   f24, FOFFSET(24)(sp)
0379     FLREG   f25, FOFFSET(25)(sp)
0380     FLREG   f26, FOFFSET(26)(sp)
0381     FLREG   f27, FOFFSET(27)(sp)
0382     FLREG   f28, FOFFSET(28)(sp)
0383     FLREG   f29, FOFFSET(29)(sp)
0384     FLREG   f30, FOFFSET(30)(sp)
0385     FLREG   f31, FOFFSET(31)(sp)
0386 #endif /* __riscv_flen */
0387 
0388     addi    sp, sp, FRAME_SIZE
0389     ret