This is an automated email from the ASF dual-hosted git repository. gnutt pushed a commit to branch pr789 in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 934fccc2ffd225a98c42fa508e21d56d7c0db0b9 Author: zhongan <zhon...@xiaomi.com> AuthorDate: Thu Apr 2 11:20:20 2020 +0800 Add fpu support. Change-Id: I1220a58a635546cc954ff04cfacca356923b4b51 Signed-off-by: zhongan <zhon...@xiaomi.com> --- arch/risc-v/include/rv32im/irq.h | 129 +++++++++++++++++- arch/risc-v/src/common/up_internal.h | 8 ++ arch/risc-v/src/rv32im/up_fpu.S | 251 +++++++++++++++++++++++++++++++++++ 3 files changed, 386 insertions(+), 2 deletions(-) diff --git a/arch/risc-v/include/rv32im/irq.h b/arch/risc-v/include/rv32im/irq.h index 3944d9d..567a75c 100644 --- a/arch/risc-v/include/rv32im/irq.h +++ b/arch/risc-v/include/rv32im/irq.h @@ -132,11 +132,63 @@ #ifdef CONFIG_ARCH_CHIP_GAP8 /* 31 registers, ePC, plus 6 loop registers */ -# define XCPTCONTEXT_REGS (32 + 6) +# define INT_XCPT_REGS (32 + 6) #else -# define XCPTCONTEXT_REGS 33 +# define INT_XCPT_REGS 33 #endif +#define INT_XCPT_SIZE (4 * INT_XCPT_REGS) + +#ifdef CONFIG_ARCH_FPU + +#if defined(CONFIG_ARCH_DPFPU) +# define FPU_REG_SIZE 2 +#elif defined(CONFIG_ARCH_QPFPU) +# define FPU_REG_SIZE 4 +#else +# define FPU_REG_SIZE 1 +#endif + +# define REG_F0_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 0) +# define REG_F1_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 1) +# define REG_F2_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 2) +# define REG_F3_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 3) +# define REG_F4_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 4) +# define REG_F5_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 5) +# define REG_F6_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 6) +# define REG_F7_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 7) +# define REG_F8_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 8) +# define REG_F9_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 9) +# define REG_F10_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 10) +# define REG_F11_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 11) +# define REG_F12_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 12) +# define REG_F13_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 13) +# define REG_F14_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 14) +# define REG_F15_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 15) +# define REG_F16_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 16) +# define REG_F17_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 17) +# define REG_F18_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 18) +# define REG_F19_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 19) +# define REG_F20_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 20) +# define REG_F21_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 21) +# define REG_F22_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 22) +# define REG_F23_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 23) +# define REG_F24_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 24) +# define REG_F25_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 25) +# define REG_F26_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 26) +# define REG_F27_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 27) +# define REG_F28_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 28) +# define REG_F29_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 29) +# define REG_F30_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 30) +# define REG_F31_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 31) +# define REG_FCSR_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 32) + +# define FPU_XCPT_REGS (FPU_REG_SIZE * 33) +#else +# define FPU_XCPT_REGS 0 +#endif + +#define XCPTCONTEXT_REGS (INT_XCPT_REGS + FPU_XCPT_REGS) #define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS) /* In assembly language, values have to be referenced as byte address @@ -178,6 +230,42 @@ # define REG_X30 (4*REG_X30_NDX) # define REG_X31 (4*REG_X31_NDX) # define REG_INT_CTX (4*REG_INT_CTX_NDX) +#ifdef CONFIG_ARCH_FPU +# define REG_F0 (4*REG_F0_NDX) +# define REG_F1 (4*REG_F1_NDX) +# define REG_F2 (4*REG_F2_NDX) +# define REG_F3 (4*REG_F3_NDX) +# define REG_F4 (4*REG_F4_NDX) +# define REG_F5 (4*REG_F5_NDX) +# define REG_F6 (4*REG_F6_NDX) +# define REG_F7 (4*REG_F7_NDX) +# define REG_F8 (4*REG_F8_NDX) +# define REG_F9 (4*REG_F9_NDX) +# define REG_F10 (4*REG_F10_NDX) +# define REG_F11 (4*REG_F11_NDX) +# define REG_F12 (4*REG_F12_NDX) +# define REG_F13 (4*REG_F13_NDX) +# define REG_F14 (4*REG_F14_NDX) +# define REG_F15 (4*REG_F15_NDX) +# define REG_F16 (4*REG_F16_NDX) +# define REG_F17 (4*REG_F17_NDX) +# define REG_F18 (4*REG_F18_NDX) +# define REG_F19 (4*REG_F19_NDX) +# define REG_F20 (4*REG_F20_NDX) +# define REG_F21 (4*REG_F21_NDX) +# define REG_F22 (4*REG_F22_NDX) +# define REG_F23 (4*REG_F23_NDX) +# define REG_F24 (4*REG_F24_NDX) +# define REG_F25 (4*REG_F25_NDX) +# define REG_F26 (4*REG_F26_NDX) +# define REG_F27 (4*REG_F27_NDX) +# define REG_F28 (4*REG_F28_NDX) +# define REG_F29 (4*REG_F29_NDX) +# define REG_F30 (4*REG_F30_NDX) +# define REG_F31 (4*REG_F31_NDX) +# define REG_FCSR (4*REG_FCSR_NDX) +#endif + #else # define REG_EPC REG_EPC_NDX # define REG_X1 REG_X1_NDX @@ -212,6 +300,43 @@ # define REG_X30 REG_X30_NDX # define REG_X31 REG_X31_NDX # define REG_INT_CTX REG_INT_CTX_NDX + +#ifdef CONFIG_ARCH_FPU +# define REG_F0 REG_F0_NDX +# define REG_F1 REG_F1_NDX +# define REG_F2 REG_F2_NDX +# define REG_F3 REG_F3_NDX +# define REG_F4 REG_F4_NDX +# define REG_F5 REG_F5_NDX +# define REG_F6 REG_F6_NDX +# define REG_F7 REG_F7_NDX +# define REG_F8 REG_F8_NDX +# define REG_F9 REG_F9_NDX +# define REG_F10 REG_F10_NDX +# define REG_F11 REG_F11_NDX +# define REG_F12 REG_F12_NDX +# define REG_F13 REG_F13_NDX +# define REG_F14 REG_F14_NDX +# define REG_F15 REG_F15_NDX +# define REG_F16 REG_F16_NDX +# define REG_F17 REG_F17_NDX +# define REG_F18 REG_F18_NDX +# define REG_F19 REG_F19_NDX +# define REG_F20 REG_F20_NDX +# define REG_F21 REG_F21_NDX +# define REG_F22 REG_F22_NDX +# define REG_F23 REG_F23_NDX +# define REG_F24 REG_F24_NDX +# define REG_F25 REG_F25_NDX +# define REG_F26 REG_F26_NDX +# define REG_F27 REG_F27_NDX +# define REG_F28 REG_F28_NDX +# define REG_F29 REG_F29_NDX +# define REG_F30 REG_F30_NDX +# define REG_F31 REG_F31_NDX +# define REG_FCSR REG_FCSR_NDX +#endif + #endif /* Now define more user friendly alternative name that can be used either diff --git a/arch/risc-v/src/common/up_internal.h b/arch/risc-v/src/common/up_internal.h index ef9a9b2..068d05f 100644 --- a/arch/risc-v/src/common/up_internal.h +++ b/arch/risc-v/src/common/up_internal.h @@ -193,6 +193,14 @@ void up_sigdeliver(void); int up_swint(int irq, FAR void *context, FAR void *arg); uint32_t up_get_newintctx(void); +#ifdef CONFIG_ARCH_FPU +void up_savefpu(uint32_t *regs); +void up_restorefpu(const uint32_t *regs); +#else +# define up_savefpu(regs) +# define up_restorefpu(regs) +#endif + /* Low level serial output **************************************************/ void up_lowputc(char ch); diff --git a/arch/risc-v/src/rv32im/up_fpu.S b/arch/risc-v/src/rv32im/up_fpu.S new file mode 100644 index 0000000..f24c867 --- /dev/null +++ b/arch/risc-v/src/rv32im/up_fpu.S @@ -0,0 +1,251 @@ +/************************************************************************************ + * arch/risc-v/src/rv32im/up_fpu.S + * + * Copyright (C) 2018 Pinecone Inc. All rights reserved. + * Author: Zhang Xiaoqin <zhangxiao...@pinecone.net> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include <nuttx/config.h> +#include <arch/rv32im/irq.h> + +#ifdef CONFIG_ARCH_FPU + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .globl up_fpuconfig + .globl up_savefpu + .globl up_restorefpu + + .file "up_fpu.S" + +#define FS_MASK 0x6000 +#define FS_OFF 0x0000 +#define FS_INITIAL 0x2000 +#define FS_CLEAN 0x4000 +#define FS_DIRTY 0x6000 + +#if defined(CONFIG_ARCH_DPFPU) +# define FLOAD fld +# define FSTORE fsd +#elif defined(CONFIG_ARCH_QPFPU) +# define FLOAD flq +# define FSTORE fsq +#else +# define FLOAD flw +# define FSTORE fsw +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_fpuconfig + * + * Description: + * init fpu + * + * C Function Prototype: + * void up_fpuconfig(void); + * + * Input Parameters: + * None + * + * Returned Value: + * This function does not return anything explicitly. + * + ************************************************************************************/ + + .type up_fpuconfig, function + +up_fpuconfig: + li a0, FS_INITIAL + csrs mstatus, a0 + csrwi fcsr, 0 + ret + +/************************************************************************************ + * Name: up_savefpu + * + * Description: + * Given the pointer to a register save area (in A0), save the state of the + * floating point registers. + * + * C Function Prototype: + * void up_savefpu(uint32_t *regs); + * + * Input Parameters: + * regs - A pointer to the register save area in which to save the floating point + * registers + * + * Returned Value: + * None + * + ************************************************************************************/ + + .type up_savefpu, function + +up_savefpu: + lw t0, REG_INT_CTX(a0) + li t1, FS_MASK + and t2, t0, t1 + li t1, FS_DIRTY + bne t2, t1, 1f + li t1, ~FS_MASK + and t0, t0, t1 + li t1, FS_CLEAN + or t0, t0, t1 + sw t0, REG_INT_CTX(a0) + + /* Store all floating point registers */ + + FSTORE f0, REG_F0(a0) + FSTORE f1, REG_F1(a0) + FSTORE f2, REG_F2(a0) + FSTORE f3, REG_F3(a0) + FSTORE f4, REG_F4(a0) + FSTORE f5, REG_F5(a0) + FSTORE f6, REG_F6(a0) + FSTORE f7, REG_F7(a0) + FSTORE f8, REG_F8(a0) + FSTORE f9, REG_F9(a0) + FSTORE f10, REG_F10(a0) + FSTORE f11, REG_F11(a0) + FSTORE f12, REG_F12(a0) + FSTORE f13, REG_F13(a0) + FSTORE f14, REG_F14(a0) + FSTORE f15, REG_F15(a0) + FSTORE f16, REG_F16(a0) + FSTORE f17, REG_F17(a0) + FSTORE f18, REG_F18(a0) + FSTORE f19, REG_F19(a0) + FSTORE f20, REG_F20(a0) + FSTORE f21, REG_F21(a0) + FSTORE f22, REG_F22(a0) + FSTORE f23, REG_F23(a0) + FSTORE f24, REG_F24(a0) + FSTORE f25, REG_F25(a0) + FSTORE f26, REG_F26(a0) + FSTORE f27, REG_F27(a0) + FSTORE f28, REG_F28(a0) + FSTORE f29, REG_F29(a0) + FSTORE f30, REG_F30(a0) + FSTORE f31, REG_F31(a0) + + frcsr t0 + sw t0, REG_FCSR(a0) + +1: + ret + +/************************************************************************************ + * Name: up_restorefpu + * + * Description: + * Given the pointer to a register save area (in A0), restore the state of the + * floating point registers. + * + * C Function Prototype: + * void up_restorefpu(const uint32_t *regs); + * + * Input Parameters: + * regs - A pointer to the register save area containing the floating point + * registers. + * + * Returned Value: + * This function does not return anything explicitly. However, it is called from + * interrupt level assembly logic that assumes that r0 is preserved. + * + ************************************************************************************/ + + .type up_restorefpu, function + +up_restorefpu: + lw t0, REG_INT_CTX(a0) + li t1, FS_MASK + and t2, t0, t1 + li t1, FS_INITIAL + ble t2, t1, 1f + + /* Load all floating point registers */ + + FLOAD f0, REG_F0(a0) + FLOAD f1, REG_F1(a0) + FLOAD f2, REG_F2(a0) + FLOAD f3, REG_F3(a0) + FLOAD f4, REG_F4(a0) + FLOAD f5, REG_F5(a0) + FLOAD f6, REG_F6(a0) + FLOAD f7, REG_F7(a0) + FLOAD f8, REG_F8(a0) + FLOAD f9, REG_F9(a0) + FLOAD f10, REG_F10(a0) + FLOAD f11, REG_F11(a0) + FLOAD f12, REG_F12(a0) + FLOAD f13, REG_F13(a0) + FLOAD f14, REG_F14(a0) + FLOAD f15, REG_F15(a0) + FLOAD f16, REG_F16(a0) + FLOAD f17, REG_F17(a0) + FLOAD f18, REG_F18(a0) + FLOAD f19, REG_F19(a0) + FLOAD f20, REG_F20(a0) + FLOAD f21, REG_F21(a0) + FLOAD f22, REG_F22(a0) + FLOAD f23, REG_F23(a0) + FLOAD f24, REG_F24(a0) + FLOAD f25, REG_F25(a0) + FLOAD f26, REG_F26(a0) + FLOAD f27, REG_F27(a0) + FLOAD f28, REG_F28(a0) + FLOAD f29, REG_F29(a0) + FLOAD f30, REG_F30(a0) + FLOAD f31, REG_F31(a0) + + /* Store the floating point control and status register */ + + lw t0, REG_FCSR(a0) + fscsr t0 + +1: + ret + +#endif /* CONFIG_ARCH_FPU */