/** * @brief Guard code for @p CH_IRQ_PROLOGUE(). * * @notapi */ void dbg_check_enter_isr(void) { port_lock_from_isr(); if ((dbg_isr_cnt < 0) || (dbg_lock_cnt != 0)) chDbgPanic("SV#8"); dbg_isr_cnt++; port_unlock_from_isr(); }
/** * @brief Guard code for @p CH_IRQ_EPILOGUE(). * * @notapi */ void _dbg_check_leave_isr(void) { port_lock_from_isr(); if ((ch.dbg_isr_cnt <= 0) || (ch.dbg_lock_cnt != 0)) chSysHalt("SV#9"); ch.dbg_isr_cnt--; port_unlock_from_isr(); }
/** * @brief Guard code for @p CH_IRQ_EPILOGUE(). * * @notapi */ void dbg_check_leave_isr(void) { port_lock_from_isr(); if ((dbg_isr_cnt <= 0) || (dbg_lock_cnt != 0)) chDbgPanic("SV#9"); dbg_isr_cnt--; port_unlock_from_isr(); }
/** * @brief Guard code for @p CH_IRQ_PROLOGUE(). * * @notapi */ void _dbg_check_enter_isr(void) { port_lock_from_isr(); if ((ch.dbg_isr_cnt < 0) || (ch.dbg_lock_cnt != 0)) chSysHalt("SV#8"); ch.dbg_isr_cnt++; port_unlock_from_isr(); }
/** * @brief Guard code for @p CH_IRQ_PROLOGUE(). * * @notapi */ void _dbg_check_enter_isr(void) { port_lock_from_isr(); if ((nil.isr_cnt < (cnt_t)0) || (nil.lock_cnt != (cnt_t)0)) { chSysHalt("SV#8"); } nil.isr_cnt++; port_unlock_from_isr(); }
/** * @brief Guard code for @p CH_IRQ_EPILOGUE(). * * @notapi */ void _dbg_check_leave_isr(void) { port_lock_from_isr(); if ((ch.dbg.isr_cnt <= (cnt_t)0) || (ch.dbg.lock_cnt != (cnt_t)0)) { chSysHalt("SV#9", __func__); } ch.dbg.isr_cnt--; port_unlock_from_isr(); }
/** * @brief Guard code for @p CH_IRQ_PROLOGUE(). * * @notapi */ void _dbg_check_enter_isr(void) { port_lock_from_isr(); if ((ch.dbg.isr_cnt < (cnt_t)0) || (ch.dbg.lock_cnt != (cnt_t)0)) { chSysHalt("SV#8", __func__); } ch.dbg.isr_cnt++; port_unlock_from_isr(); }
/** * @brief Guard code for @p CH_IRQ_EPILOGUE(). * * @notapi */ void _dbg_check_leave_isr(void) { port_lock_from_isr(); if ((nil.isr_cnt <= (cnt_t)0) || (nil.lock_cnt != (cnt_t)0)) { chSysHalt("SV#9"); } nil.isr_cnt--; port_unlock_from_isr(); }
/** * @brief Inserts in the circular debug trace buffer an ISR-leave record. * * @param[in] isr name of the isr * * @notapi */ void _trace_isr_leave(const char *isr) { if ((ch.dbg.trace_buffer.suspended & CH_DBG_TRACE_MASK_ISR) == 0U) { port_lock_from_isr(); ch.dbg.trace_buffer.ptr->type = CH_TRACE_TYPE_ISR_LEAVE; ch.dbg.trace_buffer.ptr->state = 0U; ch.dbg.trace_buffer.ptr->u.isr.name = isr; trace_next(); port_unlock_from_isr(); } }
/** * @brief Inserts in the circular debug trace buffer an ISR-enter record. * * @param[in] isr name of the isr * * @notapi */ void _dbg_trace_isr_enter(const char *isr) { if ((ch.dbg.trace_buffer.suspended & CH_TRACE_SUSPEND_ISR_ENTER) == 0U) { port_lock_from_isr(); ch.dbg.trace_buffer.ptr->type = CH_TRACE_TYPE_ISR_ENTER; ch.dbg.trace_buffer.ptr->state = 0U; ch.dbg.trace_buffer.ptr->u.isr.name = isr; trace_next(); port_unlock_from_isr(); } }
/** * @brief NMI vector. * @details The NMI vector is used for exception mode re-entering after a * context switch. */ void NMIVector(void) { register struct extctx *ctxp; register uint32_t psp __asm("psp"); /* Discarding the current exception context and positioning the stack to point to the real one.*/ ctxp = (struct extctx *)psp; ctxp++; psp = (uint32_t)ctxp; port_unlock_from_isr(); }
/** * @brief Exception exit redirection to _port_switch_from_isr(). */ void _port_irq_epilogue(void) { port_lock_from_isr(); if ((SCB->ICSR & SCB_ICSR_RETTOBASE_Msk) != 0) { /* The port_extctx structure is pointed by the PSP register.*/ struct port_extctx *ctxp = (struct port_extctx *)__get_PSP(); /* Adding an artificial exception return context, there is no need to populate it fully.*/ ctxp--; /* Writing back the modified PSP value.*/ __set_PSP((uint32_t)ctxp); /* Setting up a fake XPSR register value.*/ ctxp->xpsr = (regarm_t)0x01000000; /* The exit sequence is different depending on if a preemption is required or not.*/ if (chSchIsRescRequiredI()) { /* Preemption is required we need to enforce a context switch.*/ ctxp->pc = (regarm_t)_port_switch_from_isr; #if CORTEX_USE_FPU /* Enforcing a lazy FPU state save by accessing the FPCSR register.*/ (void) __get_FPSCR(); #endif } else { /* Preemption not required, we just need to exit the exception atomically.*/ ctxp->pc = (regarm_t)_port_exit_from_isr; } #if CORTEX_USE_FPU { uint32_t fpccr; /* Saving the special register SCB_FPCCR into the reserved offset of the Cortex-M4 exception frame.*/ (ctxp + 1)->fpccr = (regarm_t)(fpccr = FPU->FPCCR); /* Now the FPCCR is modified in order to not restore the FPU status from the artificial return context.*/ FPU->FPCCR = fpccr | FPU_FPCCR_LSPACT_Msk; } #endif /* Note, returning without unlocking is intentional, this is done in order to keep the rest of the context switch atomic.*/ return; } port_unlock_from_isr(); }
/** * @brief Exception exit redirection to _port_switch_from_isr(). */ void _port_irq_epilogue(void) { port_lock_from_isr(); if ((SCB_ICSR & ICSR_RETTOBASE) != 0) { struct extctx *ctxp; register uint32_t psp __asm("psp"); /* Current PSP value.*/ ctxp = (struct extctx *)psp; /* Adding an artificial exception return context, there is no need to populate it fully.*/ ctxp--; psp = (uint32_t)ctxp; ctxp->xpsr = (regarm_t)0x01000000; /* The exit sequence is different depending on if a preemption is required or not.*/ if (chSchIsPreemptionRequired()) { #if CORTEX_USE_FPU /* Triggering a lazy FPU state save.*/ register uint32_t fpscr __asm("fpscr"); ctxp->r0 = (regarm_t)fpscr; #endif /* Preemption is required we need to enforce a context switch.*/ ctxp->pc = (regarm_t)_port_switch_from_isr; } else { /* Preemption not required, we just need to exit the exception atomically.*/ ctxp->pc = (regarm_t)_port_exit_from_isr; } #if CORTEX_USE_FPU { uint32_t fpccr; /* Saving the special register SCB_FPCCR into the reserved offset of the Cortex-M4 exception frame.*/ (ctxp + 1)->fpccr = (regarm_t)(fpccr = SCB_FPCCR); /* Now the FPCCR is modified in order to not restore the FPU status from the artificial return context.*/ SCB_FPCCR = fpccr | FPCCR_LSPACT; } #endif /* Note, returning without unlocking is intentional, this is done in order to keep the rest of the context switch atomic.*/ return; } port_unlock_from_isr(); }
/** * @brief NMI vector. * @details The NMI vector is used for exception mode re-entering after a * context switch. */ void NMI_Handler(void) { /* The port_extctx structure is pointed by the PSP register.*/ struct port_extctx *ctxp = (struct port_extctx *)__get_PSP(); /* Discarding the current exception context and positioning the stack to point to the real one.*/ ctxp++; /* Writing back the modified PSP value.*/ __set_PSP((uint32_t)ctxp); /* Restoring the normal interrupts status.*/ port_unlock_from_isr(); }
/** * @brief Exception exit redirection to _port_switch_from_isr(). */ void _port_irq_epilogue(void) { port_lock_from_isr(); if ((SCB_ICSR & ICSR_RETTOBASE) != 0) { struct extctx *ctxp; register uint32_t psp __asm("psp"); /* Current PSP value.*/ ctxp = (struct extctx *)psp; #if CORTEX_USE_FPU /* Enforcing a lazy FPU state save. Note, it goes in the original context because the FPCAR register has not been modified.*/ { volatile register uint32_t fpscr __asm("fpscr"); (void)fpscr; } #endif /* Adding an artificial exception return context, there is no need to populate it fully.*/ ctxp--; ctxp->xpsr = (regarm_t)0x01000000; #if CORTEX_USE_FPU ctxp->fpscr = (regarm_t)SCB_FPDSCR; #endif psp = (uint32_t)ctxp; /* The exit sequence is different depending on if a preemption is required or not.*/ if (chSchIsPreemptionRequired()) { /* Preemption is required we need to enforce a context switch.*/ ctxp->pc = (regarm_t)_port_switch_from_isr; } else { /* Preemption not required, we just need to exit the exception atomically.*/ ctxp->pc = (regarm_t)_port_exit_from_isr; } /* Note, returning without unlocking is intentional, this is done in order to keep the rest of the context switch atomic.*/ return; } port_unlock_from_isr(); }
/** * @brief Exception exit redirection to _port_switch_from_isr(). */ void _port_irq_epilogue(void) { port_lock_from_isr(); if ((SCB->ICSR & SCB_ICSR_RETTOBASE_Msk) != 0) { struct port_extctx *ctxp; #if CORTEX_USE_FPU /* Enforcing a lazy FPU state save by accessing the FPCSR register.*/ (void) __get_FPSCR(); #endif /* The port_extctx structure is pointed by the PSP register.*/ ctxp = (struct port_extctx *)__get_PSP(); /* Adding an artificial exception return context, there is no need to populate it fully.*/ ctxp--; /* Setting up a fake XPSR register value.*/ ctxp->xpsr = (regarm_t)0x01000000; #if CORTEX_USE_FPU ctxp->fpscr = (regarm_t)FPU->FPDSCR; #endif /* Writing back the modified PSP value.*/ __set_PSP((uint32_t)ctxp); /* The exit sequence is different depending on if a preemption is required or not.*/ if (chSchIsPreemptionRequired()) { /* Preemption is required we need to enforce a context switch.*/ ctxp->pc = (regarm_t)_port_switch_from_isr; } else { /* Preemption not required, we just need to exit the exception atomically.*/ ctxp->pc = (regarm_t)_port_exit_from_isr; } /* Note, returning without unlocking is intentional, this is done in order to keep the rest of the context switch atomic.*/ return; } port_unlock_from_isr(); }
/** * @brief SVC vector. * @details The SVC vector is used for exception mode re-entering after a * context switch. * @note The PendSV vector is only used in advanced kernel mode. */ void SVCallVector(void) { struct extctx *ctxp; /* Current PSP value.*/ ctxp = (struct extctx *)__get_PSP(); /* Discarding the current exception context and positioning the stack to point to the real one.*/ ctxp++; #if CORTEX_USE_FPU /* Restoring the special register SCB_FPCCR.*/ SCB_FPCCR = (uint32_t)ctxp->fpccr; SCB_FPCAR = SCB_FPCAR + sizeof (struct extctx); #endif __set_PSP((unsigned long)ctxp); port_unlock_from_isr(); }
/** * @brief SVC vector. * @details The SVC vector is used for exception mode re-entering after a * context switch. * @note The PendSV vector is only used in advanced kernel mode. */ void SVCallVector(void) { struct extctx *ctxp; #if CORTEX_USE_FPU /* Enforcing unstacking of the FP part of the context.*/ SCB_FPCCR &= ~FPCCR_LSPACT; #endif /* Current PSP value.*/ ctxp = (struct extctx *)__get_PSP(); /* Discarding the current exception context and positioning the stack to point to the real one.*/ ctxp++; /* Restoring real position of the original stack frame.*/ __set_PSP((unsigned long)ctxp); port_unlock_from_isr(); }
/** * @brief SVC vector. * @details The SVC vector is used for exception mode re-entering after a * context switch. * @note The PendSV vector is only used in advanced kernel mode. */ void SVCallVector(void) { struct extctx *ctxp; register uint32_t psp __asm("psp"); #if CORTEX_USE_FPU /* Enforcing unstacking of the FP part of the context.*/ SCB_FPCCR &= ~FPCCR_LSPACT; #endif /* Current PSP value.*/ ctxp = (struct extctx *)psp; /* Discarding the current exception context and positioning the stack to point to the real one.*/ ctxp++; /* Restoring real position of the original stack frame.*/ psp = (uint32_t)ctxp; port_unlock_from_isr(); }
/** * @brief SVC vector. * @details The SVC vector is used for exception mode re-entering after a * context switch. * @note The PendSV vector is only used in advanced kernel mode. */ void SVC_Handler(void) { struct port_extctx *ctxp; #if CORTEX_USE_FPU /* Enforcing unstacking of the FP part of the context.*/ FPU->FPCCR &= ~FPU_FPCCR_LSPACT_Msk; #endif /* The port_extctx structure is pointed by the PSP register.*/ ctxp = (struct port_extctx *)__get_PSP(); /* Discarding the current exception context and positioning the stack to point to the real one.*/ ctxp++; /* Restoring real position of the original stack frame.*/ __set_PSP((uint32_t)ctxp); /* Restoring the normal interrupts status.*/ port_unlock_from_isr(); }
/** * @brief SVC vector. * @details The SVC vector is used for exception mode re-entering after a * context switch. * @note The PendSV vector is only used in advanced kernel mode. */ void SVC_Handler(void) { /* The port_extctx structure is pointed by the PSP register.*/ struct port_extctx *ctxp = (struct port_extctx *)__get_PSP(); /* Discarding the current exception context and positioning the stack to point to the real one.*/ ctxp++; #if CORTEX_USE_FPU /* Restoring the special register FPCCR.*/ FPU->FPCCR = (uint32_t)ctxp->fpccr; FPU->FPCAR = FPU->FPCAR + sizeof (struct port_extctx); #endif /* Writing back the modified PSP value.*/ __set_PSP((uint32_t)ctxp); /* Restoring the normal interrupts status.*/ port_unlock_from_isr(); }