|
0
|
1 #ifndef CYGONCE_HAL_HAL_INTR_H |
|
|
2 #define CYGONCE_HAL_HAL_INTR_H |
|
|
3 |
|
2
|
4 //========================================================================== |
|
0
|
5 // |
|
2
|
6 // hal_intr.h |
|
0
|
7 // |
|
2
|
8 // HAL Interrupt and clock support |
|
0
|
9 // |
|
2
|
10 //========================================================================== |
|
0
|
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#### |
|
2
|
32 //========================================================================== |
|
0
|
33 //#####DESCRIPTIONBEGIN#### |
|
|
34 // |
|
2
|
35 // Author(s): nickg |
|
|
36 // Contributors: nickg, jskov, |
|
|
37 // gthomas, jlarmour |
|
|
38 // Date: 1999-02-16 |
|
|
39 // Purpose: Define Interrupt support |
|
|
40 // Description: The macros defined here provide the HAL APIs for handling |
|
|
41 // interrupts and the clock. |
|
0
|
42 // |
|
|
43 // Usage: |
|
2
|
44 // #include <cyg/hal/hal_intr.h> |
|
|
45 // ... |
|
|
46 // |
|
0
|
47 // |
|
|
48 //####DESCRIPTIONEND#### |
|
|
49 // |
|
2
|
50 //========================================================================== |
|
0
|
51 |
|
|
52 #include <pkgconf/hal.h> |
|
|
53 |
|
|
54 #include <cyg/infra/cyg_type.h> |
|
|
55 #include <cyg/hal/hal_io.h> |
|
|
56 |
|
2
|
57 //-------------------------------------------------------------------------- |
|
|
58 // MIPS vectors. |
|
0
|
59 |
|
2
|
60 // These are the exception codes presented in the Cause register and |
|
|
61 // correspond to VSRs. These values are the ones to use for HAL_VSR_GET/SET |
|
0
|
62 |
|
2
|
63 // External interrupt |
|
|
64 #define CYGNUM_HAL_VECTOR_INTERRUPT 0 |
|
|
65 // TLB modification exception |
|
|
66 #define CYGNUM_HAL_VECTOR_TLB_MOD 1 |
|
|
67 // TLB miss (Load or IFetch) |
|
|
68 #define CYGNUM_HAL_VECTOR_TLB_LOAD_REFILL 2 |
|
|
69 // TLB miss (Store) |
|
|
70 #define CYGNUM_HAL_VECTOR_TLB_STORE_REFILL 3 |
|
|
71 // Address error (Load or Ifetch) |
|
|
72 #define CYGNUM_HAL_VECTOR_LOAD_ADDRESS 4 |
|
|
73 // Address error (store) |
|
|
74 #define CYGNUM_HAL_VECTOR_STORE_ADDRESS 5 |
|
|
75 // Bus error (Ifetch) |
|
|
76 #define CYGNUM_HAL_VECTOR_IBE 6 |
|
|
77 // Bus error (data load or store) |
|
|
78 #define CYGNUM_HAL_VECTOR_DBE 7 |
|
|
79 // System call |
|
|
80 #define CYGNUM_HAL_VECTOR_SYSTEM_CALL 8 |
|
|
81 // Break point |
|
|
82 #define CYGNUM_HAL_VECTOR_BREAKPOINT 9 |
|
|
83 // Reserved instruction |
|
|
84 #define CYGNUM_HAL_VECTOR_RESERVED_INSTRUCTION 10 |
|
|
85 // Coprocessor unusable |
|
|
86 #define CYGNUM_HAL_VECTOR_COPROCESSOR 11 |
|
|
87 // Arithmetic overflow |
|
|
88 #define CYGNUM_HAL_VECTOR_OVERFLOW 12 |
|
|
89 // Reserved |
|
|
90 #define CYGNUM_HAL_VECTOR_RESERVED_13 13 |
|
|
91 // Floating point exception - not applicable yet |
|
|
92 // #define CYGNUM_HAL_VECTOR_FPE 15 |
|
0
|
93 |
|
2
|
94 #define CYGNUM_HAL_VSR_MIN 0 |
|
|
95 #define CYGNUM_HAL_VSR_MAX 13 |
|
|
96 #define CYGNUM_HAL_VSR_COUNT 14 |
|
|
97 |
|
|
98 // Exception vectors. These are the values used when passed out to an |
|
|
99 // external exception handler using cyg_hal_deliver_exception() |
|
0
|
100 |
|
2
|
101 #define CYGNUM_HAL_EXCEPTION_DATA_TLBERROR_ACCESS CYGNUM_HAL_VECTOR_TLB_MOD |
|
|
102 #define CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_ACCESS \ |
|
|
103 CYGNUM_HAL_VECTOR_TLB_LOAD_REFILL |
|
|
104 #define CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_WRITE \ |
|
|
105 CYGNUM_HAL_VECTOR_TLB_STORE_REFILL |
|
|
106 #define CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS \ |
|
|
107 CYGNUM_HAL_VECTOR_LOAD_ADDRESS |
|
|
108 #define CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_WRITE \ |
|
|
109 CYGNUM_HAL_VECTOR_STORE_ADDRESS |
|
|
110 #define CYGNUM_HAL_EXCEPTION_CODE_ACCESS CYGNUM_HAL_VECTOR_IBE |
|
|
111 #define CYGNUM_HAL_EXCEPTION_DATA_ACCESS CYGNUM_HAL_VECTOR_DBE |
|
|
112 #define CYGNUM_HAL_EXCEPTION_SYSTEM_CALL CYGNUM_HAL_VECTOR_SYSTEM_CALL |
|
|
113 #define CYGNUM_HAL_EXCEPTION_INSTRUCTION_BP CYGNUM_HAL_VECTOR_BREAKPOINT |
|
|
114 #define CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION \ |
|
|
115 CYGNUM_HAL_VECTOR_RESERVED_INSTRUCTION |
|
|
116 #define CYGNUM_HAL_EXCEPTION_COPROCESSOR CYGNUM_HAL_VECTOR_COPROCESSOR |
|
|
117 #define CYGNUM_HAL_EXCEPTION_OVERFLOW CYGNUM_HAL_VECTOR_OVERFLOW |
|
|
118 |
|
|
119 // Min/Max exception numbers and how many there are |
|
|
120 #define CYGNUM_HAL_EXCEPTION_MIN 1 |
|
|
121 #define CYGNUM_HAL_EXCEPTION_MAX 13 |
|
|
122 #define CYGNUM_HAL_EXCEPTION_COUNT 13 |
|
0
|
123 |
|
|
124 // Interrupt vectors. |
|
|
125 |
|
|
126 #if defined(CYG_HAL_MIPS_TX3904) || defined(CYG_HAL_MIPS_SIM) |
|
|
127 |
|
|
128 // These are decoded via the IP bits of the cause |
|
|
129 // register when an external interrupt is delivered. |
|
|
130 |
|
2
|
131 #define CYGNUM_HAL_INTERRUPT_1 0 |
|
|
132 #define CYGNUM_HAL_INTERRUPT_2 1 |
|
|
133 #define CYGNUM_HAL_INTERRUPT_3 2 |
|
|
134 #define CYGNUM_HAL_INTERRUPT_4 3 |
|
|
135 #define CYGNUM_HAL_INTERRUPT_5 4 |
|
|
136 #define CYGNUM_HAL_INTERRUPT_6 5 |
|
|
137 #define CYGNUM_HAL_INTERRUPT_7 6 |
|
|
138 #define CYGNUM_HAL_INTERRUPT_DMAC1_CH3 7 |
|
|
139 #define CYGNUM_HAL_INTERRUPT_DMAC1_CH2 8 |
|
|
140 #define CYGNUM_HAL_INTERRUPT_DMAC0_CH1 9 |
|
|
141 #define CYGNUM_HAL_INTERRUPT_DMAC0_CH0 10 |
|
|
142 #define CYGNUM_HAL_INTERRUPT_SIO_0 11 |
|
|
143 #define CYGNUM_HAL_INTERRUPT_SIO_1 12 |
|
|
144 #define CYGNUM_HAL_INTERRUPT_TMR_0 13 |
|
|
145 #define CYGNUM_HAL_INTERRUPT_TMR_1 14 |
|
|
146 #define CYGNUM_HAL_INTERRUPT_TMR_2 15 |
|
|
147 #define CYGNUM_HAL_INTERRUPT_0 16 |
|
0
|
148 |
|
2
|
149 // Min/Max ISR numbers and how many there are |
|
|
150 #define CYGNUM_HAL_ISR_MIN 0 |
|
|
151 #define CYGNUM_HAL_ISR_MAX 16 |
|
|
152 #define CYGNUM_HAL_ISR_COUNT 17 |
|
0
|
153 |
|
|
154 // The vector used by the Real time clock |
|
2
|
155 #define CYGNUM_HAL_INTERRUPT_RTC CYGNUM_HAL_INTERRUPT_TMR_0 |
|
0
|
156 |
|
|
157 #endif |
|
|
158 |
|
2
|
159 //-------------------------------------------------------------------------- |
|
0
|
160 // Static data used by HAL |
|
|
161 |
|
|
162 // ISR tables |
|
2
|
163 externC volatile CYG_ADDRESS hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT]; |
|
|
164 externC volatile CYG_ADDRWORD hal_interrupt_data[CYGNUM_HAL_ISR_COUNT]; |
|
|
165 externC volatile CYG_ADDRESS hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT]; |
|
0
|
166 |
|
|
167 // VSR table |
|
2
|
168 externC volatile CYG_ADDRESS hal_vsr_table[CYGNUM_HAL_VSR_MAX+1]; |
|
0
|
169 |
|
2
|
170 //-------------------------------------------------------------------------- |
|
0
|
171 // Default ISR |
|
|
172 |
|
|
173 externC cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data); |
|
|
174 |
|
2
|
175 //-------------------------------------------------------------------------- |
|
0
|
176 // Interrupt state storage |
|
|
177 |
|
|
178 typedef cyg_uint32 CYG_INTERRUPT_STATE; |
|
|
179 |
|
2
|
180 //-------------------------------------------------------------------------- |
|
0
|
181 // Interrupt control macros |
|
2
|
182 // Beware of the nops in this code. These fill load/store delay slots to |
|
|
183 // prevent following code being run in the wrong state. |
|
0
|
184 |
|
|
185 #define HAL_DISABLE_INTERRUPTS(_old_) \ |
|
|
186 { \ |
|
|
187 asm volatile ( \ |
|
|
188 "mfc0 $8,$12; nop;" \ |
|
|
189 "move %0,$8;" \ |
|
|
190 "and $8,$8,0XFFFFFFFE;" \ |
|
|
191 "mtc0 $8,$12;" \ |
|
|
192 "nop; nop; nop;" \ |
|
|
193 "and %0,%0,0X1;" \ |
|
|
194 : "=r"(_old_) \ |
|
|
195 : \ |
|
|
196 : "$8" \ |
|
|
197 ); \ |
|
|
198 } |
|
|
199 |
|
|
200 #define HAL_ENABLE_INTERRUPTS() \ |
|
|
201 { \ |
|
|
202 asm volatile ( \ |
|
|
203 "mfc0 $8,$12; nop;" \ |
|
|
204 "or $8,$8,1;" \ |
|
|
205 "mtc0 $8,$12;" \ |
|
|
206 "nop; nop; nop;" \ |
|
|
207 : \ |
|
|
208 : \ |
|
|
209 : "$8" \ |
|
|
210 ); \ |
|
|
211 } |
|
|
212 |
|
|
213 #define HAL_RESTORE_INTERRUPTS(_old_) \ |
|
|
214 { \ |
|
|
215 asm volatile ( \ |
|
|
216 "mfc0 $8,$12; nop;" \ |
|
|
217 "and %0,%0,0x1;" \ |
|
|
218 "or $8,$8,%0;" \ |
|
|
219 "mtc0 $8,$12;" \ |
|
|
220 "nop; nop; nop;" \ |
|
|
221 : \ |
|
|
222 : "r"(_old_) \ |
|
|
223 : "$8" \ |
|
|
224 ); \ |
|
|
225 } |
|
|
226 |
|
|
227 #define HAL_QUERY_INTERRUPTS( _state_ ) \ |
|
|
228 { \ |
|
|
229 asm volatile ( \ |
|
|
230 "mfc0 %0,$12; nop;" \ |
|
|
231 "and %0,%0,0x1;" \ |
|
|
232 : "=r"(_state_) \ |
|
|
233 : \ |
|
|
234 : "$8" \ |
|
|
235 ); \ |
|
|
236 } |
|
|
237 |
|
2
|
238 //-------------------------------------------------------------------------- |
|
0
|
239 // Vector translation. |
|
|
240 // For chained interrupts we only have a single vector though which all |
|
|
241 // are passed. For unchained interrupts we have a vector per interrupt. |
|
|
242 |
|
|
243 #if defined(CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN) |
|
|
244 |
|
|
245 #define HAL_TRANSLATE_VECTOR(_vector_,_index_) (_index_) = 0 |
|
|
246 |
|
|
247 #else |
|
|
248 |
|
|
249 #define HAL_TRANSLATE_VECTOR(_vector_,_index_) (_index_) = (_vector_) |
|
|
250 |
|
|
251 #endif |
|
|
252 |
|
2
|
253 //-------------------------------------------------------------------------- |
|
0
|
254 // Interrupt and VSR attachment macros |
|
|
255 |
|
2
|
256 #define HAL_INTERRUPT_IN_USE( _vector_, _state_) \ |
|
|
257 CYG_MACRO_START \ |
|
|
258 cyg_uint32 _index_; \ |
|
|
259 HAL_TRANSLATE_VECTOR ((_vector_), _index_); \ |
|
|
260 \ |
|
|
261 if( hal_interrupt_handlers[_index_] == (CYG_ADDRESS)hal_default_isr ) \ |
|
|
262 (_state_) = 0; \ |
|
|
263 else \ |
|
|
264 (_state_) = 1; \ |
|
|
265 CYG_MACRO_END |
|
|
266 |
|
|
267 #define HAL_INTERRUPT_ATTACH( _vector_, _isr_, _data_, _object_ ) \ |
|
|
268 { \ |
|
|
269 cyg_uint32 _index_; \ |
|
|
270 HAL_TRANSLATE_VECTOR( _vector_, _index_ ); \ |
|
|
271 \ |
|
|
272 if( hal_interrupt_handlers[_index_] == (CYG_ADDRESS)hal_default_isr ) \ |
|
|
273 { \ |
|
|
274 hal_interrupt_handlers[_index_] = (CYG_ADDRESS)_isr_; \ |
|
|
275 hal_interrupt_data[_index_] = (CYG_ADDRWORD)_data_; \ |
|
|
276 hal_interrupt_objects[_index_] = (CYG_ADDRESS)_object_; \ |
|
|
277 } \ |
|
0
|
278 } |
|
|
279 |
|
|
280 #define HAL_INTERRUPT_DETACH( _vector_, _isr_ ) \ |
|
|
281 { \ |
|
|
282 cyg_uint32 _index_; \ |
|
|
283 HAL_TRANSLATE_VECTOR( _vector_, _index_ ); \ |
|
|
284 \ |
|
|
285 if( hal_interrupt_handlers[_index_] == (CYG_ADDRESS)_isr_ ) \ |
|
|
286 { \ |
|
|
287 hal_interrupt_handlers[_index_] = (CYG_ADDRESS)hal_default_isr; \ |
|
|
288 hal_interrupt_data[_index_] = 0; \ |
|
|
289 hal_interrupt_objects[_index_] = 0; \ |
|
|
290 } \ |
|
|
291 } |
|
|
292 |
|
|
293 #define HAL_VSR_GET( _vector_, _pvsr_ ) \ |
|
|
294 *(_pvsr_) = (void (*)())hal_vsr_table[_vector_]; |
|
|
295 |
|
|
296 |
|
2
|
297 #define HAL_VSR_SET( _vector_, _vsr_, _poldvsr_ ) CYG_MACRO_START \ |
|
|
298 if( _poldvsr_ != NULL) \ |
|
|
299 *(CYG_ADDRESS *)_poldvsr_ = (CYG_ADDRESS)hal_vsr_table[_vector_]; \ |
|
|
300 hal_vsr_table[_vector_] = (CYG_ADDRESS)_vsr_; \ |
|
|
301 CYG_MACRO_END |
|
|
302 |
|
|
303 // This is an ugly name, but what it means is: grab the VSR back to eCos |
|
|
304 // internal handling, or if you like, the default handler. But if |
|
|
305 // cooperating with GDB and CygMon, the default behaviour is to pass most |
|
|
306 // exceptions to CygMon. This macro undoes that so that eCos handles the |
|
|
307 // exception. So use it with care. |
|
0
|
308 |
|
2
|
309 externC void __default_exception_vsr(void); |
|
|
310 externC void __default_interrupt_vsr(void); |
|
|
311 |
|
|
312 #define HAL_VSR_SET_TO_ECOS_HANDLER( _vector_, _poldvsr_ ) CYG_MACRO_START \ |
|
|
313 HAL_VSR_SET( _vector_, _vector_ == CYGNUM_HAL_VECTOR_INTERRUPT \ |
|
|
314 ? (CYG_ADDRESS)__default_interrupt_vsr \ |
|
|
315 : (CYG_ADDRESS)__default_exception_vsr, \ |
|
|
316 _poldvsr_ ); \ |
|
|
317 CYG_MACRO_END |
|
|
318 |
|
|
319 //-------------------------------------------------------------------------- |
|
0
|
320 // Interrupt controller access |
|
|
321 |
|
|
322 #if defined(CYG_HAL_MIPS_TX3904) || defined(CYG_HAL_MIPS_SIM) |
|
|
323 |
|
2
|
324 #define CYG_HAL_MIPS_TX3904_ILR0 0xFFFFC010 |
|
|
325 #define CYG_HAL_MIPS_TX3904_CConR 0xFFFFE000 |
|
0
|
326 |
|
|
327 // Array which stores the configured priority levels for the configured |
|
|
328 // interrupts. |
|
2
|
329 externC volatile CYG_BYTE hal_interrupt_level[CYGNUM_HAL_ISR_COUNT]; |
|
0
|
330 |
|
|
331 |
|
2
|
332 #define HAL_INTERRUPT_MASK( _vector_ ) \ |
|
|
333 { \ |
|
|
334 HAL_IO_REGISTER _reg_ = CYG_HAL_MIPS_TX3904_ILR0; \ |
|
|
335 CYG_WORD32 _ilr_; \ |
|
|
336 _reg_ += (_vector_)&0xC; \ |
|
|
337 HAL_READ_UINT32( _reg_, _ilr_ ); \ |
|
|
338 _ilr_ &= ~(7 << (((_vector_)&0x3)<<3)); \ |
|
|
339 HAL_WRITE_UINT32( _reg_, _ilr_ ); \ |
|
0
|
340 } |
|
|
341 |
|
|
342 #define HAL_INTERRUPT_UNMASK( _vector_ ) \ |
|
|
343 { \ |
|
2
|
344 HAL_IO_REGISTER _reg_ = CYG_HAL_MIPS_TX3904_ILR0; \ |
|
0
|
345 CYG_WORD32 _ilr_; \ |
|
|
346 _reg_ += (_vector_)&0xC; \ |
|
|
347 HAL_READ_UINT32( _reg_, _ilr_ ); \ |
|
|
348 _ilr_ |= hal_interrupt_level[_vector_] << (((_vector_)&0x3)<<3); \ |
|
|
349 HAL_WRITE_UINT32( _reg_, _ilr_ ); \ |
|
|
350 } |
|
|
351 |
|
|
352 #define HAL_INTERRUPT_ACKNOWLEDGE( _vector_ ) \ |
|
|
353 { \ |
|
2
|
354 if( _vector_ <= CYGNUM_HAL_INTERRUPT_7 || \ |
|
|
355 _vector_ == CYGNUM_HAL_INTERRUPT_0 ) \ |
|
0
|
356 { \ |
|
|
357 cyg_uint32 _val_ = _vector_ + 1; \ |
|
2
|
358 if( _val_ == CYGNUM_HAL_INTERRUPT_0 + 1 ) _val_ = 0; \ |
|
|
359 HAL_WRITE_UINT8( CYG_HAL_MIPS_TX3904_CConR+1, _val_); \ |
|
0
|
360 } \ |
|
|
361 } |
|
|
362 |
|
|
363 #define HAL_INTERRUPT_CONFIGURE( _vector_, _level_, _up_ ) \ |
|
|
364 { \ |
|
2
|
365 if( _vector_ <= CYGNUM_HAL_INTERRUPT_7 || \ |
|
|
366 _vector_ == CYGNUM_HAL_INTERRUPT_0 ) \ |
|
0
|
367 { \ |
|
|
368 cyg_uint32 _val_ = 0; \ |
|
|
369 if( _up_ ) _val_ |= 1; \ |
|
|
370 if( !(_level_) ) _val_ |= 2; \ |
|
2
|
371 HAL_WRITE_UINT16( CYG_HAL_MIPS_TX3904_CConR+2, _val_ ); \ |
|
0
|
372 } \ |
|
|
373 } |
|
|
374 |
|
|
375 #define HAL_INTERRUPT_SET_LEVEL( _vector_, _level_ ) \ |
|
|
376 { \ |
|
2
|
377 HAL_IO_REGISTER _reg_ = CYG_HAL_MIPS_TX3904_ILR0; \ |
|
0
|
378 CYG_WORD32 _ilr_; \ |
|
|
379 _reg_ += (_vector_)&0xC; \ |
|
|
380 HAL_READ_UINT32( _reg_, _ilr_ ); \ |
|
|
381 _ilr_ |= (_level_) << (((_vector_)&0x3)<<3); \ |
|
|
382 HAL_WRITE_UINT32( _reg_, _ilr_ ); \ |
|
|
383 hal_interrupt_level[_vector_] = _level_; \ |
|
|
384 } |
|
|
385 |
|
|
386 #else |
|
|
387 |
|
|
388 #error Unspecified platform for MIPS |
|
|
389 |
|
|
390 #endif |
|
|
391 |
|
2
|
392 //-------------------------------------------------------------------------- |
|
0
|
393 // Clock control |
|
|
394 |
|
|
395 #if defined(CYG_HAL_MIPS_TX3904) || defined(CYG_HAL_MIPS_SIM) |
|
|
396 |
|
2
|
397 #define CYG_HAL_MIPS_TX3904_TIMER_BASE 0xFFFFF000 |
|
|
398 #define CYG_HAL_MIPS_TX3904_TIMER_CR (CYG_HAL_MIPS_TX3904_TIMER_BASE + 0x00) |
|
|
399 #define CYG_HAL_MIPS_TX3904_TIMER_SR (CYG_HAL_MIPS_TX3904_TIMER_BASE + 0x04) |
|
|
400 #define CYG_HAL_MIPS_TX3904_TIMER_CPR (CYG_HAL_MIPS_TX3904_TIMER_BASE + 0x08) |
|
|
401 #define CYG_HAL_MIPS_TX3904_TIMER_IMR (CYG_HAL_MIPS_TX3904_TIMER_BASE + 0x10) |
|
|
402 #define CYG_HAL_MIPS_TX3904_TIMER_DR (CYG_HAL_MIPS_TX3904_TIMER_BASE + 0x20) |
|
|
403 #define CYG_HAL_MIPS_TX3904_TIMER_RR (CYG_HAL_MIPS_TX3904_TIMER_BASE + 0xF0) |
|
0
|
404 |
|
2
|
405 #define HAL_CLOCK_INITIALIZE( _period_ ) \ |
|
|
406 { \ |
|
|
407 HAL_WRITE_UINT32( CYG_HAL_MIPS_TX3904_TIMER_DR, 0x00000003 ); \ |
|
|
408 HAL_WRITE_UINT32( CYG_HAL_MIPS_TX3904_TIMER_CPR, _period_ ); \ |
|
|
409 HAL_WRITE_UINT32( CYG_HAL_MIPS_TX3904_TIMER_SR, 0x00000000 ); \ |
|
|
410 HAL_WRITE_UINT32( CYG_HAL_MIPS_TX3904_TIMER_IMR, 0x00008001 ); \ |
|
|
411 HAL_WRITE_UINT32( CYG_HAL_MIPS_TX3904_TIMER_CR, 0x000000C0 ); \ |
|
|
412 } |
|
|
413 |
|
|
414 #define HAL_CLOCK_RESET( _vector_, _period_ ) \ |
|
|
415 { \ |
|
|
416 HAL_WRITE_UINT32( CYG_HAL_MIPS_TX3904_TIMER_SR, 0x00000000 ); \ |
|
0
|
417 } |
|
|
418 |
|
2
|
419 #if defined(CYGHWR_HAL_MIPS_TX3904_TRR_REQUIRES_SYNC) && \ |
|
|
420 !defined(CYG_HAL_MIPS_SIM) |
|
|
421 |
|
|
422 // We need to sync and check the coprocessor 0 condition - this indicates |
|
|
423 // whether data is present in the write buffer. We need to wait until |
|
|
424 // that data to be written is flushed out. This works around a tx39 bug. |
|
|
425 // gcc will insert a NOP after the asm insns. |
|
0
|
426 |
|
2
|
427 # define HAL_CLOCK_READ( _pvalue_ ) \ |
|
|
428 CYG_MACRO_START \ |
|
|
429 asm volatile ( \ |
|
|
430 "sync; nop; 1: ; bc0f 1b" \ |
|
|
431 : \ |
|
|
432 : \ |
|
|
433 : "$0" \ |
|
|
434 ); \ |
|
|
435 HAL_READ_UINT32( CYG_HAL_MIPS_TX3904_TIMER_RR, *(_pvalue_) ); \ |
|
|
436 CYG_MACRO_END |
|
|
437 |
|
|
438 #else |
|
|
439 |
|
|
440 # define HAL_CLOCK_READ( _pvalue_ ) \ |
|
|
441 CYG_MACRO_START \ |
|
|
442 HAL_READ_UINT32( CYG_HAL_MIPS_TX3904_TIMER_RR, *(_pvalue_) ); \ |
|
|
443 CYG_MACRO_END |
|
|
444 |
|
|
445 #endif |
|
|
446 |
|
|
447 #ifdef CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY |
|
|
448 #define HAL_CLOCK_LATENCY( _pvalue_ ) HAL_CLOCK_READ(_pvalue_) |
|
|
449 #endif |
|
0
|
450 |
|
|
451 #else |
|
|
452 |
|
|
453 #error Unspecified platform for MIPS |
|
|
454 |
|
|
455 #endif |
|
|
456 |
|
2
|
457 //-------------------------------------------------------------------------- |
|
|
458 // Timeout exception support. This is only enabled on the real TX39 hardware. |
|
|
459 |
|
|
460 #if defined(CYG_HAL_MIPS_TX3904) |
|
|
461 |
|
|
462 #define HAL_TX39_DEBUG_TOE_ENABLE() \ |
|
|
463 { \ |
|
|
464 HAL_IO_REGISTER _reg_ = CYG_HAL_MIPS_TX3904_CConR; \ |
|
|
465 CYG_WORD32 _cconr_; \ |
|
|
466 HAL_READ_UINT32( _reg_, _cconr_); \ |
|
|
467 _cconr_ |= 0x04000000; \ |
|
|
468 HAL_WRITE_UINT32( _reg_, _cconr_); \ |
|
|
469 } |
|
|
470 |
|
|
471 #define HAL_TX39_DEBUG_TOE_DISABLE() \ |
|
|
472 { \ |
|
|
473 HAL_IO_REGISTER _reg_ = CYG_HAL_MIPS_TX3904_CConR; \ |
|
|
474 CYG_WORD32 _cconr_; \ |
|
|
475 HAL_READ_UINT32( _reg_, _cconr_); \ |
|
|
476 _cconr_ &= 0xFBFFFFFF; \ |
|
|
477 HAL_WRITE_UINT32( _reg_, _cconr_); \ |
|
|
478 } |
|
|
479 |
|
|
480 #else |
|
|
481 |
|
|
482 #define HAL_TX39_DEBUG_TOE_ENABLE() |
|
|
483 |
|
|
484 #define HAL_TX39_DEBUG_TOE_DISABLE() |
|
|
485 |
|
|
486 #endif |
|
|
487 |
|
|
488 //-------------------------------------------------------------------------- |
|
0
|
489 #endif // ifndef CYGONCE_HAL_HAL_INTR_H |
|
|
490 // End of hal_intr.h |