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