Esempio n. 1
0
void up_sigdeliver(void)
{
#ifndef CONFIG_DISABLE_SIGNALS
  FAR _TCB  *rtcb = (_TCB*)g_readytorun.head;
  chipreg_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. */

  ez80_copystate(regs, rtcb->xcp.regs);
  regs[XCPT_PC] = rtcb->xcp.saved_pc;
  regs[XCPT_I]  = rtcb->xcp.saved_i;

  /* 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[XCPT_I]);

  /* 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);
  ez80_restorecontext(regs);
#endif
}
Esempio n. 2
0
void up_sigdeliver(void)
{
	struct tcb_s *rtcb = this_task();
	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;

	board_autoled_on(LED_SIGNAL);

	svdbg("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_copyfullstate(regs, rtcb->xcp.regs);
	regs[REG_PC] = rtcb->xcp.saved_pc;
	regs[REG_CPSR] = rtcb->xcp.saved_cpsr;

	/* 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_CPSR]);

	/* 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).
	 */

	svdbg("Resuming\n");
	(void)irqsave();
	rtcb->pterrno = saved_errno;

	/* Then restore the correct state for this thread of execution. */

	board_autoled_off(LED_SIGNAL);
#ifdef CONFIG_TASK_SCHED_HISTORY
	/* Save the task name which will be scheduled */
	save_task_scheduling_status(rtcb);
#endif
	up_fullcontextrestore(regs);
}
Esempio n. 3
0
void up_sigdeliver(void)
{
  struct tcb_s *rtcb = (struct tcb_s*)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;

  board_led_on(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_EIP]        = rtcb->xcp.saved_eip;
  regs[REG_EFLAGS]     = rtcb->xcp.saved_eflags;

  /* 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_EFLAGS]);

  /* 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. */

  board_led_off(LED_SIGNAL);
  up_fullcontextrestore(regs);
}
Esempio n. 4
0
void up_sigdeliver(struct Trapframe *tf)
{
    sig_deliver_t sigdeliver;

    pop_xcptcontext(&current_task->xcp);
    sigdeliver = current_task->xcp.sigdeliver;
    current_task->xcp.sigdeliver = NULL;
    local_irq_enable();
    sigdeliver(current_task);
    local_irq_disable();
}
Esempio n. 5
0
void up_sigdeliver(void)
{
  _TCB  *rtcb = (_TCB*)g_readytorun.head;
#if 0
  uint32_t regs[XCPTCONTEXT_REGS+3];  /* Why +3? See below */
#else
  uint32_t regs[XCPTCONTEXT_REGS];
#endif
  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_SR]         = rtcb->xcp.saved_sr;

  /* 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_SR]);

  /* 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. This is an
   * unusual case that must be handled by up_fullcontextresore. This case is
   * unusal in two ways:
   *
   *   1. It is not a context switch between threads.  Rather, up_fullcontextrestore
   *      must behave more it more like a longjmp within the same task, using
   *      he same stack.
   *   2. In this case, up_fullcontextrestore is called with r12 pointing to
   *      a register save area on the stack to be destroyed.  This is
   *      dangerous because there is the very real possibility that the new
   *      stack pointer might overlap with the register save area and hat stack
   *      usage in up_fullcontextrestore might corrupt the register save data
   *      before the state is restored.  At present, there does not appear to
   *      be any stack overlap problems.  If there were, then adding 3 words
   *      to the size of register save structure size will protect its contents.
   */

  up_ledoff(LED_SIGNAL);
  up_fullcontextrestore(regs);
}
Esempio n. 6
0
void up_sigdeliver(void)
{
  struct tcb_s *rtcb = this_task();
  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;

  board_autoled_on(LED_SIGNAL);

  sinfo("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_EPC]        = rtcb->xcp.saved_epc;
  regs[REG_STATUS]     = rtcb->xcp.saved_status;

  /* 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 */

  up_irq_restore((irqstate_t)regs[REG_STATUS]);

  /* 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).
   */

  sinfo("Resuming EPC: %08x STATUS: %08x\n", regs[REG_EPC], regs[REG_STATUS]);

  (void)up_irq_save();
  rtcb->pterrno = saved_errno;

  /* Then restore the correct state for this thread of
   * execution.
   */

  board_autoled_off(LED_SIGNAL);
  up_fullcontextrestore(regs);

  /* up_fullcontextrestore() should not return but could if the software
   * interrupts are disabled.
   */

  PANIC();
}
void up_sigdeliver(void)
{
    /* NOTE the "magic" guard space added to regs.  This is a little kludge
     * because up_fullcontextrestore (called below) will do a stack-to-stack
     * copy an may overwrite the regs[] array contents.  Sorry.
     */

    struct tcb_s  *rtcb = (struct tcb_s*)g_readytorun.head;
    uint32_t regs[XCPTCONTEXT_REGS + 4];
    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;

    board_led_on(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_copyfullstate(regs, rtcb->xcp.regs);
    regs[REG_PC]         = rtcb->xcp.saved_pc;
    regs[REG_PRIMASK]    = rtcb->xcp.saved_primask;
    regs[REG_XPSR]       = rtcb->xcp.saved_xpsr;
#ifdef CONFIG_BUILD_PROTECTED
    regs[REG_LR]         = rtcb->xcp.saved_lr;
#endif

    /* 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((uint8_t)regs[REG_PRIMASK]);

    /* Deliver the signal */

    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.
     */

    board_led_off(LED_SIGNAL);
    up_fullcontextrestore(regs);
}
Esempio n. 8
0
void up_sigdeliver(void)
{
  struct tcb_s  *rtcb = this_task();
  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;

  board_autoled_on(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_copyfullstate(regs, rtcb->xcp.regs);
  regs[REG_PC]         = rtcb->xcp.saved_pc;
#ifdef CONFIG_ARMV7M_USEBASEPRI
  regs[REG_BASEPRI]    = rtcb->xcp.saved_basepri;
#else
  regs[REG_PRIMASK]    = rtcb->xcp.saved_primask;
#endif
  regs[REG_XPSR]       = rtcb->xcp.saved_xpsr;
#ifdef CONFIG_BUILD_PROTECTED
  regs[REG_LR]         = rtcb->xcp.saved_lr;
#endif

  /* 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 */

#ifdef CONFIG_ARMV7M_USEBASEPRI
  irqrestore((uint8_t)regs[REG_BASEPRI]);
#else
  irqrestore((uint16_t)regs[REG_PRIMASK]);
#endif

  /* Deliver the signal */

  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.
   */

  board_autoled_off(LED_SIGNAL);
  up_fullcontextrestore(regs);
}
Esempio n. 9
0
void up_sigdeliver(void)
{
#ifndef CONFIG_DISABLE_SIGNALS
  FAR struct tcb_s *rtcb = (struct tcb_s*)g_readytorun.head;
  chipreg_t regs[XCPTCONTEXT_REGS];
  FAR uint32_t *regs32 = (FAR uint32_t*)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;

  board_led_on(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);
  regs32[REG_PC/2] = rtcb->xcp.saved_pc;
  regs[REG_FLAGS]  = rtcb->xcp.saved_i;

  /* Get a local copy of the sigdeliver function pointer. We do this so
   * that we can nullify the sigdeliver function point in the TCB and
   * accept more signal deliveries while processing the current pending
   * signals.
   */

  sigdeliver           = (sig_deliver_t)rtcb->xcp.sigdeliver;
  rtcb->xcp.sigdeliver = NULL;

  /* Then restore the task interrupt state. */

  if ((regs[REG_FLAGS] & Z16F_CNTRL_FLAGS_IRQE) != 0)
    {
       EI();
    }

  /* 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. */

  board_led_off(LED_SIGNAL);
  SIGNAL_RETURN(regs);
#endif
}