Beispiel #1
0
static int kinetis_busfault(int irq, FAR void *context)
{
  (void)up_irq_save();
  _err("PANIC!!! Bus fault recived\n");
  PANIC();
  return 0;
}
Beispiel #2
0
void _exit(int status)
{
    struct tcb_s *tcb;

    /* Disable interrupts.  They will be restored when the next task is
     * started.
     */

    (void)up_irq_save();

    sinfo("TCB=%p exiting\n", this_task());

#ifdef CONFIG_DUMP_ON_EXIT
    sinfo("Other tasks:\n");
    sched_foreach(_xtensa_dumponexit, NULL);
#endif

#if XCHAL_CP_NUM > 0
    /* Disable co-processor support for the task that is exit-ing. */

    tcb = this_task();
    xtensa_coproc_disable(&tcb->xcp.cpstate, XTENSA_CP_ALLSET);
#endif

    /* Destroy the task at the head of the ready to run list. */

    (void)task_exit();

    /* Now, perform the context switch to the new ready-to-run task at the
     * head of the list.
     */

    tcb = this_task();

#if XCHAL_CP_NUM > 0
    /* Set up the co-processor state for the newly started thread. */

    xtensa_coproc_restorestate(&tcb->xcp.cpstate);
#endif

#ifdef CONFIG_ARCH_ADDRENV
    /* Make sure that the address environment for the previously running
     * task is closed down gracefully (data caches dump, MMU flushed) and
     * set up the address environment for the new thread at the head of
     * the ready-to-run list.
     */

    (void)group_addrenv(tcb);
#endif

    /* Then switch contexts */

    xtensa_context_restore(tcb->xcp.regs);

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

    PANIC();
}
Beispiel #3
0
static int xmc4_usagefault(int irq, FAR void *context, FAR void *arg)
{
  (void)up_irq_save();
  _err("PANIC!!! Usage fault received\n");
  PANIC();
  return 0;
}
Beispiel #4
0
irqstate_t enter_critical_section(void)
{
  FAR struct tcb_s *rtcb;

  /* Do nothing if called from an interrupt handler */

  if (up_interrupt_context())
    {
      /* The value returned does not matter.  We assume only that it is a
       * scalar here.
       */

      return (irqstate_t)0;
    }

  /* Do we already have interrupts disabled? */

  rtcb = this_task();
  DEBUGASSERT(rtcb != NULL);

  if (rtcb->irqcount > 0)
    {
      /* Yes... make sure that the spinlock is set and increment the IRQ
       * lock count.
       */

      DEBUGASSERT(g_cpu_irqlock == SP_LOCKED && rtcb->irqcount < INT16_MAX);
      rtcb->irqcount++;
    }
  else
    {
      /* NO.. Take the spinlock to get exclusive access and set the lock
       * count to 1.
       *
       * We must avoid that case where a context occurs between taking the
       * g_cpu_irqlock and disabling interrupts.  Also interrupts disables
       * must follow a stacked order.  We cannot other context switches to
       * re-order the enabling/disabling of interrupts.
       *
       * The scheduler accomplishes this by treating the irqcount like
       * lockcount:  Both will disable pre-emption.
       */

      spin_setbit(&g_cpu_irqset, this_cpu(), &g_cpu_irqsetlock,
                  &g_cpu_irqlock);
      rtcb->irqcount = 1;

#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
      /* Note that we have entered the critical section */

      sched_note_csection(rtcb, true);
#endif
    }

  /* Then disable interrupts (they may already be disabled, be we need to
   * return valid interrupt status in any event).
   */

  return up_irq_save();
}
Beispiel #5
0
int irq_unexpected_isr(int irq, FAR void *context)
{
  (void)up_irq_save();
  lldbg("irq: %d\n", irq);
  PANIC();
  return OK; /* Won't get here */
}
Beispiel #6
0
static int sam_pendsv(int irq, FAR void *context)
{
  (void)up_irq_save();
  _err("PANIC!!! PendSV received\n");
  PANIC();
  return 0;
}
Beispiel #7
0
static int stm32_dbgmonitor(int irq, FAR void *context, FAR void *arg)
{
  (void)up_irq_save();
  _err("PANIC!!! Debug Monitor received\n");
  PANIC();
  return 0;
}
Beispiel #8
0
static void _up_assert(int errorcode)
{
  /* Flush any buffered SYSLOG data */

  (void)syslog_flush();

  /* Are we in an interrupt handler or the idle task? */

  if (g_current_regs || this_task()->pid == 0)
    {
       (void)up_irq_save();
        for (; ; )
          {
#if CONFIG_BOARD_RESET_ON_ASSERT >= 1
            board_reset(0);
#endif
#ifdef CONFIG_ARCH_LEDS
            board_autoled_on(LED_PANIC);
            up_mdelay(250);
            board_autoled_off(LED_PANIC);
            up_mdelay(250);
#endif
          }
    }
  else
    {
#if CONFIG_BOARD_RESET_ON_ASSERT >= 2
      board_reset(0);
#endif
      exit(errorcode);
    }
}
Beispiel #9
0
static int lpc43_busfault(int irq, FAR void *context, FAR void *arg)
{
  (void)up_irq_save();
  _err("PANIC!!! Bus fault recived\n");
  PANIC();
  return 0;
}
Beispiel #10
0
static int lpc43_usagefault(int irq, FAR void *context)
{
  (void)up_irq_save();
  dbg("PANIC!!! Usage fault received\n");
  PANIC();
  return 0;
}
Beispiel #11
0
static int lpc43_dbgmonitor(int irq, FAR void *context)
{
  (void)up_irq_save();
  dbg("PANIC!!! Debug Monitor received\n");
  PANIC();
  return 0;
}
Beispiel #12
0
static int lpc43_nmi(int irq, FAR void *context)
{
  (void)up_irq_save();
  dbg("PANIC!!! NMI received\n");
  PANIC();
  return 0;
}
Beispiel #13
0
static int sam_reserved(int irq, FAR void *context)
{
  (void)up_irq_save();
  _err("PANIC!!! Reserved interrupt\n");
  PANIC();
  return 0;
}
Beispiel #14
0
static int sam_busfault(int irq, FAR void *context)
{
  (void)up_irq_save();
  _err("PANIC!!! Bus fault received: %08x\n", getreg32(NVIC_CFAULTS));
  PANIC();
  return 0;
}
Beispiel #15
0
static int stm32_usagefault(int irq, FAR void *context, FAR void *arg)
{
  (void)up_irq_save();
  _err("PANIC!!! Usage fault received: %08x\n", getreg32(NVIC_CFAULTS));
  PANIC();
  return 0;
}
Beispiel #16
0
static int sam_nmi(int irq, FAR void *context)
{
  (void)up_irq_save();
  _err("PANIC!!! NMI received\n");
  PANIC();
  return 0;
}
Beispiel #17
0
void up_sigdeliver(void)
{
#ifndef CONFIG_DISABLE_SIGNALS
  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_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. */

  up_irq_restore(regs[REG_SR] & 0x000000f0);

  /* 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\n");
  (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);
#endif
}
Beispiel #18
0
void _exit(int status)
{
  struct tcb_s *tcb;

  /* Disable interrupts.  They will be restored when the next
   * task is started.
   */

  (void)up_irq_save();

  sinfo("TCB=%p exiting\n", this_task());

#ifdef CONFIG_DUMP_ON_EXIT
  sinfo("Other tasks:\n");
  sched_foreach(_up_dumponexit, NULL);
#endif

  /* Destroy the task at the head of the ready to run list. */

  (void)task_exit();

  /* Now, perform the context switch to the new ready-to-run task at the
   * head of the list.
   */

  tcb = this_task();

#ifdef CONFIG_ARCH_ADDRENV
  /* Make sure that the address environment for the previously running
   * task is closed down gracefully (data caches dump, MMU flushed) and
   * set up the address environment for the new thread at the head of
   * the ready-to-run list.
   */

  (void)group_addrenv(tcb);
#endif

  /* Then switch contexts */

  up_fullcontextrestore(tcb->xcp.regs);

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

  PANIC();
}
Beispiel #19
0
  /* Then disable interrupts (they may already be disabled, be we need to
   * return valid interrupt status in any event).
   */

  return up_irq_save();
}
#else /* defined(CONFIG_SCHED_INSTRUMENTATION_CSECTION) */
irqstate_t enter_critical_section(void)
{
  /* Check if we were called from an interrupt handler */

  if (!up_interrupt_context())
    {
      FAR struct tcb_s *rtcb = this_task();
      DEBUGASSERT(rtcb != NULL);

      /* No.. note that we have entered the critical section */

      sched_note_csection(rtcb, true);
    }

  /* And disable interrupts */

  return up_irq_save();
}
Beispiel #20
0
int up_memfault(int irq, FAR void *context, FAR void *arg)
{
  /* Dump some memory management fault info */

  (void)up_irq_save();
  _alert("PANIC!!! Memory Management Fault:\n");
  mfinfo("  IRQ: %d context: %p\n", irq, regs);
  _alert("  CFAULTS: %08x MMFAR: %08x\n",
        getreg32(NVIC_CFAULTS), getreg32(NVIC_MEMMANAGE_ADDR));
  mfinfo("  BASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n",
         getbasepri(), getprimask(), getipsr(), getcontrol());
  mfinfo("  R0: %08x %08x %08x %08x %08x %08x %08x %08x\n",
         regs[REG_R0],  regs[REG_R1],  regs[REG_R2],  regs[REG_R3],
         regs[REG_R4],  regs[REG_R5],  regs[REG_R6],  regs[REG_R7]);
  mfinfo("  R8: %08x %08x %08x %08x %08x %08x %08x %08x\n",
         regs[REG_R8],  regs[REG_R9],  regs[REG_R10], regs[REG_R11],
         regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]);

