RISC-V: Implement option to run NuttX in supervisor mode (S-mode)

- Add config "ARCH_USE_S_MODE" which controls whether the kernel
  runs in M-mode or S-mode
- Add more MSTATUS and most of the SSTATUS register definitions
- Add more MIP flags for interrupt delegation
- Add handling of interrupts from S-mode
- Add handling of FPU from S-mode
- Add new context handling functions that are not dependent on the trap
  handlers / ecall

NOTE: S-mode requires a companion SW (SBI) which is not yet implemented,
      thus S-mode is not usable as is, yet.
This commit is contained in:
Ville Juven 2022-03-17 11:20:42 +02:00 committed by Alan Carvalho de Assis
parent c37474b5bd
commit c15b6701ce
31 changed files with 737 additions and 188 deletions

View File

@ -102,6 +102,7 @@ config ARCH_CHIP_MPFS
select ARCH_HAVE_RESET
select ARCH_HAVE_SPI_CS_CONTROL
select ARCH_HAVE_PWM_MULTICHAN
select ARCH_HAVE_S_MODE
select PMP_HAS_LIMITED_FEATURES
---help---
MicroChip Polarfire processor (RISC-V 64bit core with GCVX extensions).
@ -189,6 +190,27 @@ config ARCH_MMU_TYPE_SV39
bool
default n
config ARCH_HAVE_S_MODE
bool
default n
# Option to run NuttX in supervisor mode. This is obviously not usable in
# flat mode, is questionable in protected mode, but is mandatory in kernel
# mode.
#
# Kernel mode requires this as M-mode uses flat addressing and the kernel
# memory must be mapped in order to share memory between the kernel and
# different user tasks which reside in virtual memory.
config ARCH_USE_S_MODE
bool "Run the NuttX kernel in S-mode"
default n
depends on ARCH_HAVE_S_MODE && BUILD_KERNEL && ARCH_USE_MMU
---help---
Most of the RISC-V implementations run in M-mode (flat addressing)
and/or U-mode (in case of separate kernel-/userspaces). This provides
an option to run the kernel in S-mode, if the target supports it.
# MPU has certain architecture dependent configurations, which are presented
# here. Default is that the full RISC-V PMP specification is supported.

View File

@ -299,13 +299,27 @@
/* In mstatus register */
#define MSTATUS_UIE (0x1 << 0) /* User Interrupt Enable */
#define MSTATUS_SIE (0x1 << 1) /* Supervisor Interrupt Enable */
#define MSTATUS_MIE (0x1 << 3) /* Machine Interrupt Enable */
#define MSTATUS_SPIE (0x1 << 5) /* Supervisor Previous Interrupt Enable */
#define MSTATUS_MPIE (0x1 << 7) /* Machine Previous Interrupt Enable */
#define MSTATUS_SPPU (0x0 << 8) /* Supervisor Previous Privilege (u-mode) */
#define MSTATUS_SPPS (0x1 << 8) /* Supervisor Previous Privilege (s-mode) */
#define MSTATUS_MPPU (0x0 << 11) /* Machine Previous Privilege (u-mode) */
#define MSTATUS_MPPS (0x1 << 11) /* Machine Previous Privilege (s-mode) */
#define MSTATUS_MPPM (0x3 << 11) /* Machine Previous Privilege (m-mode) */
#define MSTATUS_MPP_MASK (0x3 << 11)
#define MSTATUS_FS (0x3 << 13) /* Machine Floating-point Status */
#define MSTATUS_FS_INIT (0x1 << 13)
#define MSTATUS_FS_CLEAN (0x2 << 13)
#define MSTATUS_FS_DIRTY (0x3 << 13)
#define MSTATUS_MPRV (0x1 << 17) /* Modify Privilege */
#define MSTATUS_SUM (0x1 << 18) /* S mode access to U mode memory */
#define MSTATUS_MXR (0x1 << 19) /* Make executable / readable */
#define MSTATUS_TVM (0x1 << 20) /* Trap access to satp from S mode */
#define MSTATUS_TW (0x1 << 21) /* Trap WFI instruction from S mode */
#define MSTATUS_TSR (0x1 << 22) /* Trap supervisor return (sret) */
/* Mask of preserved bits for mstatus */
@ -317,19 +331,50 @@
/* In mie (machine interrupt enable) register */
#define MIE_SSIE (0x1 << 1) /* Supervisor Software Interrupt Enable */
#define MIE_MSIE (0x1 << 3) /* Machine Software Interrupt Enable */
#define MIE_STIE (0x1 << 5) /* Supervisor Timer Interrupt Enable */
#define MIE_MTIE (0x1 << 7) /* Machine Timer Interrupt Enable */
#define MIE_SEIE (0x1 << 9) /* Supervisor External Interrupt Enable */
#define MIE_MEIE (0x1 << 11) /* Machine External Interrupt Enable */
/* In mip (machine interrupt pending) register */
#define MIP_MTIP (0x1 << 7)
#define MIP_SSIP (0x1 << 1)
#define MIP_STIP (0x1 << 5)
#define MIP_MTIP (0x1 << 7)
#define MIP_SEIP (0x1 << 9)
/* In sstatus register (which is a view of mstatus) */
#define SSTATUS_SIE MSTATUS_SIE
#define SSTATUS_SPIE MSTATUS_SPIE
#define SSTATUS_SPPU MSTATUS_SPPU
#define SSTATUS_SPPS MSTATUS_SPPS
#define SSTATUS_FS MSTATUS_FS
#define SSTATUS_FS_INIT MSTATUS_FS_INIT
#define SSTATUS_FS_CLEAN MSTATUS_FS_CLEAN
#define SSTATUS_FS_DIRTY MSTATUS_FS_DIRTY
#define SSTATUS_SUM MSTATUS_SUM
#define SSTATUS_MXR MSTATUS_MXR
/* In sie register (which is a view of mie) */
#define SIE_SSIE MIE_SSIE
#define SIE_STIE MIE_STIE
#define SIE_SEIE MIE_SEIE
/* In sip register (which is a view of mip) */
#define SIP_SSIP MIP_SSIP
#define SIP_STIP MIP_STIP
#define SIP_SEIP MIP_SEIP
/* In pmpcfg (PMP configuration) register */
#define PMPCFG_R (1 << 0) /* readable ? */
#define PMPCFG_W (1 << 1) /* writeable ? */
#define PMPCFG_X (1 << 2) /* excutable ? */
#define PMPCFG_W (1 << 1) /* writable ? */
#define PMPCFG_X (1 << 2) /* executable ? */
#define PMPCFG_RWX_MASK (7 << 0) /* access rights mask */
#define PMPCFG_A_OFF (0 << 3) /* null region (disabled) */
#define PMPCFG_A_TOR (1 << 3) /* top of range */

