Add fpu support.

This commit is contained in:
zhongan 2020-04-02 11:20:20 +08:00 committed by Gregory Nutt
parent 957c14d95e
commit 0d3691a460
3 changed files with 371 additions and 2 deletions

View File

@ -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

View File

@ -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);

View File

@ -0,0 +1,236 @@
/************************************************************************************
* arch/risc-v/src/rv32im/up_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/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 */