mirror of
https://github.com/apache/nuttx.git
synced 2026-10-06 22:05:21 +00:00
arch:rv64:c906:enable DP FPU support.
Signed-off-by: hotislandn <hotislandn@hotmail.com>
This commit is contained in:
parent
07b65d10f1
commit
d898bc445c
12 changed files with 591 additions and 34 deletions
|
|
@ -1,37 +1,20 @@
|
|||
/****************************************************************************
|
||||
* arch/risc-v/include/rv64gc/irq.h
|
||||
*
|
||||
* Copyright (C) 2011, 2013, 2015 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
* 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 <pettitkd@gmail.com>
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
236
arch/risc-v/src/rv64gc/riscv_fpu.S
Normal file
236
arch/risc-v/src/rv64gc/riscv_fpu.S
Normal file
|
|
@ -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 <nuttx/config.h>
|
||||
#include <arch/rv64gc/irq.h>
|
||||
|
||||
#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 */
|
||||
62
boards/risc-v/c906/smartl-c906/configs/fpu/defconfig
Normal file
62
boards/risc-v/c906/smartl-c906/configs/fpu/defconfig
Normal file
|
|
@ -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"
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
92
boards/risc-v/c906/smartl-c906/src/c906_ostest.c
Normal file
92
boards/risc-v/c906/smartl-c906/src/c906_ostest.c
Normal file
|
|
@ -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 <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <syscall.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
|
||||
/****************************************************************************
|
||||
* 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 */
|
||||
Loading…
Add table
Add a link
Reference in a new issue