View File

@ -35,8 +35,10 @@
#include <arch/types.h>
#include <arch/arch.h>
#include <arch/csr.h>
#include <arch/chip/irq.h>
#include <arch/mode.h>
/****************************************************************************
* Pre-processor Definitions
@ -47,7 +49,7 @@
/* IRQ 0-15 : (exception:interrupt=0) */
#define RISCV_IRQ_IAMISALIGNED (0) /* Instruction Address Misaligned */
#define RISCV_IRQ_IAFAULT (1) /* Instruction Address Fault */
#define RISCV_IRQ_IAFAULT (1) /* Instruction Access Fault */
#define RISCV_IRQ_IINSTRUCTION (2) /* Illegal Instruction */
#define RISCV_IRQ_BPOINT (3) /* Break Point */
#define RISCV_IRQ_LAMISALIGNED (4) /* Load Address Misaligned */
@ -61,7 +63,7 @@
#define RISCV_IRQ_INSTRUCTIONPF (12) /* Instruction page fault */
#define RISCV_IRQ_LOADPF (13) /* Load page fault */
#define RISCV_IRQ_RESERVED (14) /* Reserved */
#define RISCV_IRQ_SROREPF (15) /* Store/AMO page fault */
#define RISCV_IRQ_STOREPF (15) /* Store/AMO page fault */
#define RISCV_MAX_EXCEPTION (15)
@ -96,6 +98,16 @@
# define CONFIG_SYS_NNEST 2
#endif
/* Amount of interrupt stacks (amount of harts) */
#ifdef CONFIG_IRQ_NSTACKS
# define IRQ_NSTACKS CONFIG_IRQ_NSTACKS
#elif defined CONFIG_SMP
# define IRQ_NSTACKS CONFIG_SMP_NCPUS
#else
# define IRQ_NSTACKS 1
#endif
/* Processor PC */
#define REG_EPC_NDX 0
@ -469,7 +481,7 @@ struct xcpt_syscall_s
{
uintptr_t sysreturn; /* The return PC */
#ifndef CONFIG_BUILD_FLAT
uintptr_t int_ctx; /* Interrupt context (i.e. mstatus) */
uintptr_t int_ctx; /* Interrupt context (i.e. m-/sstatus) */
#endif
};
#endif
@ -577,9 +589,9 @@ static inline irqstate_t up_irq_save(void)
__asm__ __volatile__
(
"csrrc %0, mstatus, %1\n"
"csrrc %0, " __XSTR(CSR_STATUS) ", %1\n"
: "=r" (flags)
: "r"(MSTATUS_MIE)
: "r"(STATUS_IE)
: "memory"
);
@ -602,7 +614,7 @@ static inline void up_irq_restore(irqstate_t flags)
{
__asm__ __volatile__
(
"csrw mstatus, %0\n"
"csrw " __XSTR(CSR_STATUS) ", %0\n"
: /* no output */
: "r" (flags)
: "memory"

101
arch/risc-v/include/mode.h Normal file
View File

@ -0,0 +1,101 @@
/****************************************************************************
* arch/risc-v/include/mode.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.
*
****************************************************************************/
#ifndef __ARCH_RISCV_INCLUDE_MODE_H
#define __ARCH_RISCV_INCLUDE_MODE_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/irq.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_ARCH_USE_S_MODE
/* CSR definitions */
# define CSR_STATUS sstatus /* Global status register */
# define CSR_EPC sepc /* Exception program counter */
# define CSR_IE sie /* Interrupt enable register */
# define CSR_CAUSE scause /* Interrupt cause register */
/* In status register */
# define STATUS_IE SSTATUS_SIE /* Global interrupt enable */
# define STATUS_PIE SSTATUS_SPIE /* Previous interrupt enable */
# define STATUS_PPP SSTATUS_SPPS /* Previous privilege */
# define STATUS_SUM SSTATUS_SUM /* Access to user memory */
/* Interrupt bits */
# define IE_EIE SIE_SEIE /* External interrupt enable */
# define IE_SIE SIE_SSIE /* Software interrupt enable */
# define IE_TIE SIE_STIE /* Timer interrupt enable */
/* External, timer and software interrupt */
# define RISCV_IRQ_EXT RISCV_IRQ_SEXT /* PLIC IRQ */
# define RISCV_IRQ_TIMER RISCV_IRQ_STIMER /* Timer IRQ */
# define RISCV_IRQ_SOFT RISCV_IRQ_SSOFT /* SW IRQ */
/* Define return from exception */
# define ERET sret
#else
/* CSR definitions */
# define CSR_STATUS mstatus /* Global status register */
# define CSR_EPC mepc /* Exception program counter */
# define CSR_IE mie /* Interrupt enable register */
# define CSR_CAUSE mcause /* Interrupt cause register */
/* In status register */
# define STATUS_IE MSTATUS_MIE /* Global interrupt enable */
# define STATUS_PIE MSTATUS_MPIE /* Previous interrupt enable */
# define STATUS_PPP MSTATUS_MPPM /* Previous privilege */
# define STATUS_SUM 0 /* Not needed in M-mode */
/* Interrupt bits */
# define IE_EIE MIE_MEIE /* External interrupt enable */
# define IE_SIE MIE_MSIE /* Software interrupt enable */
# define IE_TIE MIE_MTIE /* Timer interrupt enable */
/* External, timer and software interrupt */
# define RISCV_IRQ_EXT RISCV_IRQ_MEXT /* PLIC IRQ */
# define RISCV_IRQ_TIMER RISCV_IRQ_MTIMER /* Timer IRQ */
# define RISCV_IRQ_SOFT RISCV_IRQ_MSOFT /* SW IRQ */
/* Define return from exception */
# define ERET mret
#endif
#endif /* __ARCH_RISCV_INCLUDE_MODE_H */

View File

@ -31,6 +31,8 @@
#include <nuttx/config.h>
#include <arch/arch.h>
#ifndef __ASSEMBLY__
# include <stdint.h>
#endif
@ -122,50 +124,17 @@
#define SYS_signal_handler_return (7)
#endif /* !CONFIG_BUILD_FLAT */
/* sys_call macros **********************************************************/
#ifndef __ASSEMBLY__
/* Context switching system calls *******************************************/
/* SYS call 0:
*
* int riscv_saveusercontext(uintptr_t *saveregs);
*
* Return:
* 0: Normal Return
* 1: Context Switch Return
*/
#define riscv_saveusercontext(saveregs) \
(int)sys_call1(SYS_save_context, (uintptr_t)(saveregs))
/* SYS call 1:
*
* void riscv_fullcontextrestore(uintptr_t *restoreregs) noreturn_function;
*/
#define riscv_fullcontextrestore(restoreregs) \
sys_call1(SYS_restore_context, (uintptr_t)(restoreregs))
/* SYS call 2:
*
* void riscv_switchcontext(uintptr_t **saveregs, uintptr_t *restoreregs);
*/
#define riscv_switchcontext(saveregs, restoreregs) \
sys_call2(SYS_switch_context, (uintptr_t)(saveregs), (uintptr_t)(restoreregs))
#ifdef CONFIG_BUILD_KERNEL
/* SYS call 3:
*
* void riscv_syscall_return(void);
*/
#define riscv_syscall_return() sys_call0(SYS_syscall_return)
#if defined (CONFIG_ARCH_USE_S_MODE) && defined (__KERNEL__)
# define ASM_SYS_CALL \
" addi sp, sp, -16\n" /* Make room */ \
REGSTORE " ra, 0(sp)\n" /* Save ra */ \
" jal ra, riscv_syscall_dispatch\n" /* Dispatch (modifies ra) */ \
REGLOAD " ra, 0(sp)\n" /* Restore ra */ \
" addi sp, sp, 16\n" /* Restore sp */
#else
# define ASM_SYS_CALL \
"ecall"
#endif
#endif /* __ASSEMBLY__ */
/****************************************************************************
* Public Types
@ -207,7 +176,7 @@ static inline uintptr_t sys_call0(unsigned int nbr)
asm volatile
(
"ecall"
ASM_SYS_CALL
:: "r"(r0)
: "memory"
);
@ -232,7 +201,7 @@ static inline uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1)
asm volatile
(
"ecall"
ASM_SYS_CALL
:: "r"(r0), "r"(r1)
: "memory"
);
@ -259,7 +228,7 @@ static inline uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1,
asm volatile
(
"ecall"
ASM_SYS_CALL
:: "r"(r0), "r"(r1), "r"(r2)
: "memory"
);
@ -287,7 +256,7 @@ static inline uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1,
asm volatile
(
"ecall"
ASM_SYS_CALL
:: "r"(r0), "r"(r1), "r"(r2), "r"(r3)
: "memory"
);
@ -317,7 +286,7 @@ static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1,
asm volatile
(
"ecall"
ASM_SYS_CALL
:: "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4)
: "memory"
);
@ -348,7 +317,7 @@ static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1,
asm volatile
(
"ecall"
ASM_SYS_CALL
:: "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5)
: "memory"
);
@ -381,7 +350,7 @@ static inline uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1,
asm volatile
(
"ecall"
ASM_SYS_CALL
:: "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5), "r"(r6)
: "memory"
);

View File

@ -24,6 +24,12 @@ ifeq ($(CONFIG_OPENSBI),y)
include opensbi/Make.defs
endif
# Kernel runs in supervisor mode or machine mode ?
ifeq ($(CONFIG_ARCH_USE_S_MODE),y)
include common/supervisor/Make.defs
endif
ARCH_SRCDIR = $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src
INCLUDES += ${shell $(INCDIR) "$(CC)" $(ARCH_SRCDIR)$(DELIM)chip}

View File

@ -34,6 +34,7 @@ CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
CMN_CSRCS += riscv_sigdeliver.c riscv_udelay.c riscv_unblocktask.c riscv_usestack.c
CMN_CSRCS += riscv_idle.c riscv_tcbinfo.c riscv_getnewintctx.c riscv_doirq.c
CMN_CSRCS += riscv_cpuindex.c
ifeq ($(CONFIG_SCHED_BACKTRACE),y)
CMN_CSRCS += riscv_backtrace.c

View File

@ -34,7 +34,7 @@ CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
CMN_CSRCS += riscv_sigdeliver.c riscv_unblocktask.c riscv_usestack.c
CMN_CSRCS += riscv_mdelay.c riscv_idle.c riscv_doirq.c
CMN_CSRCS += riscv_tcbinfo.c riscv_getnewintctx.c
CMN_CSRCS += riscv_tcbinfo.c riscv_getnewintctx.c riscv_cpuindex.c
ifeq ($(CONFIG_SCHED_BACKTRACE),y)
CMN_CSRCS += riscv_backtrace.c

View File

@ -48,7 +48,16 @@
uintptr_t riscv_mhartid(void)
{
#ifdef CONFIG_ARCH_USE_S_MODE
/* Kernel is in S-mode */
#error "Missing functionality..."
#else
/* Kernel is in M-mode */
return READ_CSR(mhartid);
#endif
}
/****************************************************************************

View File

@ -26,6 +26,9 @@
#include <arch/arch.h>
#include <arch/irq.h>
#include <arch/mode.h>
#include "riscv_exception_macros.S"
/****************************************************************************
* Pre-processor Definitions
@ -50,16 +53,13 @@
* Public Symbols
****************************************************************************/
#ifdef CONFIG_IRQ_NSTACKS
# define IRQ_NSTACKS CONFIG_IRQ_NSTACKS
#elif defined CONFIG_SMP
# define IRQ_NSTACKS CONFIG_SMP_NCPUS
#else
# define IRQ_NSTACKS 1
#endif
/****************************************************************************
* Name: exception_common
*
* Description:
* Handles interrupts. If kernel is in S-mode, handles delegated interrupts
* in S-mode interrupt handler.
*
****************************************************************************/
.section .text
@ -69,48 +69,16 @@
exception_common:
addi sp, sp, -XCPTCONTEXT_SIZE
save_ctx sp
REGSTORE x1, REG_X1(sp) /* ra */
#ifdef RISCV_SAVE_GP
REGSTORE x3, REG_X3(sp) /* gp */
#endif
REGSTORE x4, REG_X4(sp) /* tp */
REGSTORE x5, REG_X5(sp) /* t0 */
REGSTORE x6, REG_X6(sp) /* t1 */
REGSTORE x7, REG_X7(sp) /* t2 */
REGSTORE x8, REG_X8(sp) /* s0 */
REGSTORE x9, REG_X9(sp) /* s1 */
REGSTORE x10, REG_X10(sp) /* a0 */
REGSTORE x11, REG_X11(sp) /* a1 */
REGSTORE x12, REG_X12(sp) /* a2 */
REGSTORE x13, REG_X13(sp) /* a3 */
REGSTORE x14, REG_X14(sp) /* a4 */
REGSTORE x15, REG_X15(sp) /* a5 */
REGSTORE x16, REG_X16(sp) /* a6 */
REGSTORE x17, REG_X17(sp) /* a7 */
REGSTORE x18, REG_X18(sp) /* s2 */
REGSTORE x19, REG_X19(sp) /* s3 */
REGSTORE x20, REG_X20(sp) /* s4 */
REGSTORE x21, REG_X21(sp) /* s5 */
REGSTORE x22, REG_X22(sp) /* s6 */
REGSTORE x23, REG_X23(sp) /* s7 */
REGSTORE x24, REG_X24(sp) /* s8 */
REGSTORE x25, REG_X25(sp) /* s9 */
REGSTORE x26, REG_X26(sp) /* s10 */
REGSTORE x27, REG_X27(sp) /* s11 */
REGSTORE x28, REG_X28(sp) /* t3 */
REGSTORE x29, REG_X29(sp) /* t4 */
REGSTORE x30, REG_X30(sp) /* t5 */
REGSTORE x31, REG_X31(sp) /* t6 */
csrr s0, mstatus
REGSTORE s0, REG_INT_CTX(sp) /* mstatus */
csrr s0, CSR_STATUS
REGSTORE s0, REG_INT_CTX(sp) /* status */
addi s0, sp, XCPTCONTEXT_SIZE
REGSTORE s0, REG_X2(sp) /* original SP */
REGSTORE s0, REG_X2(sp) /* original SP */
csrr s0, mepc
REGSTORE s0, REG_EPC(sp) /* exception PC */
csrr s0, CSR_EPC
REGSTORE s0, REG_EPC(sp) /* exception PC */
#ifdef CONFIG_ARCH_FPU
mv a0, sp
@ -119,24 +87,29 @@ exception_common:
/* Setup arg0(exception cause), arg1(context) */
csrr a0, mcause /* exception cause */
csrr a0, CSR_CAUSE /* exception cause */
mv a1, sp /* context = sp */
#if CONFIG_ARCH_INTERRUPTSTACK > 15
/* Load mhartid (cpuid) */
csrr s0, mhartid
/* Offset to hartid */
mv s0, a0 /* save cause */
jal x1, riscv_mhartid /* get hartid */
/* Switch to interrupt stack */
#if IRQ_NSTACKS > 1
li t0, (CONFIG_ARCH_INTERRUPTSTACK & ~15)
mul t0, s0, t0
la s0, g_intstacktop
sub sp, s0, t0
mul t0, a0, t0
la a0, g_intstacktop
sub sp, a0, t0
#else
la sp, g_intstacktop
#endif
mv a0, s0 /* restore cause */
/* Call interrupt handler in C */
jal x1, riscv_dispatch_irq
@ -159,62 +132,27 @@ exception_common:
jal x1, riscv_restorefpu /* restore FPU context */
#endif
/* If context switch is needed, return a new sp */
/* If context switch is needed, return a new sp */
mv sp, a0
REGLOAD s0, REG_EPC(sp) /* restore mepc */
csrw mepc, s0
REGLOAD s0, REG_INT_CTX(sp) /* restore mstatus */
csrw mstatus, s0
REGLOAD s0, REG_EPC(sp) /* restore sepc */
csrw CSR_EPC, s0
#ifdef RISCV_SAVE_GP
REGLOAD x3, REG_X3(sp) /* gp */
#endif
REGLOAD x4, REG_X4(sp) /* tp */
REGLOAD x5, REG_X5(sp) /* t0 */
REGLOAD x6, REG_X6(sp) /* t1 */
REGLOAD x7, REG_X7(sp) /* t2 */
REGLOAD x8, REG_X8(sp) /* s0 */
REGLOAD x9, REG_X9(sp) /* s1 */
REGLOAD x10, REG_X10(sp) /* a0 */
REGLOAD x11, REG_X11(sp) /* a1 */
REGLOAD x12, REG_X12(sp) /* a2 */
REGLOAD x13, REG_X13(sp) /* a3 */
REGLOAD x14, REG_X14(sp) /* a4 */
REGLOAD x15, REG_X15(sp) /* a5 */
REGLOAD x16, REG_X16(sp) /* a6 */
REGLOAD x17, REG_X17(sp) /* a7 */
REGLOAD x18, REG_X18(sp) /* s2 */
REGLOAD x19, REG_X19(sp) /* s3 */
REGLOAD x20, REG_X20(sp) /* s4 */
REGLOAD x21, REG_X21(sp) /* s5 */
REGLOAD x22, REG_X22(sp) /* s6 */
REGLOAD x23, REG_X23(sp) /* s7 */
REGLOAD x24, REG_X24(sp) /* s8 */
REGLOAD x25, REG_X25(sp) /* s9 */
REGLOAD x26, REG_X26(sp) /* s10 */
REGLOAD x27, REG_X27(sp) /* s11 */
REGLOAD x28, REG_X28(sp) /* t3 */
REGLOAD x29, REG_X29(sp) /* t4 */
REGLOAD x30, REG_X30(sp) /* t5 */
REGLOAD x31, REG_X31(sp) /* t6 */
REGLOAD s0, REG_INT_CTX(sp) /* restore sstatus */
csrw CSR_STATUS, s0
REGLOAD x1, REG_X1(sp) /* ra */
load_ctx sp
REGLOAD sp, REG_X2(sp) /* restore original sp */
REGLOAD sp, REG_SP(sp) /* restore original sp */
/* Return from Machine Interrupt */
/* Return from exception */
mret
ERET
/************************************************************************************
/*****************************************************************************
* Name: g_intstackalloc and g_intstacktop
************************************************************************************/
/************************************************************************************
* Name: g_intstackalloc and g_intstacktop
************************************************************************************/
****************************************************************************/
#if CONFIG_ARCH_INTERRUPTSTACK > 15
.bss

View File

@ -0,0 +1,130 @@
/****************************************************************************
* arch/risc-v/src/common/supervisor/riscv_exception_macros.S
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
.file "riscv_exception_macros.S"
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <arch/arch.h>
#include <arch/irq.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Name: save_ctx
*
* Parameter:
* in - Pointer to where the save is performed (e.g. sp)
*
* Description:
* Save the common context registers (i.e. work / temp / etc).
*
****************************************************************************/
.macro save_ctx in
REGSTORE x1, REG_X1(\in) /* ra */
#ifdef RISCV_SAVE_GP
REGSTORE x3, REG_X3(\in) /* gp */
#endif
REGSTORE x4, REG_X4(\in) /* tp */
REGSTORE x5, REG_X5(\in) /* t0 */
REGSTORE x6, REG_X6(\in) /* t1 */
REGSTORE x7, REG_X7(\in) /* t2 */
REGSTORE x8, REG_X8(\in) /* s0 */
REGSTORE x9, REG_X9(\in) /* s1 */
REGSTORE x10, REG_X10(\in) /* a0 */
REGSTORE x11, REG_X11(\in) /* a1 */
REGSTORE x12, REG_X12(\in) /* a2 */
REGSTORE x13, REG_X13(\in) /* a3 */
REGSTORE x14, REG_X14(\in) /* a4 */
REGSTORE x15, REG_X15(\in) /* a5 */
REGSTORE x16, REG_X16(\in) /* a6 */
REGSTORE x17, REG_X17(\in) /* a7 */
REGSTORE x18, REG_X18(\in) /* s2 */
REGSTORE x19, REG_X19(\in) /* s3 */
REGSTORE x20, REG_X20(\in) /* s4 */
REGSTORE x21, REG_X21(\in) /* s5 */
REGSTORE x22, REG_X22(\in) /* s6 */
REGSTORE x23, REG_X23(\in) /* s7 */
REGSTORE x24, REG_X24(\in) /* s8 */
REGSTORE x25, REG_X25(\in) /* s9 */
REGSTORE x26, REG_X26(\in) /* s10 */
REGSTORE x27, REG_X27(\in) /* s11 */
REGSTORE x28, REG_X28(\in) /* t3 */
REGSTORE x29, REG_X29(\in) /* t4 */
REGSTORE x30, REG_X30(\in) /* t5 */
REGSTORE x31, REG_X31(\in) /* t6 */
.endm
/****************************************************************************
* Name: load_ctx
*
* Parameter:
* out - Pointer to where the load is performed (e.g. sp)
*
* Description:
* Load the common context registers (i.e. work / temp / etc).
*
****************************************************************************/
.macro load_ctx out
REGLOAD x1, REG_X1(\out) /* ra */
#ifdef RISCV_SAVE_GP
REGLOAD x3, REG_X3(\out) /* gp */
#endif
REGLOAD x4, REG_X4(\out) /* tp */
REGLOAD x5, REG_X5(\out) /* t0 */
REGLOAD x6, REG_X6(\out) /* t1 */
REGLOAD x7, REG_X7(\out) /* t2 */
REGLOAD x8, REG_X8(\out) /* s0 */
REGLOAD x9, REG_X9(\out) /* s1 */
REGLOAD x10, REG_X10(\out) /* a0 */
REGLOAD x11, REG_X11(\out) /* a1 */
REGLOAD x12, REG_X12(\out) /* a2 */
REGLOAD x13, REG_X13(\out) /* a3 */
REGLOAD x14, REG_X14(\out) /* a4 */
REGLOAD x15, REG_X15(\out) /* a5 */
REGLOAD x16, REG_X16(\out) /* a6 */
REGLOAD x17, REG_X17(\out) /* a7 */
REGLOAD x18, REG_X18(\out) /* s2 */
REGLOAD x19, REG_X19(\out) /* s3 */
REGLOAD x20, REG_X20(\out) /* s4 */
REGLOAD x21, REG_X21(\out) /* s5 */
REGLOAD x22, REG_X22(\out) /* s6 */
REGLOAD x23, REG_X23(\out) /* s7 */
REGLOAD x24, REG_X24(\out) /* s8 */
REGLOAD x25, REG_X25(\out) /* s9 */
REGLOAD x26, REG_X26(\out) /* s10 */
REGLOAD x27, REG_X27(\out) /* s11 */
REGLOAD x28, REG_X28(\out) /* t3 */
REGLOAD x29, REG_X29(\out) /* t4 */
REGLOAD x30, REG_X30(\out) /* t5 */
REGLOAD x31, REG_X31(\out) /* t6 */
.endm

View File

@ -26,6 +26,7 @@
#include <arch/arch.h>
#include <arch/irq.h>
#include <arch/mode.h>
#ifdef CONFIG_ARCH_FPU
@ -74,7 +75,7 @@
riscv_fpuconfig:
li a0, FS_INITIAL
csrs mstatus, a0
csrs CSR_STATUS, a0
csrwi fcsr, 0
ret

View File

@ -32,6 +32,8 @@
#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include <arch/mode.h>
#include "riscv_internal.h"
/****************************************************************************
@ -48,23 +50,23 @@
uintptr_t riscv_get_newintctx(void)
{
/* Set machine previous privilege mode to machine mode. Reegardless of
/* Set machine previous privilege mode to privileged mode. Regardless of
* how NuttX is configured and of what kind of thread is being started.
* That is because all threads, even user-mode threads will start in
* kernel trampoline at nxtask_start() or pthread_start().
* The thread's privileges will be dropped before transitioning to
* user code. Also set machine previous interrupt enable.
* user code. Also set machine / supervisor previous interrupt enable.
*
* Mask the bits which should be preserved (from ISA spec)
*/
uintptr_t mstatus = READ_CSR(mstatus);
uintptr_t status = READ_CSR(CSR_STATUS);
mstatus &= MSTATUS_WPRI;
status &= MSTATUS_WPRI;
return (mstatus | MSTATUS_MPPM | MSTATUS_MPIE
return (status | STATUS_PPP | STATUS_SUM | STATUS_PIE
#ifdef CONFIG_ARCH_FPU
| MSTATUS_FS_INIT
| MSTATUS_FS_INIT
#endif
);
}

View File

@ -32,6 +32,7 @@
# include <nuttx/arch.h>
# include <sys/types.h>
# include <stdint.h>
# include <syscall.h>
#endif
/****************************************************************************
@ -315,6 +316,53 @@ int riscv_pause_handler(int irq, void *c, void *arg);
uintptr_t riscv_mhartid(void);
/* If kernel runs in Supervisor mode, a system call trampoline is needed */
#ifdef CONFIG_ARCH_USE_S_MODE
void riscv_syscall_dispatch(void) noreturn_function;
void *riscv_perform_syscall(uintptr_t *regs);
#endif
/* Context switching via system calls ***************************************/
/* SYS call 0:
*
* int riscv_saveusercontext(uintptr_t *saveregs);
*
* Return:
* 0: Normal Return
* 1: Context Switch Return
*/
#define riscv_saveusercontext(saveregs) \
sys_call1(SYS_save_context, (uintptr_t)saveregs)
/* SYS call 1:
*
* void riscv_fullcontextrestore(uintptr_t *restoreregs) noreturn_function;
*/
#define riscv_fullcontextrestore(restoreregs) \
sys_call1(SYS_restore_context, (uintptr_t)restoreregs)
/* SYS call 2:
*
* void riscv_switchcontext(uintptr_t *saveregs, uintptr_t *restoreregs);
*/
#define riscv_switchcontext(saveregs, restoreregs) \
sys_call2(SYS_switch_context, (uintptr_t)saveregs, (uintptr_t)restoreregs)
#ifdef CONFIG_BUILD_KERNEL
/* SYS call 3:
*
* void riscv_syscall_return(void);
*/
#define riscv_syscall_return() sys_call0(SYS_syscall_return)
#endif /* CONFIG_BUILD_KERNEL */
#undef EXTERN
#ifdef __cplusplus
}

View File

@ -146,12 +146,13 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
* privileged thread mode.
*/
tcb->xcp.sigdeliver = sigdeliver;
CURRENT_REGS[REG_EPC] = (uintptr_t)riscv_sigdeliver;
int_ctx = CURRENT_REGS[REG_INT_CTX];
int_ctx &= ~MSTATUS_MPIE;
tcb->xcp.sigdeliver = sigdeliver;
CURRENT_REGS[REG_EPC] = (uintptr_t)riscv_sigdeliver;
int_ctx = CURRENT_REGS[REG_INT_CTX];
int_ctx &= ~STATUS_PIE;
#ifndef CONFIG_BUILD_FLAT
int_ctx |= MSTATUS_MPPM;
int_ctx |= STATUS_PPP;
#endif
CURRENT_REGS[REG_INT_CTX] = int_ctx;
@ -201,7 +202,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
tcb->xcp.regs[REG_EPC] = (uintptr_t)riscv_sigdeliver;
int_ctx = tcb->xcp.regs[REG_INT_CTX];
int_ctx &= ~MSTATUS_MPIE;
int_ctx &= ~STATUS_PIE;
tcb->xcp.regs[REG_INT_CTX] = int_ctx;
@ -312,9 +313,9 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
tcb->xcp.regs[REG_EPC] = (uintptr_t)riscv_sigdeliver;
int_ctx = tcb->xcp.regs[REG_INT_CTX];
int_ctx &= ~MSTATUS_MPIE;
#ifdef CONFIG_BUILD_PROTECTED
int_ctx |= MSTATUS_MPPM;
int_ctx &= ~STATUS_PIE;
#ifndef CONFIG_BUILD_FLAT
int_ctx |= STATUS_PPP;
#endif
tcb->xcp.regs[REG_INT_CTX] = int_ctx;
}
@ -353,9 +354,9 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
CURRENT_REGS[REG_EPC] = (uintptr_t)riscv_sigdeliver;
int_ctx = CURRENT_REGS[REG_INT_CTX];
int_ctx &= ~MSTATUS_MPIE;
int_ctx &= ~STATUS_PIE;
#ifndef CONFIG_BUILD_FLAT
int_ctx |= MSTATUS_MPPM;
int_ctx |= STATUS_PPP;
#endif
CURRENT_REGS[REG_INT_CTX] = int_ctx;
@ -429,7 +430,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
tcb->xcp.regs[REG_EPC] = (uintptr_t)riscv_sigdeliver;
int_ctx = tcb->xcp.regs[REG_INT_CTX];
int_ctx &= ~MSTATUS_MPIE;
int_ctx &= ~STATUS_PIE;
tcb->xcp.regs[REG_INT_CTX] = int_ctx;
}

View File

@ -122,13 +122,17 @@ static void dispatch_syscall(void)
"slli a0, a0, 3\n" /* a0=Offset for the stub lookup table */
#endif
"add t0, t0, a0\n" /* t0=The address in the table */
REGLOAD " t0, 0(t0)\n" /* t0=The address of the stub for this syscall */
REGLOAD " t0, 0(t0)\n" /* t0=The address of the stub for this syscall */
"jalr ra, t0\n" /* Call the stub (modifies ra) */
REGLOAD " ra, 0(sp)\n" /* Restore ra */
"addi sp, sp, " STACK_FRAME_SIZE "\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 */
#ifdef CONFIG_ARCH_USE_S_MODE
" j riscv_syscall_dispatch" /* Return from the syscall */
#else
" ecall" /* Return from the syscall */
#endif
);
}
#endif
@ -332,7 +336,7 @@ int riscv_swint(int irq, void *context, void *arg)
regs[REG_A0] = regs[REG_A2]; /* argc */
regs[REG_A1] = regs[REG_A3]; /* argv */
#endif
regs[REG_INT_CTX] &= ~MSTATUS_MPPM; /* User mode */
regs[REG_INT_CTX] &= ~STATUS_PPP; /* User mode */
}
break;
#endif
@ -364,7 +368,7 @@ int riscv_swint(int irq, void *context, void *arg)
regs[REG_A0] = regs[REG_A2]; /* pthread entry */
regs[REG_A1] = regs[REG_A3]; /* arg */
regs[REG_INT_CTX] &= ~MSTATUS_MPPM; /* User mode */
regs[REG_INT_CTX] &= ~STATUS_PPP; /* User mode */
}
break;
#endif
@ -403,7 +407,7 @@ int riscv_swint(int irq, void *context, void *arg)
regs[REG_EPC] =
(uintptr_t)ARCH_DATA_RESERVE->ar_sigtramp & ~1;
#endif
regs[REG_INT_CTX] &= ~MSTATUS_MPPM; /* User mode */
regs[REG_INT_CTX] &= ~STATUS_PPP; /* User mode */
/* Change the parameter ordering to match the expectation of struct
* userpace_s signal_handler.
@ -453,7 +457,7 @@ int riscv_swint(int irq, void *context, void *arg)
DEBUGASSERT(rtcb->xcp.sigreturn != 0);
regs[REG_EPC] = rtcb->xcp.sigreturn & ~1;
regs[REG_INT_CTX] |= MSTATUS_MPPM; /* Machine mode */
regs[REG_INT_CTX] |= STATUS_PPP; /* Privileged mode */
rtcb->xcp.sigreturn = 0;
@ -501,7 +505,7 @@ int riscv_swint(int irq, void *context, void *arg)
rtcb->xcp.syscall[index].sysreturn = regs[REG_EPC];
#ifndef CONFIG_BUILD_FLAT
rtcb->xcp.syscall[index].int_ctx = regs[REG_INT_CTX];
rtcb->xcp.syscall[index].int_ctx = regs[REG_INT_CTX];
#endif
rtcb->xcp.nsyscalls = index + 1;
@ -509,7 +513,7 @@ int riscv_swint(int irq, void *context, void *arg)
regs[REG_EPC] = (uintptr_t)dispatch_syscall & ~1;
#ifndef CONFIG_BUILD_FLAT
regs[REG_INT_CTX] |= MSTATUS_MPPM; /* Machine mode */
regs[REG_INT_CTX] |= STATUS_PPP; /* Privileged mode */
#endif
/* Offset A0 to account for the reserved values */

