Mercurial > nand-ecoscentric
annotate packages/kernel/current/include/intr.hxx @ 2266:13625e7b9d1f
Implement FIFO variant of scheduling of DSRs and make it the
default. This is reworked patch originally suggested by Stefan
Sommerfeld <sommerfeld@mikrom.com>.
* cdl/interrupts.cdl (CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST): make it
cdl_component.
* cdl/interrupts.cdl (CYGSEM_KERNEL_INTERRUPTS_DSRS_LIST_FIFO):
new option for CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST.
* include/intr.hxx (class Cyg_Interrupt): new static variable
dsr_list_tail.
* src/intr/intr.cxx (call_pending_DSRs_inner): add
CYGSEM_KERNEL_INTERRUPTS_DSRS_LIST_FIFO variant.
(post_dsr): likewise.
* tests/intr0.cxx: fix comments to match actual option names.
* tests/kintr0.c: likewise.2006-03-27 Marco Cruz <marco@daruma.com.br>
| author | nickg |
|---|---|
| date | Fri, 11 Aug 2006 09:29:31 +0000 |
| parents | d2c90368aeef |
| children | 74dbf4c3f2e1 |
| 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 //========================================================================== | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
11 //####ECOSGPLCOPYRIGHTBEGIN#### |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
12 // ------------------------------------------- |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
13 // This file is part of eCos, the Embedded Configurable Operating System. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
14 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
15 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
16 // eCos is free software; you can redistribute it and/or modify it under |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
17 // the terms of the GNU General Public License as published by the Free |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
18 // Software Foundation; either version 2 or (at your option) any later version. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
19 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
20 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
21 // WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
22 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
23 // for more details. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
24 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
25 // You should have received a copy of the GNU General Public License along |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
26 // with eCos; if not, write to the Free Software Foundation, Inc., |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
27 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
28 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
29 // As a special exception, if other files instantiate templates or use macros |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
30 // or inline functions from this file, or you compile this file and link it |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
31 // with other works to produce a work based on this file, this file does not |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
32 // by itself cause the resulting work to be covered by the GNU General Public |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
33 // License. However the source code for this file must still be made available |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
34 // in accordance with section (3) of the GNU General Public License. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
35 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
36 // This exception does not invalidate any other reasons why a work based on |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
37 // this file might be covered by the GNU General Public License. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
38 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
39 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
|
210
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
40 // at http://sources.redhat.com/ecos/ecos-license/ |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
41 // ------------------------------------------- |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
42 //####ECOSGPLCOPYRIGHTEND#### |
| 0 | 43 //========================================================================== |
| 44 //#####DESCRIPTIONBEGIN#### | |
| 45 // | |
| 2 | 46 // Author(s): nickg |
| 47 // Contributors: nickg | |
| 48 // Date: 1997-09-09 | |
| 49 // Purpose: Define Interrupt class interfaces | |
| 50 // Description: The classes defined here provide the APIs for handling | |
| 0 | 51 // interrupts. |
| 52 // Usage: #include "intr.hxx" | |
| 2 | 53 // |
| 0 | 54 // |
| 55 //####DESCRIPTIONEND#### | |
| 56 // | |
| 57 //========================================================================== | |
| 58 | |
| 59 #include <cyg/kernel/ktypes.h> | |
| 60 | |
|
177
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
61 #include <cyg/kernel/smp.hxx> |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
62 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
63 // ------------------------------------------------------------------------- |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
64 // Default definitions |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
65 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
66 // Some HALs define the ISR table to be a different size to the number |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
67 // of ISR vectors. These HALs will define CYGNUM_HAL_ISR_TABLE_SIZE. All |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
68 // other HALs will have the table size equal to the number of vectors. |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
69 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
70 #ifndef CYGNUM_HAL_ISR_TABLE_SIZE |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
71 # define CYGNUM_HAL_ISR_TABLE_SIZE CYGNUM_HAL_ISR_COUNT |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
72 #endif |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
73 |
| 0 | 74 // ------------------------------------------------------------------------- |
| 75 // Function prototype typedefs | |
| 76 | |
| 77 | |
| 78 // VSR = Vector Service Routine. This is the code attached directly to an | |
| 79 // interrupt vector. It is very architecture/platform specific and usually | |
| 80 // must be written in assembler. | |
| 81 | |
| 82 typedef void cyg_VSR(); | |
| 83 | |
| 84 // ISR = Interrupt Service Routine. This is called from the default | |
| 85 // VSR in response to an interrupt. It may access shared data but may | |
| 86 // not call kernel routines. The return value may be | |
| 87 // Cyg_Interrupt::HANDLED and/or Cyg_Interrupt::CALL_DSR. | |
| 88 | |
| 89 typedef cyg_uint32 cyg_ISR(cyg_vector vector, CYG_ADDRWORD data); | |
| 90 | |
| 91 // DSR = Deferred Service Routine. This is called if the ISR returns | |
| 92 // the Cyg_Interrupt::CALL_DSR bit. It is called at a "safe" point in | |
| 93 // the kernel where it may make calls on kernel routines. The count | |
| 94 // argument indicates how many times the ISR has asked for the DSR to | |
| 95 // be posted since the last time the DSR ran. | |
| 96 | |
| 97 typedef void cyg_DSR(cyg_vector vector, cyg_ucount32 count, CYG_ADDRWORD data); | |
| 98 | |
| 99 // ------------------------------------------------------------------------- | |
| 100 // Include HAL definitions | |
| 101 | |
| 102 class Cyg_Interrupt; | |
| 103 | |
| 104 #include <cyg/hal/hal_arch.h> | |
| 105 | |
| 106 #include <cyg/hal/hal_intr.h> | |
| 107 | |
|
8
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
2
diff
changeset
|
108 #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
|
109 #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
|
110 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
|
111 #endif |
|
ece80412419a
Merge from eCos master repository on 1999-05-21-22:05:54-BST
jlarmour
parents:
2
diff
changeset
|
112 |
| 0 | 113 externC void interrupt_end( |
| 114 cyg_uint32 isr_ret, | |
| 115 Cyg_Interrupt *intr, | |
| 116 HAL_SavedRegisters *ctx | |
| 117 ); | |
| 118 | |
| 2 | 119 externC void cyg_interrupt_post_dsr( CYG_ADDRWORD intr_obj ); |
| 120 externC void cyg_interrupt_call_pending_DSRs( void ); | |
| 121 | |
| 0 | 122 // ------------------------------------------------------------------------- |
| 123 // Interrupt class. This both represents each interrupt and provides a static | |
| 124 // interface for controlling the interrupt hardware. | |
| 125 | |
| 126 class Cyg_Interrupt | |
| 127 { | |
| 128 | |
| 129 friend class Cyg_Scheduler; | |
| 130 friend void interrupt_end( cyg_uint32, | |
| 131 Cyg_Interrupt *, | |
| 132 HAL_SavedRegisters *); | |
| 2 | 133 friend void cyg_interrupt_post_dsr( CYG_ADDRWORD intr_obj ); |
| 134 friend void cyg_interrupt_call_pending_DSRs( void ); | |
| 0 | 135 |
| 136 cyg_vector vector; // Interrupt vector | |
| 137 | |
| 138 cyg_priority priority; // Queuing priority | |
| 139 | |
| 140 cyg_ISR *isr; // Pointer to ISR | |
| 141 | |
| 142 cyg_DSR *dsr; // Pointer to DSR | |
| 143 | |
| 144 CYG_ADDRWORD data; // Data pointer | |
| 145 | |
| 146 | |
| 147 | |
| 148 // DSR handling interface called by the scheduler | |
| 149 | |
| 150 // Check for pending DSRs | |
| 151 static cyg_bool DSRs_pending(); | |
| 152 | |
| 153 // Call any pending DSRs | |
| 154 static void call_pending_DSRs(); | |
| 2 | 155 static void call_pending_DSRs_inner(); |
| 156 | |
| 157 // DSR handling interface called by the scheduler and HAL | |
| 158 // interrupt arbiters. | |
| 0 | 159 |
| 160 void post_dsr(); // Post the DSR for this interrupt | |
| 2 | 161 |
| 162 | |
| 0 | 163 |
| 164 // Data structures for handling DSR calls. We implement two DSR | |
| 165 // handling mechanisms, a list based one and a table based | |
| 166 // one. The list based mechanism is safe with respect to temporary | |
| 167 // overloads and will not run out of resource. However it requires | |
| 168 // extra data per interrupt object, and interrupts must be turned | |
| 169 // off briefly when delivering the DSR. The table based mechanism | |
| 170 // does not need unnecessary interrupt switching, but may be prone | |
| 171 // to overflow on overload. However, since a correctly programmed | |
| 172 // real time application should not experience such a condition, | |
| 173 // the table based mechanism is more efficient for real use. The | |
| 174 // list based mechainsm is enabled by default since it is safer to | |
| 175 // use during development. | |
| 176 | |
| 177 #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE | |
| 178 | |
|
182
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
177
diff
changeset
|
179 static Cyg_Interrupt *dsr_table[CYGNUM_KERNEL_CPU_MAX] |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
177
diff
changeset
|
180 [CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE] |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
177
diff
changeset
|
181 CYGBLD_ANNOTATE_VARIABLE_INTR; |
| 0 | 182 |
|
182
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
177
diff
changeset
|
183 static cyg_ucount32 dsr_table_head[CYGNUM_KERNEL_CPU_MAX] |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
177
diff
changeset
|
184 CYGBLD_ANNOTATE_VARIABLE_INTR; |
| 0 | 185 |
|
182
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
177
diff
changeset
|
186 static volatile cyg_ucount32 dsr_table_tail[CYGNUM_KERNEL_CPU_MAX] |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
177
diff
changeset
|
187 CYGBLD_ANNOTATE_VARIABLE_INTR; |
| 0 | 188 |
| 189 #endif | |
| 190 #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST | |
| 191 | |
|
177
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
192 // Number of DSR posts made |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
193 volatile cyg_ucount32 dsr_count CYGBLD_ANNOTATE_VARIABLE_INTR; |
| 0 | 194 |
|
177
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
195 // next DSR in list |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
196 Cyg_Interrupt* volatile next_dsr CYGBLD_ANNOTATE_VARIABLE_INTR; |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
197 |
|
2266
13625e7b9d1f
Implement FIFO variant of scheduling of DSRs and make it the
nickg
parents:
210
diff
changeset
|
198 // head of static list of pending DSRs |
|
182
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
177
diff
changeset
|
199 static Cyg_Interrupt* volatile dsr_list[CYGNUM_KERNEL_CPU_MAX] |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
177
diff
changeset
|
200 CYGBLD_ANNOTATE_VARIABLE_INTR; |
|
2266
13625e7b9d1f
Implement FIFO variant of scheduling of DSRs and make it the
nickg
parents:
210
diff
changeset
|
201 |
|
13625e7b9d1f
Implement FIFO variant of scheduling of DSRs and make it the
nickg
parents:
210
diff
changeset
|
202 # ifdef CYGSEM_KERNEL_INTERRUPTS_DSRS_LIST_FIFO |
|
13625e7b9d1f
Implement FIFO variant of scheduling of DSRs and make it the
nickg
parents:
210
diff
changeset
|
203 // tail of static list of pending DSRs |
|
13625e7b9d1f
Implement FIFO variant of scheduling of DSRs and make it the
nickg
parents:
210
diff
changeset
|
204 static Cyg_Interrupt* volatile dsr_list_tail[CYGNUM_KERNEL_CPU_MAX] |
|
13625e7b9d1f
Implement FIFO variant of scheduling of DSRs and make it the
nickg
parents:
210
diff
changeset
|
205 CYGBLD_ANNOTATE_VARIABLE_INTR; |
|
13625e7b9d1f
Implement FIFO variant of scheduling of DSRs and make it the
nickg
parents:
210
diff
changeset
|
206 # endif |
|
13625e7b9d1f
Implement FIFO variant of scheduling of DSRs and make it the
nickg
parents:
210
diff
changeset
|
207 |
|
13625e7b9d1f
Implement FIFO variant of scheduling of DSRs and make it the
nickg
parents:
210
diff
changeset
|
208 #endif // defined CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST |
| 0 | 209 |
| 210 #ifdef CYGIMP_KERNEL_INTERRUPTS_CHAIN | |
| 211 | |
| 212 // The default mechanism for handling interrupts is to attach just | |
| 213 // one Interrupt object to each vector. In some cases, and on some | |
| 214 // hardware, this is not possible, and each vector must carry a chain | |
| 215 // of interrupts. | |
| 216 | |
| 217 Cyg_Interrupt *next; // Next Interrupt in list | |
| 218 | |
| 219 // Chaining ISR inserted in HAL vector | |
| 220 static cyg_uint32 chain_isr(cyg_vector vector, CYG_ADDRWORD data); | |
| 221 | |
| 222 // Table of interrupt chains | |
|
177
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
223 static Cyg_Interrupt *chain_list[CYGNUM_HAL_ISR_TABLE_SIZE]; |
| 0 | 224 |
| 225 #endif | |
| 2 | 226 |
|
177
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
227 // Interrupt disable data. Interrupt disable can be nested. On |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
228 // each CPU this is controlled by disable_counter[cpu]. When the |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
229 // counter is first incremented from zero to one, the |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
230 // interrupt_disable_spinlock is claimed using spin_intsave(), the |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
231 // original interrupt enable state being saved in |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
232 // interrupt_disable_state[cpu]. When the counter is decremented |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
233 // back to zero the spinlock is cleared using clear_intsave(). |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
234 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
235 // The spinlock is necessary in SMP systems since a thread |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
236 // accessing data shared with an ISR may be scheduled on a |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
237 // different CPU to the one that handles the interrupt. So, merely |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
238 // blocking local interrupts would be ineffective. SMP aware |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
239 // device drivers should either use their own spinlocks to protect |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
240 // data, or use the API supported by this class, via |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
241 // cyg_drv_isr_lock()/_unlock(). Note that it now becomes |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
242 // essential that ISRs do this if they are to be SMP-compatible. |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
243 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
244 // In a single CPU system, this mechanism reduces to just |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
245 // disabling/enabling interrupts. |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
246 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
247 // Disable level counter. This counts the number of times |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
248 // interrupts have been disabled. |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
249 static volatile cyg_int32 disable_counter[CYGNUM_KERNEL_CPU_MAX] |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
250 CYGBLD_ANNOTATE_VARIABLE_INTR; |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
251 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
252 // Interrupt disable spinlock. This is claimed by any CPU that has |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
253 // disabled interrupts via the Cyg_Interrupt API. |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
254 static Cyg_SpinLock interrupt_disable_spinlock CYGBLD_ANNOTATE_VARIABLE_INTR; |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
255 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
256 // Saved interrupt state. When each CPU first disables interrupts |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
257 // the original state of the interrupts are saved here to be |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
258 // restored later. |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
259 static CYG_INTERRUPT_STATE interrupt_disable_state[CYGNUM_KERNEL_CPU_MAX] |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
260 CYGBLD_ANNOTATE_VARIABLE_INTR; |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
261 |
| 0 | 262 |
| 263 public: | |
| 264 | |
| 265 Cyg_Interrupt // Initialize interrupt | |
| 266 ( | |
| 267 cyg_vector vector, // Vector to attach to | |
| 268 cyg_priority priority, // Queue priority | |
| 269 CYG_ADDRWORD data, // Data pointer | |
| 270 cyg_ISR *isr, // Interrupt Service Routine | |
| 271 cyg_DSR *dsr // Deferred Service Routine | |
| 272 ); | |
| 273 | |
| 274 ~Cyg_Interrupt(); | |
| 275 | |
| 276 // ISR return values | |
| 277 enum { | |
| 278 HANDLED = 1, // Interrupt was handled | |
| 279 CALL_DSR = 2 // Schedule DSR | |
| 280 }; | |
| 281 | |
| 282 // Interrupt management | |
| 283 | |
| 284 void attach(); // Attach to vector | |
| 285 | |
| 286 | |
| 287 void detach(); // Detach from vector | |
| 288 | |
| 289 | |
| 290 // Static Interrupt management functions | |
| 291 | |
| 292 // Get the current service routine | |
| 293 static void get_vsr(cyg_vector vector, cyg_VSR **vsr); | |
| 294 | |
| 295 // Install a vector service routine | |
| 296 static void set_vsr( | |
| 297 cyg_vector vector, // hardware vector to replace | |
| 298 cyg_VSR *vsr, // my new service routine | |
| 299 cyg_VSR **old = NULL // pointer to old vsr, if required | |
| 300 ); | |
| 301 | |
| 302 | |
| 303 // Static interrupt masking functions | |
| 304 | |
| 305 // Disable interrupts at the CPU | |
| 306 static void disable_interrupts(); | |
| 307 | |
| 308 // Re-enable CPU interrupts | |
| 309 static void enable_interrupts(); | |
| 310 | |
| 311 // Are interrupts enabled at the CPU? | |
| 312 static inline cyg_bool interrupts_enabled() | |
| 313 { | |
|
177
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
314 return (0 == disable_counter[CYG_KERNEL_CPU_THIS()]); |
| 0 | 315 } |
| 316 | |
| 317 // Get the vector for the following calls | |
| 318 inline cyg_vector get_vector() | |
| 319 { | |
| 320 return vector; | |
| 321 } | |
| 322 | |
| 323 // Static PIC control functions | |
| 324 | |
| 325 // Mask a specific interrupt in a PIC | |
| 326 static void mask_interrupt(cyg_vector vector); | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
327 // The same but not interrupt safe |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
328 static void mask_interrupt_intunsafe(cyg_vector vector); |
| 0 | 329 |
| 330 // Clear PIC mask | |
| 331 static void unmask_interrupt(cyg_vector vector); | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
332 // The same but not interrupt safe |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
333 static void unmask_interrupt_intunsafe(cyg_vector vector); |
| 0 | 334 |
| 335 // Acknowledge interrupt at PIC | |
| 336 static void acknowledge_interrupt(cyg_vector vector); | |
| 337 | |
| 338 // Change interrupt detection at PIC | |
| 339 static void configure_interrupt( | |
| 340 cyg_vector vector, // vector to control | |
| 341 cyg_bool level, // level or edge triggered | |
| 342 cyg_bool up // hi/lo level, rising/falling edge | |
| 343 ); | |
|
177
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
344 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
345 #ifdef CYGPKG_KERNEL_SMP_SUPPORT |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
346 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
347 // SMP support for associating an interrupt with a specific CPU. |
| 0 | 348 |
|
177
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
349 static void set_cpu( cyg_vector, HAL_SMP_CPU_TYPE cpu ); |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
350 static HAL_SMP_CPU_TYPE get_cpu( cyg_vector ); |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
351 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
130
diff
changeset
|
352 #endif |
| 0 | 353 }; |
| 354 | |
| 355 #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS | |
| 356 // ------------------------------------------------------------------------- | |
| 357 // Check for pending DSRs | |
| 358 | |
| 359 inline cyg_bool Cyg_Interrupt::DSRs_pending() | |
| 360 { | |
|
182
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
177
diff
changeset
|
361 HAL_SMP_CPU_TYPE cpu = CYG_KERNEL_CPU_THIS(); |
| 0 | 362 #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE |
| 363 | |
|
182
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
177
diff
changeset
|
364 return dsr_table_head[cpu] != dsr_table_tail[cpu]; |
| 0 | 365 |
| 366 #endif | |
| 367 #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST | |
| 368 | |
|
182
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
177
diff
changeset
|
369 return dsr_list[cpu] != NULL; |
| 0 | 370 |
| 371 #endif | |
| 372 }; | |
| 373 #endif // CYGIMP_KERNEL_INTERRUPTS_DSRS | |
| 374 | |
| 375 // ------------------------------------------------------------------------- | |
| 376 #endif // ifndef CYGONCE_KERNEL_INTR_HXX | |
| 377 // EOF intr.hxx |
