arch: risc-v: Add support for PROTECTED build to rv64gc

This commit is contained in:
Masayuki Ishikawa
2020-02-14 16:04:19 +09:00
committed by patacongo
parent ddc8f52202
commit 1a4ff4c4cd
8 changed files with 651 additions and 164 deletions
+6 -3
View File
@@ -285,10 +285,13 @@
/* This structure represents the return state from a system call */
#ifdef CONFIG_BUILD_KERNEL
#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
@@ -316,7 +319,7 @@ struct xcptcontext
uint64_t saved_epc; /* Trampoline PC */
uint64_t saved_int_ctx; /* Interrupt context with interrupts disabled. */
#ifdef CONFIG_BUILD_KERNEL
#ifdef CONFIG_BUILD_PROTECTED
/* This is the saved address to use when returning from a user-space
* signal handler.
*/
@@ -324,7 +327,7 @@ struct xcptcontext
uint32_t sigreturn;
#endif
#ifdef CONFIG_BUILD_KERNEL
#ifdef CONFIG_LIB_SYSCALL
/* The following array holds information needed to return from each nested
* system call.
*/
+149 -11
View File
@@ -56,11 +56,21 @@
#define SYS_syscall 0x00
/* The SYS_signal_handler_return is executed here... its value is not always
* available in this context and so is assumed to be 7.
*/
#ifndef SYS_signal_handler_return
# define SYS_signal_handler_return (7)
#elif SYS_signal_handler_return != 7
# error "SYS_signal_handler_return was assumed to be 7"
#endif
/* Configuration ************************************************************/
/* SYS call 1 and 2 are defined for internal use by the RISC-V port (see
* arch/risc-v/include/rv64gc/syscall.h). In addition, SYS call 3 is the
* return from a SYS call in kernel mode. The first four syscall values must,
* arch/risc-v/include/rv64gc/syscall.h). In addition, SYS call 3 is the
* return from a SYS call in kernel mode. The first four syscall values must,
* therefore, be reserved (0 is not used).
*/
@@ -144,7 +154,20 @@ extern "C"
*
****************************************************************************/
uintptr_t sys_call0(unsigned int nbr);
static inline uintptr_t sys_call0(unsigned int nbr)
{
register long r0 asm("a0") = (long)(nbr);
asm volatile
(
"ecall"
:: "r"(r0)
);
asm volatile("nop" : "=r"(r0));
return r0;
}
/****************************************************************************
* Name: up_syscall1
@@ -154,7 +177,21 @@ uintptr_t sys_call0(unsigned int nbr);
*
****************************************************************************/
uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1);
static inline uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1)
{
register long r0 asm("a0") = (long)(nbr);
register long r1 asm("a1") = (long)(parm1);
asm volatile
(
"ecall"
:: "r"(r0), "r"(r1)
);
asm volatile("nop" : "=r"(r0));
return r0;
}
/****************************************************************************
* Name: up_syscall2
@@ -164,7 +201,23 @@ uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1);
*
****************************************************************************/
uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1, uintptr_t parm2);
static inline uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1,
uintptr_t parm2)
{
register long r0 asm("a0") = (long)(nbr);
register long r1 asm("a1") = (long)(parm1);
register long r2 asm("a2") = (long)(parm2);
asm volatile
(
"ecall"
:: "r"(r0), "r"(r1), "r"(r2)
);
asm volatile("nop" : "=r"(r0));
return r0;
}
/****************************************************************************
* Name: up_syscall3
@@ -174,8 +227,24 @@ uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1, uintptr_t parm2);
*
****************************************************************************/
uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1, uintptr_t parm2,
uintptr_t parm3);
static inline uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1,
uintptr_t parm2, uintptr_t parm3)
{
register long r0 asm("a0") = (long)(nbr);
register long r1 asm("a1") = (long)(parm1);
register long r2 asm("a2") = (long)(parm2);
register long r3 asm("a3") = (long)(parm3);
asm volatile
(
"ecall"
:: "r"(r0), "r"(r1), "r"(r2), "r"(r3)
);
asm volatile("nop" : "=r"(r0));
return r0;
}
/****************************************************************************
* Name: up_syscall4
@@ -185,8 +254,26 @@ uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1, uintptr_t parm2,
*
****************************************************************************/
uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1, uintptr_t parm2,
uintptr_t parm3, uintptr_t parm4);
static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1,
uintptr_t parm2, uintptr_t parm3,
uintptr_t parm4)
{
register long r0 asm("a0") = (long)(nbr);
register long r1 asm("a1") = (long)(parm1);
register long r2 asm("a2") = (long)(parm2);
register long r3 asm("a3") = (long)(parm3);
register long r4 asm("a4") = (long)(parm4);
asm volatile
(
"ecall"
:: "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4)
);
asm volatile("nop" : "=r"(r0));
return r0;
}
/****************************************************************************
* Name: up_syscall5
@@ -196,8 +283,59 @@ uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1, uintptr_t parm2,
*
****************************************************************************/
uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1, uintptr_t parm2,
uintptr_t parm3, uintptr_t parm4, uintptr_t parm5);
static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1,
uintptr_t parm2, uintptr_t parm3,
uintptr_t parm4, uintptr_t parm5)
{
register long r0 asm("a0") = (long)(nbr);
register long r1 asm("a1") = (long)(parm1);
register long r2 asm("a2") = (long)(parm2);
register long r3 asm("a3") = (long)(parm3);
register long r4 asm("a4") = (long)(parm4);
register long r5 asm("a5") = (long)(parm5);
asm volatile
(
"ecall"
:: "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5)
);
asm volatile("nop" : "=r"(r0));
return r0;
}
/****************************************************************************
* Name: up_syscall6
*
* Description:
* System call SYS_ argument and six additional parameters.
*
****************************************************************************/
static inline uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1,
uintptr_t parm2, uintptr_t parm3,
uintptr_t parm4, uintptr_t parm5,
uintptr_t parm6)
{
register long r0 asm("a0") = (long)(nbr);
register long r1 asm("a1") = (long)(parm1);
register long r2 asm("a2") = (long)(parm2);
register long r3 asm("a3") = (long)(parm3);
register long r4 asm("a4") = (long)(parm4);
register long r5 asm("a5") = (long)(parm5);
register long r6 asm("a6") = (long)(parm6);
asm volatile
(
"ecall"
:: "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5), "r"(r6)
);
asm volatile("nop" : "=r"(r0));
return r0;
}
#undef EXTERN
#ifdef __cplusplus
+128
View File
@@ -0,0 +1,128 @@
/****************************************************************************
* arch/risc-v/src/rv64gc/svcall.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_SRC_RV64GC_SVCALL_H
#define __ARCH_RISCV_SRC_RV64GC_SVCALL_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#ifdef CONFIG_LIB_SYSCALL
# include <syscall.h>
#endif
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
/* This logic uses three system calls {0,1,2} for context switching and one
* for the syscall return. So a minimum of four syscall values must be
* reserved. If CONFIG_BUILD_PROTECTED is defined, then four more syscall
* values must be reserved.
*/
#ifdef CONFIG_LIB_SYSCALL
# ifdef CONFIG_BUILD_PROTECTED
# ifndef CONFIG_SYS_RESERVED
# error "CONFIG_SYS_RESERVED must be defined to have the value 8"
# elif CONFIG_SYS_RESERVED != 8
# error "CONFIG_SYS_RESERVED must have the value 8"
# endif
# else
# ifndef CONFIG_SYS_RESERVED
# error "CONFIG_SYS_RESERVED must be defined to have the value 4"
# elif CONFIG_SYS_RESERVED != 4
# error "CONFIG_SYS_RESERVED must have the value 4"
# endif
# endif
#endif
/* RV64GC system calls ******************************************************/
/* SYS call 0:
*
* int up_saveusercontext(uint32_t *saveregs);
*/
#define SYS_save_context (0)
/* SYS call 1:
*
* void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function;
*/
#define SYS_restore_context (1)
/* SYS call 2:
*
* void up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs);
*/
#define SYS_switch_context (2)
#ifdef CONFIG_LIB_SYSCALL
/* SYS call 3:
*
* void up_syscall_return(void);
*/
#define SYS_syscall_return (3)
#ifdef CONFIG_BUILD_PROTECTED
/* SYS call 4:
*
* void up_task_start(main_t taskentry, int argc, FAR char *argv[])
* noreturn_function;
*/
#define SYS_task_start (4)
/* SYS call 5:
*
* void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg)
* noreturn_function
*/
#define SYS_pthread_start (5)
/* SYS call 6:
*
* void signal_handler(_sa_sigaction_t sighand, int signo,
* FAR siginfo_t *info, FAR void *ucontext);
*/
#define SYS_signal_handler (6)
/* SYS call 7:
*
* void signal_handler_return(void);
*/
#define SYS_signal_handler_return (7)
#endif /* CONFIG_BUILD_PROTECTED */
#endif /* CONFIG_LIB_SYSCALL */
#endif /* __ARCH_RISCV_SRC_RV64GC_SVCALL_H */
-19
View File
@@ -88,25 +88,6 @@ void up_initial_state(struct tcb_s *tcb)
xcp->regs[REG_EPC] = (uintptr_t)tcb->start;
/* If this task is running PIC, then set the PIC base register to the
* address of the allocated D-Space region.
*/
#ifdef CONFIG_PIC
# warning "Missing logic"
#endif
/* Set privileged- or unprivileged-mode, depending on how NuttX is
* configured and what kind of thread is being started.
*
* If the kernel build is not selected, then all threads run in
* privileged thread mode.
*/
#ifdef CONFIG_BUILD_KERNEL
# warning "Missing logic"
#endif
/* Set the initial value of the interrupt context register.
*
* Since various RISC-V platforms use different interrupt
@@ -0,0 +1,76 @@
/****************************************************************************
* arch/risc-v/src/rv64gc/up_signal_dispatch.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 <nuttx/arch.h>
#include "svcall.h"
#include "up_internal.h"
#if (defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)) || \
defined(CONFIG_BUILD_KERNEL)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_signal_dispatch
*
* Description:
* In the kernel mode build, this function will be called to execute a
* a signal handler in user-space. When the signal is delivered, a
* kernel-mode stub will first run to perform some housekeeping functions.
* This kernel-mode stub will then be called transfer control to the user
* mode signal handler by calling this function.
*
* Normally the a user-mode signaling handling stub will also execute
* before the ultimate signal handler is called. See
* arch/arm/src/armv[6\7]/up_signal_handler. This function is the
* user-space, signal handler trampoline function. It is called from
* up_signal_dispatch() in user-mode.
*
* Input Parameters:
* sighand - The address user-space signal handling function
* signo, info, and ucontext - Standard arguments to be passed to the
* signal handling function.
*
* Returned Value:
* None. This function does not return in the normal sense. It returns
* via an architecture specific system call made by up_signal_handler().
* However, this will look like a normal return by the caller of
* up_signal_dispatch.
*
****************************************************************************/
void up_signal_dispatch(_sa_sigaction_t sighand, int signo,
FAR siginfo_t *info, FAR void *ucontext)
{
/* Let sys_call4() do all of the work */
sys_call4(SYS_signal_handler, (uintptr_t)sighand, (uintptr_t)signo,
(uintptr_t)info, (uintptr_t)ucontext);
}
#endif /* (CONFIG_BUILD_PROTECTED || CONFIG_BUILD_KERNEL) && !CONFIG_DISABLE_PTHREAD */
@@ -0,0 +1,97 @@
/****************************************************************************
* arch/risc-v/src/rv64gc/up_signal_handler.S
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <arch/syscall.h>
#if defined(CONFIG_BUILD_PROTECTED) && !defined(__KERNEL__)
/****************************************************************************
* File info
****************************************************************************/
.file "up_signal_handler.S"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_signal_handler
*
* Description:
* This function is the user-space, signal handler trampoline function. It
* is called from up_signal_dispatch() in user-mode.
*
* Input Parameters:
* a0 = sighand
* The address user-space signal handling function
* a1-a3 = signo, info, and ucontext
* Standard arguments to be passed to the signal handling function.
*
* Returned Value:
* None. This function does not return in the normal sense. It returns
* via the SYS_signal_handler_return (see svcall.h)
*
****************************************************************************/
.text
.globl up_signal_handler
.type up_signal_handler, function
up_signal_handler:
/* Save ra on the stack */
addi sp, sp, -8
sd ra, (sp)
/* Call the signal handler */
mv t0, a0 /* t0=sighand */
mv a0, a1 /* a0=signo */
mv a1, a2 /* a1=info */
mv a2, a3 /* a2=ucontext */
jalr t0 /* Call the signal handler (modifies ra) */
/* Restore the register */
ld ra, (sp) /* Restore ra in sp */
addi sp, sp, 8
/* Execute the SYS_signal_handler_return SVCall (will not return) */
li a0, SYS_signal_handler_return
ecall
nop
.size up_signal_handler, .-up_signal_handler
.end
#endif /* CONFIG_BUILD_PROTECTED && !__KERNEL__ */
+195 -20
View File
@@ -41,15 +41,19 @@
#include <stdint.h>
#include <string.h>
#include <syscall.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/sched.h>
#include <arch/irq.h>
#include <nuttx/sched.h>
#include <nuttx/userspace.h>
#ifdef CONFIG_LIB_SYSCALL
# include <syscall.h>
#endif
#include "signal/signal.h"
#include "svcall.h"
#include "up_internal.h"
/****************************************************************************
@@ -93,15 +97,38 @@ static void up_registerdump(const uint64_t *regs)
* Name: dispatch_syscall
*
* Description:
* Call the stub function corresponding to the system call.
* Call the stub function corresponding to the system call. NOTE the non-
* standard parameter passing:
*
* A0 = SYS_ call number
* A1 = parm0
* A2 = parm1
* A3 = parm2
* A4 = parm3
* A5 = parm4
* A6 = parm5
*
****************************************************************************/
#ifdef CONFIG_BUILD_KERNEL
#ifdef CONFIG_LIB_SYSCALL
static void dispatch_syscall(void) naked_function;
static void dispatch_syscall(void)
{
# error "Missing logic"
asm volatile
(
" addi sp, sp, -8\n" /* Create a stack frame to hold ra */
" sd 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 */
" ld t0, 0(t0)\n" /* t0=The address of the stub for this syscall */
" jalr ra, t0\n" /* Call the stub (modifies ra) */
" ld ra, 0(sp)\n" /* Restore ra */
" addi sp, sp, 8\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
@@ -184,7 +211,7 @@ int up_swint(int irq, FAR void *context, FAR void *arg)
}
break;
/* A0=SYS_syscall_return: This a switch context command:
/* A0=SYS_syscall_return: This is a SYSCALL return command:
*
* void up_sycall_return(void);
*
@@ -196,7 +223,7 @@ int up_swint(int irq, FAR void *context, FAR void *arg)
* unprivileged thread mode.
*/
#ifdef CONFIG_BUILD_KERNEL
#ifdef CONFIG_LIB_SYSCALL
case SYS_syscall_return:
{
struct tcb_s *rtcb = sched_self();
@@ -210,20 +237,162 @@ int up_swint(int irq, FAR void *context, FAR void *arg)
* the original mode.
*/
CURRENT_REGS[REG_EPC] = rtcb->xcp.syscall[index].sysreturn;
#error "Missing logic -- need to restore the original mode"
rtcb->xcp.nsyscalls = index;
regs[REG_EPC] = rtcb->xcp.syscall[index].sysreturn;
#ifdef CONFIG_BUILD_PROTECTED
regs[REG_INT_CTX] = rtcb->xcp.syscall[index].int_ctx;
#endif
/* The return value must be in A0-A1.
* dispatch_syscall() temporarily moved the value for R0 into A2.
*/
regs[REG_A0] = regs[REG_A2];
/* Save the new SYSCALL nesting level */
rtcb->xcp.nsyscalls = index;
/* Handle any signal actions that were deferred while processing
* the system call.
*/
rtcb->flags &= ~TCB_FLAG_SYSCALL;
rtcb->flags &= ~TCB_FLAG_SYSCALL;
(void)nxsig_unmask_pendingsignal();
}
break;
#endif
/* R0=SYS_task_start: This a user task start
*
* void up_task_start(main_t taskentry, int argc,
* FAR char *argv[]) noreturn_function;
*
* At this point, the following values are saved in context:
*
* A0 = SYS_task_start
* A1 = taskentry
* A2 = argc
* A3 = argv
*/
#ifdef CONFIG_BUILD_PROTECTED
case SYS_task_start:
{
/* Set up to return to the user-space task start-up function in
* unprivileged mode.
*/
regs[REG_EPC] = (uintptr_t)USERSPACE->task_startup & ~1;
regs[REG_A0] = regs[REG_A1]; /* Task entry */
regs[REG_A1] = regs[REG_A2]; /* argc */
regs[REG_A2] = regs[REG_A3]; /* argv */
regs[REG_INT_CTX] &= ~MSTATUS_MPPM; /* User mode */
}
break;
#endif
/* R0=SYS_pthread_start: This a user pthread start
*
* void up_pthread_start(pthread_startroutine_t entrypt,
* pthread_addr_t arg) noreturn_function;
*
* At this point, the following values are saved in context:
*
* R0 = SYS_pthread_start
* R1 = entrypt
* R2 = arg
*/
#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_PTHREAD)
case SYS_pthread_start:
{
/* Set up to return to the user-space pthread start-up function in
* unprivileged mode.
*/
regs[REG_EPC] = (uintptr_t)USERSPACE->pthread_startup & ~1;
/* Change the parameter ordering to match the expectation of struct
* userpace_s pthread_startup:
*/
regs[REG_A0] = regs[REG_A1]; /* pthread entry */
regs[REG_A1] = regs[REG_A2]; /* arg */
regs[REG_INT_CTX] &= ~MSTATUS_MPPM; /* User mode */
}
break;
#endif
/* R0=SYS_signal_handler: This a user signal handler callback
*
* void signal_handler(_sa_sigaction_t sighand, int signo,
* FAR siginfo_t *info, FAR void *ucontext);
*
* At this point, the following values are saved in context:
*
* R0 = SYS_signal_handler
* R1 = sighand
* R2 = signo
* R3 = info
* R4 = ucontext
*/
#ifdef CONFIG_BUILD_PROTECTED
case SYS_signal_handler:
{
struct tcb_s *rtcb = sched_self();
/* Remember the caller's return address */
DEBUGASSERT(rtcb->xcp.sigreturn == 0);
rtcb->xcp.sigreturn = regs[REG_EPC];
/* Set up to return to the user-space pthread start-up function in
* unprivileged mode.
*/
regs[REG_EPC] = (uintptr_t)USERSPACE->signal_handler & ~1;
regs[REG_INT_CTX] &= ~MSTATUS_MPPM; /* User mode */
/* Change the parameter ordering to match the expectation of struct
* userpace_s signal_handler.
*/
regs[REG_A0] = regs[REG_A1]; /* sighand */
regs[REG_A1] = regs[REG_A2]; /* signal */
regs[REG_A2] = regs[REG_A3]; /* info */
regs[REG_A3] = regs[REG_A4]; /* ucontext */
}
break;
#endif
/* R0=SYS_signal_handler_return: This a user signal handler callback
*
* void signal_handler_return(void);
*
* At this point, the following values are saved in context:
*
* R0 = SYS_signal_handler_return
*/
#ifdef CONFIG_BUILD_PROTECTED
case SYS_signal_handler_return:
{
struct tcb_s *rtcb = sched_self();
/* Set up to return to the kernel-mode signal dispatching logic. */
DEBUGASSERT(rtcb->xcp.sigreturn != 0);
regs[REG_EPC] = rtcb->xcp.sigreturn & ~1;
regs[REG_INT_CTX] |= MSTATUS_MPPM; /* Machine mode */
rtcb->xcp.sigreturn = 0;
}
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.
@@ -231,7 +400,7 @@ int up_swint(int irq, FAR void *context, FAR void *arg)
default:
{
#ifdef CONFIG_BUILD_KERNEL
#ifdef CONFIG_LIB_SYSCALL
FAR struct tcb_s *rtcb = sched_self();
int index = rtcb->xcp.nsyscalls;
@@ -247,20 +416,26 @@ int up_swint(int irq, FAR void *context, FAR void *arg)
/* 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.syscall[index].sysreturn = regs[REG_EPC];
#ifdef CONFIG_BUILD_PROTECTED
rtcb->xcp.syscall[index].int_ctx = regs[REG_INT_CTX];
#endif
rtcb->xcp.nsyscalls = index + 1;
regs[REG_EPC] = (uint32_t)dispatch_syscall;
#error "Missing logic -- Need to set privileged mode"
regs[REG_EPC] = (uintptr_t)dispatch_syscall & ~1;
/* Offset R0 to account for the reserved values */
#ifdef CONFIG_BUILD_PROTECTED
regs[REG_INT_CTX] |= MSTATUS_MPPM; /* Machine mode */
#endif
CURRENT_REGS[REG_A0] -= CONFIG_SYS_RESERVED;
/* Offset A0 to account for the reserved values */
regs[REG_A0] -= CONFIG_SYS_RESERVED;
/* Indicate that we are in a syscall handler. */
rtcb->flags |= TCB_FLAG_SYSCALL;
rtcb->flags |= TCB_FLAG_SYSCALL;
#else
svcerr("ERROR: Bad SYS call: %d\n", regs[REG_A0]);
#endif
-111
View File
@@ -1,111 +0,0 @@
/****************************************************************************
* arch/riscv/src/rv64gc/up_syscall.S
*
* Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Modified for RISC-V:
*
* Copyright (C) 2016 Ken Pettit. All rights reserved.
* Author: Ken Pettit <pettitkd@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Public Symbols
****************************************************************************/
.file "up_syscall0.S"
.global sys_call0
.global sys_call1
.global sys_call2
.global sys_call3
.global sys_call4
.global sys_call5
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_syscall0, up_syscall1, up_syscall2, up_syscall3
*
* Description:
* up_syscall0 - System call SYS_ argument and no additional parameters.
* up_syscall1 - System call SYS_ argument and one additional parameter.
* up_syscall2 - System call SYS_ argument and two additional parameters.
* up_syscall3 - System call SYS_ argument and three additional parameters.
* up_syscall4 - System call SYS_ argument and four additional parameters.
* up_syscall5 - System call SYS_ argument and five additional parameters.
*
* Assumption:
* All interrupts are disabled except for the software interrupts.
*
****************************************************************************/
.text
sys_call0: /* a0 holds the syscall number */
sys_call1: /* a0 holds the syscall number, argument in a1 */
sys_call2: /* a0 holds the syscall number, arguments in a1 and a2 */
sys_call3: /* a0 holds the syscall number, arguments in a1, a2, and a3 */
sys_call4: /* a0 holds the syscall number, arguments in a1, a2, a3 and a4 */
sys_call5: /* a0 holds the syscall number, arguments in a1, a2, a3, a4 and a5 */
/* Issue the ECALL opcode to perform a SW interrupt to the OS */
ecall
/* The actual interrupt may not a occur for a few more cycles. Let's
* put a few nop's here in hope that the SW interrupt occurs during
* the sequence of nops.
*/
nop
nop
/* Then return with the result of the software interrupt in v0 */
ret
nop