mirror of
https://github.com/apache/nuttx.git
synced 2026-08-28 12:50:36 +00:00
arch/risc-v: Merge rv32im and rv64gc into common
Signed-off-by: Huang Qi <huangqi3@xiaomi.com>
This commit is contained in:
parent
efca63e9e3
commit
10bb48b9b4
73 changed files with 701 additions and 2030 deletions
|
|
@ -199,9 +199,6 @@ endif
|
|||
source "arch/risc-v/src/opensbi/Kconfig"
|
||||
source "arch/risc-v/src/common/Kconfig"
|
||||
|
||||
if ARCH_RV32
|
||||
source "arch/risc-v/src/rv32im/Kconfig"
|
||||
endif
|
||||
if ARCH_CHIP_FE310
|
||||
source "arch/risc-v/src/fe310/Kconfig"
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -31,21 +31,457 @@
|
|||
|
||||
/* Include chip-specific IRQ definitions (including IRQ numbers) */
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/types.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <stdint.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <arch/csr.h>
|
||||
#include <arch/chip/irq.h>
|
||||
|
||||
/* Include RISC-V architecture-specific IRQ definitions */
|
||||
|
||||
#if defined(CONFIG_ARCH_RV32)
|
||||
# include <arch/rv32im/irq.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARCH_RV64)
|
||||
# include <arch/rv64gc/irq.h>
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/* If this is a kernel build, how many nested system calls should we
|
||||
* support?
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_SYS_NNEST
|
||||
# define CONFIG_SYS_NNEST 2
|
||||
#endif
|
||||
|
||||
/* Processor PC */
|
||||
|
||||
#define REG_EPC_NDX 0
|
||||
|
||||
/* General pupose registers
|
||||
* $0: Zero register does not need to be saved
|
||||
* $1: ra (return address)
|
||||
*/
|
||||
|
||||
#define REG_X1_NDX 1
|
||||
|
||||
/* $2: Stack POinter
|
||||
* $3: Global Pointer
|
||||
* $4: Thread Pointer
|
||||
*/
|
||||
|
||||
#define REG_X2_NDX 2
|
||||
#define REG_X3_NDX 3
|
||||
#define REG_X4_NDX 4
|
||||
|
||||
/* $5-$7 = t0-t3: Temporary registers */
|
||||
|
||||
#define REG_X5_NDX 5
|
||||
#define REG_X6_NDX 6
|
||||
#define REG_X7_NDX 7
|
||||
|
||||
/* $8: s0 / fp Frame pointer */
|
||||
|
||||
#define REG_X8_NDX 8
|
||||
|
||||
/* $89 s1 Saved register */
|
||||
|
||||
#define REG_X9_NDX 9
|
||||
|
||||
/* $10-$17 = a0-a7: Argument registers */
|
||||
|
||||
#define REG_X10_NDX 10
|
||||
#define REG_X11_NDX 11
|
||||
#define REG_X12_NDX 12
|
||||
#define REG_X13_NDX 13
|
||||
#define REG_X14_NDX 14
|
||||
#define REG_X15_NDX 15
|
||||
#define REG_X16_NDX 16
|
||||
#define REG_X17_NDX 17
|
||||
|
||||
/* $18-$27 = s2-s11: Saved registers */
|
||||
|
||||
#define REG_X18_NDX 18
|
||||
#define REG_X19_NDX 19
|
||||
#define REG_X20_NDX 20
|
||||
#define REG_X21_NDX 21
|
||||
#define REG_X22_NDX 22
|
||||
#define REG_X23_NDX 23
|
||||
#define REG_X24_NDX 24
|
||||
#define REG_X25_NDX 25
|
||||
#define REG_X26_NDX 26
|
||||
#define REG_X27_NDX 27
|
||||
|
||||
/* $28-31 = t3-t6: Temporary (Volatile) registers */
|
||||
|
||||
#define REG_X28_NDX 28
|
||||
#define REG_X29_NDX 29
|
||||
#define REG_X30_NDX 30
|
||||
#define REG_X31_NDX 31
|
||||
|
||||
/* Interrupt Context register */
|
||||
|
||||
#define REG_INT_CTX_NDX 32
|
||||
|
||||
#ifdef CONFIG_ARCH_RISCV_INTXCPT_EXTREGS
|
||||
# define INT_XCPT_REGS (33 + CONFIG_ARCH_RISCV_INTXCPT_EXTREGS)
|
||||
#else
|
||||
# define INT_XCPT_REGS 33
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_RV32
|
||||
# define INT_REG_SIZE 4
|
||||
#else
|
||||
# define INT_REG_SIZE 8
|
||||
#endif
|
||||
|
||||
#define INT_XCPT_SIZE (INT_REG_SIZE * INT_XCPT_REGS)
|
||||
|
||||
#ifdef CONFIG_ARCH_RV32
|
||||
# if defined(CONFIG_ARCH_DPFPU)
|
||||
# define FPU_REG_SIZE 2
|
||||
# elif defined(CONFIG_ARCH_QPFPU)
|
||||
# define FPU_REG_SIZE 4
|
||||
# elif defined(CONFIG_ARCH_FPU)
|
||||
# define FPU_REG_SIZE 1
|
||||
# endif
|
||||
#else
|
||||
# if defined(CONFIG_ARCH_QPFPU)
|
||||
# define FPU_REG_SIZE 2
|
||||
# else
|
||||
# define FPU_REG_SIZE 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
# 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 (INT_REG_SIZE * 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
|
||||
* register save table offsets.
|
||||
*/
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
# define REG_EPC (INT_REG_SIZE*REG_EPC_NDX)
|
||||
# define REG_X1 (INT_REG_SIZE*REG_X1_NDX)
|
||||
# define REG_X2 (INT_REG_SIZE*REG_X2_NDX)
|
||||
# define REG_X3 (INT_REG_SIZE*REG_X3_NDX)
|
||||
# define REG_X4 (INT_REG_SIZE*REG_X4_NDX)
|
||||
# define REG_X5 (INT_REG_SIZE*REG_X5_NDX)
|
||||
# define REG_X6 (INT_REG_SIZE*REG_X6_NDX)
|
||||
# define REG_X7 (INT_REG_SIZE*REG_X7_NDX)
|
||||
# define REG_X8 (INT_REG_SIZE*REG_X8_NDX)
|
||||
# define REG_X9 (INT_REG_SIZE*REG_X9_NDX)
|
||||
# define REG_X10 (INT_REG_SIZE*REG_X10_NDX)
|
||||
# define REG_X11 (INT_REG_SIZE*REG_X11_NDX)
|
||||
# define REG_X12 (INT_REG_SIZE*REG_X12_NDX)
|
||||
# define REG_X13 (INT_REG_SIZE*REG_X13_NDX)
|
||||
# define REG_X14 (INT_REG_SIZE*REG_X14_NDX)
|
||||
# define REG_X15 (INT_REG_SIZE*REG_X15_NDX)
|
||||
# define REG_X16 (INT_REG_SIZE*REG_X16_NDX)
|
||||
# define REG_X17 (INT_REG_SIZE*REG_X17_NDX)
|
||||
# define REG_X18 (INT_REG_SIZE*REG_X18_NDX)
|
||||
# define REG_X19 (INT_REG_SIZE*REG_X19_NDX)
|
||||
# define REG_X20 (INT_REG_SIZE*REG_X20_NDX)
|
||||
# define REG_X21 (INT_REG_SIZE*REG_X21_NDX)
|
||||
# define REG_X22 (INT_REG_SIZE*REG_X22_NDX)
|
||||
# define REG_X23 (INT_REG_SIZE*REG_X23_NDX)
|
||||
# define REG_X24 (INT_REG_SIZE*REG_X24_NDX)
|
||||
# define REG_X25 (INT_REG_SIZE*REG_X25_NDX)
|
||||
# define REG_X26 (INT_REG_SIZE*REG_X26_NDX)
|
||||
# define REG_X27 (INT_REG_SIZE*REG_X27_NDX)
|
||||
# define REG_X28 (INT_REG_SIZE*REG_X28_NDX)
|
||||
# define REG_X29 (INT_REG_SIZE*REG_X29_NDX)
|
||||
# define REG_X30 (INT_REG_SIZE*REG_X30_NDX)
|
||||
# define REG_X31 (INT_REG_SIZE*REG_X31_NDX)
|
||||
# define REG_INT_CTX (INT_REG_SIZE*REG_INT_CTX_NDX)
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
# define REG_F0 (INT_REG_SIZE*REG_F0_NDX)
|
||||
# define REG_F1 (INT_REG_SIZE*REG_F1_NDX)
|
||||
# define REG_F2 (INT_REG_SIZE*REG_F2_NDX)
|
||||
# define REG_F3 (INT_REG_SIZE*REG_F3_NDX)
|
||||
# define REG_F4 (INT_REG_SIZE*REG_F4_NDX)
|
||||
# define REG_F5 (INT_REG_SIZE*REG_F5_NDX)
|
||||
# define REG_F6 (INT_REG_SIZE*REG_F6_NDX)
|
||||
# define REG_F7 (INT_REG_SIZE*REG_F7_NDX)
|
||||
# define REG_F8 (INT_REG_SIZE*REG_F8_NDX)
|
||||
# define REG_F9 (INT_REG_SIZE*REG_F9_NDX)
|
||||
# define REG_F10 (INT_REG_SIZE*REG_F10_NDX)
|
||||
# define REG_F11 (INT_REG_SIZE*REG_F11_NDX)
|
||||
# define REG_F12 (INT_REG_SIZE*REG_F12_NDX)
|
||||
# define REG_F13 (INT_REG_SIZE*REG_F13_NDX)
|
||||
# define REG_F14 (INT_REG_SIZE*REG_F14_NDX)
|
||||
# define REG_F15 (INT_REG_SIZE*REG_F15_NDX)
|
||||
# define REG_F16 (INT_REG_SIZE*REG_F16_NDX)
|
||||
# define REG_F17 (INT_REG_SIZE*REG_F17_NDX)
|
||||
# define REG_F18 (INT_REG_SIZE*REG_F18_NDX)
|
||||
# define REG_F19 (INT_REG_SIZE*REG_F19_NDX)
|
||||
# define REG_F20 (INT_REG_SIZE*REG_F20_NDX)
|
||||
# define REG_F21 (INT_REG_SIZE*REG_F21_NDX)
|
||||
# define REG_F22 (INT_REG_SIZE*REG_F22_NDX)
|
||||
# define REG_F23 (INT_REG_SIZE*REG_F23_NDX)
|
||||
# define REG_F24 (INT_REG_SIZE*REG_F24_NDX)
|
||||
# define REG_F25 (INT_REG_SIZE*REG_F25_NDX)
|
||||
# define REG_F26 (INT_REG_SIZE*REG_F26_NDX)
|
||||
# define REG_F27 (INT_REG_SIZE*REG_F27_NDX)
|
||||
# define REG_F28 (INT_REG_SIZE*REG_F28_NDX)
|
||||
# define REG_F29 (INT_REG_SIZE*REG_F29_NDX)
|
||||
# define REG_F30 (INT_REG_SIZE*REG_F30_NDX)
|
||||
# define REG_F31 (INT_REG_SIZE*REG_F31_NDX)
|
||||
# define REG_FCSR (INT_REG_SIZE*REG_FCSR_NDX)
|
||||
#endif
|
||||
|
||||
#else
|
||||
# define REG_EPC REG_EPC_NDX
|
||||
# define REG_X1 REG_X1_NDX
|
||||
# define REG_X2 REG_X2_NDX
|
||||
# define REG_X3 REG_X3_NDX
|
||||
# define REG_X4 REG_X4_NDX
|
||||
# define REG_X5 REG_X5_NDX
|
||||
# define REG_X6 REG_X6_NDX
|
||||
# define REG_X7 REG_X7_NDX
|
||||
# define REG_X8 REG_X8_NDX
|
||||
# define REG_X9 REG_X9_NDX
|
||||
# define REG_X10 REG_X10_NDX
|
||||
# define REG_X11 REG_X11_NDX
|
||||
# define REG_X12 REG_X12_NDX
|
||||
# define REG_X13 REG_X13_NDX
|
||||
# define REG_X14 REG_X14_NDX
|
||||
# define REG_X15 REG_X15_NDX
|
||||
# define REG_X16 REG_X16_NDX
|
||||
# define REG_X17 REG_X17_NDX
|
||||
# define REG_X18 REG_X18_NDX
|
||||
# define REG_X19 REG_X19_NDX
|
||||
# define REG_X20 REG_X20_NDX
|
||||
# define REG_X21 REG_X21_NDX
|
||||
# define REG_X22 REG_X22_NDX
|
||||
# define REG_X23 REG_X23_NDX
|
||||
# define REG_X24 REG_X24_NDX
|
||||
# define REG_X25 REG_X25_NDX
|
||||
# define REG_X26 REG_X26_NDX
|
||||
# define REG_X27 REG_X27_NDX
|
||||
# define REG_X28 REG_X28_NDX
|
||||
# define REG_X29 REG_X29_NDX
|
||||
# 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
|
||||
* in assembly or C contexts.
|
||||
*/
|
||||
|
||||
/* $1 = ra: Return address */
|
||||
|
||||
#define REG_RA REG_X1
|
||||
|
||||
/* $2 = sp: The value of the stack pointer on return from the exception */
|
||||
|
||||
#define REG_SP REG_X2
|
||||
|
||||
/* $3 = gp: Only needs to be saved under conditions where there are
|
||||
* multiple, per-thread values for the GP.
|
||||
*/
|
||||
|
||||
#define REG_GP REG_X3
|
||||
|
||||
/* $4 = tp: Thread Pointer */
|
||||
|
||||
#define REG_TP REG_X4
|
||||
|
||||
/* $5-$7 = t0-t2: Caller saved temporary registers */
|
||||
|
||||
#define REG_T0 REG_X5
|
||||
#define REG_T1 REG_X6
|
||||
#define REG_T2 REG_X7
|
||||
|
||||
/* $8 = either s0 or fp: Depends if a frame pointer is used or not */
|
||||
|
||||
#define REG_S0 REG_X8
|
||||
#define REG_FP REG_X8
|
||||
|
||||
/* $9 = s1: Caller saved register */
|
||||
|
||||
#define REG_S1 REG_X9
|
||||
|
||||
/* $10-$17 = a0-a7: Argument registers */
|
||||
|
||||
#define REG_A0 REG_X10
|
||||
#define REG_A1 REG_X11
|
||||
#define REG_A2 REG_X12
|
||||
#define REG_A3 REG_X13
|
||||
#define REG_A4 REG_X14
|
||||
#define REG_A5 REG_X15
|
||||
#define REG_A6 REG_X16
|
||||
#define REG_A7 REG_X17
|
||||
|
||||
/* $18-$27 = s2-s11: Callee saved registers */
|
||||
|
||||
#define REG_S2 REG_X18
|
||||
#define REG_S3 REG_X19
|
||||
#define REG_S4 REG_X20
|
||||
#define REG_S5 REG_X21
|
||||
#define REG_S6 REG_X22
|
||||
#define REG_S7 REG_X23
|
||||
#define REG_S8 REG_X24
|
||||
#define REG_S9 REG_X25
|
||||
#define REG_S10 REG_X26
|
||||
#define REG_S11 REG_X27
|
||||
|
||||
/* $28-$31 = t3-t6: Caller saved temporary registers */
|
||||
|
||||
#define REG_T3 REG_X28
|
||||
#define REG_T4 REG_X29
|
||||
#define REG_T5 REG_X30
|
||||
#define REG_T6 REG_X31
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/* This structure represents the return state from a system call */
|
||||
|
||||
#ifdef CONFIG_LIB_SYSCALL
|
||||
struct xcpt_syscall_s
|
||||
{
|
||||
uintptr_t sysreturn; /* The return PC */
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
uintptr_t int_ctx; /* Interrupt context (i.e. mstatus) */
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
/* The following structure is included in the TCB and defines the complete
|
||||
* state of the thread.
|
||||
*/
|
||||
|
||||
struct xcptcontext
|
||||
{
|
||||
/* The following function pointer is non-NULL if there are pending signals
|
||||
* to be processed.
|
||||
*/
|
||||
|
||||
void *sigdeliver; /* Actual type is sig_deliver_t */
|
||||
|
||||
/* These additional register save locations are used to implement the
|
||||
* signal delivery trampoline.
|
||||
*
|
||||
* REVISIT: Because there is only one copy of these save areas,
|
||||
* only a single signal handler can be active. This precludes
|
||||
* queuing of signal actions. As a result, signals received while
|
||||
* another signal handler is executing will be ignored!
|
||||
*/
|
||||
|
||||
uintptr_t saved_epc; /* Trampoline PC */
|
||||
uintptr_t saved_int_ctx; /* Interrupt context with interrupts disabled. */
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
/* This is the saved address to use when returning from a user-space
|
||||
* signal handler.
|
||||
*/
|
||||
|
||||
uintptr_t sigreturn;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LIB_SYSCALL
|
||||
/* The following array holds information needed to return from each nested
|
||||
* system call.
|
||||
*/
|
||||
|
||||
uint8_t nsyscalls;
|
||||
struct xcpt_syscall_s syscall[CONFIG_SYS_NNEST];
|
||||
|
||||
#endif
|
||||
|
||||
/* Register save area */
|
||||
|
||||
uintptr_t regs[XCPTCONTEXT_REGS];
|
||||
};
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* arch/risc-v/include/rv32im/mcause.h
|
||||
* arch/risc-v/include/mcause.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
|
|
@ -18,8 +18,8 @@
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_RISCV_INCLUDE_RV32IM_MCAUSE_H
|
||||
#define __ARCH_RISCV_INCLUDE_RV32IM_MCAUSE_H
|
||||
#ifndef __ARCH_RISCV_INCLUDE_MCAUSE_H
|
||||
#define __ARCH_RISCV_INCLUDE_MCAUSE_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
|
|
@ -59,5 +59,5 @@
|
|||
|
||||
#define MCAUSE_MAX_EXCEPTION (15)
|
||||
|
||||
#endif /* __ARCH_RISCV_INCLUDE_RV32IM_MCAUSE_H */
|
||||
#endif /* __ARCH_RISCV_INCLUDE_MCAUSE_H */
|
||||
|
||||
|
|
@ -1,461 +0,0 @@
|
|||
/****************************************************************************
|
||||
* arch/risc-v/include/rv32im/irq.h
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* This file should never be included directly but, rather, only indirectly
|
||||
* through nuttx/irq.h
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_RISCV_INCLUDE_RV32IM_IRQ_H
|
||||
#define __ARCH_RISCV_INCLUDE_RV32IM_IRQ_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/types.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/* How many nested system calls should we support? */
|
||||
|
||||
#ifndef CONFIG_SYS_NNEST
|
||||
# define CONFIG_SYS_NNEST 2
|
||||
#endif
|
||||
|
||||
/* Processor PC */
|
||||
|
||||
#define REG_EPC_NDX 0
|
||||
|
||||
/* General pupose registers */
|
||||
|
||||
/* $0: Zero register does not need to be saved
|
||||
* $1: ra (return address)
|
||||
*/
|
||||
|
||||
#define REG_X1_NDX 1
|
||||
|
||||
/* $2: Stack Pointer
|
||||
* $3: Global Pointer
|
||||
* $4: Thread Pointer
|
||||
*/
|
||||
|
||||
#define REG_X2_NDX 2
|
||||
#define REG_X3_NDX 3
|
||||
#define REG_X4_NDX 4
|
||||
|
||||
/* $5-$7 = t0-t3: Temporary registers */
|
||||
|
||||
#define REG_X5_NDX 5
|
||||
#define REG_X6_NDX 6
|
||||
#define REG_X7_NDX 7
|
||||
|
||||
/* $8: s0 / fp Frame pointer */
|
||||
|
||||
#define REG_X8_NDX 8
|
||||
|
||||
/* $89 s1 Saved register */
|
||||
|
||||
#define REG_X9_NDX 9
|
||||
|
||||
/* $10-$17 = a0-a7: Argument registers */
|
||||
|
||||
#define REG_X10_NDX 10
|
||||
#define REG_X11_NDX 11
|
||||
#define REG_X12_NDX 12
|
||||
#define REG_X13_NDX 13
|
||||
#define REG_X14_NDX 14
|
||||
#define REG_X15_NDX 15
|
||||
#define REG_X16_NDX 16
|
||||
#define REG_X17_NDX 17
|
||||
|
||||
/* $18-$27 = s2-s11: Saved registers */
|
||||
|
||||
#define REG_X18_NDX 18
|
||||
#define REG_X19_NDX 19
|
||||
#define REG_X20_NDX 20
|
||||
#define REG_X21_NDX 21
|
||||
#define REG_X22_NDX 22
|
||||
#define REG_X23_NDX 23
|
||||
#define REG_X24_NDX 24
|
||||
#define REG_X25_NDX 25
|
||||
#define REG_X26_NDX 26
|
||||
#define REG_X27_NDX 27
|
||||
|
||||
/* $28-31 = t3-t6: Temporary (Volatile) registers */
|
||||
|
||||
#define REG_X28_NDX 28
|
||||
#define REG_X29_NDX 29
|
||||
#define REG_X30_NDX 30
|
||||
#define REG_X31_NDX 31
|
||||
|
||||
/* Interrupt Context register */
|
||||
|
||||
#define REG_INT_CTX_NDX 32
|
||||
|
||||
#ifdef CONFIG_ARCH_RISCV_INTXCPT_EXTREGS
|
||||
#define INT_XCPT_REGS (33 + CONFIG_ARCH_RISCV_INTXCPT_EXTREGS)
|
||||
#else
|
||||
#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
|
||||
* offsets. But in C, it is more convenient to reference registers as
|
||||
* register save table offsets.
|
||||
*/
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
# define REG_EPC (4*REG_EPC_NDX)
|
||||
# define REG_X1 (4*REG_X1_NDX)
|
||||
# define REG_X2 (4*REG_X2_NDX)
|
||||
# define REG_X3 (4*REG_X3_NDX)
|
||||
# define REG_X4 (4*REG_X4_NDX)
|
||||
# define REG_X5 (4*REG_X5_NDX)
|
||||
# define REG_X6 (4*REG_X6_NDX)
|
||||
# define REG_X7 (4*REG_X7_NDX)
|
||||
# define REG_X8 (4*REG_X8_NDX)
|
||||
# define REG_X9 (4*REG_X9_NDX)
|
||||
# define REG_X10 (4*REG_X10_NDX)
|
||||
# define REG_X11 (4*REG_X11_NDX)
|
||||
# define REG_X12 (4*REG_X12_NDX)
|
||||
# define REG_X13 (4*REG_X13_NDX)
|
||||
# define REG_X14 (4*REG_X14_NDX)
|
||||
# define REG_X15 (4*REG_X15_NDX)
|
||||
# define REG_X16 (4*REG_X16_NDX)
|
||||
# define REG_X17 (4*REG_X17_NDX)
|
||||
# define REG_X18 (4*REG_X18_NDX)
|
||||
# define REG_X19 (4*REG_X19_NDX)
|
||||
# define REG_X20 (4*REG_X20_NDX)
|
||||
# define REG_X21 (4*REG_X21_NDX)
|
||||
# define REG_X22 (4*REG_X22_NDX)
|
||||
# define REG_X23 (4*REG_X23_NDX)
|
||||
# define REG_X24 (4*REG_X24_NDX)
|
||||
# define REG_X25 (4*REG_X25_NDX)
|
||||
# define REG_X26 (4*REG_X26_NDX)
|
||||
# define REG_X27 (4*REG_X27_NDX)
|
||||
# define REG_X28 (4*REG_X28_NDX)
|
||||
# define REG_X29 (4*REG_X29_NDX)
|
||||
# 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
|
||||
# define REG_X2 REG_X2_NDX
|
||||
# define REG_X3 REG_X3_NDX
|
||||
# define REG_X4 REG_X4_NDX
|
||||
# define REG_X5 REG_X5_NDX
|
||||
# define REG_X6 REG_X6_NDX
|
||||
# define REG_X7 REG_X7_NDX
|
||||
# define REG_X8 REG_X8_NDX
|
||||
# define REG_X9 REG_X9_NDX
|
||||
# define REG_X10 REG_X10_NDX
|
||||
# define REG_X11 REG_X11_NDX
|
||||
# define REG_X12 REG_X12_NDX
|
||||
# define REG_X13 REG_X13_NDX
|
||||
# define REG_X14 REG_X14_NDX
|
||||
# define REG_X15 REG_X15_NDX
|
||||
# define REG_X16 REG_X16_NDX
|
||||
# define REG_X17 REG_X17_NDX
|
||||
# define REG_X18 REG_X18_NDX
|
||||
# define REG_X19 REG_X19_NDX
|
||||
# define REG_X20 REG_X20_NDX
|
||||
# define REG_X21 REG_X21_NDX
|
||||
# define REG_X22 REG_X22_NDX
|
||||
# define REG_X23 REG_X23_NDX
|
||||
# define REG_X24 REG_X24_NDX
|
||||
# define REG_X25 REG_X25_NDX
|
||||
# define REG_X26 REG_X26_NDX
|
||||
# define REG_X27 REG_X27_NDX
|
||||
# define REG_X28 REG_X28_NDX
|
||||
# define REG_X29 REG_X29_NDX
|
||||
# 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
|
||||
* in assembly or C contexts.
|
||||
*/
|
||||
|
||||
/* $1 = ra: Return address */
|
||||
|
||||
#define REG_RA REG_X1
|
||||
|
||||
/* $2 = sp: The value of the stack pointer on return from the exception */
|
||||
|
||||
#define REG_SP REG_X2
|
||||
|
||||
/* $3 = gp: Only needs to be saved under conditions where there are
|
||||
* multiple, per-thread values for the GP.
|
||||
*/
|
||||
|
||||
#define REG_GP REG_X3
|
||||
|
||||
/* $4 = tp: Thread Pointer */
|
||||
|
||||
#define REG_TP REG_X4
|
||||
|
||||
/* $5-$7 = t0-t2: Caller saved temporary registers */
|
||||
|
||||
#define REG_T0 REG_X5
|
||||
#define REG_T1 REG_X6
|
||||
#define REG_T2 REG_X7
|
||||
|
||||
/* $8 = either s0 or fp: Depends if a frame pointer is used or not */
|
||||
|
||||
#define REG_S0 REG_X8
|
||||
#define REG_FP REG_X8
|
||||
|
||||
/* $9 = s1: Caller saved register */
|
||||
|
||||
#define REG_S1 REG_X9
|
||||
|
||||
/* $10-$17 = a0-a7: Argument registers */
|
||||
|
||||
#define REG_A0 REG_X10
|
||||
#define REG_A1 REG_X11
|
||||
#define REG_A2 REG_X12
|
||||
#define REG_A3 REG_X13
|
||||
#define REG_A4 REG_X14
|
||||
#define REG_A5 REG_X15
|
||||
#define REG_A6 REG_X16
|
||||
#define REG_A7 REG_X17
|
||||
|
||||
/* $18-$27 = s2-s11: Callee saved registers */
|
||||
|
||||
#define REG_S2 REG_X18
|
||||
#define REG_S3 REG_X19
|
||||
#define REG_S4 REG_X20
|
||||
#define REG_S5 REG_X21
|
||||
#define REG_S6 REG_X22
|
||||
#define REG_S7 REG_X23
|
||||
#define REG_S8 REG_X24
|
||||
#define REG_S9 REG_X25
|
||||
#define REG_S10 REG_X26
|
||||
#define REG_S11 REG_X27
|
||||
|
||||
/* $28-$31 = t3-t6: Caller saved temporary registers */
|
||||
|
||||
#define REG_T3 REG_X28
|
||||
#define REG_T4 REG_X29
|
||||
#define REG_T5 REG_X30
|
||||
#define REG_T6 REG_X31
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/* This structure represents the return state from a system call */
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
struct xcpt_syscall_s
|
||||
{
|
||||
uint32_t sysreturn; /* The return PC */
|
||||
};
|
||||
#endif
|
||||
|
||||
/* The following structure is included in the TCB and defines the complete
|
||||
* state of the thread.
|
||||
*/
|
||||
|
||||
struct xcptcontext
|
||||
{
|
||||
/* The following function pointer is non-NULL if there are pending signals
|
||||
* to be processed.
|
||||
*/
|
||||
|
||||
void *sigdeliver; /* Actual type is sig_deliver_t */
|
||||
|
||||
/* These additional register save locations are used to implement the
|
||||
* signal delivery trampoline.
|
||||
*
|
||||
* REVISIT: Because there is only one copy of these save areas,
|
||||
* only a single signal handler can be active. This precludes
|
||||
* queuing of signal actions. As a result, signals received while
|
||||
* another signal handler is executing will be ignored!
|
||||
*/
|
||||
|
||||
uint32_t saved_epc; /* Trampoline PC */
|
||||
uint32_t saved_int_ctx; /* Interrupt context with interrupts disabled. */
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* This is the saved address to use when returning from a user-space
|
||||
* signal handler.
|
||||
*/
|
||||
|
||||
uint32_t sigreturn;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* The following array holds information needed to return from each nested
|
||||
* system call.
|
||||
*/
|
||||
|
||||
uint8_t nsyscalls;
|
||||
struct xcpt_syscall_s syscall[CONFIG_SYS_NNEST];
|
||||
|
||||
#endif
|
||||
|
||||
/* Register save area */
|
||||
|
||||
uint32_t regs[XCPTCONTEXT_REGS];
|
||||
};
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#endif /* __ARCH_RISCV_INCLUDE_RV32IM_IRQ_H */
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <arch/rv32im/mcause.h>
|
||||
#include <arch/mcause.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
|
|
|
|||
|
|
@ -1,468 +0,0 @@
|
|||
/****************************************************************************
|
||||
* arch/risc-v/include/rv64gc/irq.h
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* This file should never be included directly but, rather, only indirectly
|
||||
* through nuttx/irq.h
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_RISCV_INCLUDE_RV64GC_IRQ_H
|
||||
#define __ARCH_RISCV_INCLUDE_RV64GC_IRQ_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/types.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/* If this is a kernel build, how many nested system calls should we
|
||||
* support?
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_SYS_NNEST
|
||||
# define CONFIG_SYS_NNEST 2
|
||||
#endif
|
||||
|
||||
/* Processor PC */
|
||||
|
||||
#define REG_EPC_NDX 0
|
||||
|
||||
/* General pupose registers
|
||||
* $0: Zero register does not need to be saved
|
||||
* $1: ra (return address)
|
||||
*/
|
||||
|
||||
#define REG_X1_NDX 1
|
||||
|
||||
/* $2: Stack POinter
|
||||
* $3: Global Pointer
|
||||
* $4: Thread Pointer
|
||||
*/
|
||||
|
||||
#define REG_X2_NDX 2
|
||||
#define REG_X3_NDX 3
|
||||
#define REG_X4_NDX 4
|
||||
|
||||
/* $5-$7 = t0-t3: Temporary registers */
|
||||
|
||||
#define REG_X5_NDX 5
|
||||
#define REG_X6_NDX 6
|
||||
#define REG_X7_NDX 7
|
||||
|
||||
/* $8: s0 / fp Frame pointer */
|
||||
|
||||
#define REG_X8_NDX 8
|
||||
|
||||
/* $89 s1 Saved register */
|
||||
|
||||
#define REG_X9_NDX 9
|
||||
|
||||
/* $10-$17 = a0-a7: Argument registers */
|
||||
|
||||
#define REG_X10_NDX 10
|
||||
#define REG_X11_NDX 11
|
||||
#define REG_X12_NDX 12
|
||||
#define REG_X13_NDX 13
|
||||
#define REG_X14_NDX 14
|
||||
#define REG_X15_NDX 15
|
||||
#define REG_X16_NDX 16
|
||||
#define REG_X17_NDX 17
|
||||
|
||||
/* $18-$27 = s2-s11: Saved registers */
|
||||
|
||||
#define REG_X18_NDX 18
|
||||
#define REG_X19_NDX 19
|
||||
#define REG_X20_NDX 20
|
||||
#define REG_X21_NDX 21
|
||||
#define REG_X22_NDX 22
|
||||
#define REG_X23_NDX 23
|
||||
#define REG_X24_NDX 24
|
||||
#define REG_X25_NDX 25
|
||||
#define REG_X26_NDX 26
|
||||
#define REG_X27_NDX 27
|
||||
|
||||
/* $28-31 = t3-t6: Temporary (Volatile) registers */
|
||||
|
||||
#define REG_X28_NDX 28
|
||||
#define REG_X29_NDX 29
|
||||
#define REG_X30_NDX 30
|
||||
#define REG_X31_NDX 31
|
||||
|
||||
/* Interrupt Context register */
|
||||
|
||||
#define REG_INT_CTX_NDX 32
|
||||
|
||||
#ifdef CONFIG_ARCH_RISCV_INTXCPT_EXTREGS
|
||||
#define INT_XCPT_REGS (33 + CONFIG_ARCH_RISCV_INTXCPT_EXTREGS)
|
||||
#else
|
||||
#define INT_XCPT_REGS 33
|
||||
#endif
|
||||
|
||||
#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
|
||||
* register save table offsets.
|
||||
*/
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
# define REG_EPC (8*REG_EPC_NDX)
|
||||
# define REG_X1 (8*REG_X1_NDX)
|
||||
# define REG_X2 (8*REG_X2_NDX)
|
||||
# define REG_X3 (8*REG_X3_NDX)
|
||||
# define REG_X4 (8*REG_X4_NDX)
|
||||
# define REG_X5 (8*REG_X5_NDX)
|
||||
# define REG_X6 (8*REG_X6_NDX)
|
||||
# define REG_X7 (8*REG_X7_NDX)
|
||||
# define REG_X8 (8*REG_X8_NDX)
|
||||
# define REG_X9 (8*REG_X9_NDX)
|
||||
# define REG_X10 (8*REG_X10_NDX)
|
||||
# define REG_X11 (8*REG_X11_NDX)
|
||||
# define REG_X12 (8*REG_X12_NDX)
|
||||
# define REG_X13 (8*REG_X13_NDX)
|
||||
# define REG_X14 (8*REG_X14_NDX)
|
||||
# define REG_X15 (8*REG_X15_NDX)
|
||||
# define REG_X16 (8*REG_X16_NDX)
|
||||
# define REG_X17 (8*REG_X17_NDX)
|
||||
# define REG_X18 (8*REG_X18_NDX)
|
||||
# define REG_X19 (8*REG_X19_NDX)
|
||||
# define REG_X20 (8*REG_X20_NDX)
|
||||
# define REG_X21 (8*REG_X21_NDX)
|
||||
# define REG_X22 (8*REG_X22_NDX)
|
||||
# define REG_X23 (8*REG_X23_NDX)
|
||||
# define REG_X24 (8*REG_X24_NDX)
|
||||
# define REG_X25 (8*REG_X25_NDX)
|
||||
# define REG_X26 (8*REG_X26_NDX)
|
||||
# define REG_X27 (8*REG_X27_NDX)
|
||||
# define REG_X28 (8*REG_X28_NDX)
|
||||
# define REG_X29 (8*REG_X29_NDX)
|
||||
# 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
|
||||
# define REG_X2 REG_X2_NDX
|
||||
# define REG_X3 REG_X3_NDX
|
||||
# define REG_X4 REG_X4_NDX
|
||||
# define REG_X5 REG_X5_NDX
|
||||
# define REG_X6 REG_X6_NDX
|
||||
# define REG_X7 REG_X7_NDX
|
||||
# define REG_X8 REG_X8_NDX
|
||||
# define REG_X9 REG_X9_NDX
|
||||
# define REG_X10 REG_X10_NDX
|
||||
# define REG_X11 REG_X11_NDX
|
||||
# define REG_X12 REG_X12_NDX
|
||||
# define REG_X13 REG_X13_NDX
|
||||
# define REG_X14 REG_X14_NDX
|
||||
# define REG_X15 REG_X15_NDX
|
||||
# define REG_X16 REG_X16_NDX
|
||||
# define REG_X17 REG_X17_NDX
|
||||
# define REG_X18 REG_X18_NDX
|
||||
# define REG_X19 REG_X19_NDX
|
||||
# define REG_X20 REG_X20_NDX
|
||||
# define REG_X21 REG_X21_NDX
|
||||
# define REG_X22 REG_X22_NDX
|
||||
# define REG_X23 REG_X23_NDX
|
||||
# define REG_X24 REG_X24_NDX
|
||||
# define REG_X25 REG_X25_NDX
|
||||
# define REG_X26 REG_X26_NDX
|
||||
# define REG_X27 REG_X27_NDX
|
||||
# define REG_X28 REG_X28_NDX
|
||||
# define REG_X29 REG_X29_NDX
|
||||
# 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
|
||||
* in assembly or C contexts.
|
||||
*/
|
||||
|
||||
/* $1 = ra: Return address */
|
||||
|
||||
#define REG_RA REG_X1
|
||||
|
||||
/* $2 = sp: The value of the stack pointer on return from the exception */
|
||||
|
||||
#define REG_SP REG_X2
|
||||
|
||||
/* $3 = gp: Only needs to be saved under conditions where there are
|
||||
* multiple, per-thread values for the GP.
|
||||
*/
|
||||
|
||||
#define REG_GP REG_X3
|
||||
|
||||
/* $4 = tp: Thread Pointer */
|
||||
|
||||
#define REG_TP REG_X4
|
||||
|
||||
/* $5-$7 = t0-t2: Caller saved temporary registers */
|
||||
|
||||
#define REG_T0 REG_X5
|
||||
#define REG_T1 REG_X6
|
||||
#define REG_T2 REG_X7
|
||||
|
||||
/* $8 = either s0 or fp: Depends if a frame pointer is used or not */
|
||||
|
||||
#define REG_S0 REG_X8
|
||||
#define REG_FP REG_X8
|
||||
|
||||
/* $9 = s1: Caller saved register */
|
||||
|
||||
#define REG_S1 REG_X9
|
||||
|
||||
/* $10-$17 = a0-a7: Argument registers */
|
||||
|
||||
#define REG_A0 REG_X10
|
||||
#define REG_A1 REG_X11
|
||||
#define REG_A2 REG_X12
|
||||
#define REG_A3 REG_X13
|
||||
#define REG_A4 REG_X14
|
||||
#define REG_A5 REG_X15
|
||||
#define REG_A6 REG_X16
|
||||
#define REG_A7 REG_X17
|
||||
|
||||
/* $18-$27 = s2-s11: Callee saved registers */
|
||||
|
||||
#define REG_S2 REG_X18
|
||||
#define REG_S3 REG_X19
|
||||
#define REG_S4 REG_X20
|
||||
#define REG_S5 REG_X21
|
||||
#define REG_S6 REG_X22
|
||||
#define REG_S7 REG_X23
|
||||
#define REG_S8 REG_X24
|
||||
#define REG_S9 REG_X25
|
||||
#define REG_S10 REG_X26
|
||||
#define REG_S11 REG_X27
|
||||
|
||||
/* $28-$31 = t3-t6: Caller saved temporary registers */
|
||||
|
||||
#define REG_T3 REG_X28
|
||||
#define REG_T4 REG_X29
|
||||
#define REG_T5 REG_X30
|
||||
#define REG_T6 REG_X31
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/* This structure represents the return state from a system call */
|
||||
|
||||
#ifdef CONFIG_LIB_SYSCALL
|
||||
struct xcpt_syscall_s
|
||||
{
|
||||
uint64_t sysreturn; /* The return PC */
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
uint64_t int_ctx; /* Interrupt context (i.e. mstatus) */
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
/* The following structure is included in the TCB and defines the complete
|
||||
* state of the thread.
|
||||
*/
|
||||
|
||||
struct xcptcontext
|
||||
{
|
||||
/* The following function pointer is non-NULL if there are pending signals
|
||||
* to be processed.
|
||||
*/
|
||||
|
||||
void *sigdeliver; /* Actual type is sig_deliver_t */
|
||||
|
||||
/* These additional register save locations are used to implement the
|
||||
* signal delivery trampoline.
|
||||
*
|
||||
* REVISIT: Because there is only one copy of these save areas,
|
||||
* only a single signal handler can be active. This precludes
|
||||
* queuing of signal actions. As a result, signals received while
|
||||
* another signal handler is executing will be ignored!
|
||||
*/
|
||||
|
||||
uint64_t saved_epc; /* Trampoline PC */
|
||||
uint64_t saved_int_ctx; /* Interrupt context with interrupts disabled. */
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
/* This is the saved address to use when returning from a user-space
|
||||
* signal handler.
|
||||
*/
|
||||
|
||||
uint32_t sigreturn;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LIB_SYSCALL
|
||||
/* The following array holds information needed to return from each nested
|
||||
* system call.
|
||||
*/
|
||||
|
||||
uint8_t nsyscalls;
|
||||
struct xcpt_syscall_s syscall[CONFIG_SYS_NNEST];
|
||||
|
||||
#endif
|
||||
|
||||
/* Register save area */
|
||||
|
||||
uint64_t regs[XCPTCONTEXT_REGS];
|
||||
};
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#endif /* __ARCH_RISCV_INCLUDE_RV64GC_IRQ_H */
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/rv32im/irq.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Symbols
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ void up_irqinitialize(void)
|
|||
|
||||
/* currents_regs is non-NULL only while processing an interrupt */
|
||||
|
||||
g_current_regs = NULL;
|
||||
CURRENT_REGS = NULL;
|
||||
|
||||
/* Attach the ecall interrupt handler */
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
volatile uint32_t *g_current_regs = NULL;
|
||||
volatile uintptr_t *g_current_regs[1];
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
|
|
@ -51,10 +51,10 @@ volatile uint32_t *g_current_regs = NULL;
|
|||
* bl602_dispatch_irq
|
||||
****************************************************************************/
|
||||
|
||||
void *bl602_dispatch_irq(uint32_t vector, uint32_t *regs)
|
||||
void *bl602_dispatch_irq(uintptr_t vector, uintptr_t *regs)
|
||||
{
|
||||
uint32_t irq = vector & 0x3ff; /* E24 [9:0] */
|
||||
uint32_t *mepc = regs;
|
||||
uintptr_t irq = vector & 0x3ff; /* E24 [9:0] */
|
||||
uintptr_t *mepc = regs;
|
||||
|
||||
/* If current is interrupt */
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ void *bl602_dispatch_irq(uint32_t vector, uint32_t *regs)
|
|||
|
||||
if (BL602_IRQ_ECALLM == irq)
|
||||
{
|
||||
*mepc += 2;
|
||||
*mepc += 4;
|
||||
}
|
||||
|
||||
/* Acknowledge the interrupt */
|
||||
|
|
@ -78,13 +78,13 @@ void *bl602_dispatch_irq(uint32_t vector, uint32_t *regs)
|
|||
PANIC();
|
||||
#else
|
||||
/* Current regs non-zero indicates that we are processing an interrupt;
|
||||
* g_current_regs is also used to manage interrupt level context switches.
|
||||
* CURRENT_REGS is also used to manage interrupt level context switches.
|
||||
*
|
||||
* Nested interrupts are not supported
|
||||
*/
|
||||
|
||||
DEBUGASSERT(g_current_regs == NULL);
|
||||
g_current_regs = regs;
|
||||
DEBUGASSERT(CURRENT_REGS == NULL);
|
||||
CURRENT_REGS = regs;
|
||||
|
||||
/* Deliver the IRQ */
|
||||
|
||||
|
|
@ -92,18 +92,18 @@ void *bl602_dispatch_irq(uint32_t vector, uint32_t *regs)
|
|||
|
||||
#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV)
|
||||
/* Check for a context switch. If a context switch occurred, then
|
||||
* g_current_regs will have a different value than it did on entry. If an
|
||||
* CURRENT_REGS will have a different value than it did on entry. If an
|
||||
* interrupt level context switch has occurred, then restore the floating
|
||||
* point state and the establish the correct address environment before
|
||||
* returning from the interrupt.
|
||||
*/
|
||||
|
||||
if (regs != g_current_regs)
|
||||
if (regs != CURRENT_REGS)
|
||||
{
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Restore floating point registers */
|
||||
|
||||
riscv_restorefpu((uint32_t *)g_current_regs);
|
||||
riscv_restorefpu((uintptr_t *)CURRENT_REGS);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
|
|
@ -121,13 +121,13 @@ void *bl602_dispatch_irq(uint32_t vector, uint32_t *regs)
|
|||
#endif /* CONFIG_SUPPRESS_INTERRUPTS */
|
||||
|
||||
/* If a context switch occurred while processing the interrupt then
|
||||
* g_current_regs may have change value. If we return any value different
|
||||
* CURRENT_REGS may have change value. If we return any value different
|
||||
* from the input regs, then the lower level will know that a context
|
||||
* switch occurred during interrupt processing.
|
||||
*/
|
||||
|
||||
regs = (uint32_t *)g_current_regs;
|
||||
g_current_regs = NULL;
|
||||
regs = (uintptr_t *)CURRENT_REGS;
|
||||
CURRENT_REGS = NULL;
|
||||
|
||||
return regs;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ static struct boot2_partition_table_s g_boot2_partition_table unused_data;
|
|||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t g_idle_topstack = 0;
|
||||
uintptr_t g_idle_topstack;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/csr.h>
|
||||
#include <arch/rv64gc/irq.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "c906_memorymap.h"
|
||||
|
|
|
|||
|
|
@ -57,14 +57,6 @@
|
|||
# define CONFIG_BOARD_RESET_ON_ASSERT 0
|
||||
#endif
|
||||
|
||||
/* Format output with register width and hex */
|
||||
|
||||
#ifdef CONFIG_ARCH_RV32
|
||||
# define PRIxREG "%08"PRIxPTR
|
||||
#else
|
||||
# define PRIxREG "%016"PRIxPTR
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
|
@ -106,35 +98,35 @@ static inline void riscv_registerdump(volatile uintptr_t *regs)
|
|||
{
|
||||
/* Are user registers available from interrupt processing? */
|
||||
|
||||
_alert("EPC:" PRIxREG "\n", regs[REG_EPC]);
|
||||
_alert("A0:" PRIxREG " A1:" PRIxREG "A2:" PRIxREG
|
||||
" A3:" PRIxREG "\n",
|
||||
_alert("EPC: %" PRIxREG "\n", regs[REG_EPC]);
|
||||
_alert("A0: %" PRIxREG " A1: %" PRIxREG " A2: %" PRIxREG
|
||||
" A3: %" PRIxREG "\n",
|
||||
regs[REG_A0], regs[REG_A1], regs[REG_A2], regs[REG_A3]);
|
||||
_alert("A4:" PRIxREG " A5:" PRIxREG "A6:" PRIxREG
|
||||
" A7:" PRIxREG "\n",
|
||||
_alert("A4: %" PRIxREG " A5: %" PRIxREG " A6: %" PRIxREG
|
||||
" A7: %" PRIxREG "\n",
|
||||
regs[REG_A4], regs[REG_A5], regs[REG_A6], regs[REG_A7]);
|
||||
_alert("T0:" PRIxREG " T1:" PRIxREG " T2:" PRIxREG
|
||||
" T3:" PRIxREG "\n",
|
||||
_alert("T0: %" PRIxREG " T1: %" PRIxREG " T2: %" PRIxREG
|
||||
" T3: %" PRIxREG "\n",
|
||||
regs[REG_T0], regs[REG_T1], regs[REG_T2], regs[REG_T3]);
|
||||
_alert("T4:" PRIxREG " T5:" PRIxREG " T6:" PRIxREG "\n",
|
||||
_alert("T4: %" PRIxREG " T5: %" PRIxREG " T6: %" PRIxREG "\n",
|
||||
regs[REG_T4], regs[REG_T5], regs[REG_T6]);
|
||||
_alert("S0:" PRIxREG " S1:" PRIxREG " S2:" PRIxREG
|
||||
" S3:" PRIxREG "\n",
|
||||
_alert("S0: %" PRIxREG " S1: %" PRIxREG " S2: %" PRIxREG
|
||||
" S3: %" PRIxREG "\n",
|
||||
regs[REG_S0], regs[REG_S1], regs[REG_S2], regs[REG_S3]);
|
||||
_alert("S4:" PRIxREG " S5:" PRIxREG " S6:" PRIxREG
|
||||
" S7:" PRIxREG "\n",
|
||||
_alert("S4: %" PRIxREG " S5: %" PRIxREG " S6: %" PRIxREG
|
||||
" S7: %" PRIxREG "\n",
|
||||
regs[REG_S4], regs[REG_S5], regs[REG_S6], regs[REG_S7]);
|
||||
_alert("S8:" PRIxREG " S9:" PRIxREG " S10:" PRIxREG
|
||||
" S11:" PRIxREG "\n",
|
||||
_alert("S8: %" PRIxREG " S9: %" PRIxREG " S10: %" PRIxREG
|
||||
" S11: %" PRIxREG "\n",
|
||||
regs[REG_S8], regs[REG_S9], regs[REG_S10], regs[REG_S11]);
|
||||
#ifdef RISCV_SAVE_GP
|
||||
_alert("GP:" PRIxREG " SP:" PRIxREG " FP:" PRIxREG
|
||||
" TP:" PRIxREG " RA:" PRIxREG "\n",
|
||||
_alert("GP: %" PRIxREG " SP: %" PRIxREG " FP: %" PRIxREG
|
||||
" TP: %" PRIxREG " RA: %" PRIxREG "\n",
|
||||
regs[REG_GP], regs[REG_SP], regs[REG_FP], regs[REG_TP],
|
||||
regs[REG_RA]);
|
||||
#else
|
||||
_alert("SP:" PRIxREG " FP:" PRIxREG " TP:" PRIxREG
|
||||
" RA:" PRIxREG "\n",
|
||||
_alert("SP: %" PRIxREG " FP: %" PRIxREG " TP: %" PRIxREG
|
||||
" RA: %" PRIxREG "\n",
|
||||
regs[REG_SP], regs[REG_FP], regs[REG_TP], regs[REG_RA]);
|
||||
#endif
|
||||
}
|
||||
|
|
@ -338,10 +330,10 @@ static void riscv_dumpstate(void)
|
|||
|
||||
/* Show interrupt stack info */
|
||||
|
||||
_alert("sp: " PRIxREG "\n", sp);
|
||||
_alert("sp: %" PRIxREG "\n", sp);
|
||||
_alert("IRQ stack:\n");
|
||||
_alert(" base: " PRIxREG "\n", istackbase);
|
||||
_alert(" size: " PRIxREG "\n", istacksize);
|
||||
_alert(" base: %" PRIxREG "\n", istackbase);
|
||||
_alert(" size: %" PRIxREG "\n", istacksize);
|
||||
|
||||
/* Does the current stack pointer lie within the interrupt
|
||||
* stack?
|
||||
|
|
@ -356,7 +348,7 @@ static void riscv_dumpstate(void)
|
|||
/* Extract the user stack pointer */
|
||||
|
||||
sp = CURRENT_REGS[REG_SP];
|
||||
_alert("sp: " PRIxREG "\n", sp);
|
||||
_alert("sp: %" PRIxREG "\n", sp);
|
||||
}
|
||||
else if (CURRENT_REGS)
|
||||
{
|
||||
|
|
@ -367,12 +359,12 @@ static void riscv_dumpstate(void)
|
|||
/* Show user stack info */
|
||||
|
||||
_alert("User stack:\n");
|
||||
_alert(" base: " PRIxREG "\n", ustackbase);
|
||||
_alert(" size: " PRIxREG "\n", ustacksize);
|
||||
_alert(" base: %" PRIxREG "\n", ustackbase);
|
||||
_alert(" size: %" PRIxREG "\n", ustacksize);
|
||||
#else
|
||||
_alert("sp: " PRIxREG "\n", sp);
|
||||
_alert("stack base: " PRIxREG "\n", ustackbase);
|
||||
_alert("stack size: " PRIxREG "\n", ustacksize);
|
||||
_alert("sp: %" PRIxREG "\n", sp);
|
||||
_alert("stack base: %" PRIxREG "\n", ustackbase);
|
||||
_alert("stack size: %" PRIxREG "\n", ustacksize);
|
||||
#endif
|
||||
|
||||
/* Dump the user stack if the stack pointer lies within the allocated user
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ int up_backtrace(struct tcb_s *tcb, void **buffer, int size, int skip)
|
|||
{
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 15
|
||||
ret = backtrace((void *)&g_intstackalloc,
|
||||
(void *)((uint32_t)&g_intstackalloc +
|
||||
(void *)((uintptr_t)&g_intstackalloc +
|
||||
CONFIG_ARCH_INTERRUPTSTACK),
|
||||
(void *)getfp(), NULL, buffer, size, &skip);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* arch/risc-v/src/rv32im/riscv_copyfullstate.c
|
||||
* arch/risc-v/src/common/riscv_copyfullstate.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
void riscv_copyfullstate(uint32_t *dest, uint32_t *src)
|
||||
void riscv_copyfullstate(uintptr_t *dest, uintptr_t *src)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* arch/risc-v/src/rv32im/riscv_copystate.c
|
||||
* arch/risc-v/src/common/riscv_copystate.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
|
|
@ -51,12 +51,12 @@
|
|||
|
||||
/* A little faster than most memcpy's */
|
||||
|
||||
void riscv_copystate(uint32_t *dest, uint32_t *src)
|
||||
void riscv_copystate(uintptr_t *dest, uintptr_t *src)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
uint32_t *regs = dest;
|
||||
uintptr_t *regs = dest;
|
||||
#endif
|
||||
|
||||
/* In the RISC-V model, the state is copied from the stack to the TCB,
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* arch/risc-v/src/rv32im/riscv_doirq.c
|
||||
* arch/risc-v/src/common/riscv_doirq.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
|
|
@ -57,20 +57,20 @@
|
|||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t *up_doirq(int irq, uint32_t *regs)
|
||||
uintptr_t *up_doirq(int irq, uintptr_t *regs)
|
||||
{
|
||||
board_autoled_on(LED_INIRQ);
|
||||
#ifdef CONFIG_SUPPRESS_INTERRUPTS
|
||||
PANIC();
|
||||
#else
|
||||
/* Current regs non-zero indicates that we are processing an interrupt;
|
||||
* g_current_regs is also used to manage interrupt level context switches.
|
||||
* CURRENT_REGS is also used to manage interrupt level context switches.
|
||||
*
|
||||
* Nested interrupts are not supported
|
||||
*/
|
||||
|
||||
DEBUGASSERT(g_current_regs == NULL);
|
||||
g_current_regs = regs;
|
||||
DEBUGASSERT(CURRENT_REGS == NULL);
|
||||
CURRENT_REGS = regs;
|
||||
|
||||
/* Disable further occurrences of this interrupt (until the interrupt
|
||||
* sources have been clear by the driver).
|
||||
|
|
@ -84,18 +84,18 @@ uint32_t *up_doirq(int irq, uint32_t *regs)
|
|||
|
||||
#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV)
|
||||
/* Check for a context switch. If a context switch occurred, then
|
||||
* g_current_regs will have a different value than it did on entry. If an
|
||||
* CURRENT_REGS will have a different value than it did on entry. If an
|
||||
* interrupt level context switch has occurred, then restore the floating
|
||||
* point state and the establish the correct address environment before
|
||||
* returning from the interrupt.
|
||||
*/
|
||||
|
||||
if (regs != g_current_regs)
|
||||
if (regs != CURRENT_REGS)
|
||||
{
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Restore floating point registers */
|
||||
|
||||
riscv_restorefpu((uint32_t *)g_current_regs);
|
||||
riscv_restorefpu((uintptr_t *)CURRENT_REGS);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
|
|
@ -111,18 +111,18 @@ uint32_t *up_doirq(int irq, uint32_t *regs)
|
|||
#endif
|
||||
|
||||
/* If a context switch occurred while processing the interrupt then
|
||||
* g_current_regs may have change value. If we return any value different
|
||||
* CURRENT_REGS may have change value. If we return any value different
|
||||
* from the input regs, then the lower level will know that a context
|
||||
* switch occurred during interrupt processing.
|
||||
*/
|
||||
|
||||
regs = (uint32_t *)g_current_regs;
|
||||
regs = (uintptr_t *)CURRENT_REGS;
|
||||
|
||||
/* Set g_current_regs to NULL to indicate that we are no longer in an
|
||||
/* Set CURRENT_REGS to NULL to indicate that we are no longer in an
|
||||
* interrupt handler.
|
||||
*/
|
||||
|
||||
g_current_regs = NULL;
|
||||
CURRENT_REGS = NULL;
|
||||
|
||||
/* Unmask the last interrupt (global interrupts are still disabled) */
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* arch/risc-v/src/rv32im/riscv_exception.c
|
||||
* arch/risc-v/src/common/riscv_exception.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <nuttx/syslog/syslog.h>
|
||||
#include <arch/rv32im/mcause.h>
|
||||
#include <arch/mcause.h>
|
||||
|
||||
#include "riscv_arch.h"
|
||||
#include "riscv_internal.h"
|
||||
|
|
@ -72,9 +72,9 @@ static const char *g_reasons_str[MCAUSE_MAX_EXCEPTION + 1] =
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
void riscv_exception(uint32_t mcause, uint32_t *regs)
|
||||
void riscv_exception(uintptr_t mcause, uintptr_t *regs)
|
||||
{
|
||||
uint32_t cause = mcause & MCAUSE_INTERRUPT_MASK;
|
||||
uintptr_t cause = mcause & MCAUSE_INTERRUPT_MASK;
|
||||
|
||||
#ifdef CONFIG_DEBUG_INFO
|
||||
if (mcause > MCAUSE_MAX_EXCEPTION)
|
||||
|
|
@ -90,7 +90,7 @@ void riscv_exception(uint32_t mcause, uint32_t *regs)
|
|||
|
||||
_alert("PANIC!!! Exception = %08" PRIx32 "\n", cause);
|
||||
up_irq_save();
|
||||
g_current_regs = regs;
|
||||
CURRENT_REGS = regs;
|
||||
PANIC();
|
||||
}
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* arch/risc-v/src/rv64gc/riscv_fault.c
|
||||
* arch/risc-v/src/common/riscv_fault.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
|
|
@ -54,61 +54,61 @@
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_fault(int irq, uint64_t *regs)
|
||||
void up_fault(int irq, uintptr_t *regs)
|
||||
{
|
||||
CURRENT_REGS = regs;
|
||||
|
||||
_alert("EPC:%016" PRIx64 "\n",
|
||||
_alert("EPC: %" PRIxREG "\n",
|
||||
CURRENT_REGS[REG_EPC]);
|
||||
|
||||
_alert("Fault IRQ=%d\n", irq);
|
||||
|
||||
/* Dump register info */
|
||||
|
||||
_alert("A0:%016" PRIx64 " A1:%016" PRIx64 " A2:%016" PRIx64
|
||||
" A3:%016" PRIx64 "\n",
|
||||
_alert("A0: %" PRIxREG " A1: %" PRIxREG " A2: %" PRIxREG
|
||||
" A3: %" PRIxREG "\n",
|
||||
CURRENT_REGS[REG_A0], CURRENT_REGS[REG_A1],
|
||||
CURRENT_REGS[REG_A2], CURRENT_REGS[REG_A3]);
|
||||
|
||||
_alert("A4:%016" PRIx64 " A5:%016" PRIx64 " A6:%016" PRIx64
|
||||
" A7:%016" PRIx64 "\n",
|
||||
_alert("A4: %" PRIxREG " A5: %" PRIxREG " A6: %" PRIxREG
|
||||
" A7: %" PRIxREG "\n",
|
||||
CURRENT_REGS[REG_A4], CURRENT_REGS[REG_A5],
|
||||
CURRENT_REGS[REG_A6], CURRENT_REGS[REG_A7]);
|
||||
|
||||
_alert("T0:%016" PRIx64 " T1:%016" PRIx64 " T2:%016" PRIx64
|
||||
" T3:%016" PRIx64 "\n",
|
||||
_alert("T0: %" PRIxREG " T1: %" PRIxREG " T2: %" PRIxREG
|
||||
" T3: %" PRIxREG "\n",
|
||||
CURRENT_REGS[REG_T0], CURRENT_REGS[REG_T1],
|
||||
CURRENT_REGS[REG_T2], CURRENT_REGS[REG_T3]);
|
||||
|
||||
_alert("T4:%016" PRIx64 " T5:%016" PRIx64
|
||||
" T6:%016" PRIx64 "\n",
|
||||
_alert("T4: %" PRIxREG " T5: %" PRIxREG
|
||||
" T6: %" PRIxREG "\n",
|
||||
CURRENT_REGS[REG_T4], CURRENT_REGS[REG_T5],
|
||||
CURRENT_REGS[REG_T6]);
|
||||
|
||||
_alert("S0:%016" PRIx64 " S1:%016" PRIx64 " S2:%016" PRIx64
|
||||
" S3:%016" PRIx64 "\n",
|
||||
_alert("S0: %" PRIxREG " S1: %" PRIxREG " S2: %" PRIxREG
|
||||
" S3: %" PRIxREG "\n",
|
||||
CURRENT_REGS[REG_S0], CURRENT_REGS[REG_S1],
|
||||
CURRENT_REGS[REG_S2], CURRENT_REGS[REG_S3]);
|
||||
|
||||
_alert("S4:%016" PRIx64 " S5:%016" PRIx64 " S6:%016" PRIx64
|
||||
" S7:%016" PRIx64 "\n",
|
||||
_alert("S4: %" PRIxREG " S5: %" PRIxREG " S6: %" PRIxREG
|
||||
" S7: %" PRIxREG "\n",
|
||||
CURRENT_REGS[REG_S4], CURRENT_REGS[REG_S5],
|
||||
CURRENT_REGS[REG_S6], CURRENT_REGS[REG_S7]);
|
||||
|
||||
_alert("S8:%016" PRIx64 " S9:%016" PRIx64 " S10:%016" PRIx64
|
||||
" S11:%016" PRIx64 "\n",
|
||||
_alert("S8: %" PRIxREG " S9: %" PRIxREG " S10: %" PRIxREG
|
||||
" S11: %" PRIxREG "\n",
|
||||
CURRENT_REGS[REG_S8], CURRENT_REGS[REG_S9],
|
||||
CURRENT_REGS[REG_S10], CURRENT_REGS[REG_S11]);
|
||||
|
||||
#ifdef RISCV_SAVE_GP
|
||||
_alert("GP:%016" PRIx64 " SP:%016" PRIx64 " FP:%016" PRIx64
|
||||
" TP:%016 " PRIx64 "RA:%016" PRIx64 "\n",
|
||||
_alert("GP: %" PRIxREG " SP: %" PRIxREG " FP: %" PRIxREG
|
||||
" TP: %" PRIxREG "RA: %" PRIxREG "\n",
|
||||
CURRENT_REGS[REG_GP], CURRENT_REGS[REG_SP],
|
||||
CURRENT_REGS[REG_FP], CURRENT_REGS[REG_TP],
|
||||
CURRENT_REGS[REG_RA]);
|
||||
#else
|
||||
_alert("SP:%016" PRIx64 " FP:%016" PRIx64 " TP:%016" PRIx64
|
||||
" RA:%016" PRIx64 "\n",
|
||||
_alert("SP: %" PRIxREG " FP: %" PRIxREG " TP: %" PRIxREG
|
||||
" RA: %" PRIxREG "\n",
|
||||
CURRENT_REGS[REG_SP], CURRENT_REGS[REG_FP],
|
||||
CURRENT_REGS[REG_TP], CURRENT_REGS[REG_RA]);
|
||||
#endif
|
||||
|
|
@ -24,11 +24,7 @@
|
|||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#ifdef CONFIG_ARCH_RV32
|
||||
#include <arch/rv32im/irq.h>
|
||||
#else
|
||||
#include <arch/rv64gc/irq.h>
|
||||
#endif
|
||||
#include <arch/irq.h>
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
|
||||
|
|
|
|||
|
|
@ -45,17 +45,20 @@
|
|||
#define INTSTACK_COLOR 0xdeadbeef
|
||||
#define HEAP_COLOR 'h'
|
||||
|
||||
/* Format output with register width and hex */
|
||||
|
||||
#ifdef CONFIG_ARCH_RV32
|
||||
# define PRIxREG "08" PRIxPTR
|
||||
#else
|
||||
# define PRIxREG "016" PRIxPTR
|
||||
#endif
|
||||
|
||||
/* In the RISC_V model, the state is copied from the stack to the TCB, but
|
||||
* only a referenced is passed to get the state from the TCB.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARCH_RV64
|
||||
#define riscv_savestate(regs) riscv_copystate(regs, (uint64_t*)CURRENT_REGS)
|
||||
#define riscv_savestate(regs) riscv_copystate(regs, (uintptr_t*)CURRENT_REGS)
|
||||
#define riscv_restorestate(regs) (CURRENT_REGS = regs)
|
||||
#else
|
||||
#define riscv_savestate(regs) riscv_copystate(regs, (uint32_t*)g_current_regs)
|
||||
#define riscv_restorestate(regs) (g_current_regs = regs)
|
||||
#endif
|
||||
|
||||
#define _START_TEXT &_stext
|
||||
#define _END_TEXT &_etext
|
||||
|
|
@ -101,20 +104,14 @@ extern "C"
|
|||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#ifdef CONFIG_ARCH_RV64
|
||||
#ifdef CONFIG_SMP
|
||||
EXTERN volatile uint64_t *g_current_regs[CONFIG_SMP_NCPUS];
|
||||
EXTERN volatile uintptr_t *g_current_regs[CONFIG_SMP_NCPUS];
|
||||
# define CURRENT_REGS (g_current_regs[up_cpu_index()])
|
||||
#else
|
||||
EXTERN volatile uint64_t *g_current_regs[1];
|
||||
EXTERN volatile uintptr_t *g_current_regs[1];
|
||||
# define CURRENT_REGS (g_current_regs[0])
|
||||
#endif
|
||||
EXTERN uintptr_t g_idle_topstack;
|
||||
#else
|
||||
EXTERN volatile uint32_t *g_current_regs;
|
||||
# define CURRENT_REGS (g_current_regs)
|
||||
EXTERN uint32_t g_idle_topstack;
|
||||
#endif
|
||||
|
||||
/* Address of the saved user stack pointer */
|
||||
|
||||
|
|
@ -167,26 +164,16 @@ void riscv_addregion(void);
|
|||
|
||||
void riscv_ack_irq(int irq);
|
||||
|
||||
#ifdef CONFIG_ARCH_RV64
|
||||
void riscv_copystate(uint64_t *dest, uint64_t *src);
|
||||
void riscv_copyfullstate(uint64_t *dest, uint64_t *src);
|
||||
#else
|
||||
void riscv_copystate(uint32_t *dest, uint32_t *src);
|
||||
void riscv_copyfullstate(uint32_t *dest, uint32_t *src);
|
||||
#endif
|
||||
void riscv_copystate(uintptr_t *dest, uintptr_t *src);
|
||||
void riscv_copyfullstate(uintptr_t *dest, uintptr_t *src);
|
||||
|
||||
void riscv_sigdeliver(void);
|
||||
int riscv_swint(int irq, void *context, void *arg);
|
||||
uint32_t riscv_get_newintctx(void);
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
#ifdef CONFIG_ARCH_RV64
|
||||
void riscv_savefpu(uint64_t *regs);
|
||||
void riscv_restorefpu(const uint64_t *regs);
|
||||
#else /* !CONFIG_ARCH_RV64 */
|
||||
void riscv_savefpu(uint32_t *regs);
|
||||
void riscv_restorefpu(const uint32_t *regs);
|
||||
#endif /* CONFIG_ARCH_RV64 */
|
||||
void riscv_savefpu(uintptr_t *regs);
|
||||
void riscv_restorefpu(const uintptr_t *regs);
|
||||
#else
|
||||
# define riscv_savefpu(regs)
|
||||
# define riscv_restorefpu(regs)
|
||||
|
|
@ -224,7 +211,7 @@ void rpmsg_serialinit(void);
|
|||
|
||||
/* Exception Handler ********************************************************/
|
||||
|
||||
void riscv_exception(uint32_t mcause, uint32_t *regs);
|
||||
void riscv_exception(uintptr_t mcause, uintptr_t *regs);
|
||||
|
||||
/* Debug ********************************************************************/
|
||||
|
||||
|
|
|
|||
|
|
@ -64,6 +64,6 @@ bool up_interrupt_context(void)
|
|||
|
||||
return ret;
|
||||
#else
|
||||
return g_current_regs != NULL;
|
||||
return CURRENT_REGS != NULL;
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* arch/risc-v/src/rv64gc/riscv_schedulesigaction.c
|
||||
* arch/risc-v/src/common/riscv_schedulesigaction.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
|
|
@ -80,7 +80,7 @@
|
|||
#ifndef CONFIG_SMP
|
||||
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
{
|
||||
uint64_t int_ctx;
|
||||
uintptr_t int_ctx;
|
||||
|
||||
sinfo("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver);
|
||||
|
||||
|
|
@ -152,8 +152,8 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
|||
|
||||
riscv_savestate(tcb->xcp.regs);
|
||||
|
||||
sinfo("PC/STATUS Saved: %016" PRIx64 "/%016" PRIx64
|
||||
" New: %016" PRIx64 "/%016" PRIx64 "\n",
|
||||
sinfo("PC/STATUS Saved: %" PRIxREG "/%" PRIxREG
|
||||
" New: %" PRIxREG "/%" PRIxREG "\n",
|
||||
tcb->xcp.saved_epc, tcb->xcp.saved_int_ctx,
|
||||
CURRENT_REGS[REG_EPC], CURRENT_REGS[REG_INT_CTX]);
|
||||
}
|
||||
|
|
@ -188,8 +188,8 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
|||
|
||||
tcb->xcp.regs[REG_INT_CTX] = int_ctx;
|
||||
|
||||
sinfo("PC/STATUS Saved: %016" PRIx64 "/%016" PRIx64
|
||||
" New: %016" PRIx64 "/%016" PRIx64 "\n",
|
||||
sinfo("PC/STATUS Saved: %" PRIxREG "/%" PRIxREG
|
||||
" New: %" PRIxREG "/%" PRIxREG "\n",
|
||||
tcb->xcp.saved_epc, tcb->xcp.saved_int_ctx,
|
||||
tcb->xcp.regs[REG_EPC], tcb->xcp.regs[REG_INT_CTX]);
|
||||
}
|
||||
|
|
@ -200,7 +200,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
|||
#ifdef CONFIG_SMP
|
||||
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
{
|
||||
uint64_t int_ctx;
|
||||
uintptr_t int_ctx;
|
||||
int cpu;
|
||||
int me;
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* arch/risc-v/src/rv64gc/riscv_sigdeliver.c
|
||||
* arch/risc-v/src/common/riscv_sigdeliver.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
|
|
@ -57,7 +57,7 @@
|
|||
void riscv_sigdeliver(void)
|
||||
{
|
||||
struct tcb_s *rtcb = this_task();
|
||||
uint64_t regs[XCPTCONTEXT_REGS];
|
||||
uintptr_t regs[XCPTCONTEXT_REGS];
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* In the SMP case, we must terminate the critical section while the signal
|
||||
|
|
@ -115,7 +115,7 @@ void riscv_sigdeliver(void)
|
|||
* errno that is needed by the user logic (it is probably EINTR).
|
||||
*/
|
||||
|
||||
sinfo("Resuming EPC: %016" PRIx64 " INT_CTX: %016" PRIx64 "\n",
|
||||
sinfo("Resuming EPC: %" PRIxREG " INT_CTX: %" PRIxREG "\n",
|
||||
regs[REG_EPC], regs[REG_INT_CTX]);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* arch/risc-v/src/rv64gc/riscv_swint.c
|
||||
* arch/risc-v/src/common/riscv_swint.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
|
|
@ -42,6 +42,10 @@
|
|||
#include "svcall.h"
|
||||
#include "riscv_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
|
@ -51,29 +55,35 @@
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_SYSCALL_INFO
|
||||
static void riscv_registerdump(const uint64_t *regs)
|
||||
static void riscv_registerdump(const uintptr_t *regs)
|
||||
{
|
||||
svcinfo("EPC:%08x\n",
|
||||
svcinfo("EPC: %" PRIxREG "\n",
|
||||
regs[REG_EPC]);
|
||||
svcinfo("A0:%08x A1:%08x A2:%08x A3:%08x A4:%08x A5:%08x "
|
||||
"A6:%08x A7:%08x\n",
|
||||
svcinfo("A0: %" PRIxREG " A1: %" PRIxREG " A2: %" PRIxREG " A3: %" PRIxREG
|
||||
" A4: %" PRIxREG " A5: %" PRIxREG " A6: %" PRIxREG " A7: %" PRIxREG
|
||||
"\n",
|
||||
regs[REG_A0], regs[REG_A1], regs[REG_A2], regs[REG_A3],
|
||||
regs[REG_A4], regs[REG_A5], regs[REG_A6], regs[REG_A7]);
|
||||
svcinfo("T0:%08x T1:%08x T2:%08x T3:%08x T4:%08x T5:%08x T6:%08x\n",
|
||||
svcinfo("T0: %" PRIxREG " T1: %" PRIxREG " T2: %" PRIxREG " T3: %" PRIxREG
|
||||
" T4: %" PRIxREG " T5: %" PRIxREG " T6: %" PRIxREG "\n",
|
||||
regs[REG_T0], regs[REG_T1], regs[REG_T2], regs[REG_T3],
|
||||
regs[REG_T4], regs[REG_T5], regs[REG_T6]);
|
||||
svcinfo("S0:%08x S1:%08x S2:%08x S3:%08x S4:%08x S5:%08x "
|
||||
"S6:%08x S7:%08x\n",
|
||||
svcinfo("S0: %" PRIxREG " S1: %" PRIxREG " S2: %" PRIxREG " S3: %" PRIxREG
|
||||
" S4: %" PRIxREG " S5: %" PRIxREG " S6: %" PRIxREG " S7: %" PRIxREG
|
||||
"\n",
|
||||
regs[REG_S0], regs[REG_S1], regs[REG_S2], regs[REG_S3],
|
||||
regs[REG_S4], regs[REG_S5], regs[REG_S6], regs[REG_S7]);
|
||||
svcinfo("S8:%08x S9:%08x S10:%08x S11:%08x\n",
|
||||
svcinfo("S8: %" PRIxREG " S9: %" PRIxREG " S10: %"PRIxREG
|
||||
" S11: %" PRIxREG "\n",
|
||||
regs[REG_S8], regs[REG_S9], regs[REG_S10], regs[REG_S11]);
|
||||
#ifdef RISCV_SAVE_GP
|
||||
svcinfo("GP:%08x SP:%08x FP:%08x TP:%08x RA:%08x\n",
|
||||
svcinfo("GP: %" PRIxREG " SP: %" PRIxREG " FP: %" PRIxREG
|
||||
" TP: %" PRIxREG " RA: %" PRIxREG "\n",
|
||||
regs[REG_GP], regs[REG_SP], regs[REG_FP], regs[REG_TP],
|
||||
regs[REG_RA]);
|
||||
#else
|
||||
svcinfo("SP:%08x FP:%08x TP:%08x RA:%08x\n",
|
||||
svcinfo("SP: %" PRIxREG " FP: %" PRIxREG " TP: %" PRIxREG " RA: %" PRIxREG
|
||||
"\n",
|
||||
regs[REG_SP], regs[REG_FP], regs[REG_TP], regs[REG_RA]);
|
||||
#endif
|
||||
}
|
||||
|
|
@ -98,6 +108,7 @@ static void riscv_registerdump(const uint64_t *regs)
|
|||
|
||||
#ifdef CONFIG_LIB_SYSCALL
|
||||
static void dispatch_syscall(void) naked_function;
|
||||
#ifdef CONFIG_ARCH_RV64
|
||||
static void dispatch_syscall(void)
|
||||
{
|
||||
asm volatile
|
||||
|
|
@ -116,6 +127,26 @@ static void dispatch_syscall(void)
|
|||
" ecall" /* Return from the syscall */
|
||||
);
|
||||
}
|
||||
#else
|
||||
static void dispatch_syscall(void)
|
||||
{
|
||||
asm volatile
|
||||
(
|
||||
" addi sp, sp, -4\n" /* Create a stack frame to hold ra */
|
||||
" sw ra, 0(sp)\n" /* Save ra in the stack frame */
|
||||
" la t0, g_stublookup\n" /* t0=The base of the stub lookup table */
|
||||
" slli a0, a0, 3\n" /* a0=Offset for the stub lookup table */
|
||||
" add t0, t0, a0\n" /* t0=The address in the table */
|
||||
" lw t0, 0(t0)\n" /* t0=The address of the stub for this syscall */
|
||||
" jalr ra, t0\n" /* Call the stub (modifies ra) */
|
||||
" lw ra, 0(sp)\n" /* Restore ra */
|
||||
" addi sp, sp, 4\n" /* Destroy the stack frame */
|
||||
" mv a2, a0\n" /* a2=Save return value in a0 */
|
||||
" li a0, 3\n" /* a0=SYS_syscall_return (3) */
|
||||
" ecall" /* Return from the syscall */
|
||||
);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -133,7 +164,7 @@ static void dispatch_syscall(void)
|
|||
|
||||
int riscv_swint(int irq, void *context, void *arg)
|
||||
{
|
||||
uint64_t *regs = (uint64_t *)context;
|
||||
uintptr_t *regs = (uintptr_t *)context;
|
||||
|
||||
DEBUGASSERT(regs && regs == CURRENT_REGS);
|
||||
|
||||
|
|
@ -170,7 +201,7 @@ int riscv_swint(int irq, void *context, void *arg)
|
|||
case SYS_restore_context:
|
||||
{
|
||||
DEBUGASSERT(regs[REG_A1] != 0);
|
||||
CURRENT_REGS = (uint64_t *)regs[REG_A1];
|
||||
CURRENT_REGS = (uintptr_t *)regs[REG_A1];
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -193,8 +224,8 @@ int riscv_swint(int irq, void *context, void *arg)
|
|||
case SYS_switch_context:
|
||||
{
|
||||
DEBUGASSERT(regs[REG_A1] != 0 && regs[REG_A2] != 0);
|
||||
riscv_copystate((uint64_t *)regs[REG_A1], regs);
|
||||
CURRENT_REGS = (uint64_t *)regs[REG_A2];
|
||||
riscv_copystate((uintptr_t *)regs[REG_A1], regs);
|
||||
CURRENT_REGS = (uintptr_t *)regs[REG_A2];
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -455,7 +486,7 @@ int riscv_swint(int irq, void *context, void *arg)
|
|||
|
||||
rtcb->flags |= TCB_FLAG_SYSCALL;
|
||||
#else
|
||||
svcerr("ERROR: Bad SYS call: %" PRId64 "\n", regs[REG_A0]);
|
||||
svcerr("ERROR: Bad SYS call: %" PRIdPTR "\n", regs[REG_A0]);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
|
@ -469,7 +500,7 @@ int riscv_swint(int irq, void *context, void *arg)
|
|||
if (regs != CURRENT_REGS)
|
||||
{
|
||||
svcinfo("SWInt Return: Context switch!\n");
|
||||
riscv_registerdump((const uint32_t *)CURRENT_REGS);
|
||||
riscv_registerdump((const uintptr_t *)CURRENT_REGS);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/rv32im/irq.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/rv32im/irq.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
#include <arch/board/board.h>
|
||||
|
||||
#include <arch/irq.h>
|
||||
#include <arch/rv32im/mcause.h>
|
||||
#include <arch/mcause.h>
|
||||
|
||||
#include "riscv_internal.h"
|
||||
#include "hardware/esp32c3_interrupt.h"
|
||||
|
|
@ -60,7 +60,7 @@
|
|||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
volatile uint32_t *g_current_regs;
|
||||
volatile uintptr_t *g_current_regs[1];
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
|
|
@ -373,7 +373,7 @@ void esp32c3_free_cpuint(uint8_t periphid)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
IRAM_ATTR uint32_t *esp32c3_dispatch_irq(uint32_t mcause, uint32_t *regs)
|
||||
IRAM_ATTR uintptr_t *esp32c3_dispatch_irq(uintptr_t mcause, uintptr_t *regs)
|
||||
{
|
||||
int irq;
|
||||
|
||||
|
|
@ -390,14 +390,14 @@ IRAM_ATTR uint32_t *esp32c3_dispatch_irq(uint32_t mcause, uint32_t *regs)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Check "g_current_regs" only in interrupt or ecall */
|
||||
/* Check "CURRENT_REGS" only in interrupt or ecall */
|
||||
|
||||
DEBUGASSERT(g_current_regs == NULL);
|
||||
DEBUGASSERT(CURRENT_REGS == NULL);
|
||||
}
|
||||
|
||||
g_current_regs = regs;
|
||||
CURRENT_REGS = regs;
|
||||
|
||||
irqinfo("INFO: mcause=%08" PRIX32 "\n", mcause);
|
||||
irqinfo("INFO: mcause=%08" PRIXPTR "\n", mcause);
|
||||
|
||||
/* If the board supports LEDs, turn on an LED now to indicate that we are
|
||||
* processing an interrupt.
|
||||
|
|
@ -436,8 +436,8 @@ IRAM_ATTR uint32_t *esp32c3_dispatch_irq(uint32_t mcause, uint32_t *regs)
|
|||
}
|
||||
}
|
||||
|
||||
regs = (uint32_t *)g_current_regs;
|
||||
g_current_regs = NULL;
|
||||
regs = (uintptr_t *)CURRENT_REGS;
|
||||
CURRENT_REGS = NULL;
|
||||
|
||||
board_autoled_off(LED_INIRQ);
|
||||
|
||||
|
|
|
|||
|
|
@ -116,6 +116,6 @@ void esp32c3_free_cpuint(uint8_t periphid);
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t *esp32c3_dispatch_irq(uint32_t mcause, uint32_t *regs);
|
||||
uintptr_t *esp32c3_dispatch_irq(uintptr_t mcause, uintptr_t *regs);
|
||||
|
||||
#endif /* __ARCH_RISCV_SRC_ESP32C3_ESP32C3_IRQ_H */
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ HDR_ATTR static void (*_entry_point)(void) = &__start;
|
|||
|
||||
uint8_t g_idlestack[CONFIG_IDLETHREAD_STACKSIZE]
|
||||
aligned_data(16) locate_data(".noinit");
|
||||
uint32_t g_idle_topstack = ESP32C3_IDLESTACK_TOP;
|
||||
uintptr_t g_idle_topstack = ESP32C3_IDLESTACK_TOP;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/rv32im/irq.h>
|
||||
#include <arch/irq.h>
|
||||
#include <arch/esp32c3/irq.h>
|
||||
|
||||
#include "chip.h"
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/rv32im/irq.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "fe310_memorymap.h"
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ void up_irqinitialize(void)
|
|||
|
||||
/* currents_regs is non-NULL only while processing an interrupt */
|
||||
|
||||
g_current_regs = NULL;
|
||||
CURRENT_REGS = NULL;
|
||||
|
||||
/* Attach the ecall interrupt handler */
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
volatile uint32_t * g_current_regs;
|
||||
volatile uintptr_t *g_current_regs[1];
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
|
|
@ -52,10 +52,10 @@ volatile uint32_t * g_current_regs;
|
|||
* fe310_dispatch_irq
|
||||
****************************************************************************/
|
||||
|
||||
void *fe310_dispatch_irq(uint32_t vector, uint32_t *regs)
|
||||
void *fe310_dispatch_irq(uintptr_t vector, uintptr_t *regs)
|
||||
{
|
||||
uint32_t irq = (vector >> 27) | (vector & 0xf);
|
||||
uint32_t *mepc = regs;
|
||||
uintptr_t irq = (vector >> 27) | (vector & 0xf);
|
||||
uintptr_t *mepc = regs;
|
||||
|
||||
/* Firstly, check if the irq is machine external interrupt */
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ void *fe310_dispatch_irq(uint32_t vector, uint32_t *regs)
|
|||
|
||||
if (FE310_IRQ_ECALLM == irq)
|
||||
{
|
||||
*mepc += 2;
|
||||
*mepc += 4;
|
||||
}
|
||||
|
||||
/* Acknowledge the interrupt */
|
||||
|
|
@ -83,13 +83,13 @@ void *fe310_dispatch_irq(uint32_t vector, uint32_t *regs)
|
|||
PANIC();
|
||||
#else
|
||||
/* Current regs non-zero indicates that we are processing an interrupt;
|
||||
* g_current_regs is also used to manage interrupt level context switches.
|
||||
* CURRENT_REGS is also used to manage interrupt level context switches.
|
||||
*
|
||||
* Nested interrupts are not supported
|
||||
*/
|
||||
|
||||
DEBUGASSERT(g_current_regs == NULL);
|
||||
g_current_regs = regs;
|
||||
DEBUGASSERT(CURRENT_REGS == NULL);
|
||||
CURRENT_REGS = regs;
|
||||
|
||||
/* Deliver the IRQ */
|
||||
|
||||
|
|
@ -111,13 +111,13 @@ void *fe310_dispatch_irq(uint32_t vector, uint32_t *regs)
|
|||
#endif
|
||||
|
||||
/* If a context switch occurred while processing the interrupt then
|
||||
* g_current_regs may have change value. If we return any value different
|
||||
* CURRENT_REGS may have change value. If we return any value different
|
||||
* from the input regs, then the lower level will know that a context
|
||||
* switch occurred during interrupt processing.
|
||||
*/
|
||||
|
||||
regs = (uint32_t *)g_current_regs;
|
||||
g_current_regs = NULL;
|
||||
regs = (uintptr_t *)CURRENT_REGS;
|
||||
CURRENT_REGS = NULL;
|
||||
|
||||
return regs;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@
|
|||
* address.
|
||||
*/
|
||||
|
||||
uint32_t g_idle_topstack = FE310_IDLESTACK_TOP;
|
||||
uintptr_t g_idle_topstack = FE310_IDLESTACK_TOP;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/rv64gc/irq.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "k210_memorymap.h"
|
||||
|
|
|
|||
|
|
@ -46,9 +46,9 @@
|
|||
* such value for each processor that can receive an interrupt.
|
||||
*/
|
||||
|
||||
volatile uint64_t *g_current_regs[CONFIG_SMP_NCPUS];
|
||||
volatile uintptr_t *g_current_regs[CONFIG_SMP_NCPUS];
|
||||
#else
|
||||
volatile uint64_t *g_current_regs[1];
|
||||
volatile uintptr_t *g_current_regs[1];
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
extern void up_fault(int irq, uint64_t *regs);
|
||||
extern void up_fault(int irq, uintptr_t *regs);
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
|
|
@ -51,10 +51,10 @@ extern void up_fault(int irq, uint64_t *regs);
|
|||
* k210_dispatch_irq
|
||||
****************************************************************************/
|
||||
|
||||
void *k210_dispatch_irq(uint64_t vector, uint64_t *regs)
|
||||
void *k210_dispatch_irq(uintptr_t vector, uintptr_t *regs)
|
||||
{
|
||||
uint32_t irq = (vector >> (27 + 32)) | (vector & 0xf);
|
||||
uint64_t *mepc = regs;
|
||||
uintptr_t irq = (vector >> (27 + 32)) | (vector & 0xf);
|
||||
uintptr_t *mepc = regs;
|
||||
|
||||
/* Check if fault happened */
|
||||
|
||||
|
|
@ -120,7 +120,7 @@ void *k210_dispatch_irq(uint64_t vector, uint64_t *regs)
|
|||
* switch occurred during interrupt processing.
|
||||
*/
|
||||
|
||||
regs = (uint64_t *)CURRENT_REGS;
|
||||
regs = (uintptr_t *)CURRENT_REGS;
|
||||
CURRENT_REGS = NULL;
|
||||
|
||||
return regs;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/rv32im/irq.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ void up_irqinitialize(void)
|
|||
|
||||
/* currents_regs is non-NULL only while processing an interrupt */
|
||||
|
||||
g_current_regs = NULL;
|
||||
CURRENT_REGS = NULL;
|
||||
|
||||
/* Attach the ecall interrupt handler */
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
volatile uint32_t * g_current_regs;
|
||||
volatile uintptr_t *g_current_regs[1];
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
|
|
@ -51,10 +51,10 @@ volatile uint32_t * g_current_regs;
|
|||
* litex_dispatch_irq
|
||||
****************************************************************************/
|
||||
|
||||
void *litex_dispatch_irq(uint32_t vector, uint32_t *regs)
|
||||
void *litex_dispatch_irq(uintptr_t vector, uintptr_t *regs)
|
||||
{
|
||||
uint32_t irq = (vector >> 27) | (vector & 0xf);
|
||||
uint32_t *mepc = regs;
|
||||
uintptr_t irq = (vector >> 27) | (vector & 0xf);
|
||||
uintptr_t *mepc = regs;
|
||||
int i;
|
||||
|
||||
/* Firstly, check if the irq is machine external interrupt */
|
||||
|
|
@ -99,13 +99,13 @@ void *litex_dispatch_irq(uint32_t vector, uint32_t *regs)
|
|||
PANIC();
|
||||
#else
|
||||
/* Current regs non-zero indicates that we are processing an interrupt;
|
||||
* g_current_regs is also used to manage interrupt level context switches.
|
||||
* CURRENT_REGS is also used to manage interrupt level context switches.
|
||||
*
|
||||
* Nested interrupts are not supported
|
||||
*/
|
||||
|
||||
DEBUGASSERT(g_current_regs == NULL);
|
||||
g_current_regs = regs;
|
||||
DEBUGASSERT(CURRENT_REGS == NULL);
|
||||
CURRENT_REGS = regs;
|
||||
|
||||
/* Deliver the IRQ */
|
||||
|
||||
|
|
@ -114,13 +114,13 @@ void *litex_dispatch_irq(uint32_t vector, uint32_t *regs)
|
|||
#endif
|
||||
|
||||
/* If a context switch occurred while processing the interrupt then
|
||||
* g_current_regs may have change value. If we return any value different
|
||||
* CURRENT_REGS may have change value. If we return any value different
|
||||
* from the input regs, then the lower level will know that a context
|
||||
* switch occurred during interrupt processing.
|
||||
*/
|
||||
|
||||
regs = (uint32_t *)g_current_regs;
|
||||
g_current_regs = NULL;
|
||||
regs = (uintptr_t *)CURRENT_REGS;
|
||||
CURRENT_REGS = NULL;
|
||||
|
||||
return regs;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@
|
|||
* address.
|
||||
*/
|
||||
|
||||
uint32_t g_idle_topstack = LITEX_IDLESTACK_TOP;
|
||||
uintptr_t g_idle_topstack = LITEX_IDLESTACK_TOP;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/csr.h>
|
||||
#include <arch/rv64gc/irq.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "mpfs_memorymap.h"
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
volatile uint64_t *g_current_regs[1];
|
||||
volatile uintptr_t *g_current_regs[1];
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/rv32im/irq.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
|
|
@ -105,26 +105,11 @@ exception_common:
|
|||
sw x30, 30*4(sp) /* t5 */
|
||||
sw x31, 31*4(sp) /* t6 */
|
||||
|
||||
#if defined(INT_XCPT_REGS) && INT_XCPT_REGS >= 39
|
||||
csrr x28, 0x7b0
|
||||
csrr x29, 0x7b1
|
||||
csrr x30, 0x7b2
|
||||
sw x28, 33*4(sp)
|
||||
sw x29, 34*4(sp)
|
||||
sw x30, 35*4(sp)
|
||||
csrr x28, 0x7b4
|
||||
csrr x29, 0x7b5
|
||||
csrr x30, 0x7b6
|
||||
sw x28, 36*4(sp)
|
||||
sw x29, 37*4(sp)
|
||||
sw x30, 38*4(sp)
|
||||
#endif
|
||||
|
||||
csrr s0, mstatus
|
||||
sw s0, 32*4(sp) /* mstatus */
|
||||
sw s0, 32*4(sp) /* mstatus */
|
||||
|
||||
addi s0, sp, XCPTCONTEXT_SIZE
|
||||
sw s0, 2*4(sp) /* original SP */
|
||||
sw s0, 2*4(sp) /* original SP */
|
||||
|
||||
/* Setup arg0(exception cause), arg1(context) */
|
||||
|
||||
|
|
@ -154,21 +139,6 @@ exception_common:
|
|||
lw s0, 32*4(sp) /* restore mstatus */
|
||||
csrw mstatus, s0
|
||||
|
||||
#if defined(INT_XCPT_REGS) && INT_XCPT_REGS >= 39
|
||||
lw x28, 36*4(sp)
|
||||
lw x29, 37*4(sp)
|
||||
lw x30, 38*4(sp)
|
||||
csrrw x0, 0x7b4, x28
|
||||
csrrw x0, 0x7b5, x29
|
||||
csrrw x0, 0x7b6, x30
|
||||
lw x28, 33*4(sp)
|
||||
lw x29, 34*4(sp)
|
||||
lw x30, 35*4(sp)
|
||||
csrrw x0, 0x7b0, x28
|
||||
csrrw x0, 0x7b1, x29
|
||||
csrrw x0, 0x7b2, x30
|
||||
#endif
|
||||
|
||||
lw x3, 3*4(sp) /* gp */
|
||||
lw x4, 4*4(sp) /* tp */
|
||||
lw x5, 5*4(sp) /* t0 */
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ void up_irqinitialize(void)
|
|||
|
||||
/* currents_regs is non-NULL only while processing an interrupt */
|
||||
|
||||
g_current_regs = NULL;
|
||||
CURRENT_REGS = NULL;
|
||||
|
||||
/* Attach the ecall interrupt handler */
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
volatile uint32_t * g_current_regs;
|
||||
volatile uintptr_t *g_current_regs[1];
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
|
|
@ -52,16 +52,16 @@ volatile uint32_t * g_current_regs;
|
|||
* qemu_rv32_dispatch_irq
|
||||
****************************************************************************/
|
||||
|
||||
void *qemu_rv32_dispatch_irq(uint32_t vector, uint32_t *regs)
|
||||
void *qemu_rv32_dispatch_irq(uintptr_t vector, uintptr_t *regs)
|
||||
{
|
||||
uint32_t irq = (vector >> 27) | (vector & 0xf);
|
||||
uint32_t *mepc = regs;
|
||||
uintptr_t irq = (vector >> 27) | (vector & 0xf);
|
||||
uintptr_t *mepc = regs;
|
||||
|
||||
/* Firstly, check if the irq is machine external interrupt */
|
||||
|
||||
if (QEMU_RV32_IRQ_MEXT == irq)
|
||||
{
|
||||
uint32_t val = getreg32(QEMU_RV32_PLIC_CLAIM);
|
||||
uintptr_t val = getreg32(QEMU_RV32_PLIC_CLAIM);
|
||||
|
||||
/* Add the value to nuttx irq which is offset to the mext */
|
||||
|
||||
|
|
@ -79,13 +79,13 @@ void *qemu_rv32_dispatch_irq(uint32_t vector, uint32_t *regs)
|
|||
PANIC();
|
||||
#else
|
||||
/* Current regs non-zero indicates that we are processing an interrupt;
|
||||
* g_current_regs is also used to manage interrupt level context switches.
|
||||
* CURRENT_REGS is also used to manage interrupt level context switches.
|
||||
*
|
||||
* Nested interrupts are not supported
|
||||
*/
|
||||
|
||||
DEBUGASSERT(g_current_regs == NULL);
|
||||
g_current_regs = regs;
|
||||
DEBUGASSERT(CURRENT_REGS == NULL);
|
||||
CURRENT_REGS = regs;
|
||||
|
||||
/* Deliver the IRQ */
|
||||
|
||||
|
|
@ -100,13 +100,13 @@ void *qemu_rv32_dispatch_irq(uint32_t vector, uint32_t *regs)
|
|||
#endif
|
||||
|
||||
/* If a context switch occurred while processing the interrupt then
|
||||
* g_current_regs may have change value. If we return any value different
|
||||
* CURRENT_REGS may have change value. If we return any value different
|
||||
* from the input regs, then the lower level will know that a context
|
||||
* switch occurred during interrupt processing.
|
||||
*/
|
||||
|
||||
regs = (uint32_t *)g_current_regs;
|
||||
g_current_regs = NULL;
|
||||
regs = (uintptr_t *)CURRENT_REGS;
|
||||
CURRENT_REGS = NULL;
|
||||
|
||||
return regs;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
* for CPU0 and this value is used in up_initial_state()
|
||||
*/
|
||||
|
||||
uint32_t g_idle_topstack = QEMU_RV32_IDLESTACK_TOP;
|
||||
uintptr_t g_idle_topstack = QEMU_RV32_IDLESTACK_TOP;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||
#
|
||||
|
||||
comment "RV32IM Configuration Options"
|
||||
|
||||
config RV32IM_SYSTEM_CSRRS_SUPPORT
|
||||
bool "Supports RV core feature identification via CSRRS opcode"
|
||||
default n
|
||||
---help---
|
||||
Specifies if the architecture supports the SYSTEM opcode for reading
|
||||
Control Status Registers to obtain the RV core option flags.
|
||||
|
||||
config RV32IM_CUSTOM_IRQ_SUPPORT
|
||||
bool "Has custom implementation for IRQ handling"
|
||||
default n
|
||||
---help---
|
||||
Allows overriding the standard IRQ processing as described
|
||||
in the RISC-V architecture documents. This allows architecture
|
||||
specific code to support non-standard IRQ processing in the core.
|
||||
|
|
@ -1,191 +0,0 @@
|
|||
/****************************************************************************
|
||||
* arch/risc-v/src/rv32im/riscv_schedulesigaction.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 <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include <sched.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include "sched/sched.h"
|
||||
#include "riscv_internal.h"
|
||||
#include "riscv_arch.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_schedule_sigaction
|
||||
*
|
||||
* Description:
|
||||
* This function is called by the OS when one or more
|
||||
* signal handling actions have been queued for execution.
|
||||
* The architecture specific code must configure things so
|
||||
* that the 'sigdeliver' callback is executed on the thread
|
||||
* specified by 'tcb' as soon as possible.
|
||||
*
|
||||
* This function may be called from interrupt handling logic.
|
||||
*
|
||||
* This operation should not cause the task to be unblocked
|
||||
* nor should it cause any immediate execution of sigdeliver.
|
||||
* Typically, a few cases need to be considered:
|
||||
*
|
||||
* (1) This function may be called from an interrupt handler
|
||||
* During interrupt processing, all xcptcontext structures
|
||||
* should be valid for all tasks. That structure should
|
||||
* be modified to invoke sigdeliver() either on return
|
||||
* from (this) interrupt or on some subsequent context
|
||||
* switch to the recipient task.
|
||||
* (2) If not in an interrupt handler and the tcb is NOT
|
||||
* the currently executing task, then again just modify
|
||||
* the saved xcptcontext structure for the recipient
|
||||
* task so it will invoke sigdeliver when that task is
|
||||
* later resumed.
|
||||
* (3) If not in an interrupt handler and the tcb IS the
|
||||
* currently executing task -- just call the signal
|
||||
* handler now.
|
||||
*
|
||||
* Assumptions:
|
||||
* Called from critical section
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
{
|
||||
uint32_t int_ctx;
|
||||
|
||||
sinfo("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver);
|
||||
|
||||
/* Refuse to handle nested signal actions */
|
||||
|
||||
if (!tcb->xcp.sigdeliver)
|
||||
{
|
||||
/* First, handle some special cases when the signal is
|
||||
* being delivered to the currently executing task.
|
||||
*/
|
||||
|
||||
sinfo("rtcb=0x%p g_current_regs=0x%p\n",
|
||||
this_task(), g_current_regs);
|
||||
|
||||
if (tcb == this_task())
|
||||
{
|
||||
/* CASE 1: We are not in an interrupt handler and
|
||||
* a task is signalling itself for some reason.
|
||||
*/
|
||||
|
||||
if (!g_current_regs)
|
||||
{
|
||||
/* In this case just deliver the signal now. */
|
||||
|
||||
sigdeliver(tcb);
|
||||
}
|
||||
|
||||
/* CASE 2: We are in an interrupt handler AND the
|
||||
* interrupted task is the same as the one that
|
||||
* must receive the signal, then we will have to modify
|
||||
* the return state as well as the state in the TCB.
|
||||
*
|
||||
* Hmmm... there looks like a latent bug here: The following
|
||||
* logic would fail in the strange case where we are in an
|
||||
* interrupt handler, the thread is signalling itself, but
|
||||
* a context switch to another task has occurred so that
|
||||
* g_current_regs does not refer to the thread of this_task()!
|
||||
*/
|
||||
|
||||
else
|
||||
{
|
||||
/* Save the return EPC and STATUS registers. These will be
|
||||
* restored by the signal trampoline after the signals have
|
||||
* been delivered.
|
||||
*/
|
||||
|
||||
tcb->xcp.sigdeliver = sigdeliver;
|
||||
tcb->xcp.saved_epc = g_current_regs[REG_EPC];
|
||||
tcb->xcp.saved_int_ctx = g_current_regs[REG_INT_CTX];
|
||||
|
||||
/* Then set up to vector to the trampoline with interrupts
|
||||
* disabled
|
||||
*/
|
||||
|
||||
g_current_regs[REG_EPC] = (uint32_t)riscv_sigdeliver;
|
||||
|
||||
int_ctx = g_current_regs[REG_INT_CTX];
|
||||
int_ctx &= ~MSTATUS_MPIE;
|
||||
|
||||
g_current_regs[REG_INT_CTX] = int_ctx;
|
||||
|
||||
/* And make sure that the saved context in the TCB
|
||||
* is the same as the interrupt return context.
|
||||
*/
|
||||
|
||||
riscv_savestate(tcb->xcp.regs);
|
||||
|
||||
sinfo("PC/STATUS Saved: %08" PRIx32 "/%08" PRIx32
|
||||
" New: %08" PRIx32 "/%08" PRIx32 "\n",
|
||||
tcb->xcp.saved_epc, tcb->xcp.saved_int_ctx,
|
||||
g_current_regs[REG_EPC], g_current_regs[REG_INT_CTX]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise, we are (1) signaling a task is not running
|
||||
* from an interrupt handler or (2) we are not in an
|
||||
* interrupt handler and the running task is signalling
|
||||
* some non-running task.
|
||||
*/
|
||||
|
||||
else
|
||||
{
|
||||
/* Save the return EPC and STATUS registers. These will be
|
||||
* restored by the signal trampoline after the signals have
|
||||
* been delivered.
|
||||
*/
|
||||
|
||||
tcb->xcp.sigdeliver = sigdeliver;
|
||||
tcb->xcp.saved_epc = tcb->xcp.regs[REG_EPC];
|
||||
tcb->xcp.saved_int_ctx = tcb->xcp.regs[REG_INT_CTX];
|
||||
|
||||
/* Then set up to vector to the trampoline with interrupts
|
||||
* disabled
|
||||
*/
|
||||
|
||||
tcb->xcp.regs[REG_EPC] = (uint32_t)riscv_sigdeliver;
|
||||
|
||||
int_ctx = tcb->xcp.regs[REG_INT_CTX];
|
||||
int_ctx &= ~MSTATUS_MPIE;
|
||||
|
||||
tcb->xcp.regs[REG_INT_CTX] = int_ctx;
|
||||
|
||||
sinfo("PC/STATUS Saved: %08" PRIx32 "/%08" PRIx32
|
||||
" New: %08" PRIx32 "/%08" PRIx32 "\n",
|
||||
tcb->xcp.saved_epc, tcb->xcp.saved_int_ctx,
|
||||
tcb->xcp.regs[REG_EPC], tcb->xcp.regs[REG_INT_CTX]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
/****************************************************************************
|
||||
* arch/risc-v/src/rv32im/riscv_sigdeliver.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 <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include <sched.h>
|
||||
#include <syscall.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "sched/sched.h"
|
||||
#include "riscv_internal.h"
|
||||
#include "riscv_arch.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: riscv_sigdeliver
|
||||
*
|
||||
* Description:
|
||||
* This is the a signal handling trampoline. When a signal action was
|
||||
* posted. The task context was mucked with and forced to branch to this
|
||||
* location with interrupts disabled.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void riscv_sigdeliver(void)
|
||||
{
|
||||
struct tcb_s *rtcb = this_task();
|
||||
uint32_t regs[XCPTCONTEXT_REGS];
|
||||
|
||||
board_autoled_on(LED_SIGNAL);
|
||||
|
||||
sinfo("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n",
|
||||
rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head);
|
||||
DEBUGASSERT(rtcb->xcp.sigdeliver != NULL);
|
||||
|
||||
/* Save the return state on the stack. */
|
||||
|
||||
riscv_copyfullstate(regs, rtcb->xcp.regs);
|
||||
|
||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||
/* Then make sure that interrupts are enabled. Signal handlers must always
|
||||
* run with interrupts enabled.
|
||||
*/
|
||||
|
||||
up_irq_enable();
|
||||
#endif
|
||||
|
||||
/* Deliver the signals */
|
||||
|
||||
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
|
||||
|
||||
/* Output any debug messages BEFORE restoring errno (because they may
|
||||
* alter errno), then disable interrupts again and restore the original
|
||||
* errno that is needed by the user logic (it is probably EINTR).
|
||||
*/
|
||||
|
||||
sinfo("Resuming EPC: %08" PRIx32 " INT_CTX: %08" PRIx32 "\n",
|
||||
regs[REG_EPC], regs[REG_INT_CTX]);
|
||||
|
||||
up_irq_save();
|
||||
|
||||
/* Modify the saved return state with the actual saved values in the
|
||||
* TCB. This depends on the fact that nested signal handling is
|
||||
* not supported. Therefore, these values will persist throughout the
|
||||
* signal handling action.
|
||||
*
|
||||
* Keeping this data in the TCB resolves a security problem in protected
|
||||
* and kernel mode: The regs[] array is visible on the user stack and
|
||||
* could be modified by a hostile program.
|
||||
*/
|
||||
|
||||
regs[REG_EPC] = rtcb->xcp.saved_epc;
|
||||
regs[REG_INT_CTX] = rtcb->xcp.saved_int_ctx;
|
||||
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
|
||||
|
||||
/* Then restore the correct state for this thread of
|
||||
* execution.
|
||||
*/
|
||||
|
||||
board_autoled_off(LED_SIGNAL);
|
||||
riscv_fullcontextrestore(regs);
|
||||
|
||||
/* riscv_fullcontextrestore() should not return but could if the software
|
||||
* interrupts are disabled.
|
||||
*/
|
||||
|
||||
DEBUGPANIC();
|
||||
}
|
||||
|
|
@ -1,320 +0,0 @@
|
|||
/****************************************************************************
|
||||
* arch/risc-v/src/rv32im/riscv_swint.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 <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <syscall.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/sched.h>
|
||||
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "signal/signal.h"
|
||||
#include "riscv_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: riscv_registerdump
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_SYSCALL_INFO
|
||||
static void riscv_registerdump(const uint32_t *regs)
|
||||
{
|
||||
svcinfo("EPC:%08x\n",
|
||||
regs[REG_EPC]);
|
||||
svcinfo("A0:%08x A1:%08x A2:%08x A3:%08x A4:%08x A5:%08x "
|
||||
"A6:%08x A7:%08x\n",
|
||||
regs[REG_A0], regs[REG_A1], regs[REG_A2], regs[REG_A3],
|
||||
regs[REG_A4], regs[REG_A5], regs[REG_A6], regs[REG_A7]);
|
||||
svcinfo("T0:%08x T1:%08x T2:%08x T3:%08x T4:%08x T5:%08x T6:%08x\n",
|
||||
regs[REG_T0], regs[REG_T1], regs[REG_T2], regs[REG_T3],
|
||||
regs[REG_T4], regs[REG_T5], regs[REG_T6]);
|
||||
svcinfo("S0:%08x S1:%08x S2:%08x S3:%08x S4:%08x S5:%08x "
|
||||
"S6:%08x S7:%08x\n",
|
||||
regs[REG_S0], regs[REG_S1], regs[REG_S2], regs[REG_S3],
|
||||
regs[REG_S4], regs[REG_S5], regs[REG_S6], regs[REG_S7]);
|
||||
svcinfo("S8:%08x S9:%08x S10:%08x S11:%08x\n",
|
||||
regs[REG_S8], regs[REG_S9], regs[REG_S10], regs[REG_S11]);
|
||||
#ifdef RISCV_SAVE_GP
|
||||
svcinfo("GP:%08x SP:%08x FP:%08x TP:%08x RA:%08x\n",
|
||||
regs[REG_GP], regs[REG_SP], regs[REG_FP],
|
||||
regs[REG_TP], regs[REG_RA]);
|
||||
#else
|
||||
svcinfo("SP:%08x FP:%08x TP:%08x RA:%08x\n",
|
||||
regs[REG_SP], regs[REG_FP], regs[REG_TP], regs[REG_RA]);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: dispatch_syscall
|
||||
*
|
||||
* Description:
|
||||
* Call the stub function corresponding to the system call.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
static void dispatch_syscall(void) naked_function;
|
||||
static void dispatch_syscall(void)
|
||||
{
|
||||
# error "Missing logic"
|
||||
|
||||
/* Refer to arch/arm/src/armv7-m/up_svcall.h for how this is done for
|
||||
* ARM
|
||||
*
|
||||
* __asm__ __volatile__
|
||||
* (
|
||||
* Save registers
|
||||
* Get the base of the stub lookup table
|
||||
* Get the offset of the stub for this syscall
|
||||
* Load the entry of the stub for this syscall
|
||||
* Call the stub
|
||||
* Restore registers
|
||||
* Return from the syscall
|
||||
* );
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: riscv_swint
|
||||
*
|
||||
* Description:
|
||||
* This is software interrupt exception handler that performs context
|
||||
* switching and manages system calls
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int riscv_swint(int irq, void *context, void *arg)
|
||||
{
|
||||
uint32_t *regs = (uint32_t *)context;
|
||||
|
||||
DEBUGASSERT(regs && regs == g_current_regs);
|
||||
|
||||
/* Software interrupt 0 is invoked with REG_A0 (REG_X10) = system call
|
||||
* command and REG_A1-6 = variable number of
|
||||
* arguments depending on the system call.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_DEBUG_SYSCALL_INFO
|
||||
svcinfo("Entry: regs: %p cmd: %d\n", regs, regs[REG_A0]);
|
||||
riscv_registerdump(regs);
|
||||
#endif
|
||||
|
||||
/* Skip ECALL instruction */
|
||||
|
||||
regs[REG_EPC] += 4;
|
||||
|
||||
/* Handle the SWInt according to the command in $a0 */
|
||||
|
||||
switch (regs[REG_A0])
|
||||
{
|
||||
/* A0=SYS_save_context: This is a save context command:
|
||||
*
|
||||
* int riscv_saveusercontext(uint32_t *saveregs);
|
||||
*
|
||||
* At this point, the following values are saved in context:
|
||||
*
|
||||
* A0 = SYS_save_context
|
||||
* A1 = saveregs
|
||||
*
|
||||
* Return:
|
||||
* 0: Normal return
|
||||
* 1: Context switch return
|
||||
*
|
||||
* In this case, we simply need to copy the current registers to the
|
||||
* save register space references in the saved A1 and return.
|
||||
*/
|
||||
|
||||
case SYS_save_context:
|
||||
{
|
||||
DEBUGASSERT(regs[REG_A1] != 0);
|
||||
riscv_copystate((uint32_t *)regs[REG_A1], regs);
|
||||
((uint32_t *)regs[REG_A1])[REG_A0] = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
/* A0=SYS_restore_context: This a restore context command:
|
||||
*
|
||||
* void
|
||||
* riscv_fullcontextrestore(uint32_t *restoreregs) noreturn_function;
|
||||
*
|
||||
* At this point, the following values are saved in context:
|
||||
*
|
||||
* A0 = SYS_restore_context
|
||||
* A1 = restoreregs
|
||||
*
|
||||
* In this case, we simply need to set g_current_regs to restore
|
||||
* register area referenced in the saved R1. context == g_current_regs
|
||||
* is the normal exception return.
|
||||
* By setting g_current_regs = context[R1], we force the return to the
|
||||
* saved context referenced in $a1.
|
||||
*/
|
||||
|
||||
case SYS_restore_context:
|
||||
{
|
||||
DEBUGASSERT(regs[REG_A1] != 0);
|
||||
g_current_regs = (uint32_t *)regs[REG_A1];
|
||||
}
|
||||
break;
|
||||
|
||||
/* A0=SYS_switch_context: This a switch context command:
|
||||
*
|
||||
* void riscv_switchcontext(uint32_t *saveregs, uint32_t *restoreregs);
|
||||
*
|
||||
* At this point, the following values are saved in context:
|
||||
*
|
||||
* A0 = SYS_switch_context
|
||||
* A1 = saveregs
|
||||
* A2 = restoreregs
|
||||
*
|
||||
* In this case, we save the context registers to the save register
|
||||
* area referenced by the saved contents of R5 and then set
|
||||
* g_current_regs to the save register area referenced by the saved
|
||||
* contents of R6.
|
||||
*/
|
||||
|
||||
case SYS_switch_context:
|
||||
{
|
||||
DEBUGASSERT(regs[REG_A1] != 0 && regs[REG_A2] != 0);
|
||||
riscv_copystate((uint32_t *)regs[REG_A1], regs);
|
||||
g_current_regs = (uint32_t *)regs[REG_A2];
|
||||
}
|
||||
break;
|
||||
|
||||
/* A0=SYS_syscall_return: This a switch context command:
|
||||
*
|
||||
* void up_sycall_return(void);
|
||||
*
|
||||
* At this point, the following values are saved in context:
|
||||
*
|
||||
* A0 = SYS_syscall_return
|
||||
*
|
||||
* We need to restore the saved return address and return in
|
||||
* unprivileged thread mode.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
case SYS_syscall_return:
|
||||
{
|
||||
struct tcb_s *rtcb = nxsched_self();
|
||||
int index = (int)rtcb->xcp.nsyscalls - 1;
|
||||
|
||||
/* Make sure that there is a saved syscall return address. */
|
||||
|
||||
DEBUGASSERT(index >= 0);
|
||||
|
||||
/* Setup to return to the saved syscall return address in
|
||||
* the original mode.
|
||||
*/
|
||||
|
||||
g_current_regs[REG_EPC] = rtcb->xcp.syscall[index].sysreturn;
|
||||
#error "Missing logic -- need to restore the original mode"
|
||||
rtcb->xcp.nsyscalls = index;
|
||||
|
||||
/* Handle any signal actions that were deferred while processing
|
||||
* the system call.
|
||||
*/
|
||||
|
||||
rtcb->flags &= ~TCB_FLAG_SYSCALL;
|
||||
(void)nxsig_unmask_pendingsignal();
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
/* This is not an architecture-specify system call. If NuttX is built
|
||||
* as a standalone kernel with a system call interface, then all of the
|
||||
* additional system calls must be handled as in the default case.
|
||||
*/
|
||||
|
||||
default:
|
||||
{
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
struct tcb_s *rtcb = nxsched_self();
|
||||
int index = rtcb->xcp.nsyscalls;
|
||||
|
||||
/* Verify that the SYS call number is within range */
|
||||
|
||||
DEBUGASSERT(g_current_regs[REG_A0] < SYS_maxsyscall);
|
||||
|
||||
/* Make sure that we got here that there is a no saved syscall
|
||||
* return address. We cannot yet handle nested system calls.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(index < CONFIG_SYS_NNEST);
|
||||
|
||||
/* Setup to return to dispatch_syscall in privileged mode. */
|
||||
|
||||
rtcb->xcpsyscall[index].sysreturn = regs[REG_EPC];
|
||||
#error "Missing logic -- Need to save mode"
|
||||
rtcb->xcp.nsyscalls = index + 1;
|
||||
|
||||
regs[REG_EPC] = (uint32_t)dispatch_syscall;
|
||||
#error "Missing logic -- Need to set privileged mode"
|
||||
|
||||
/* Offset R0 to account for the reserved values */
|
||||
|
||||
g_current_regs[REG_A0] -= CONFIG_SYS_RESERVED;
|
||||
|
||||
/* Indicate that we are in a syscall handler. */
|
||||
|
||||
rtcb->flags |= TCB_FLAG_SYSCALL;
|
||||
#else
|
||||
svcerr("ERROR: Bad SYS call: %" PRId32 "\n", regs[REG_A0]);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Report what happened. That might difficult in the case of a context
|
||||
* switch
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_DEBUG_SYSCALL_INFO
|
||||
if (regs != g_current_regs)
|
||||
{
|
||||
svcinfo("SWInt Return: Context switch!\n");
|
||||
riscv_registerdump((const uint32_t *)g_current_regs);
|
||||
}
|
||||
else
|
||||
{
|
||||
svcinfo("SWInt Return: %d\n", regs[REG_A0]);
|
||||
}
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/rv32im/irq.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ void up_irqinitialize(void)
|
|||
|
||||
/* currents_regs is non-NULL only while processing an interrupt */
|
||||
|
||||
g_current_regs = NULL;
|
||||
CURRENT_REGS = NULL;
|
||||
|
||||
/* Attach the ecall interrupt handler */
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
volatile uint32_t * g_current_regs;
|
||||
volatile uintptr_t *g_current_regs[1];
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
|
|
@ -53,11 +53,11 @@ volatile uint32_t * g_current_regs;
|
|||
****************************************************************************/
|
||||
|
||||
LOCATE_ITCM
|
||||
void *rv32m1_dispatch_irq(uint32_t vector, uint32_t *regs)
|
||||
void *rv32m1_dispatch_irq(uintptr_t vector, uintptr_t *regs)
|
||||
{
|
||||
int vec = vector & 0x1f;
|
||||
int irq = (vector >> 27) + vec;
|
||||
uint32_t *mepc = regs;
|
||||
uintptr_t vec = vector & 0x1f;
|
||||
uintptr_t irq = (vector >> 27) + vec;
|
||||
uintptr_t *mepc = regs;
|
||||
|
||||
int irqofs = 0;
|
||||
|
||||
|
|
@ -65,14 +65,14 @@ void *rv32m1_dispatch_irq(uint32_t vector, uint32_t *regs)
|
|||
|
||||
if (RV32M1_IRQ_ECALL_M == irq)
|
||||
{
|
||||
*mepc += 2;
|
||||
*mepc += 4;
|
||||
}
|
||||
|
||||
if (RV32M1_IRQ_INTMUX0 <= irq)
|
||||
{
|
||||
uint32_t const chn = irq - RV32M1_IRQ_INTMUX0;
|
||||
uint32_t regaddr = RV32M1_INTMUX_CH_BASE(chn) + INTMUX_CH_VEC_OFFSET;
|
||||
uint32_t regval = getreg32(regaddr);
|
||||
uintptr_t chn = irq - RV32M1_IRQ_INTMUX0;
|
||||
uintptr_t regaddr = RV32M1_INTMUX_CH_BASE(chn) + INTMUX_CH_VEC_OFFSET;
|
||||
uintptr_t regval = getreg32(regaddr);
|
||||
|
||||
/* CH_VEC coudle be 0 while INTMUX doesn't latch pending source
|
||||
* interrupts. In that case a spurious interrupt is being serviced,
|
||||
|
|
@ -109,13 +109,13 @@ void *rv32m1_dispatch_irq(uint32_t vector, uint32_t *regs)
|
|||
PANIC();
|
||||
#else
|
||||
/* Current regs non-zero indicates that we are processing an interrupt;
|
||||
* g_current_regs is also used to manage interrupt level context switches.
|
||||
* CURRENT_REGS is also used to manage interrupt level context switches.
|
||||
*
|
||||
* Nested interrupts are not supported
|
||||
*/
|
||||
|
||||
DEBUGASSERT(g_current_regs == NULL);
|
||||
g_current_regs = regs;
|
||||
DEBUGASSERT(CURRENT_REGS == NULL);
|
||||
CURRENT_REGS = regs;
|
||||
|
||||
/* Deliver the IRQ */
|
||||
|
||||
|
|
@ -133,13 +133,13 @@ void *rv32m1_dispatch_irq(uint32_t vector, uint32_t *regs)
|
|||
#endif
|
||||
|
||||
/* If a context switch occurred while processing the interrupt then
|
||||
* g_current_regs may have change value. If we return any value different
|
||||
* CURRENT_REGS may have change value. If we return any value different
|
||||
* from the input regs, then the lower level will know that a context
|
||||
* switch occurred during interrupt processing.
|
||||
*/
|
||||
|
||||
regs = (uint32_t *)g_current_regs;
|
||||
g_current_regs = NULL;
|
||||
regs = (uintptr_t *)CURRENT_REGS;
|
||||
CURRENT_REGS = NULL;
|
||||
|
||||
return regs;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@
|
|||
* address.
|
||||
*/
|
||||
|
||||
uint32_t g_idle_topstack = RV32M1_IDLESTACK_TOP;
|
||||
uintptr_t g_idle_topstack = RV32M1_IDLESTACK_TOP;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
|
|
|
|||
|
|
@ -1,62 +0,0 @@
|
|||
/****************************************************************************
|
||||
* arch/risc-v/src/rv64gc/riscv_copyfullstate.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 <arch/irq.h>
|
||||
|
||||
#include "riscv_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: riscv_copyfullstate
|
||||
*
|
||||
* Description:
|
||||
* Copy the entire register save area (including the floating point
|
||||
* registers if applicable). This is a little faster than most memcpy's
|
||||
* since it does 64-bit transfers.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void riscv_copyfullstate(uint64_t *dest, uint64_t *src)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* 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:
|
||||
*/
|
||||
|
||||
if (src != dest)
|
||||
{
|
||||
for (i = 0; i < XCPTCONTEXT_REGS; i++)
|
||||
{
|
||||
*dest++ = *src++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
/****************************************************************************
|
||||
* arch/risc-v/src/rv64gc/riscv_copystate.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 <arch/irq.h>
|
||||
|
||||
#include "riscv_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: riscv_copystate
|
||||
****************************************************************************/
|
||||
|
||||
/* A little faster than most memcpy's */
|
||||
|
||||
void riscv_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:
|
||||
*/
|
||||
|
||||
if (src != dest)
|
||||
{
|
||||
/* 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
|
||||
riscv_savefpu(regs);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -53,7 +53,6 @@ CONFIG_RAM_SIZE=134217728
|
|||
CONFIG_RAM_START=0xc0800000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_RV32IM_CUSTOM_IRQ_SUPPORT=y
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_STACK_COLORATION=y
|
||||
CONFIG_START_DAY=20
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ CONFIG_RAM_SIZE=134217728
|
|||
CONFIG_RAM_START=0xc0800000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_RV32IM_CUSTOM_IRQ_SUPPORT=y
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_STACK_COLORATION=y
|
||||
CONFIG_START_DAY=20
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@ CONFIG_RAM_SIZE=134217728
|
|||
CONFIG_RAM_START=0xc0800000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_RV32IM_CUSTOM_IRQ_SUPPORT=y
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_STACK_COLORATION=y
|
||||
CONFIG_START_DAY=20
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@ CONFIG_RAM_SIZE=134217728
|
|||
CONFIG_RAM_START=0xc0800000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_RV32IM_CUSTOM_IRQ_SUPPORT=y
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_STACK_COLORATION=y
|
||||
CONFIG_START_DAY=20
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ CONFIG_RAM_SIZE=134217728
|
|||
CONFIG_RAM_START=0xc0800000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_RV32IM_CUSTOM_IRQ_SUPPORT=y
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_STACK_COLORATION=y
|
||||
CONFIG_START_DAY=20
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@ CONFIG_RAM_SIZE=134217728
|
|||
CONFIG_RAM_START=0xc0800000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_RV32IM_CUSTOM_IRQ_SUPPORT=y
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_STACK_COLORATION=y
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@ CONFIG_RAM_SIZE=134217728
|
|||
CONFIG_RAM_START=0xc0800000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_RV32IM_CUSTOM_IRQ_SUPPORT=y
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_STACK_COLORATION=y
|
||||
CONFIG_START_DAY=20
|
||||
|
|
|
|||
|
|
@ -54,7 +54,6 @@ CONFIG_RAM_SIZE=134217728
|
|||
CONFIG_RAM_START=0xc0800000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_RV32IM_CUSTOM_IRQ_SUPPORT=y
|
||||
CONFIG_SCHED_CPULOAD=y
|
||||
CONFIG_SCHED_CPULOAD_EXTCLK=y
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
|
|
|
|||
|
|
@ -103,7 +103,6 @@ CONFIG_RAM_START=0xc0800000
|
|||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_READLINE_CMD_HISTORY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_RV32IM_CUSTOM_IRQ_SUPPORT=y
|
||||
CONFIG_SCHED_ATEXIT=y
|
||||
CONFIG_SCHED_HAVE_PARENT=y
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@
|
|||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static uint64_t g_saveregs[XCPTCONTEXT_REGS];
|
||||
static uintptr_t g_saveregs[XCPTCONTEXT_REGS];
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
|
|
@ -76,7 +76,7 @@ void arch_getfpu(FAR uint32_t *fpusave)
|
|||
|
||||
/* Return only the floating register values */
|
||||
|
||||
memcpy(fpusave, &g_saveregs[INT_XCPT_REGS], (8 * FPU_XCPT_REGS));
|
||||
memcpy(fpusave, &g_saveregs[INT_XCPT_REGS], INT_REG_SIZE * FPU_XCPT_REGS);
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ void arch_getfpu(FAR uint32_t *fpusave)
|
|||
|
||||
bool arch_cmpfpu(FAR const uint32_t *fpusave1, FAR const uint32_t *fpusave2)
|
||||
{
|
||||
return memcmp(fpusave1, fpusave2, (8 * FPU_XCPT_REGS)) == 0;
|
||||
return memcmp(fpusave1, fpusave2, INT_REG_SIZE * FPU_XCPT_REGS) == 0;
|
||||
}
|
||||
|
||||
#endif /* HAVE_FPU */
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@ CONFIG_RAM_SIZE=268435456
|
|||
CONFIG_RAM_START=0x40000000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_RV32IM_CUSTOM_IRQ_SUPPORT=y
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_STACK_COLORATION=y
|
||||
CONFIG_START_DAY=20
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue