mirror of
https://github.com/apache/nuttx.git
synced 2026-06-04 14:53:47 +08:00
Add task init and signal scheduling logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3338 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
+30
-17
@@ -57,23 +57,25 @@
|
|||||||
/* Storage order: %ebx, $esi, %edi, %ebp, sp, and return PC */
|
/* Storage order: %ebx, $esi, %edi, %ebp, sp, and return PC */
|
||||||
|
|
||||||
#ifdef __ASSEMBLY__
|
#ifdef __ASSEMBLY__
|
||||||
# define REG_EBX (0*4)
|
# define REG_EBX (0*4)
|
||||||
# define REG_ESI (1*4)
|
# define REG_ESI (1*4)
|
||||||
# define REG_EDI (2*4)
|
# define REG_EDI (2*4)
|
||||||
# define REG_EBP (3*4)
|
# define REG_EBP (3*4)
|
||||||
# define REG_SP (4*4)
|
# define REG_SP (4*4)
|
||||||
# define REG_PC (5*4)
|
# define REG_PC (5*4)
|
||||||
|
# define REG_FLAGS (6*4)
|
||||||
#else
|
#else
|
||||||
# define REG_EBX (0)
|
# define REG_EBX (0)
|
||||||
# define REG_ESI (1)
|
# define REG_ESI (1)
|
||||||
# define REG_EDI (2)
|
# define REG_EDI (2)
|
||||||
# define REG_EBP (3)
|
# define REG_EBP (3)
|
||||||
# define REG_SP (4)
|
# define REG_SP (4)
|
||||||
# define REG_PC (5)
|
# define REG_PC (5)
|
||||||
|
# define REG_FLAGS (6)
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
#define XCPTCONTEXT_REGS (6)
|
#define XCPTCONTEXT_REGS (7)
|
||||||
#define XCPTCONTEXT_SIZE (6 * XCPTCONTEXT_REGS)
|
#define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Types
|
* Public Types
|
||||||
@@ -84,9 +86,20 @@
|
|||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
struct xcptcontext
|
struct xcptcontext
|
||||||
{
|
{
|
||||||
void *sigdeliver; /* Actual type is sig_deliver_t */
|
/* The following function pointer is non-zero if there are pending signals
|
||||||
|
* to be processed.
|
||||||
|
*/
|
||||||
|
|
||||||
/* Storage order: %ebx, $esi, %edi, %ebp, sp, and return PC */
|
#ifndef CONFIG_DISABLE_SIGNALS
|
||||||
|
void *sigdeliver; /* Actual type is sig_deliver_t */
|
||||||
|
|
||||||
|
/* These are saved copies of LR and CPSR used during signal processing. */
|
||||||
|
|
||||||
|
uint32_t saved_pc;
|
||||||
|
uint32_t saved_flags;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Register save area */
|
||||||
|
|
||||||
uint32_t regs[XCPTCONTEXT_REGS];
|
uint32_t regs[XCPTCONTEXT_REGS];
|
||||||
};
|
};
|
||||||
@@ -117,7 +130,7 @@ static inline irqstate_t irqflags()
|
|||||||
|
|
||||||
static inline bool irqdisabled(irqstate_t flags)
|
static inline bool irqdisabled(irqstate_t flags)
|
||||||
{
|
{
|
||||||
return ((flags & X86_FLAGS_IF) == 0);
|
return ((flags & X86_FLAGS_IF) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable interrupts unconditionally */
|
/* Disable interrupts unconditionally */
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* arch/x86/src/i486/up_initialstate.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
*
|
||||||
|
* 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>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <nuttx/arch.h>
|
||||||
|
#include <arch/arch.h>
|
||||||
|
|
||||||
|
#include "up_internal.h"
|
||||||
|
#include "up_arch.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_initial_state
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* A new thread is being started and a new TCB has been created. This
|
||||||
|
* function is called to initialize the processor specific portions of the
|
||||||
|
* new TCB.
|
||||||
|
*
|
||||||
|
* This function must setup the intial architecture registers and/or stack
|
||||||
|
* so that execution will begin at tcb->start on the next context switch.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void up_initial_state(_TCB *tcb)
|
||||||
|
{
|
||||||
|
struct xcptcontext *xcp = &tcb->xcp;
|
||||||
|
|
||||||
|
/* Initialize the initial exception register context structure */
|
||||||
|
|
||||||
|
memset(xcp, 0, sizeof(struct xcptcontext));
|
||||||
|
|
||||||
|
/* Save the initial stack pointer */
|
||||||
|
|
||||||
|
xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
|
||||||
|
|
||||||
|
/* Save the task entry point */
|
||||||
|
|
||||||
|
xcp->regs[REG_PC] = (uint32_t)tcb->start;
|
||||||
|
|
||||||
|
/* Enable or disable interrupts, based on user configuration. If the IF
|
||||||
|
* bit is set, maskable interrupts will be enabled.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||||
|
xcp->regs[REG_FLAGS] = X86_FLAGS_IF;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,198 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* arch/x86/src/i486/up_schedulesigaction.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
*
|
||||||
|
* 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>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sched.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <nuttx/arch.h>
|
||||||
|
|
||||||
|
#include "os_internal.h"
|
||||||
|
#include "up_internal.h"
|
||||||
|
#include "up_arch.h"
|
||||||
|
|
||||||
|
#ifndef CONFIG_DISABLE_SIGNALS
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_schedule_sigaction
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function is called by the OS when one or more signal handling
|
||||||
|
* actions have been queued for execution. The architecture specific code
|
||||||
|
* must configure things so that the 'sigdeliver' callback is executed on
|
||||||
|
* the thread specified by 'tcb' as soon as possible.
|
||||||
|
*
|
||||||
|
* This function may be called from interrupt handling logic.
|
||||||
|
*
|
||||||
|
* This operation should not cause the task to be unblocked nor should it
|
||||||
|
* cause any immediate execution of sigdeliver. Typically, a few cases need
|
||||||
|
* to be considered:
|
||||||
|
*
|
||||||
|
* (1) This function may be called from an interrupt handler. During
|
||||||
|
* interrupt processing, all xcptcontext structures should be valid for
|
||||||
|
* all tasks. That structure should be modified to invoke sigdeliver()
|
||||||
|
* either on return from (this) interrupt or on some subsequent context
|
||||||
|
* switch to the recipient task.
|
||||||
|
* (2) If not in an interrupt handler and the tcb is NOT the currently
|
||||||
|
* executing task, then again just modify the saved xcptcontext
|
||||||
|
* structure for the recipient task so it will invoke sigdeliver when
|
||||||
|
* that task is later resumed.
|
||||||
|
* (3) If not in an interrupt handler and the tcb IS the currently
|
||||||
|
* executing task -- just call the signal handler now.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void up_schedule_sigaction(_TCB *tcb, sig_deliver_t sigdeliver)
|
||||||
|
{
|
||||||
|
/* Refuse to handle nested signal actions */
|
||||||
|
|
||||||
|
sdbg("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver);
|
||||||
|
|
||||||
|
if (!tcb->xcp.sigdeliver)
|
||||||
|
{
|
||||||
|
irqstate_t flags;
|
||||||
|
|
||||||
|
/* Make sure that interrupts are disabled */
|
||||||
|
|
||||||
|
flags = irqsave();
|
||||||
|
|
||||||
|
/* First, handle some special cases when the signal is being delivered
|
||||||
|
* to the currently executing task.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sdbg("rtcb=0x%p current_regs=0x%p\n", g_readytorun.head, current_regs);
|
||||||
|
|
||||||
|
if (tcb == (_TCB*)g_readytorun.head)
|
||||||
|
{
|
||||||
|
/* CASE 1: We are not in an interrupt handler and a task is
|
||||||
|
* signalling itself for some reason.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!current_regs)
|
||||||
|
{
|
||||||
|
/* In this case just deliver the signal now. */
|
||||||
|
|
||||||
|
sigdeliver(tcb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CASE 2: We are in an interrupt handler AND the interrupted task
|
||||||
|
* is the same as the one that must receive the signal, then we will
|
||||||
|
* have to modify the return state as well as the state in the TCB.
|
||||||
|
*
|
||||||
|
* Hmmm... there looks like a latent bug here: The following logic
|
||||||
|
* would fail in the strange case where we are in an interrupt
|
||||||
|
* handler, the thread is signalling itself, but a context switch to
|
||||||
|
* another task has occurred so that current_regs does not refer to
|
||||||
|
* the thread at g_readytorun.head!
|
||||||
|
*/
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Save the return lr and cpsr and one scratch register. These
|
||||||
|
* will be restored by the signal trampoline after the signals
|
||||||
|
* have been delivered.
|
||||||
|
*/
|
||||||
|
|
||||||
|
tcb->xcp.sigdeliver = sigdeliver;
|
||||||
|
tcb->xcp.saved_pc = current_regs[REG_PC];
|
||||||
|
tcb->xcp.saved_flags = current_regs[REG_FLAGS];
|
||||||
|
|
||||||
|
/* Then set up to vector to the trampoline with interrupts
|
||||||
|
* disabled
|
||||||
|
*/
|
||||||
|
|
||||||
|
current_regs[REG_PC] = (uint32_t)up_sigdeliver;
|
||||||
|
current_regs[REG_FLAGS] = 0;
|
||||||
|
|
||||||
|
/* And make sure that the saved context in the TCB
|
||||||
|
* is the same as the interrupt return context.
|
||||||
|
*/
|
||||||
|
|
||||||
|
up_savestate(tcb->xcp.regs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, we are (1) signaling a task is not running
|
||||||
|
* from an interrupt handler or (2) we are not in an
|
||||||
|
* interrupt handler and the running task is signalling
|
||||||
|
* some non-running task.
|
||||||
|
*/
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Save the return lr and cpsr and one scratch register
|
||||||
|
* These will be restored by the signal trampoline after
|
||||||
|
* the signals have been delivered.
|
||||||
|
*/
|
||||||
|
|
||||||
|
tcb->xcp.sigdeliver = sigdeliver;
|
||||||
|
tcb->xcp.saved_pc = tcb->xcp.regs[REG_PC];
|
||||||
|
tcb->xcp.saved_flags = tcb->xcp.regs[REG_FLAGS];
|
||||||
|
|
||||||
|
/* Then set up to vector to the trampoline with interrupts
|
||||||
|
* disabled
|
||||||
|
*/
|
||||||
|
|
||||||
|
tcb->xcp.regs[REG_PC] = (uint32_t)up_sigdeliver;
|
||||||
|
tcb->xcp.regs[REG_FLAGS] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
irqrestore(flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* !CONFIG_DISABLE_SIGNALS */
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* arch/x86/src/i486/up_sigdeliver.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
*
|
||||||
|
* 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>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sched.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <nuttx/irq.h>
|
||||||
|
#include <nuttx/arch.h>
|
||||||
|
#include <arch/board/board.h>
|
||||||
|
|
||||||
|
#include "os_internal.h"
|
||||||
|
#include "up_internal.h"
|
||||||
|
#include "up_arch.h"
|
||||||
|
|
||||||
|
#ifndef CONFIG_DISABLE_SIGNALS
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_sigdeliver
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This is the a signal handling trampoline. When a signal action was
|
||||||
|
* posted. The task context was mucked with and forced to branch to this
|
||||||
|
* location with interrupts disabled.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void up_sigdeliver(void)
|
||||||
|
{
|
||||||
|
_TCB *rtcb = (_TCB*)g_readytorun.head;
|
||||||
|
uint32_t regs[XCPTCONTEXT_REGS];
|
||||||
|
sig_deliver_t sigdeliver;
|
||||||
|
|
||||||
|
/* Save the errno. This must be preserved throughout the signal handling
|
||||||
|
* so that the user code final gets the correct errno value (probably
|
||||||
|
* EINTR).
|
||||||
|
*/
|
||||||
|
|
||||||
|
int saved_errno = rtcb->pterrno;
|
||||||
|
|
||||||
|
up_ledon(LED_SIGNAL);
|
||||||
|
|
||||||
|
sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n",
|
||||||
|
rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head);
|
||||||
|
ASSERT(rtcb->xcp.sigdeliver != NULL);
|
||||||
|
|
||||||
|
/* Save the real return state on the stack. */
|
||||||
|
|
||||||
|
up_copystate(regs, rtcb->xcp.regs);
|
||||||
|
regs[REG_PC] = rtcb->xcp.saved_pc;
|
||||||
|
regs[REG_FLAGS] = rtcb->xcp.saved_flags;
|
||||||
|
|
||||||
|
/* Get a local copy of the sigdeliver function pointer. we do this so that
|
||||||
|
* we can nullify the sigdeliver function pointer in the TCB and accept
|
||||||
|
* more signal deliveries while processing the current pending signals.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sigdeliver = rtcb->xcp.sigdeliver;
|
||||||
|
rtcb->xcp.sigdeliver = NULL;
|
||||||
|
|
||||||
|
/* Then restore the task interrupt state */
|
||||||
|
|
||||||
|
irqrestore(regs[REG_FLAGS]);
|
||||||
|
|
||||||
|
/* Deliver the signals */
|
||||||
|
|
||||||
|
sigdeliver(rtcb);
|
||||||
|
|
||||||
|
/* Output any debug messages BEFORE restoring errno (because they may
|
||||||
|
* alter errno), then disable interrupts again and restore the original
|
||||||
|
* errno that is needed by the user logic (it is probably EINTR).
|
||||||
|
*/
|
||||||
|
|
||||||
|
sdbg("Resuming\n");
|
||||||
|
(void)irqsave();
|
||||||
|
rtcb->pterrno = saved_errno;
|
||||||
|
|
||||||
|
/* Then restore the correct state for this thread of execution. */
|
||||||
|
|
||||||
|
up_ledoff(LED_SIGNAL);
|
||||||
|
up_fullcontextrestore(regs);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* !CONFIG_DISABLE_SIGNALS */
|
||||||
|
|
||||||
@@ -42,9 +42,10 @@ HEAD_ASRC = qemu_head.S
|
|||||||
CMN_ASRCS =
|
CMN_ASRCS =
|
||||||
CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copystate.c \
|
CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copystate.c \
|
||||||
up_createstack.c up_mdelay.c up_udelay.c up_exit.c \
|
up_createstack.c up_mdelay.c up_udelay.c up_exit.c \
|
||||||
up_initialize.c up_interruptcontext.c up_modifyreg8.c \
|
up_initialize.c up_initialstate.c up_interruptcontext.c \
|
||||||
up_modifyreg16.c up_modifyreg32.c up_releasepending.c \
|
up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c \
|
||||||
up_releasestack.c up_reprioritizertr.c up_unblocktask.c \
|
up_releasepending.c up_releasestack.c up_reprioritizertr.c \
|
||||||
|
up_sigdeliver.c up_schedulesigaction.c up_unblocktask.c \
|
||||||
up_usestack.c
|
up_usestack.c
|
||||||
|
|
||||||
# Required QEMU files
|
# Required QEMU files
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* arch/x86/src/qemu/qemu_fullcontextrestore.S
|
* arch/x86/src/qemu/qemu_fullcontextrestore.S
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -96,24 +96,35 @@
|
|||||||
.type SYMBOL(up_fullcontextrestore), @function
|
.type SYMBOL(up_fullcontextrestore), @function
|
||||||
#endif
|
#endif
|
||||||
SYMBOL(up_fullcontextrestore):
|
SYMBOL(up_fullcontextrestore):
|
||||||
movl 4(%esp), %ecx /* U_pthread_jmpbuf in %ecx. */
|
movl 4(%esp), %ecx /* Register save area in %ecx. */
|
||||||
movl 8(%esp), %eax /* Second argument is return value. */
|
|
||||||
|
|
||||||
/* Save the return address now. */
|
/* Disable interrupts now (the will be conditionally re-enabled below) */
|
||||||
|
|
||||||
movl (REG_PC)(%ecx), %edx
|
cli
|
||||||
|
|
||||||
|
/* Save the return address. */
|
||||||
|
|
||||||
|
movl (REG_PC)(%ecx), %edx
|
||||||
|
|
||||||
/* Restore registers. */
|
/* Restore registers. */
|
||||||
|
|
||||||
movl (REG_EBX)(%ecx), %ebx
|
movl (REG_EBX)(%ecx), %ebx
|
||||||
movl (REG_ESI)(%ecx), %esi
|
movl (REG_ESI)(%ecx), %esi
|
||||||
movl (REG_EDI)(%ecx), %edi
|
movl (REG_EDI)(%ecx), %edi
|
||||||
movl (REG_EBP)(%ecx), %ebp
|
movl (REG_EBP)(%ecx), %ebp
|
||||||
movl (REG_SP)(%ecx), %esp
|
movl (REG_SP)(%ecx), %esp
|
||||||
|
|
||||||
/* Jump to saved PC. */
|
/* Conditionally restore interrupts */
|
||||||
|
|
||||||
jmp *%edx
|
testl $512, (REG_FLAGS)(%ecx)
|
||||||
|
je .Ldisabled
|
||||||
|
sti
|
||||||
|
.Ldisabled:
|
||||||
|
|
||||||
|
/* Jump to saved PC with non-zero return value in %eax. */
|
||||||
|
|
||||||
|
movl $1, %eax
|
||||||
|
jmp *%edx
|
||||||
#ifndef __CYGWIN__
|
#ifndef __CYGWIN__
|
||||||
.size SYMBOL(up_fullcontextrestore), . - SYMBOL(up_fullcontextrestore)
|
.size SYMBOL(up_fullcontextrestore), . - SYMBOL(up_fullcontextrestore)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -117,7 +117,13 @@ SYMBOL(up_saveusercontext):
|
|||||||
|
|
||||||
/* Save the framepointer */
|
/* Save the framepointer */
|
||||||
|
|
||||||
movl %ebp, (REG_EBP)(%eax)
|
movl %ebp, (REG_EBP)(%eax)
|
||||||
|
|
||||||
|
/* Save the interrupt state */
|
||||||
|
|
||||||
|
pushf
|
||||||
|
pop %ecx
|
||||||
|
movl %ecx, (REG_FLAGS)(%eax)
|
||||||
|
|
||||||
/* And return 0 */
|
/* And return 0 */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user