#ifdef CONFIG_ARMV7M_USEBASEPRI
#  ifdef REG_EXC_RETURN
  mfinfo("  xPSR: %08x BASEPRI: %08x EXC_RETURN: %08x (saved)\n",
         CURRENT_REGS[REG_XPSR],  CURRENT_REGS[REG_BASEPRI],
         CURRENT_REGS[REG_EXC_RETURN]);
#  else
  mfinfo("  xPSR: %08x BASEPRI: %08x (saved)\n",
         CURRENT_REGS[REG_XPSR],  CURRENT_REGS[REG_BASEPRI]);
#  endif
#else
#  ifdef REG_EXC_RETURN
  mfinfo("  xPSR: %08x PRIMASK: %08x EXC_RETURN: %08x (saved)\n",
         CURRENT_REGS[REG_XPSR],  CURRENT_REGS[REG_PRIMASK],
         CURRENT_REGS[REG_EXC_RETURN]);
#  else
  mfinfo("  xPSR: %08x PRIMASK: %08x (saved)\n",
         CURRENT_REGS[REG_XPSR],  CURRENT_REGS[REG_PRIMASK]);
#  endif
#endif

  PANIC();
  return OK; /* Won't get here */
}
Beispiel #21
0
static void _up_assert(int errorcode) /* noreturn_function */
{
  /* Are we in an interrupt handler or the idle task? */

  if (up_interrupt_context() || this_task()->pid == 0)
    {
       (void)up_irq_save();
        for (;;)
          {
#ifdef CONFIG_ARCH_LEDS
            board_autoled_on(LED_PANIC);
            up_mdelay(250);
            board_autoled_off(LED_PANIC);
            up_mdelay(250);
#endif
          }
    }
  else
    {
      exit(errorcode);
    }
}
Beispiel #22
0
static void _up_assert(int errorcode)
{
  /* Are we in an interrupt handler or the idle task? */

  if (g_current_regs || this_task()->pid == 0)
    {
      (void)up_irq_save();
      for (; ; )
        {
#ifdef CONFIG_ARCH_LEDS
          board_autoled_on(LED_PANIC);
          up_mdelay(250);
          board_autoled_off(LED_PANIC);
          up_mdelay(250);
#endif
        }
    }
  else
    {
      exit(errorcode);
    }
}
Beispiel #23
0
int dram_main(int argc, char *argv)
{
  /* Here we have a in memory value we can change in the debugger
   * to begin booting in NOR Flash
   */

  static volatile uint32_t wait = DRAM_BOOT_MODE;
  int ret;

  /* Disable the PMC.  This is necessary on the SAMA5D4-MB Rev C. board.  On
   * that board, the PMIC can lock up the I2C bus.  The work around is
   * awkward:
   *
   *   1. Open JP23 (disabling the WM8904 data line)
   *   2. Execute DRAMBOOT.  The WM8904 will be disabled while JP23 is open.
   *   3. At the prompt to "Send the Intel HEX file now", close JP23,
   *      enabling the WM8904.
   *   4. Send the NuttX file.  When NuttX starts, the WM8904 is initialized,
   *      JP23 will be closed and the PMIC will be initialized.
   */

  sam_pmic_initialize();

  /* DRAM was already initialized at boot time, so we are ready to load the
   * Intel HEX stream into DRAM.
   *
   * Hmm.. With no hardware handshake, there is a possibility of data loss
   * to overrunning incoming data buffer.  So far I have not seen this at
   * 115200 8N1, but still it is a possibility.
   */

  printf("Send Intel HEX file now\n");
  fflush(stdout);

  ret = hex2mem(0,                           /* Accept Intel HEX on stdin */
                (uint32_t)SAM_DDRCS_VSECTION,
                (uint32_t)(SAM_DDRCS_VSECTION + CONFIG_SAMA5_DDRCS_SIZE),
                0);
  if (ret < 0)
    {
      /* We failed the load */

      printf("ERROR: Intel HEX file load failed: %d\n", ret);
      fflush(stdout);
      for(;;);
    }

  /* No success indication.. The following cache/MMU operations will clobber
   * any I/O that we attempt (Hmm.. unless, perhaps, if we delayed.  But who
   * wants a delay?).
   */

  /* Flush the entire data cache assure that everything is in memory before
   * we disable caching.
   */

  arch_clean_dcache((uintptr_t)SAM_DDRCS_VSECTION,
                    (uintptr_t)(SAM_DDRCS_VSECTION + CONFIG_SAMA5_DDRCS_SIZE));

  /* Interrupts must be disabled through the following.  In this configuration,
   * there should only be timer interrupts.  Your NuttX configuration must use
   * CONFIG_SERIAL_LOWCONSOLE=y or printf() will hang when the interrupts
   * are disabled!
   */

  (void)up_irq_save();

  /* Disable the caches and the MMU.  Disabling the MMU should be safe here
   * because there is a 1-to-1 identity mapping between the physical and
   * virtual addressing.
   */

  cp15_disable_mmu();
  cp15_disable_caches();

  /* Invalidate caches and TLBs */

  cp15_invalidate_icache();
  cp15_invalidate_dcache_all();
  cp15_invalidate_tlbs();

  /* Then jump into NOR flash */

  while (wait)
    {
    }

  DRAM_ENTRY();

  return 0; /* We should not get here in either case */
}
Beispiel #24
0
void up_sigdeliver(void)
{
  struct tcb_s *rtcb = this_task();
#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;

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

  up_irq_restore(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)up_irq_save();
  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.
   */

  board_autoled_off(LED_SIGNAL);
  up_fullcontextrestore(regs);
}
Beispiel #25
0
unsigned int metal_irq_save_disable(void)
{
	return up_irq_save();
}
Beispiel #26
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();
}