void sparc_ex_main( void ) { int i; CYG_TEST_INIT(); for ( i = CYGNUM_HAL_EXCEPTION_MIN; i <= CYGNUM_HAL_EXCEPTION_MAX; i++ ){ int j; HAL_TRANSLATE_VECTOR( i, j ); HAL_INTERRUPT_ATTACH( j, &fail_exception_handler, j, 0 ); // we must also ensure that eCos handles the exception; // do not drop into CygMon or equivalent. // Leave USER_TRAP undisturbed so that breakpoints work. if ( CYGNUM_HAL_VECTOR_USER_TRAP != i ) { extern void hal_default_exception_vsr( void ); HAL_VSR_SET( i, (CYG_ADDRESS)hal_default_exception_vsr, NULL ); } } HAL_TRANSLATE_VECTOR( CYGNUM_HAL_VECTOR_UNALIGNED, i ); HAL_INTERRUPT_DETACH( i, &fail_exception_handler ); HAL_INTERRUPT_ATTACH( i, &skip_exception_handler, i, 0 ); CYG_TEST_INFO( "Vectors attached OK; calling do_test" ); do_test(); CYG_TEST_EXIT( "Done" ); }
externC void cyg_drv_interrupt_attach( cyg_handle_t interrupt ) { cyg_interrupt *intr = (cyg_interrupt *)interrupt; CYG_REPORT_FUNCTION(); CYG_ASSERT( intr->vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector"); CYG_ASSERT( intr->vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector"); HAL_INTERRUPT_SET_LEVEL( intr->vector, intr->priority ); #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN CYG_ASSERT( intr->next == NULL , "cyg_interrupt already on a list"); { cyg_uint32 index; HAL_TRANSLATE_VECTOR( intr->vector, index ); if( chain_list[index] == NULL ) { // First Interrupt on this chain, just assign it and // register the chain_isr with the HAL. chain_list[index] = intr; HAL_INTERRUPT_ATTACH( intr->vector, chain_isr, &chain_list[index], NULL ); } else { // There are already interrupts chained, add this one into // the chain in priority order. cyg_interrupt **p = &chain_list[index]; while( *p != NULL ) { cyg_interrupt *n = *p; if( n->priority < intr->priority ) break; p = &n->next; } intr->next = *p; *p = intr; } } #else HAL_INTERRUPT_ATTACH( intr->vector, intr->isr, intr->data, intr ); #endif CYG_REPORT_RETURN(); }
// Update mask table and interrupt controller void hal_interrupt_unmask(int vector) { cyg_uint32 index; CYG_ASSERT((CYGNUM_HAL_ISR_MIN <= (vector) && CYGNUM_HAL_ISR_MAX >= (vector)), "Illegal vector"); HAL_TRANSLATE_VECTOR(vector, index); cyg_hal_IMASK_table[index] = 1; hal_update_interrupt_controller(vector); }
// Update priority table and interrupt controller void hal_interrupt_set_level(int vector, int level) { cyg_uint32 index; CYG_ASSERT((0 <= (level) && 7 >= (level)), "Illegal level"); CYG_ASSERT((CYGNUM_HAL_ISR_MIN <= (vector) && CYGNUM_HAL_ISR_MAX >= (vector)), "Illegal vector"); HAL_TRANSLATE_VECTOR(vector, index); cyg_hal_ILVL_table[index] = (cyg_uint8) level; hal_update_interrupt_controller(vector); }
externC void cyg_drv_interrupt_detach( cyg_handle_t interrupt ) { cyg_interrupt *intr = (cyg_interrupt *)interrupt; CYG_REPORT_FUNCTION(); CYG_ASSERT( intr->vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector"); CYG_ASSERT( intr->vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector"); #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN // Remove the interrupt object from the vector chain. { cyg_uint32 index; cyg_interrupt **p; HAL_TRANSLATE_VECTOR( intr->vector, index ); p = &chain_list[index]; while( *p != NULL ) { cyg_interrupt *n = *p; if( n == intr ) { *p = intr->next; break; } p = &n->next; } // If this was the last one, detach the vector. if( chain_list[index] == NULL ) HAL_INTERRUPT_DETACH( intr->vector, chain_isr ); } #else HAL_INTERRUPT_DETACH( intr->vector, intr->isr ); #endif CYG_REPORT_RETURN(); }
// Set the priority in the interrupt control register. // Disable all interrupts while we access the hardware registers. static void hal_update_interrupt_controller(int vector) { cyg_uint32 index; cyg_uint8 level; cyg_uint32 vec_offset; cyg_uint32 icr, icr_msk_offset, icr_msk, icr_val, icr_oldval; CYG_INTERRUPT_STATE intr_state; HAL_TRANSLATE_VECTOR(vector, index); level = cyg_hal_IMASK_table[index] ? cyg_hal_ILVL_table[index] : 0; vec_offset = (vector) - HAL_PROG_INT_VEC_BASE - 1; icr = vec_offset / 8; icr_msk_offset = ((8-1)*4) - (vec_offset % 8) * 4; icr_msk = 0x0F << (icr_msk_offset); icr_val = (0x08 | (level & 0x07)) << icr_msk_offset; HAL_DISABLE_INTERRUPTS(intr_state); HAL_READ_UINT32(&MCF5272_DEVS->intc.icr[icr], icr_oldval); icr_val |= icr_oldval & 0x77777777 & ~icr_msk; HAL_WRITE_UINT32(&MCF5272_DEVS->intc.icr[icr], icr_val); HAL_RESTORE_INTERRUPTS(intr_state); }