Add support for delivery of use-mode signals in the kernel build.
This commit is contained in:
parent
aa7efbb52e
commit
12775801c9
@ -240,6 +240,15 @@ struct xcptcontext
|
||||
|
||||
uint32_t saved_pc;
|
||||
uint32_t saved_cpsr;
|
||||
|
||||
# ifdef CONFIG_BUILD_KERNEL
|
||||
/* This is the saved address to use when returning from a user-space
|
||||
* signal handler.
|
||||
*/
|
||||
|
||||
uint32_t sigreturn;
|
||||
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Register save area */
|
||||
|
@ -83,7 +83,7 @@ CMN_CSRCS += arm_va2pte.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_KERNEL),y)
|
||||
CMN_CSRCS += up_task_start.c up_pthread_start.c
|
||||
CMN_CSRCS += up_task_start.c up_pthread_start.c up_signal_dispatch.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_ADDRENV),y)
|
||||
|
@ -332,7 +332,7 @@ static void up_addrenv_destroy_region(FAR uintptr_t **list,
|
||||
* needed by the task. This region may be read/write only. NOTE: The
|
||||
* actual size of the data region that is allocated will include a
|
||||
* OS private reserved region at the beginning. The size of the
|
||||
* private, reserved region is give by ARCH_DATA_RESERVE.
|
||||
* private, reserved region is give by ARCH_DATA_RESERVE_SIZE.
|
||||
* addrenv - The location to return the representation of the task address
|
||||
* environment.
|
||||
*
|
||||
@ -378,7 +378,7 @@ int up_addrenv_create(size_t textsize, size_t datasize,
|
||||
|
||||
ret = up_addrenv_create_region(addrenv->data, ARCH_DATA_NSECTS,
|
||||
CONFIG_ARCH_DATA_VBASE,
|
||||
datasize + ARCH_DATA_RESERVE,
|
||||
datasize + ARCH_DATA_RESERVE_SIZE,
|
||||
MMU_L2_UDATAFLAGS);
|
||||
if (ret < 0)
|
||||
{
|
||||
@ -495,7 +495,7 @@ int up_addrenv_vdata(FAR group_addrenv_t *addrenv, uintptr_t textsize,
|
||||
/* Not much to do in this case */
|
||||
|
||||
DEBUGASSERT(addrenv && vdata);
|
||||
*vdata = (FAR void *)(CONFIG_ARCH_DATA_VBASE + ARCH_DATA_RESERVE);
|
||||
*vdata = (FAR void *)(CONFIG_ARCH_DATA_VBASE + ARCH_DATA_RESERVE_SIZE);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,7 @@
|
||||
|
||||
#include <arch/irq.h>
|
||||
#include <nuttx/sched.h>
|
||||
#include <nuttx/addrenv.h>
|
||||
|
||||
#include "arm.h"
|
||||
#include "svcall.h"
|
||||
@ -128,7 +129,7 @@ static void dispatch_syscall(void)
|
||||
" add sp, sp, #16\n" /* Destroy the stack frame */
|
||||
" mov r2, r0\n" /* R2=Save return value in R2 */
|
||||
" mov r0, #0\n" /* R0=SYS_syscall_return */
|
||||
" svc #0x900001" /* Return from the SYSCALL */
|
||||
" svc #0x900001\n" /* Return from the SYSCALL */
|
||||
);
|
||||
}
|
||||
#endif
|
||||
@ -202,7 +203,7 @@ uint32_t *arm_syscall(uint32_t *regs)
|
||||
|
||||
case SYS_syscall_return:
|
||||
{
|
||||
struct tcb_s *rtcb = sched_self();
|
||||
FAR struct tcb_s *rtcb = sched_self();
|
||||
int index = (int)rtcb->xcp.nsyscalls - 1;
|
||||
|
||||
/* Make sure that there is a saved SYSCALL return address. */
|
||||
@ -293,6 +294,7 @@ uint32_t *arm_syscall(uint32_t *regs)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BUILD_KERNEL) && !defined(CONFIG_DISABLE_SIGNALS)
|
||||
/* R0=SYS_signal_handler: This a user signal handler callback
|
||||
*
|
||||
* void signal_handler(_sa_sigaction_t sighand, int signo,
|
||||
@ -307,12 +309,9 @@ uint32_t *arm_syscall(uint32_t *regs)
|
||||
* ucontext (on the stack)
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_BUILD_KERNEL) && !defined(CONFIG_DISABLE_SIGNALS)
|
||||
case SYS_signal_handler:
|
||||
{
|
||||
#warning Missing logic
|
||||
#if 0
|
||||
struct tcb_s *rtcb = sched_self();
|
||||
FAR struct tcb_s *rtcb = sched_self();
|
||||
|
||||
/* Remember the caller's return address */
|
||||
|
||||
@ -323,7 +322,7 @@ uint32_t *arm_syscall(uint32_t *regs)
|
||||
* unprivileged mode.
|
||||
*/
|
||||
|
||||
regs[REG_PC] = (uint32_t)USERSPACE->signal_handler;
|
||||
regs[REG_PC] = (uint32_t)ARCH_DATA_RESERVE->ar_sigtramp;
|
||||
cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK;
|
||||
regs[REG_CPSR] = cpsr | PSR_MODE_USR;
|
||||
|
||||
@ -340,11 +339,11 @@ uint32_t *arm_syscall(uint32_t *regs)
|
||||
*/
|
||||
|
||||
regs[REG_R3] = *(uint32_t*)(regs[REG_SP+4]);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BUILD_KERNEL) && !defined(CONFIG_DISABLE_SIGNALS)
|
||||
/* R0=SYS_signal_handler_return: This a user signal handler callback
|
||||
*
|
||||
* void signal_handler_return(void);
|
||||
@ -354,12 +353,9 @@ uint32_t *arm_syscall(uint32_t *regs)
|
||||
* R0 = SYS_signal_handler_return
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_BUILD_KERNEL) && !defined(CONFIG_DISABLE_SIGNALS)
|
||||
case SYS_signal_handler_return:
|
||||
{
|
||||
#warning Missing logic
|
||||
#if 0
|
||||
struct tcb_s *rtcb = sched_self();
|
||||
FAR struct tcb_s *rtcb = sched_self();
|
||||
|
||||
/* Set up to return to the kernel-mode signal dispatching logic. */
|
||||
|
||||
@ -369,7 +365,6 @@ uint32_t *arm_syscall(uint32_t *regs)
|
||||
cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK;
|
||||
regs[REG_CPSR] = cpsr | PSR_MODE_SVC;
|
||||
rtcb->xcp.sigreturn = 0;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
@ -41,6 +41,8 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <nuttx/addrenv.h>
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
|
||||
/****************************************************************************
|
||||
@ -61,6 +63,48 @@ extern main_t main;
|
||||
* Private 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.
|
||||
*
|
||||
* R0-R3, R11 - volatile registers need not be preserved.
|
||||
* R4-R10 - static registers must be preserved
|
||||
* R12-R14 - LR and SP must be preserved
|
||||
*
|
||||
* Inputs:
|
||||
* R0 = sighand
|
||||
* The address user-space signal handling function
|
||||
* R1-R3 = signo, info, and ucontext
|
||||
* Standard arguments to be passed to the signal handling function.
|
||||
*
|
||||
* Return:
|
||||
* None. This function does not return in the normal sense. It returns
|
||||
* via the SYS_signal_handler_return (see svcall.h)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_DISABLE_SIGNALS
|
||||
static void sig_trampoline(void) naked_function;
|
||||
static void sig_trampoline(void)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
" push {lr}\n" /* Save LR on the stack */
|
||||
" mov ip, r0\n" /* IP=sighand */
|
||||
" mov r0, r1\n" /* R0=signo */
|
||||
" mov r1, r2\n" /* R1=info */
|
||||
" mov r2, r3\n" /* R2=ucontext */
|
||||
" blx ip\n" /* Call the signal handler */
|
||||
" pop {r2}\n" /* Recover LR in R2 */
|
||||
" mov lr, r2\n" /* Restore LR */
|
||||
" mov r0, #4\n" /* SYS_signal_handler_return
|
||||
" svc #0x900001\n" /* Return from the signal handler */
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -89,6 +133,14 @@ void _start(int argc, FAR char *argv[])
|
||||
{
|
||||
int ret;
|
||||
|
||||
#ifndef CONFIG_DISABLE_SIGNALS
|
||||
/* Initialize the reserved area at the beginning of the .bss/.data region
|
||||
* that is visible to the RTOS.
|
||||
*/
|
||||
|
||||
ADDRENV_DATA_RESERVE->ar_sigtramp = (addrenv_sigtramp_t)sig_trampoline;
|
||||
#endif
|
||||
|
||||
/* Call C++ constructors */
|
||||
/* Setup so that C++ destructors called on task exit */
|
||||
/* REVISIT: Missing logic */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/srcm/armv7-m/up_signal_handler.S
|
||||
* arch/arm/src/armv7-m/up_signal_handler.S
|
||||
*
|
||||
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
|
@ -85,7 +85,7 @@ CMN_CSRCS += arm_va2pte.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_KERNEL),y)
|
||||
CMN_CSRCS += up_task_start.c up_pthread_start.c
|
||||
CMN_CSRCS += up_task_start.c up_pthread_start.c up_signal_dispatch.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_ADDRENV),y)
|
||||
|
Loading…
Reference in New Issue
Block a user