Mercurial > flash_v2
diff packages/kernel/current/include/intr.hxx @ 177:4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
| author | jlarmour |
|---|---|
| date | Fri, 10 Aug 2001 19:27:55 +0000 |
| parents | eb9fd8c04db3 |
| children | f62680ef1804 |
line wrap: on
line diff
--- a/packages/kernel/current/include/intr.hxx +++ b/packages/kernel/current/include/intr.hxx @@ -49,6 +49,19 @@ #include <cyg/kernel/ktypes.h> +#include <cyg/kernel/smp.hxx> + +// ------------------------------------------------------------------------- +// Default definitions + +// Some HALs define the ISR table to be a different size to the number +// of ISR vectors. These HALs will define CYGNUM_HAL_ISR_TABLE_SIZE. All +// other HALs will have the table size equal to the number of vectors. + +#ifndef CYGNUM_HAL_ISR_TABLE_SIZE +# define CYGNUM_HAL_ISR_TABLE_SIZE CYGNUM_HAL_ISR_COUNT +#endif + // ------------------------------------------------------------------------- // Function prototype typedefs @@ -154,20 +167,24 @@ class Cyg_Interrupt #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE - static Cyg_Interrupt *dsr_table[CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE]; + static Cyg_Interrupt *dsr_table[CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE] + CYGBLD_ANNOTATE_VARIABLE_INTR; - static cyg_ucount32 dsr_table_head; + static cyg_ucount32 dsr_table_head CYGBLD_ANNOTATE_VARIABLE_INTR; - static volatile cyg_ucount32 dsr_table_tail; + static volatile cyg_ucount32 dsr_table_tail CYGBLD_ANNOTATE_VARIABLE_INTR; #endif #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST - volatile cyg_ucount32 dsr_count; // Number of DSR posts made + // Number of DSR posts made + volatile cyg_ucount32 dsr_count CYGBLD_ANNOTATE_VARIABLE_INTR; - Cyg_Interrupt* volatile next_dsr; // next DSR in list - - static Cyg_Interrupt* volatile dsr_list; // static list of pending DSRs + // next DSR in list + Cyg_Interrupt* volatile next_dsr CYGBLD_ANNOTATE_VARIABLE_INTR; + + // static list of pending DSRs + static Cyg_Interrupt* volatile dsr_list CYGBLD_ANNOTATE_VARIABLE_INTR; #endif @@ -184,11 +201,45 @@ class Cyg_Interrupt static cyg_uint32 chain_isr(cyg_vector vector, CYG_ADDRWORD data); // Table of interrupt chains - static Cyg_Interrupt *chain_list[CYGNUM_HAL_ISR_COUNT]; + static Cyg_Interrupt *chain_list[CYGNUM_HAL_ISR_TABLE_SIZE]; #endif - static cyg_int32 disable_counter; // Disable level counter + // Interrupt disable data. Interrupt disable can be nested. On + // each CPU this is controlled by disable_counter[cpu]. When the + // counter is first incremented from zero to one, the + // interrupt_disable_spinlock is claimed using spin_intsave(), the + // original interrupt enable state being saved in + // interrupt_disable_state[cpu]. When the counter is decremented + // back to zero the spinlock is cleared using clear_intsave(). + + // The spinlock is necessary in SMP systems since a thread + // accessing data shared with an ISR may be scheduled on a + // different CPU to the one that handles the interrupt. So, merely + // blocking local interrupts would be ineffective. SMP aware + // device drivers should either use their own spinlocks to protect + // data, or use the API supported by this class, via + // cyg_drv_isr_lock()/_unlock(). Note that it now becomes + // essential that ISRs do this if they are to be SMP-compatible. + + // In a single CPU system, this mechanism reduces to just + // disabling/enabling interrupts. + + // Disable level counter. This counts the number of times + // interrupts have been disabled. + static volatile cyg_int32 disable_counter[CYGNUM_KERNEL_CPU_MAX] + CYGBLD_ANNOTATE_VARIABLE_INTR; + + // Interrupt disable spinlock. This is claimed by any CPU that has + // disabled interrupts via the Cyg_Interrupt API. + static Cyg_SpinLock interrupt_disable_spinlock CYGBLD_ANNOTATE_VARIABLE_INTR; + + // Saved interrupt state. When each CPU first disables interrupts + // the original state of the interrupts are saved here to be + // restored later. + static CYG_INTERRUPT_STATE interrupt_disable_state[CYGNUM_KERNEL_CPU_MAX] + CYGBLD_ANNOTATE_VARIABLE_INTR; + public: @@ -241,7 +292,7 @@ public: // Are interrupts enabled at the CPU? static inline cyg_bool interrupts_enabled() { - return (0 == disable_counter); + return (0 == disable_counter[CYG_KERNEL_CPU_THIS()]); } // Get the vector for the following calls @@ -267,7 +318,15 @@ public: cyg_bool level, // level or edge triggered cyg_bool up // hi/lo level, rising/falling edge ); + +#ifdef CYGPKG_KERNEL_SMP_SUPPORT + + // SMP support for associating an interrupt with a specific CPU. + static void set_cpu( cyg_vector, HAL_SMP_CPU_TYPE cpu ); + static HAL_SMP_CPU_TYPE get_cpu( cyg_vector ); + +#endif }; #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS
