Mercurial > flash_v2
annotate packages/kernel/current/include/intr.hxx @ 46:797268ecc331 ecos-sw-1999-10-19
Merge from eCos master repository on 1999-10-19-18:55:31-BST
| author | jlarmour |
|---|---|
| date | Tue, 19 Oct 1999 19:19:52 +0000 |
| parents | ece80412419a |
| children | c38311975d4f |
| rev | line source |
|---|---|
| 0 | 1 #ifndef CYGONCE_KERNEL_INTR_HXX |
| 2 #define CYGONCE_KERNEL_INTR_HXX | |
| 3 | |
| 4 //========================================================================== | |
| 5 // | |
| 2 | 6 // intr.hxx |
| 0 | 7 // |
| 2 | 8 // Interrupt class declaration(s) |
| 0 | 9 // |
| 10 //========================================================================== | |
| 11 //####COPYRIGHTBEGIN#### | |
| 12 // | |
| 13 // ------------------------------------------- | |
| 14 // The contents of this file are subject to the Cygnus eCos Public License | |
| 15 // Version 1.0 (the "License"); you may not use this file except in | |
| 16 // compliance with the License. You may obtain a copy of the License at | |
| 17 // http://sourceware.cygnus.com/ecos | |
| 18 // | |
| 19 // Software distributed under the License is distributed on an "AS IS" | |
| 20 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the | |
| 21 // License for the specific language governing rights and limitations under | |
| 22 // the License. | |
| 23 // | |
| 24 // The Original Code is eCos - Embedded Cygnus Operating System, released | |
| 25 // September 30, 1998. | |
| 26 // | |
| 27 // The Initial Developer of the Original Code is Cygnus. Portions created | |
| 2 | 28 // by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. |
| 0 | 29 // ------------------------------------------- |
| 30 // | |
| 31 //####COPYRIGHTEND#### | |
| 32 //========================================================================== | |
| 33 //#####DESCRIPTIONBEGIN#### | |
| 34 // | |
| 2 | 35 // Author(s): nickg |
| 36 // Contributors: nickg | |
| 37 // Date: 1997-09-09 | |
| 38 // Purpose: Define Interrupt class interfaces | |
| 39 // Description: The classes defined here provide the APIs for handling | |
| 0 | 40 // interrupts. |
| 41 // Usage: #include "intr.hxx" | |
| 2 | 42 // |
| 0 | 43 // |
| 44 //####DESCRIPTIONEND#### | |
| 45 // | |
| 46 //========================================================================== | |
| 47 | |
| 48 #include <cyg/kernel/ktypes.h> | |
| 49 | |
| 50 // ------------------------------------------------------------------------- | |
| 51 // Function prototype typedefs | |
| 52 | |
| 53 | |
| 54 // VSR = Vector Service Routine. This is the code attached directly to an | |
| 55 // interrupt vector. It is very architecture/platform specific and usually | |
| 56 // must be written in assembler. | |
| 57 | |
| 58 typedef void cyg_VSR(); | |
| 59 | |
| 60 // ISR = Interrupt Service Routine. This is called from the default | |
| 61 // VSR in response to an interrupt. It may access shared data but may | |
| 62 // not call kernel routines. The return value may be | |
| 63 // Cyg_Interrupt::HANDLED and/or Cyg_Interrupt::CALL_DSR. | |
| 64 | |
| 65 typedef cyg_uint32 cyg_ISR(cyg_vector vector, CYG_ADDRWORD data); | |
| 66 | |
| 67 // DSR = Deferred Service Routine. This is called if the ISR returns | |
| 68 // the Cyg_Interrupt::CALL_DSR bit. It is called at a "safe" point in | |
| 69 // the kernel where it may make calls on kernel routines. The count | |
| 70 // argument indicates how many times the ISR has asked for the DSR to | |
| 71 // be posted since the last time the DSR ran. | |
| 72 | |
| 73 typedef void cyg_DSR(cyg_vector vector, cyg_ucount32 count, CYG_ADDRWORD data); | |
| 74 | |
| 75 // ------------------------------------------------------------------------- | |
| 76 // Include HAL definitions | |
| 77 | |
| 78 class Cyg_Interrupt; | |
| 79 | |
| 80 #include <cyg/hal/hal_arch.h> | |
| 81 | |
| 82 #include <cyg/hal/hal_intr.h> | |
| 83 | |
|
8
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
2
diff
changeset
|
84 #ifndef HAL_INTERRUPT_STACK_CALL_PENDING_DSRS |
|
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
2
diff
changeset
|
85 #define HAL_INTERRUPT_STACK_CALL_PENDING_DSRS() \ |
|
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
2
diff
changeset
|
86 Cyg_Interrupt::call_pending_DSRs_inner() |
|
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
2
diff
changeset
|
87 #endif |
|
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
2
diff
changeset
|
88 |
| 0 | 89 externC void interrupt_end( |
| 90 cyg_uint32 isr_ret, | |
| 91 Cyg_Interrupt *intr, | |
| 92 HAL_SavedRegisters *ctx | |
| 93 ); | |
| 94 | |
| 2 | 95 externC void cyg_interrupt_post_dsr( CYG_ADDRWORD intr_obj ); |
| 96 externC void cyg_interrupt_call_pending_DSRs( void ); | |
| 97 | |
| 0 | 98 // ------------------------------------------------------------------------- |
| 99 // Interrupt class. This both represents each interrupt and provides a static | |
| 100 // interface for controlling the interrupt hardware. | |
| 101 | |
| 102 class Cyg_Interrupt | |
| 103 { | |
| 104 | |
| 105 friend class Cyg_Scheduler; | |
| 106 friend void interrupt_end( cyg_uint32, | |
| 107 Cyg_Interrupt *, | |
| 108 HAL_SavedRegisters *); | |
| 2 | 109 friend void cyg_interrupt_post_dsr( CYG_ADDRWORD intr_obj ); |
| 110 friend void cyg_interrupt_call_pending_DSRs( void ); | |
| 0 | 111 |
| 112 cyg_vector vector; // Interrupt vector | |
| 113 | |
| 114 cyg_priority priority; // Queuing priority | |
| 115 | |
| 116 cyg_ISR *isr; // Pointer to ISR | |
| 117 | |
| 118 cyg_DSR *dsr; // Pointer to DSR | |
| 119 | |
| 120 CYG_ADDRWORD data; // Data pointer | |
| 121 | |
| 122 | |
| 123 | |
| 124 // DSR handling interface called by the scheduler | |
| 125 | |
| 126 // Check for pending DSRs | |
| 127 static cyg_bool DSRs_pending(); | |
| 128 | |
| 129 // Call any pending DSRs | |
| 130 static void call_pending_DSRs(); | |
| 2 | 131 static void call_pending_DSRs_inner(); |
| 132 | |
| 133 // DSR handling interface called by the scheduler and HAL | |
| 134 // interrupt arbiters. | |
| 0 | 135 |
| 136 void post_dsr(); // Post the DSR for this interrupt | |
| 2 | 137 |
| 138 | |
| 0 | 139 |
| 140 // Data structures for handling DSR calls. We implement two DSR | |
| 141 // handling mechanisms, a list based one and a table based | |
| 142 // one. The list based mechanism is safe with respect to temporary | |
| 143 // overloads and will not run out of resource. However it requires | |
| 144 // extra data per interrupt object, and interrupts must be turned | |
| 145 // off briefly when delivering the DSR. The table based mechanism | |
| 146 // does not need unnecessary interrupt switching, but may be prone | |
| 147 // to overflow on overload. However, since a correctly programmed | |
| 148 // real time application should not experience such a condition, | |
| 149 // the table based mechanism is more efficient for real use. The | |
| 150 // list based mechainsm is enabled by default since it is safer to | |
| 151 // use during development. | |
| 152 | |
| 153 #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE | |
| 154 | |
| 155 static Cyg_Interrupt *dsr_table[CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE]; | |
| 156 | |
| 157 static cyg_ucount32 dsr_table_head; | |
| 158 | |
| 159 static cyg_ucount32 dsr_table_tail; | |
| 160 | |
| 161 #endif | |
| 162 #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST | |
| 163 | |
| 164 cyg_ucount32 dsr_count; // Number of DSR posts made | |
| 165 | |
| 166 Cyg_Interrupt *next_dsr; // next DSR in list | |
| 167 | |
| 168 static Cyg_Interrupt *dsr_list; // static list of pending DSRs | |
| 169 | |
| 170 #endif | |
| 171 | |
| 172 #ifdef CYGIMP_KERNEL_INTERRUPTS_CHAIN | |
| 173 | |
| 174 // The default mechanism for handling interrupts is to attach just | |
| 175 // one Interrupt object to each vector. In some cases, and on some | |
| 176 // hardware, this is not possible, and each vector must carry a chain | |
| 177 // of interrupts. | |
| 178 | |
| 179 Cyg_Interrupt *next; // Next Interrupt in list | |
| 180 | |
| 181 // Chaining ISR inserted in HAL vector | |
| 182 static cyg_uint32 chain_isr(cyg_vector vector, CYG_ADDRWORD data); | |
| 183 | |
| 184 // Table of interrupt chains | |
| 2 | 185 static Cyg_Interrupt *chain_list[CYGNUM_HAL_ISR_COUNT]; |
| 0 | 186 |
| 187 #endif | |
| 2 | 188 |
| 189 static cyg_int32 disable_counter; // Disable level counter | |
| 0 | 190 |
| 191 public: | |
| 192 | |
| 193 Cyg_Interrupt // Initialize interrupt | |
| 194 ( | |
| 195 cyg_vector vector, // Vector to attach to | |
| 196 cyg_priority priority, // Queue priority | |
| 197 CYG_ADDRWORD data, // Data pointer | |
| 198 cyg_ISR *isr, // Interrupt Service Routine | |
| 199 cyg_DSR *dsr // Deferred Service Routine | |
| 200 ); | |
| 201 | |
| 202 ~Cyg_Interrupt(); | |
| 203 | |
| 204 // ISR return values | |
| 205 enum { | |
| 206 HANDLED = 1, // Interrupt was handled | |
| 207 CALL_DSR = 2 // Schedule DSR | |
| 208 }; | |
| 209 | |
| 210 // Interrupt management | |
| 211 | |
| 212 void attach(); // Attach to vector | |
| 213 | |
| 214 | |
| 215 void detach(); // Detach from vector | |
| 216 | |
| 217 | |
| 218 // Static Interrupt management functions | |
| 219 | |
| 220 // Get the current service routine | |
| 221 static void get_vsr(cyg_vector vector, cyg_VSR **vsr); | |
| 222 | |
| 223 // Install a vector service routine | |
| 224 static void set_vsr( | |
| 225 cyg_vector vector, // hardware vector to replace | |
| 226 cyg_VSR *vsr, // my new service routine | |
| 227 cyg_VSR **old = NULL // pointer to old vsr, if required | |
| 228 ); | |
| 229 | |
| 230 | |
| 231 // Static interrupt masking functions | |
| 232 | |
| 233 // Disable interrupts at the CPU | |
| 234 static void disable_interrupts(); | |
| 235 | |
| 236 // Re-enable CPU interrupts | |
| 237 static void enable_interrupts(); | |
| 238 | |
| 239 // Are interrupts enabled at the CPU? | |
| 240 static inline cyg_bool interrupts_enabled() | |
| 241 { | |
| 2 | 242 return (0 == disable_counter); |
| 0 | 243 } |
| 244 | |
| 245 // Get the vector for the following calls | |
| 246 inline cyg_vector get_vector() | |
| 247 { | |
| 248 return vector; | |
| 249 } | |
| 250 | |
| 251 // Static PIC control functions | |
| 252 | |
| 253 // Mask a specific interrupt in a PIC | |
| 254 static void mask_interrupt(cyg_vector vector); | |
| 255 | |
| 256 // Clear PIC mask | |
| 257 static void unmask_interrupt(cyg_vector vector); | |
| 258 | |
| 259 // Acknowledge interrupt at PIC | |
| 260 static void acknowledge_interrupt(cyg_vector vector); | |
| 261 | |
| 262 // Change interrupt detection at PIC | |
| 263 static void configure_interrupt( | |
| 264 cyg_vector vector, // vector to control | |
| 265 cyg_bool level, // level or edge triggered | |
| 266 cyg_bool up // hi/lo level, rising/falling edge | |
| 267 ); | |
| 268 | |
| 269 }; | |
| 270 | |
| 271 #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS | |
| 272 // ------------------------------------------------------------------------- | |
| 273 // Check for pending DSRs | |
| 274 | |
| 275 inline cyg_bool Cyg_Interrupt::DSRs_pending() | |
| 276 { | |
| 277 #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE | |
| 278 | |
| 279 return dsr_table_head != dsr_table_tail; | |
| 280 | |
| 281 #endif | |
| 282 #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST | |
| 283 | |
| 284 return dsr_list != NULL; | |
| 285 | |
| 286 #endif | |
| 287 }; | |
| 288 #endif // CYGIMP_KERNEL_INTERRUPTS_DSRS | |
| 289 | |
| 290 // ------------------------------------------------------------------------- | |
| 291 #endif // ifndef CYGONCE_KERNEL_INTR_HXX | |
| 292 // EOF intr.hxx |