View File

@ -23,11 +23,16 @@
****************************************************************************/
.section .text
.balign 4
.balign 8
.global __trap_vec
/****************************************************************************
* Name: exception_common
* Name: __trap_vec
*
* Description:
* All M-mode exceptions and interrupts will be handled from here. If
* kernel is in S-mode delegated exceptions and interrupts are handled.
*
****************************************************************************/
__trap_vec:

View File

@ -0,0 +1,28 @@
############################################################################
# arch/risc-v/src/common/supervisor/Make.defs
#
# 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.
#
############################################################################
# If the NuttX kernel runs in S-mode
CMN_ASRCS += riscv_syscall_dispatch.S
CMN_CSRCS += riscv_sbi.c riscv_perform_syscall.c
CMN_CSRCS += riscv_percpu.c
INCLUDES += ${shell $(INCDIR) "$(CC)" $(ARCH_SRCDIR)$(DELIM)common$(DELIM)supervisor}
VPATH += common$(DELIM)supervisor

View File

@ -0,0 +1,65 @@
/****************************************************************************
* arch/risc-v/src/common/supervisor/riscv_perform_syscall.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 "riscv_internal.h"
#include "group/group.h"
/****************************************************************************
* Public Functions
****************************************************************************/
void *riscv_perform_syscall(uintptr_t *regs)
{
/* Set up the interrupt register set needed by swint() */
CURRENT_REGS = regs;
/* Run the system call handler (swint) */
riscv_swint(0, regs, NULL);
#ifdef CONFIG_ARCH_ADDRENV
if (regs != CURRENT_REGS)
{
/* Make sure that the address environment for the previously
* running task is closed down gracefully (data caches dump,
* MMU flushed) and set up the address environment for the new
* thread at the head of the ready-to-run list.
*/
group_addrenv(NULL);
}
#endif
/* Set new context */
regs = (uintptr_t *)CURRENT_REGS;
CURRENT_REGS = NULL;
return regs;
}

