static int kinetis_busfault(int irq, FAR void *context) { (void)up_irq_save(); _err("PANIC!!! Bus fault recived\n"); PANIC(); return 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(); }
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; }
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(); }
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 */ }
static int sam_pendsv(int irq, FAR void *context) { (void)up_irq_save(); _err("PANIC!!! PendSV received\n"); PANIC(); return 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; }
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); } }
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; }
static int lpc43_usagefault(int irq, FAR void *context) { (void)up_irq_save(); dbg("PANIC!!! Usage fault received\n"); PANIC(); return 0; }
static int lpc43_dbgmonitor(int irq, FAR void *context) { (void)up_irq_save(); dbg("PANIC!!! Debug Monitor received\n"); PANIC(); return 0; }
static int lpc43_nmi(int irq, FAR void *context) { (void)up_irq_save(); dbg("PANIC!!! NMI received\n"); PANIC(); return 0; }
static int sam_reserved(int irq, FAR void *context) { (void)up_irq_save(); _err("PANIC!!! Reserved interrupt\n"); PANIC(); return 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; }
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; }
static int sam_nmi(int irq, FAR void *context) { (void)up_irq_save(); _err("PANIC!!! NMI received\n"); PANIC(); return 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 }
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(); }
/* 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(); }
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 */ }
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); } }
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); } }
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 */ }
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); }
unsigned int metal_irq_save_disable(void) { return up_irq_save(); }
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(); }