From d898bc445c0e181d0ce763ceb0cec169b8fde143 Mon Sep 17 00:00:00 2001 From: hotislandn Date: Wed, 10 Mar 2021 23:31:29 +0800 Subject: [PATCH] arch:rv64:c906:enable DP FPU support. Signed-off-by: hotislandn --- arch/risc-v/include/rv64gc/irq.h | 173 ++++++++++--- arch/risc-v/include/rv64gc/syscall.h | 13 +- arch/risc-v/src/c906/Kconfig | 8 + arch/risc-v/src/c906/Make.defs | 4 + arch/risc-v/src/c906/c906_irq.c | 4 + arch/risc-v/src/common/riscv_internal.h | 5 + arch/risc-v/src/rv64gc/riscv_copystate.c | 17 +- arch/risc-v/src/rv64gc/riscv_fpu.S | 236 ++++++++++++++++++ .../c906/smartl-c906/configs/fpu/defconfig | 62 +++++ .../risc-v/c906/smartl-c906/scripts/Make.defs | 7 +- boards/risc-v/c906/smartl-c906/src/Makefile | 4 + .../risc-v/c906/smartl-c906/src/c906_ostest.c | 92 +++++++ 12 files changed, 591 insertions(+), 34 deletions(-) create mode 100644 arch/risc-v/src/rv64gc/riscv_fpu.S create mode 100644 boards/risc-v/c906/smartl-c906/configs/fpu/defconfig create mode 100644 boards/risc-v/c906/smartl-c906/src/c906_ostest.c diff --git a/arch/risc-v/include/rv64gc/irq.h b/arch/risc-v/include/rv64gc/irq.h index 0e1aebb5e40..c9e51ed06ac 100644 --- a/arch/risc-v/include/rv64gc/irq.h +++ b/arch/risc-v/include/rv64gc/irq.h @@ -1,37 +1,20 @@ /**************************************************************************** * arch/risc-v/include/rv64gc/irq.h * - * Copyright (C) 2011, 2013, 2015 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at * - * Modified for RISC-V: + * http://www.apache.org/licenses/LICENSE-2.0 * - * Copyright (C) 2016 Ken Pettit. All rights reserved. - * Author: Ken Pettit - * - * 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. - * - * 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. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. * ****************************************************************************/ @@ -132,9 +115,63 @@ #define REG_INT_CTX_NDX 32 -#define XCPTCONTEXT_REGS 33 +#define INT_XCPT_REGS 33 -#define XCPTCONTEXT_SIZE (8*XCPTCONTEXT_REGS) +#define INT_XCPT_SIZE (8 * INT_XCPT_REGS) + +/* FPU REG size in uint64_t */ + +#ifdef CONFIG_ARCH_FPU +#if defined(CONFIG_ARCH_DPFPU) +# define FPU_REG_SIZE 1 +#elif defined(CONFIG_ARCH_QPFPU) +# define FPU_REG_SIZE 2 +#else +# error not supported !!! +#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 /* !CONFIG_ARCH_FPU */ +# define FPU_XCPT_REGS 0 +#endif /* CONFIG_ARCH_FPU */ + +#define XCPTCONTEXT_REGS (INT_XCPT_REGS + FPU_XCPT_REGS) + +#define XCPTCONTEXT_SIZE (8 * XCPTCONTEXT_REGS) /* In assembly language, values have to be referenced as byte address * offsets. But in C, it is more convenient to reference registers as @@ -175,6 +212,43 @@ # define REG_X30 (8*REG_X30_NDX) # define REG_X31 (8*REG_X31_NDX) # define REG_INT_CTX (8*REG_INT_CTX_NDX) + +#ifdef CONFIG_ARCH_FPU +# define REG_F0 (8*REG_F0_NDX) +# define REG_F1 (8*REG_F1_NDX) +# define REG_F2 (8*REG_F2_NDX) +# define REG_F3 (8*REG_F3_NDX) +# define REG_F4 (8*REG_F4_NDX) +# define REG_F5 (8*REG_F5_NDX) +# define REG_F6 (8*REG_F6_NDX) +# define REG_F7 (8*REG_F7_NDX) +# define REG_F8 (8*REG_F8_NDX) +# define REG_F9 (8*REG_F9_NDX) +# define REG_F10 (8*REG_F10_NDX) +# define REG_F11 (8*REG_F11_NDX) +# define REG_F12 (8*REG_F12_NDX) +# define REG_F13 (8*REG_F13_NDX) +# define REG_F14 (8*REG_F14_NDX) +# define REG_F15 (8*REG_F15_NDX) +# define REG_F16 (8*REG_F16_NDX) +# define REG_F17 (8*REG_F17_NDX) +# define REG_F18 (8*REG_F18_NDX) +# define REG_F19 (8*REG_F19_NDX) +# define REG_F20 (8*REG_F20_NDX) +# define REG_F21 (8*REG_F21_NDX) +# define REG_F22 (8*REG_F22_NDX) +# define REG_F23 (8*REG_F23_NDX) +# define REG_F24 (8*REG_F24_NDX) +# define REG_F25 (8*REG_F25_NDX) +# define REG_F26 (8*REG_F26_NDX) +# define REG_F27 (8*REG_F27_NDX) +# define REG_F28 (8*REG_F28_NDX) +# define REG_F29 (8*REG_F29_NDX) +# define REG_F30 (8*REG_F30_NDX) +# define REG_F31 (8*REG_F31_NDX) +# define REG_FCSR (8*REG_FCSR_NDX) +#endif + #else # define REG_EPC REG_EPC_NDX # define REG_X1 REG_X1_NDX @@ -209,6 +283,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/include/rv64gc/syscall.h b/arch/risc-v/include/rv64gc/syscall.h index 93f8ea5e131..bc8c9adc6d0 100644 --- a/arch/risc-v/include/rv64gc/syscall.h +++ b/arch/risc-v/include/rv64gc/syscall.h @@ -88,7 +88,18 @@ /* Context switching system calls *******************************************/ -/* SYS call 0: (not used) */ +/* SYS call 0: + * + * int up_saveusercontext(uint64_t *saveregs); + * + * Return: + * 0: Normal Return + * 1: Context Switch Return + */ + +#define SYS_save_context (0) +#define up_saveusercontext(saveregs) \ + (int)sys_call1(SYS_save_context, (uintptr_t)saveregs) /* SYS call 1: * diff --git a/arch/risc-v/src/c906/Kconfig b/arch/risc-v/src/c906/Kconfig index 412f80957a3..edf77f690e1 100644 --- a/arch/risc-v/src/c906/Kconfig +++ b/arch/risc-v/src/c906/Kconfig @@ -5,6 +5,14 @@ comment "C906 Configuration Options" +config C906_ENABLE_DPFPU + bool "C906 DP_FPU Support" + default n + select ARCH_HAVE_FPU + select ARCH_HAVE_DPFPU + ---help--- + Enable the RISC-V Double-Precision Floating Point Unit (DP-FPU). + menu "C906 Peripheral Support" # These "hidden" settings determine whether a peripheral option is available diff --git a/arch/risc-v/src/c906/Make.defs b/arch/risc-v/src/c906/Make.defs index 44b193dcd59..5b4e69c2833 100644 --- a/arch/risc-v/src/c906/Make.defs +++ b/arch/risc-v/src/c906/Make.defs @@ -39,6 +39,10 @@ ifeq ($(CONFIG_STACK_COLORATION),y) CMN_CSRCS += riscv_checkstack.c endif +ifeq ($(CONFIG_ARCH_FPU),y) +CMN_ASRCS += riscv_fpu.S +endif + ifeq ($(CONFIG_ARCH_HAVE_VFORK),y) CMN_CSRCS += riscv_vfork.c endif diff --git a/arch/risc-v/src/c906/c906_irq.c b/arch/risc-v/src/c906/c906_irq.c index 57977ebddbc..9d2449ea244 100644 --- a/arch/risc-v/src/c906/c906_irq.c +++ b/arch/risc-v/src/c906/c906_irq.c @@ -215,7 +215,11 @@ uint32_t up_get_newintctx(void) * user code. Also set machine previous interrupt enable. */ +#ifdef CONFIG_ARCH_FPU return (MSTATUS_FS_INIT | MSTATUS_MPPM | MSTATUS_MPIE); +#else + return (MSTATUS_MPPM | MSTATUS_MPIE); +#endif } /**************************************************************************** diff --git a/arch/risc-v/src/common/riscv_internal.h b/arch/risc-v/src/common/riscv_internal.h index ed583cd56e6..88b1ceb85d3 100644 --- a/arch/risc-v/src/common/riscv_internal.h +++ b/arch/risc-v/src/common/riscv_internal.h @@ -197,8 +197,13 @@ int up_swint(int irq, FAR void *context, FAR void *arg); uint32_t up_get_newintctx(void); #ifdef CONFIG_ARCH_FPU +#ifdef CONFIG_ARCH_RV64GC +void up_savefpu(uint64_t *regs); +void up_restorefpu(const uint64_t *regs); +#else /* !CONFIG_ARCH_RV64GC */ void up_savefpu(uint32_t *regs); void up_restorefpu(const uint32_t *regs); +#endif /* CONFIG_ARCH_RV64GC */ #else # define up_savefpu(regs) # define up_restorefpu(regs) diff --git a/arch/risc-v/src/rv64gc/riscv_copystate.c b/arch/risc-v/src/rv64gc/riscv_copystate.c index 37df1b82da1..3d60870fc61 100644 --- a/arch/risc-v/src/rv64gc/riscv_copystate.c +++ b/arch/risc-v/src/rv64gc/riscv_copystate.c @@ -70,6 +70,10 @@ void up_copystate(uint64_t *dest, uint64_t *src) { int i; +#ifdef CONFIG_ARCH_FPU + uint64_t *regs = dest; +#endif + /* In the RISC-V model, the state is copied from the stack to the TCB, * but only a reference is passed to get the state from the TCB. So the * following check avoids copying the TCB save area onto itself: @@ -77,9 +81,20 @@ void up_copystate(uint64_t *dest, uint64_t *src) if (src != dest) { - for (i = 0; i < XCPTCONTEXT_REGS; i++) + /* save integer registers first */ + + for (i = 0; i < INT_XCPT_REGS; i++) { *dest++ = *src++; } + + /* Save the floating point registers: This will initialize the floating + * registers at indices INT_XCPT_REGS through (XCPTCONTEXT_REGS-1). + * Do this after saving REG_INT_CTX with the ORIGINAL context pointer. + */ + +#ifdef CONFIG_ARCH_FPU + up_savefpu(regs); +#endif } } diff --git a/arch/risc-v/src/rv64gc/riscv_fpu.S b/arch/risc-v/src/rv64gc/riscv_fpu.S new file mode 100644 index 00000000000..07c0b74266c --- /dev/null +++ b/arch/risc-v/src/rv64gc/riscv_fpu.S @@ -0,0 +1,236 @@ +/************************************************************************************ + * arch/risc-v/src/rv64gc/riscv_fpu.S + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#ifdef CONFIG_ARCH_FPU + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .globl up_fpuconfig + .globl up_savefpu + .globl up_restorefpu + + .file "riscv_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 */ diff --git a/boards/risc-v/c906/smartl-c906/configs/fpu/defconfig b/boards/risc-v/c906/smartl-c906/configs/fpu/defconfig new file mode 100644 index 00000000000..6a10336d8da --- /dev/null +++ b/boards/risc-v/c906/smartl-c906/configs/fpu/defconfig @@ -0,0 +1,62 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_NSH_DISABLE_LOSMART is not set +# CONFIG_STANDARD_SERIAL is not set +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="smartl-c906" +CONFIG_ARCH_BOARD_SMARTL_C906=y +CONFIG_ARCH_CHIP="c906" +CONFIG_ARCH_CHIP_C906=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=46000 +CONFIG_BUILTIN=y +CONFIG_C906_ENABLE_DPFPU=y +CONFIG_C906_WITH_QEMU=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEV_ZERO=y +CONFIG_EXAMPLES_HELLO=y +CONFIG_FS_PROCFS=y +CONFIG_FS_ROMFS=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_MAX_TASKS=64 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_DISABLE_MKDIR=y +CONFIG_NSH_DISABLE_RM=y +CONFIG_NSH_DISABLE_RMDIR=y +CONFIG_NSH_DISABLE_UMOUNT=y +CONFIG_NSH_READLINE=y +CONFIG_NSH_STRERROR=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=262144 +CONFIG_RAM_START=0x00180000 +CONFIG_RAW_BINARY=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=7 +CONFIG_START_MONTH=3 +CONFIG_START_YEAR=2021 +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=20 +CONFIG_TESTING_GETPRIME=y +CONFIG_TESTING_OSTEST=y +CONFIG_TESTING_OSTEST_FPUSIZE=264 +CONFIG_UART0_SERIAL_CONSOLE=y +CONFIG_USERMAIN_STACKSIZE=3072 +CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/boards/risc-v/c906/smartl-c906/scripts/Make.defs b/boards/risc-v/c906/smartl-c906/scripts/Make.defs index 55fbf393695..5b55ce118dc 100644 --- a/boards/risc-v/c906/smartl-c906/scripts/Make.defs +++ b/boards/risc-v/c906/smartl-c906/scripts/Make.defs @@ -50,7 +50,12 @@ endif # ARCHCPUFLAGS = -march=rv64gcxthead -mabi=lp64d -mtune=c906 -mcmodel=medany # TODO: We are not going to enable this at this time for the CI compatiblity. -ARCHCPUFLAGS = -march=rv64gc -mabi=lp64d -mcmodel=medany +ifeq ($(CONFIG_ARCH_HAVE_DPFPU),y) + ARCHCPUFLAGS = -march=rv64gc -mabi=lp64d -mcmodel=medany +else + ARCHCPUFLAGS = -march=rv64imac -mabi=lp64 -mcmodel=medany +endif + ARCHCFLAGS = -fno-builtin -ffunction-sections -fdata-sections -fno-omit-frame-pointer ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fcheck-new -fno-rtti ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef diff --git a/boards/risc-v/c906/smartl-c906/src/Makefile b/boards/risc-v/c906/smartl-c906/src/Makefile index a61617675a9..4b5f2c7253c 100644 --- a/boards/risc-v/c906/smartl-c906/src/Makefile +++ b/boards/risc-v/c906/smartl-c906/src/Makefile @@ -30,4 +30,8 @@ ifeq ($(CONFIG_ARCH_LEDS),y) CSRCS += c906_leds.c endif +ifeq ($(CONFIG_ARCH_FPU),y) +CSRCS += c906_ostest.c +endif + include $(TOPDIR)/boards/Board.mk diff --git a/boards/risc-v/c906/smartl-c906/src/c906_ostest.c b/boards/risc-v/c906/smartl-c906/src/c906_ostest.c new file mode 100644 index 00000000000..e4529c48e13 --- /dev/null +++ b/boards/risc-v/c906/smartl-c906/src/c906_ostest.c @@ -0,0 +1,92 @@ +/**************************************************************************** + * boards/risc-v/c906/smartl-c906/src/c906_ostest.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#undef HAVE_FPU +#if defined(CONFIG_ARCH_FPU) && \ + !defined(CONFIG_TESTING_OSTEST_FPUTESTDISABLE) && \ + defined(CONFIG_TESTING_OSTEST_FPUSIZE) && \ + defined(CONFIG_SCHED_WAITPID) +# define HAVE_FPU 1 +#endif + +#ifdef HAVE_FPU + +#if CONFIG_TESTING_OSTEST_FPUSIZE != (8 * FPU_XCPT_REGS) +# error "CONFIG_TESTING_OSTEST_FPUSIZE has the wrong size" +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint64_t g_saveregs[XCPTCONTEXT_REGS]; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* Given an array of size CONFIG_TESTING_OSTEST_FPUSIZE, this function will + * return the current FPU registers. + */ + +void arch_getfpu(FAR uint32_t *fpusave) +{ + irqstate_t flags; + + /* Take a snapshot of the thread context right now */ + + flags = enter_critical_section(); + up_saveusercontext(g_saveregs); + + /* Return only the floating register values */ + + memcpy(fpusave, &g_saveregs[INT_XCPT_REGS], (8 * FPU_XCPT_REGS)); + leave_critical_section(flags); +} + +/* Given two arrays of size CONFIG_TESTING_OSTEST_FPUSIZE this function + * will compare them and return true if they are identical. + */ + +bool arch_cmpfpu(FAR const uint32_t *fpusave1, FAR const uint32_t *fpusave2) +{ + return memcmp(fpusave1, fpusave2, (8 * FPU_XCPT_REGS)) == 0; +} + +#endif /* HAVE_FPU */