Пример #1
0
FAR chipreg_t *up_doirq(uint8_t irq, FAR chipreg_t *regs)
{
  up_ledon(LED_INIRQ);

#ifdef CONFIG_SUPPRESS_INTERRUPTS

  lowsyslog("Unexpected IRQ\n");
  IRQ_ENTER(regs);
  PANIC();
  return NULL; /* Won't get here */

#else
  if (irq < NR_IRQS)
    {
       DECL_SAVESTATE();

       /* Indicate that we have entered IRQ processing logic */

       IRQ_ENTER(irq, regs);

       /* Deliver the IRQ */

       irq_dispatch(irq, regs);

       /* If a context switch occurred, 'regs' will hold the new context */

       regs = IRQ_STATE();

       /* Indicate that we are no longer in interrupt processing logic */

       IRQ_LEAVE(irq);
    }

  up_ledoff(LED_INIRQ);
  return regs;
#endif
}
FAR chipreg_t *up_doirq(uint8_t irq, FAR chipreg_t *regs)
{
  board_led_on(LED_INIRQ);

#ifdef CONFIG_SUPPRESS_INTERRUPTS

  lowsyslog(LOG_ERR, "Unexpected IRQ\n");
  IRQ_ENTER(regs);
  PANIC();
  return NULL; /* Won't get here */

#else
#ifdef CONFIG_ARCH_ADDRENV
  FAR chipreg_t *newregs;
#endif

  if (irq < NR_IRQS)
    {
      DECL_SAVESTATE();

      /* Indicate that we have entered IRQ processing logic */

      IRQ_ENTER(irq, regs);

      /* Deliver the IRQ */

      irq_dispatch(irq, regs);

#ifdef CONFIG_ARCH_ADDRENV
      /* If a context switch occurred, 'newregs' will hold the new context */

      newregs = IRQ_STATE();

      if (newregs != regs)
        {
          /* Make sure that the address environment for the previously
           * running task is closed down gracefully and set up the
           * address environment for the new thread at the head of the
           * ready-to-run list.
           */

          (void)group_addrenv(NULL);
        }

      regs = newregs;

#else
      /* If a context switch occurred, 'regs' will hold the new context */

      regs = IRQ_STATE();
#endif

      /* Indicate that we are no longer in interrupt processing logic */

      IRQ_LEAVE(irq);
    }

  board_led_off(LED_INIRQ);
  return regs;
#endif
}
Пример #3
0
void up_schedule_sigaction(FAR struct tcb_s *tcb, sig_deliver_t sigdeliver)
{
  dbg("tcb=0x%p sigdeliver=0x%04x\n", tcb, (uint16_t)sigdeliver);

  /* Refuse to handle nested signal actions */

  if (tcb->xcp.sigdeliver == NULL)
    {
      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.
       */

      if (tcb == (FAR struct tcb_s*)g_readytorun.head)
        {
          /* CASE 1:  We are not in an interrupt handler and a task is
           * signalling itself for some reason.
           */

          if (!IN_INTERRUPT())
            {
              /* 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.
           */

          else
            {
              /* Set up to vector to the trampoline with interrupts disabled. */

              z80_sigsetup(tcb, sigdeliver, IRQ_STATE());

              /* And make sure that the saved context in the TCB
               * is the same as the interrupt return context.
               */

              SAVE_IRQCONTEXT(tcb);
            }
        }

      /* 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
        {
          /* Set up to vector to the trampoline with interrupts disabled. */

          z80_sigsetup(tcb, sigdeliver, tcb->xcp.regs);
        }

      irqrestore(flags);
    }
}