View File

@ -0,0 +1,148 @@
/****************************************************************************
* arch/risc-v/src/common/supervisor/riscv_syscall_dispatch.S
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
.file "riscv_syscall_dispatch.S"
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <arch/mode.h>
#include "riscv_exception_macros.S"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Symbols
****************************************************************************/
.globl riscv_syscall_dispatch
/****************************************************************************
* Name: riscv_syscall_dispatch
*
* Description:
* Dispatch syscall from kernel
*
* C Function Prototype:
* void riscv_syscall_dispatch(void);
*
* Input Parameters:
* Assumes the context to return is already set up
*
* Returned Value:
* Return value of system call is returned into contex
*
* Assumptions:
* Task is running in privileged mode
*
****************************************************************************/
.type riscv_syscall_dispatch, function
riscv_syscall_dispatch:
addi sp, sp, -XCPTCONTEXT_SIZE /* make room */
save_ctx sp /* save current context */
/* Mask interrupts and store the status register to context */
li s1, STATUS_IE /* move IE -> PIE */
csrrc s0, CSR_STATUS, s1
and s1, s0, s1 /* if (STATUS & IE) */
beqz s1, 1f
li s1, ~STATUS_IE /* clear IE */
and s0, s0, s1
li s1, STATUS_PIE /* set PIE */
or s0, s0, s1
1:
/* Set previous privilege, we are in privileged mode now */
li s1, STATUS_PPP /* set previous privilege */
or s0, s0, s1
REGSTORE s0, REG_INT_CTX(sp) /* store status to context */
REGSTORE x1, REG_EPC(sp) /* save ra to epc */
addi s0, sp, XCPTCONTEXT_SIZE
REGSTORE s0, REG_SP(sp) /* original SP */
#ifdef CONFIG_ARCH_FPU
mv a0, sp
jal x1, riscv_savefpu /* FP registers */
#endif
mv a0, sp /* a0 = context */
/* Switch to interrupt stack */
#if CONFIG_ARCH_INTERRUPTSTACK > 15
#if IRQ_NSTACKS > 1
jal x1, riscv_mhartid /* get hartid */
li t0, (CONFIG_ARCH_INTERRUPTSTACK & ~15)
mul t0, a0, t0
la a0, g_intstacktop
sub sp, a0, t0
#else
la sp, g_intstacktop
#endif
#endif
/* Run the handler */
jal x1, riscv_perform_syscall
/* Restore (potentially new) context */
mv sp, a0 /* use sp, as a0 gets wiped */
#ifdef CONFIG_ARCH_FPU
jal x1, riscv_restorefpu /* FP registers */
#endif
REGLOAD s0, REG_EPC(sp) /* restore epc */
csrw CSR_EPC, s0
/* Restore status register, but don't enable interrupts yet */
REGLOAD s0, REG_INT_CTX(sp) /* restore status */
li s1, STATUS_IE /* move IE -> PIE */
and s1, s0, s1 /* if (STATUS & IE) */
beqz s1, 1f
li s1, ~STATUS_IE /* clear IE */
and s0, s0, s1
li s1, STATUS_PIE /* set PIE */
or s0, s0, s1
1:
csrw CSR_STATUS, s0
load_ctx sp
REGLOAD sp, REG_SP(sp) /* restore original sp */
/* return from exception, which updates the status register */
ERET

