void hal_deliver_interrupt( cyg_uint32 vector ) { register cyg_uint32 isr_result; register cyg_isr *isr; cyg_bool pendsvc = false; #if defined(CYGPKG_KERNEL_INSTRUMENT) && \ defined(CYGDBG_KERNEL_INSTRUMENT_INTR) CYG_INSTRUMENT_INTR(RAISE, vector, 0); #endif isr = (cyg_isr *)hal_interrupt_handlers[vector]; // Call the ISR isr_result = isr( vector, hal_interrupt_data[vector] ); #if !defined(CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN) // If the ISR has returned the CALL_DSR bit, post the DSR and set // the pendable SVC exception pending. if( isr_result & CYG_ISR_CALL_DSR ) { cyg_interrupt_post_dsr( hal_interrupt_objects[vector] ); // Post the pendable SVC to call interrupt_end(). But only if // the scheduler lock is currently zero. If it is non zero // then interrupt_end will do nothing useful, so avoid calling // it. if( cyg_scheduler_sched_lock == 0 ) pendsvc = true; } #else // When chaining we don't know here whether the nested interrupt // has posted a DSR, so we have to run interrupt_end() regardless. // However, the same considerations as above regarding the // scheduler lock still apply. if( cyg_scheduler_sched_lock == 0 ) pendsvc = true; #endif // Post the pendable SVC if required. if( pendsvc ) { cyg_uint32 icsr; HAL_READ_UINT32( CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_ICSR, icsr ); icsr |= CYGARC_REG_NVIC_ICSR_PENDSVSET; HAL_WRITE_UINT32( CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_ICSR, icsr ); } }
static inline cyg_uint32 hal_call_isr (cyg_uint32 vector) { cyg_ISR *isr; CYG_ADDRWORD data; cyg_uint32 isr_ret; isr = (cyg_ISR*) hal_interrupt_handlers[vector]; data = hal_interrupt_data[vector]; isr_ret = (*isr) (vector, data); #ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT if (isr_ret & CYG_ISR_CALL_DSR) { cyg_interrupt_post_dsr (hal_interrupt_objects[vector]); } #endif return isr_ret & ~CYG_ISR_CALL_DSR; }