mirror of
https://github.com/apache/nuttx.git
synced 2025-12-16 09:45:18 +08:00
libc: Call pthread_exit in user-space by up_pthread_exit
Drop to user-space in kernel/protected build with up_pthread_exit, now all pthread_cleanup functions executed in user mode. * A new syscall SYS_pthread_exit added * A new tcb flag TCB_FLAG_CANCEL_DOING added * up_pthread_exit implemented for riscv/arm arch Signed-off-by: Huang Qi <huangqi3@xiaomi.com>
This commit is contained in:
@@ -74,6 +74,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_KERNEL),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c arm_signal_dispatch.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_ADDRENV),y)
|
||||
|
||||
@@ -70,6 +70,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_KERNEL),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c arm_signal_dispatch.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_ADDRENV),y)
|
||||
|
||||
@@ -298,26 +298,28 @@ int arm_svcall(int irq, FAR void *context, FAR void *arg)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
|
||||
|
||||
/* R0=SYS_pthread_start: This a user pthread start
|
||||
*
|
||||
* void up_pthread_start(pthread_startroutine_t entrypt,
|
||||
* pthread_addr_t arg) noreturn_function;
|
||||
* void up_pthread_start(pthread_trampoline_t startup,
|
||||
* pthread_startroutine_t entrypt, pthread_addr_t arg)
|
||||
*
|
||||
* At this point, the following values are saved in context:
|
||||
*
|
||||
* R0 = SYS_pthread_start
|
||||
* R1 = entrypt
|
||||
* R2 = arg
|
||||
* R1 = startup
|
||||
* R2 = entrypt
|
||||
* R3 = arg
|
||||
*/
|
||||
|
||||
#if !defined(CONFIG_BUILD_FLAT) && !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_PC] = (uint32_t)regs[REG_R1]; /* startup */
|
||||
regs[REG_PC] = (uint32_t)regs[REG_R1] & ~1; /* startup */
|
||||
regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
|
||||
|
||||
/* Change the parameter ordering to match the expectation of the
|
||||
@@ -328,6 +330,35 @@ int arm_svcall(int irq, FAR void *context, FAR void *arg)
|
||||
regs[REG_R1] = regs[REG_R3]; /* arg */
|
||||
}
|
||||
break;
|
||||
|
||||
/* R0=SYS_pthread_exit: This pthread_exit call in user-space
|
||||
*
|
||||
* void up_pthread_exit(pthread_exitroutine_t exit,
|
||||
* FAR void *exit_value)
|
||||
*
|
||||
* At this point, the following values are saved in context:
|
||||
*
|
||||
* R0 = SYS_pthread_exit
|
||||
* R1 = pthread_exit trampoline routine
|
||||
* R2 = exit_value
|
||||
*/
|
||||
|
||||
case SYS_pthread_exit:
|
||||
{
|
||||
/* Set up to return to the user-space pthread start-up function in
|
||||
* unprivileged mode.
|
||||
*/
|
||||
|
||||
regs[REG_PC] = (uint32_t)regs[REG_R1] & ~1; /* startup */
|
||||
regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
|
||||
|
||||
/* Change the parameter ordering to match the expectation of the
|
||||
* user space pthread_startup:
|
||||
*/
|
||||
|
||||
regs[REG_R0] = regs[REG_R2]; /* exit_value */
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
/* R0=SYS_signal_handler: This a user signal handler callback
|
||||
|
||||
@@ -45,9 +45,9 @@
|
||||
#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"
|
||||
# error "CONFIG_SYS_RESERVED must be defined to have the value 9"
|
||||
# elif CONFIG_SYS_RESERVED != 9
|
||||
# error "CONFIG_SYS_RESERVED must have the value 9"
|
||||
# endif
|
||||
# else
|
||||
# ifndef CONFIG_SYS_RESERVED
|
||||
|
||||
@@ -278,30 +278,23 @@ uint32_t *arm_syscall(uint32_t *regs)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
|
||||
|
||||
/* R0=SYS_pthread_start: This a user pthread start
|
||||
*
|
||||
* void up_pthread_start(pthread_startroutine_t entrypt,
|
||||
* pthread_addr_t arg) noreturn_function;
|
||||
* void up_pthread_start(pthread_trampoline_t startup,
|
||||
* pthread_startroutine_t entrypt, pthread_addr_t arg)
|
||||
*
|
||||
* At this point, the following values are saved in context:
|
||||
*
|
||||
* R0 = SYS_pthread_start
|
||||
* R1 = entrypt
|
||||
* R2 = arg
|
||||
* R1 = startup
|
||||
* R2 = entrypt
|
||||
* R3 = arg
|
||||
*/
|
||||
|
||||
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
|
||||
case SYS_pthread_start:
|
||||
{
|
||||
/* Set up to enter the user-space pthread start-up function in
|
||||
* unprivileged mode. We need:
|
||||
*
|
||||
* R0 = entrypt
|
||||
* R1 = arg
|
||||
* PC = startup
|
||||
* CSPR = user mode
|
||||
*/
|
||||
|
||||
regs[REG_PC] = regs[REG_R0];
|
||||
regs[REG_R0] = regs[REG_R1];
|
||||
regs[REG_R1] = regs[REG_R2];
|
||||
@@ -310,6 +303,28 @@ uint32_t *arm_syscall(uint32_t *regs)
|
||||
regs[REG_CPSR] = cpsr | PSR_MODE_USR;
|
||||
}
|
||||
break;
|
||||
|
||||
/* R0=SYS_pthread_exit: This pthread_exit call in user-space
|
||||
*
|
||||
* void up_pthread_exit(pthread_exitroutine_t exit,
|
||||
* FAR void *exit_value)
|
||||
*
|
||||
* At this point, the following values are saved in context:
|
||||
*
|
||||
* R0 = SYS_pthread_exit
|
||||
* R1 = pthread_exit trampoline routine
|
||||
* R2 = exit_value
|
||||
*/
|
||||
|
||||
case SYS_pthread_exit:
|
||||
{
|
||||
regs[REG_PC] = regs[REG_R0];
|
||||
regs[REG_R0] = regs[REG_R1];
|
||||
|
||||
cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK;
|
||||
regs[REG_CPSR] = cpsr | PSR_MODE_USR;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
|
||||
@@ -44,8 +44,8 @@
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
# ifndef CONFIG_SYS_RESERVED
|
||||
# error "CONFIG_SYS_RESERVED must be defined to have the value 6"
|
||||
# elif CONFIG_SYS_RESERVED != 6
|
||||
# error "CONFIG_SYS_RESERVED must be defined to have the value 7"
|
||||
# elif CONFIG_SYS_RESERVED != 7
|
||||
# error "CONFIG_SYS_RESERVED must have the value 6"
|
||||
# endif
|
||||
#else
|
||||
@@ -109,6 +109,13 @@
|
||||
|
||||
#define SYS_pthread_start (3)
|
||||
|
||||
/* SYS call 8:
|
||||
*
|
||||
* void up_pthread_exit(pthread_exitroutine_t exit, FAR void *exit_value)
|
||||
*/
|
||||
|
||||
#define SYS_pthread_exit (6)
|
||||
|
||||
#endif /* CONFIG_BUILD_KERNEL */
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
@@ -312,19 +312,21 @@ int arm_svcall(int irq, FAR void *context, FAR void *arg)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
|
||||
|
||||
/* R0=SYS_pthread_start: This a user pthread start
|
||||
*
|
||||
* void up_pthread_start(pthread_startroutine_t entrypt,
|
||||
* pthread_addr_t arg) noreturn_function;
|
||||
* void up_pthread_start(pthread_trampoline_t startup,
|
||||
* pthread_startroutine_t entrypt, pthread_addr_t arg)
|
||||
*
|
||||
* At this point, the following values are saved in context:
|
||||
*
|
||||
* R0 = SYS_pthread_start
|
||||
* R1 = entrypt
|
||||
* R2 = arg
|
||||
* R1 = startup
|
||||
* R2 = entrypt
|
||||
* R3 = arg
|
||||
*/
|
||||
|
||||
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
|
||||
case SYS_pthread_start:
|
||||
{
|
||||
/* Set up to return to the user-space pthread start-up function in
|
||||
@@ -342,6 +344,35 @@ int arm_svcall(int irq, FAR void *context, FAR void *arg)
|
||||
regs[REG_R1] = regs[REG_R3]; /* arg */
|
||||
}
|
||||
break;
|
||||
|
||||
/* R0=SYS_pthread_exit: This pthread_exit call in user-space
|
||||
*
|
||||
* void up_pthread_exit(pthread_exitroutine_t exit,
|
||||
* FAR void *exit_value)
|
||||
*
|
||||
* At this point, the following values are saved in context:
|
||||
*
|
||||
* R0 = SYS_pthread_exit
|
||||
* R1 = pthread_exit trampoline routine
|
||||
* R2 = exit_value
|
||||
*/
|
||||
|
||||
case SYS_pthread_exit:
|
||||
{
|
||||
/* Set up to return to the user-space pthread start-up function in
|
||||
* unprivileged mode.
|
||||
*/
|
||||
|
||||
regs[REG_PC] = (uint32_t)regs[REG_R1] & ~1; /* startup */
|
||||
regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
|
||||
|
||||
/* Change the parameter ordering to match the expectation of the
|
||||
* user space pthread_startup:
|
||||
*/
|
||||
|
||||
regs[REG_R0] = regs[REG_R2]; /* exit_value */
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
/* R0=SYS_signal_handler: This a user signal handler callback
|
||||
|
||||
@@ -45,9 +45,9 @@
|
||||
#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"
|
||||
# error "CONFIG_SYS_RESERVED must be defined to have the value 9"
|
||||
# elif CONFIG_SYS_RESERVED != 9
|
||||
# error "CONFIG_SYS_RESERVED must have the value 9"
|
||||
# endif
|
||||
# else
|
||||
# ifndef CONFIG_SYS_RESERVED
|
||||
@@ -126,6 +126,13 @@
|
||||
|
||||
#define SYS_pthread_start (5)
|
||||
|
||||
/* SYS call 8:
|
||||
*
|
||||
* void up_pthread_exit(pthread_exitroutine_t exit, FAR void *exit_value)
|
||||
*/
|
||||
|
||||
#define SYS_pthread_exit (8)
|
||||
|
||||
#endif /* !CONFIG_BUILD_FLAT */
|
||||
#endif /* CONFIG_LIB_SYSCALL */
|
||||
|
||||
|
||||
@@ -273,33 +273,48 @@ uint32_t *arm_syscall(uint32_t *regs)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
|
||||
|
||||
/* R0=SYS_pthread_start: This a user pthread start
|
||||
*
|
||||
* void up_pthread_start(pthread_startroutine_t entrypt,
|
||||
* pthread_addr_t arg) noreturn_function;
|
||||
* void up_pthread_start(pthread_trampoline_t startup,
|
||||
* pthread_startroutine_t entrypt, pthread_addr_t arg)
|
||||
*
|
||||
* At this point, the following values are saved in context:
|
||||
*
|
||||
* R0 = SYS_pthread_start
|
||||
* R1 = entrypt
|
||||
* R2 = arg
|
||||
* R1 = startup
|
||||
* R2 = entrypt
|
||||
* R3 = arg
|
||||
*/
|
||||
|
||||
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
|
||||
case SYS_pthread_start:
|
||||
{
|
||||
/* Set up to enter the user-space pthread start-up function in
|
||||
* unprivileged mode. We need:
|
||||
*
|
||||
* R0 = startup
|
||||
* R1 = arg
|
||||
* PC = entrypt
|
||||
* CSPR = user mode
|
||||
*/
|
||||
regs[REG_PC] = regs[REG_R0];
|
||||
regs[REG_R0] = regs[REG_R1];
|
||||
regs[REG_R1] = regs[REG_R2];
|
||||
|
||||
regs[REG_PC] = regs[REG_R1];
|
||||
regs[REG_R0] = regs[REG_R2];
|
||||
regs[REG_R1] = regs[REG_R3];
|
||||
cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK;
|
||||
regs[REG_CPSR] = cpsr | PSR_MODE_USR;
|
||||
}
|
||||
break;
|
||||
|
||||
/* R0=SYS_pthread_exit: This pthread_exit call in user-space
|
||||
*
|
||||
* void up_pthread_exit(pthread_exitroutine_t exit,
|
||||
* FAR void *exit_value)
|
||||
*
|
||||
* At this point, the following values are saved in context:
|
||||
*
|
||||
* R0 = SYS_pthread_exit
|
||||
* R1 = pthread_exit trampoline routine
|
||||
* R2 = exit_value
|
||||
*/
|
||||
|
||||
case SYS_pthread_exit:
|
||||
{
|
||||
regs[REG_PC] = regs[REG_R0];
|
||||
regs[REG_R0] = regs[REG_R1];
|
||||
|
||||
cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK;
|
||||
regs[REG_CPSR] = cpsr | PSR_MODE_USR;
|
||||
|
||||
@@ -311,19 +311,21 @@ int arm_svcall(int irq, FAR void *context, FAR void *arg)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
|
||||
|
||||
/* R0=SYS_pthread_start: This a user pthread start
|
||||
*
|
||||
* void up_pthread_start(pthread_startroutine_t entrypt,
|
||||
* pthread_addr_t arg) noreturn_function;
|
||||
* void up_pthread_start(pthread_trampoline_t startup,
|
||||
* pthread_startroutine_t entrypt, pthread_addr_t arg)
|
||||
*
|
||||
* At this point, the following values are saved in context:
|
||||
*
|
||||
* R0 = SYS_pthread_start
|
||||
* R1 = entrypt
|
||||
* R2 = arg
|
||||
* R1 = startup
|
||||
* R2 = entrypt
|
||||
* R3 = arg
|
||||
*/
|
||||
|
||||
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
|
||||
case SYS_pthread_start:
|
||||
{
|
||||
/* Set up to return to the user-space pthread start-up function in
|
||||
@@ -338,7 +340,36 @@ int arm_svcall(int irq, FAR void *context, FAR void *arg)
|
||||
*/
|
||||
|
||||
regs[REG_R0] = regs[REG_R2]; /* pthread entry */
|
||||
regs[REG_R1] = regs[REG_R2]; /* arg */
|
||||
regs[REG_R1] = regs[REG_R3]; /* arg */
|
||||
}
|
||||
break;
|
||||
|
||||
/* R0=SYS_pthread_exit: This pthread_exit call in user-space
|
||||
*
|
||||
* void up_pthread_exit(pthread_exitroutine_t exit,
|
||||
* FAR void *exit_value)
|
||||
*
|
||||
* At this point, the following values are saved in context:
|
||||
*
|
||||
* R0 = SYS_pthread_exit
|
||||
* R1 = pthread_exit trampoline routine
|
||||
* R2 = exit_value
|
||||
*/
|
||||
|
||||
case SYS_pthread_exit:
|
||||
{
|
||||
/* Set up to return to the user-space pthread start-up function in
|
||||
* unprivileged mode.
|
||||
*/
|
||||
|
||||
regs[REG_PC] = (uint32_t)regs[REG_R1] & ~1; /* startup */
|
||||
regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
|
||||
|
||||
/* Change the parameter ordering to match the expectation of the
|
||||
* user space pthread_startup:
|
||||
*/
|
||||
|
||||
regs[REG_R0] = regs[REG_R2]; /* exit_value */
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
62
arch/arm/src/common/arm_pthread_exit.c
Normal file
62
arch/arm/src/common/arm_pthread_exit.c
Normal file
@@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/common/arm_pthread_exit.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 <pthread.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include "svcall.h"
|
||||
#include "arm_internal.h"
|
||||
|
||||
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__) && \
|
||||
!defined(CONFIG_DISABLE_PTHREAD)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_pthread_exit
|
||||
*
|
||||
* Description:
|
||||
* In this kernel mode build, this function will be called to execute a
|
||||
* pthread in user-space. This kernel-mode stub will then be called
|
||||
* transfer control to the user-mode pthread_exit.
|
||||
*
|
||||
* Input Parameters:
|
||||
* exit - The user-space pthread_exit function
|
||||
* exit_value - The pointer of the pthread exit parameter
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
****************************************************************************/
|
||||
|
||||
void up_pthread_exit(pthread_exitroutine_t exit, FAR void *exit_value)
|
||||
{
|
||||
/* Let sys_call2() do all of the work */
|
||||
|
||||
sys_call2(SYS_pthread_exit, (uintptr_t)exit, (uintptr_t)exit_value);
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_BUILD_FLAT && __KERNEL__ && !CONFIG_DISABLE_PTHREAD */
|
||||
@@ -51,6 +51,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_mpu.c arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -43,6 +43,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_mpu.c arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -43,6 +43,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -90,6 +90,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_KERNEL),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c arm_signal_dispatch.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_ADDRENV),y)
|
||||
|
||||
@@ -55,6 +55,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -51,6 +51,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -32,6 +32,7 @@ CMN_CSRCS += arm_hardfault.c arm_svcall.c arm_vectors.c arm_vfork.c
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -42,6 +42,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -54,6 +54,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -47,6 +47,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -47,6 +47,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -45,6 +45,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_mpu.c arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -51,6 +51,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_mpu.c arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -32,6 +32,7 @@ CMN_CSRCS += arm_hardfault.c arm_svcall.c arm_vectors.c arm_vfork.c
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -36,6 +36,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -31,6 +31,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
endif
|
||||
|
||||
# Source files common to all S32K1xx chip families.
|
||||
|
||||
@@ -59,6 +59,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -76,6 +76,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_KERNEL),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c arm_signal_dispatch.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_ADDRENV),y)
|
||||
|
||||
@@ -32,6 +32,7 @@ CMN_CSRCS += arm_hardfault.c arm_svcall.c arm_vectors.c arm_vfork.c
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -49,6 +49,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_mpu.c arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -67,6 +67,7 @@ ifeq ($(CONFIG_ARM_MPU),y)
|
||||
CMN_CSRCS += arm_mpu.c
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -58,7 +58,7 @@ CMN_CSRCS += arm_mpu.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -32,6 +32,7 @@ CMN_CSRCS += arm_hardfault.c arm_svcall.c arm_vectors.c arm_vfork.c
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -73,6 +73,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -72,6 +72,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -63,6 +63,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -64,6 +64,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_mpu.c arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -65,6 +65,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
else
|
||||
|
||||
@@ -59,6 +59,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_mpu.c arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -51,6 +51,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
|
||||
CMN_CSRCS += arm_pthread_exit.c
|
||||
CMN_CSRCS += arm_signal_dispatch.c
|
||||
CMN_UASRCS += arm_signal_handler.S
|
||||
endif
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
|
||||
void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg)
|
||||
{
|
||||
/* Let sys_call2() do all of the work */
|
||||
/* Let sys_call3() do all of the work */
|
||||
|
||||
sinfo("entry %p arg %p\n", entrypt, arg);
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ CHIP_CSRCS += c906_start.c c906_timerisr.c
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += riscv_task_start.c riscv_pthread_start.c
|
||||
CMN_CSRCS += riscv_pthread_exit.c
|
||||
CMN_CSRCS += riscv_signal_dispatch.c riscv_pmp.c
|
||||
CMN_UASRCS += riscv_signal_handler.S
|
||||
|
||||
|
||||
60
arch/risc-v/src/common/riscv_pthread_exit.c
Normal file
60
arch/risc-v/src/common/riscv_pthread_exit.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/****************************************************************************
|
||||
* arch/risc-v/src/common/riscv_pthread_exit.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 <pthread.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include "svcall.h"
|
||||
#include "riscv_internal.h"
|
||||
|
||||
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__) && \
|
||||
!defined(CONFIG_DISABLE_PTHREAD)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_pthread_exit
|
||||
*
|
||||
* Description:
|
||||
* In this kernel mode build, this function will be called to execute a
|
||||
* pthread in user-space. This kernel-mode stub will then be called
|
||||
* transfer control to the user-mode pthread_exit.
|
||||
*
|
||||
* Input Parameters:
|
||||
* exit - The user-space pthread_exit function
|
||||
* exit_value - The pointer of the pthread exit parameter
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
****************************************************************************/
|
||||
|
||||
void up_pthread_exit(pthread_exitroutine_t exit, FAR void *exit_value)
|
||||
{
|
||||
sys_call2(SYS_pthread_exit, (uintptr_t)exit, (uintptr_t)exit_value);
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_BUILD_FLAT && __KERNEL__ && !CONFIG_DISABLE_PTHREAD */
|
||||
@@ -57,7 +57,8 @@ CHIP_CSRCS += k210_cpupause.c k210_cpustart.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CMN_CSRCS += riscv_task_start.c riscv_pthread_start.c
|
||||
CMN_CSRCS += riscv_task_start.c
|
||||
CMN_CSRCS += riscv_pthread_start.c riscv_pthread_exit.c
|
||||
CMN_CSRCS += riscv_signal_dispatch.c
|
||||
CMN_UASRCS += riscv_signal_handler.S
|
||||
|
||||
|
||||
@@ -282,19 +282,21 @@ int riscv_swint(int irq, FAR void *context, FAR void *arg)
|
||||
break;
|
||||
#endif
|
||||
|
||||
/* R0=SYS_pthread_start: This a user pthread start
|
||||
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
|
||||
|
||||
/* A0=SYS_pthread_start: This a user pthread start
|
||||
*
|
||||
* void up_pthread_start(pthread_startroutine_t entrypt,
|
||||
* pthread_addr_t arg) noreturn_function;
|
||||
* void up_pthread_start(pthread_trampoline_t startup,
|
||||
* pthread_startroutine_t entrypt, pthread_addr_t arg)
|
||||
*
|
||||
* At this point, the following values are saved in context:
|
||||
*
|
||||
* R0 = SYS_pthread_start
|
||||
* R1 = entrypt
|
||||
* R2 = arg
|
||||
* A0 = SYS_pthread_start
|
||||
* A1 = startup
|
||||
* A2 = entrypt
|
||||
* A3 = arg
|
||||
*/
|
||||
|
||||
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
|
||||
case SYS_pthread_start:
|
||||
{
|
||||
/* Set up to return to the user-space pthread start-up function in
|
||||
@@ -312,6 +314,35 @@ int riscv_swint(int irq, FAR void *context, FAR void *arg)
|
||||
regs[REG_INT_CTX] &= ~MSTATUS_MPPM; /* User mode */
|
||||
}
|
||||
break;
|
||||
|
||||
/* R0=SYS_pthread_exit: This pthread_exit call in user-space
|
||||
*
|
||||
* void up_pthread_exit(pthread_exitroutine_t exit,
|
||||
* FAR void *exit_value)
|
||||
*
|
||||
* At this point, the following values are saved in context:
|
||||
*
|
||||
* R0 = SYS_pthread_exit
|
||||
* R1 = pthread_exit trampoline routine
|
||||
* R2 = exit_value
|
||||
*/
|
||||
|
||||
case SYS_pthread_exit:
|
||||
{
|
||||
/* Set up to enter the user-space pthread exit function in
|
||||
* unprivileged mode.
|
||||
*/
|
||||
|
||||
regs[REG_EPC] = (uintptr_t)regs[REG_A1] & ~1; /* exit */
|
||||
|
||||
/* Change the parameter ordering to match the expectation of the
|
||||
* user space pthread_exit:
|
||||
*/
|
||||
|
||||
regs[REG_A0] = regs[REG_A2]; /* exit_value */
|
||||
regs[REG_INT_CTX] &= ~MSTATUS_MPPM; /* User mode */
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
/* R0=SYS_signal_handler: This a user signal handler callback
|
||||
|
||||
@@ -46,9 +46,9 @@
|
||||
#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"
|
||||
# error "CONFIG_SYS_RESERVED must be defined to have the value 9"
|
||||
# elif CONFIG_SYS_RESERVED != 9
|
||||
# error "CONFIG_SYS_RESERVED must have the value 9"
|
||||
# endif
|
||||
# else
|
||||
# ifndef CONFIG_SYS_RESERVED
|
||||
@@ -118,13 +118,20 @@
|
||||
|
||||
/* SYS call 5:
|
||||
*
|
||||
* void up_pthread_start(pthread_startroutine_t startup,
|
||||
* void up_pthread_start(pthread_trampoline_t startup,
|
||||
* pthread_startroutine_t entrypt, pthread_addr_t arg)
|
||||
* noreturn_function
|
||||
*/
|
||||
|
||||
#define SYS_pthread_start (5)
|
||||
|
||||
/* SYS call 8:
|
||||
*
|
||||
* void up_pthread_exit(pthread_exitroutine_t exit, FAR void *exit_value)
|
||||
*/
|
||||
|
||||
#define SYS_pthread_exit (8)
|
||||
|
||||
#endif /* !CONFIG_BUILD_FLAT */
|
||||
#endif /* CONFIG_LIB_SYSCALL */
|
||||
|
||||
|
||||
@@ -40,5 +40,5 @@ CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_START_DAY=8
|
||||
CONFIG_START_MONTH=6
|
||||
CONFIG_SYSTEM_NSH=y
|
||||
CONFIG_SYS_RESERVED=8
|
||||
CONFIG_SYS_RESERVED=9
|
||||
CONFIG_USER_ENTRYPOINT="nsh_main"
|
||||
|
||||
@@ -40,5 +40,5 @@ CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_START_DAY=8
|
||||
CONFIG_START_MONTH=6
|
||||
CONFIG_SYSTEM_NSH=y
|
||||
CONFIG_SYS_RESERVED=8
|
||||
CONFIG_SYS_RESERVED=9
|
||||
CONFIG_USER_ENTRYPOINT="nsh_main"
|
||||
|
||||
@@ -40,5 +40,5 @@ CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_START_DAY=8
|
||||
CONFIG_START_MONTH=6
|
||||
CONFIG_SYSTEM_NSH=y
|
||||
CONFIG_SYS_RESERVED=8
|
||||
CONFIG_SYS_RESERVED=9
|
||||
CONFIG_USER_ENTRYPOINT="nsh_main"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user