View File

@ -37,6 +37,7 @@ CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
CMN_CSRCS += riscv_sigdeliver.c riscv_udelay.c riscv_unblocktask.c riscv_usestack.c
CMN_CSRCS += riscv_tcbinfo.c riscv_getnewintctx.c riscv_doirq.c
CMN_CSRCS += riscv_cpuindex.c
ifeq ($(CONFIG_SCHED_BACKTRACE),y)
CMN_CSRCS += riscv_backtrace.c

View File

@ -34,6 +34,7 @@ CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
CMN_CSRCS += riscv_sigdeliver.c riscv_udelay.c riscv_unblocktask.c riscv_usestack.c
CMN_CSRCS += riscv_idle.c riscv_tcbinfo.c riscv_getnewintctx.c riscv_doirq.c
CMN_CSRCS += riscv_cpuindex.c
ifeq ($(CONFIG_SCHED_BACKTRACE),y)
CMN_CSRCS += riscv_backtrace.c

View File

@ -35,6 +35,7 @@ CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
CMN_CSRCS += riscv_sigdeliver.c riscv_unblocktask.c riscv_usestack.c
CMN_CSRCS += riscv_mdelay.c riscv_idle.c riscv_doirq.c
CMN_CSRCS += riscv_tcbinfo.c riscv_cpuidlestack.c riscv_getnewintctx.c
CMN_CSRCS += riscv_cpuindex.c
ifeq ($(CONFIG_SMP), y)
CMN_CSRCS += riscv_cpuindex.c riscv_cpupause.c riscv_cpustart.c

View File

@ -34,6 +34,7 @@ CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
CMN_CSRCS += riscv_sigdeliver.c riscv_udelay.c riscv_unblocktask.c riscv_usestack.c
CMN_CSRCS += riscv_idle.c riscv_tcbinfo.c riscv_getnewintctx.c
CMN_CSRCS += riscv_cpuindex.c
ifeq ($(CONFIG_SCHED_BACKTRACE),y)
CMN_CSRCS += riscv_backtrace.c

View File

@ -58,7 +58,7 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
if (vector < RISCV_IRQ_ECALLU ||
vector == RISCV_IRQ_INSTRUCTIONPF ||
vector == RISCV_IRQ_LOADPF ||
vector == RISCV_IRQ_SROREPF ||
vector == RISCV_IRQ_STOREPF ||
vector == RISCV_IRQ_RESERVED)
{
riscv_fault(irq, regs);

View File

@ -35,6 +35,7 @@ CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
CMN_CSRCS += riscv_sigdeliver.c riscv_unblocktask.c riscv_usestack.c
CMN_CSRCS += riscv_idle.c riscv_tcbinfo.c riscv_cpuidlestack.c
CMN_CSRCS += riscv_fault.c riscv_getnewintctx.c riscv_doirq.c
CMN_CSRCS += riscv_cpuindex.c
ifeq ($(CONFIG_SMP), y)
CMN_CSRCS += riscv_cpuindex.c riscv_cpupause.c riscv_cpustart.c

View File

@ -34,6 +34,7 @@ CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
CMN_CSRCS += riscv_sigdeliver.c riscv_unblocktask.c riscv_usestack.c
CMN_CSRCS += riscv_idle.c riscv_tcbinfo.c riscv_getnewintctx.c
CMN_CSRCS += riscv_cpuindex.c
ifeq ($(CONFIG_SCHED_BACKTRACE),y)
CMN_CSRCS += riscv_backtrace.c

View File

@ -31,6 +31,8 @@
#include <nuttx/irq.h>
#include "riscv_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/

View File

@ -31,6 +31,8 @@
#include <nuttx/irq.h>
#include "riscv_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/

View File

@ -31,6 +31,8 @@
#include <nuttx/irq.h>
#include "riscv_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/

View File

@ -31,6 +31,8 @@
#include <nuttx/irq.h>
#include "riscv_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/