1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - OS - include
3   File:     interrupt.h
4 
5   Copyright 2003-2008 Nintendo.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date:: 2008-06-13#$
14   $Rev: 6581 $
15   $Author: yada $
16  *---------------------------------------------------------------------------*/
17 
18 #ifndef NITRO_OS_INTERRUPT_H_
19 #define NITRO_OS_INTERRUPT_H_
20 
21 #ifdef SDK_TWL
22 #include <twl/os/common/interrupt.h>
23 #endif
24 
25 #ifdef SDK_NITRO
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 #include <nitro/misc.h>
31 #include <nitro/types.h>
32 #include <nitro/memorymap.h>
33 #include <nitro/ioreg.h>
34 #include <nitro/os/common/thread.h>
35 
36 //---- for DMA, TIMER
37 void    OSi_EnterDmaCallback(u32 dmaNo, void (*callback) (void *), void *arg);
38 void    OSi_EnterTimerCallback(u32 timerNo, void (*callback) (void *), void *arg);
39 
40 //----------------------------------------------------------------------
41 //                  ENABLE/DISABLE flag for IME
42 //----------------------------------------------------------------------
43 #define OS_IME_DISABLE      (0UL << REG_OS_IME_IME_SHIFT)
44 #define OS_IME_ENABLE       (1UL << REG_OS_IME_IME_SHIFT)
45 
46 //----------------------------------------------------------------------
47 //                  IE/IF flags
48 //----------------------------------------------------------------------
49 #define OS_IE_V_BLANK       (1UL << REG_OS_IE_VB_SHIFT) 		//  0 VBlank
50 #define OS_IE_H_BLANK       (1UL << REG_OS_IE_HB_SHIFT) 		//  1 HBlank
51 #define OS_IE_V_COUNT       (1UL << REG_OS_IE_VE_SHIFT) 		//  2 VCounter
52 #define OS_IE_TIMER0        (1UL << REG_OS_IE_T0_SHIFT) 		//  3 timer0
53 #define OS_IE_TIMER1        (1UL << REG_OS_IE_T1_SHIFT) 		//  4 timer1
54 #define OS_IE_TIMER2        (1UL << REG_OS_IE_T2_SHIFT) 		//  5 timer2
55 #define OS_IE_TIMER3        (1UL << REG_OS_IE_T3_SHIFT) 		//  6 timer3
56 #define OS_IE_SIO           (1UL << 7                 ) 		//  7 serial communication (will not occur)
57 #define OS_IE_DMA0          (1UL << REG_OS_IE_D0_SHIFT) 		//  8 DMA0
58 #define OS_IE_DMA1          (1UL << REG_OS_IE_D1_SHIFT) 		//  9 DMA1
59 #define OS_IE_DMA2          (1UL << REG_OS_IE_D2_SHIFT) 		// 10 DMA2
60 #define OS_IE_DMA3          (1UL << REG_OS_IE_D3_SHIFT) 		// 11 DMA3
61 #define OS_IE_KEY           (1UL << REG_OS_IE_K_SHIFT)  		// 12 key
62 #define OS_IE_CARTRIDGE     (1UL << REG_OS_IE_I_D_SHIFT)        // 13 cartridge
63 #define OS_IE_SUBP          (1UL << REG_OS_IE_A7_SHIFT) 		// 16 sub processor
64 #define OS_IE_SPFIFO_SEND   (1UL << REG_OS_IE_IFE_SHIFT)        // 17 sub processor send FIFO empty
65 #define OS_IE_SPFIFO_RECV   (1UL << REG_OS_IE_IFN_SHIFT)        // 18 sub processor receive FIFO not empty
66 #define OS_IE_CARD_DATA     (1UL << REG_OS_IE_MC_SHIFT) 		// 19 card data transfer finish
67 #define OS_IE_CARD_IREQ     (1UL << REG_OS_IE_MI_SHIFT) 		// 20 card IREQ
68 
69 #ifdef SDK_ARM9
70 #define OS_IE_GXFIFO        (1UL << REG_OS_IE_GF_SHIFT) 		// 21 geometry command FIFO
71 #define OS_IRQ_TABLE_MAX     22
72 #define OS_IE_MASK_ALL      ((OSIrqMask)((1<<OS_IRQ_TABLE_MAX)-1))
73 
74 #else  //SDK_ARM7
75 #define OS_IE_POWERMAN      (1UL << REG_OS_IE_PM_SHIFT) 		// 22 Power Management IC
76 #define OS_IE_SPI           (1UL << REG_OS_IE_SPI_SHIFT)        // 23 SPI data transfer
77 #define OS_IE_WIRELESS      (1UL << REG_OS_IE_WL_SHIFT) 		// 24 Wireless module
78 #define OS_IRQ_TABLE_MAX     25
79 #define OS_IE_MASK_ALL      ((OSIrqMask)((1<<OS_IRQ_TABLE_MAX)-1))
80 
81 // Aliases to SUBP->MAINP
82 #define OS_IE_MAINP             OS_IE_SUBP
83 #define OS_IE_MPFIFO_SEND       OS_IE_SPFIFO_SEND
84 #define OS_IE_MPFIFO_RECV       OS_IE_SPFIFO_RECV
85 #define REG_OS_IE_A9_SHIFT      REG_OS_IE_A7_SHIFT
86 #endif
87 
88 // Aliases to common naming
89 #define OS_IE_FIFO_SEND         OS_IE_SPFIFO_SEND
90 #define OS_IE_FIFO_RECV         OS_IE_SPFIFO_RECV
91 
92 #ifdef SDK_NITRO
93 // Dummy irq check flag for user own use
94 //#define OS_IE_USER_FLAG0_SHIFT  		31
95 //#define OS_IE_USER_FLAG1_SHIFT  		30
96 //#define OS_IE_USER_FLAG0        		(1UL << OS_IE_USER_FLAG0_SHIFT) // user 0
97 //#define OS_IE_USER_FLAG1        		(1UL << OS_IE_USER_FLAG1_SHIFT) // user 1
98 #endif
99 
100 //---- used for internal functions
101 #define OSi_IRQCALLBACK_NO_DMA0    		0
102 #define OSi_IRQCALLBACK_NO_DMA1    		1
103 #define OSi_IRQCALLBACK_NO_DMA2    		2
104 #define OSi_IRQCALLBACK_NO_DMA3    		3
105 #define OSi_IRQCALLBACK_NO_TIMER0  		4
106 #define OSi_IRQCALLBACK_NO_TIMER1  		5
107 #define OSi_IRQCALLBACK_NO_TIMER2  		6
108 #define OSi_IRQCALLBACK_NO_TIMER3  		7
109 #ifdef SDK_ARM7
110 #define OSi_IRQCALLBACK_NO_VBLANK  		8
111 #endif
112 #ifdef SDK_ARM9
113 #define OSi_IRQCALLBACK_NUM       		(7+1)
114 #else
115 #define OSi_IRQCALLBACK_NUM       		(8+1)
116 #endif
117 
118 //----------------------------------------------------------------
119 #define OS_IRQ_MAIN_BUFFER_SIZE         (0x200)
120 
121 
122 //---- interrupt handler type
123 typedef void (*OSIrqFunction) (void);
124 
125 //---- for irq callback (internal use)
126 typedef struct
127 {
128     void    (*func) (void *);
129     u32     enable;
130     void   *arg;
131 }
132 OSIrqCallbackInfo;
133 
134 //---- irq factor type define
135 #ifndef OSi_OSIRQMASK_DEFINED
136 typedef u32 OSIrqMask;
137 #define OSi_OSIRQMASK_DEFINED
138 #endif
139 
140 //---- table of irq functions
141 extern OSIrqFunction OS_IRQTable[];
142 
143 //---- for DMA, TIMER, VBLANK(arm7) interrupt */
144 extern OSIrqCallbackInfo OSi_IrqCallbackInfo[OSi_IRQCALLBACK_NUM];
145 
146 
147 void    OS_IrqDummy(void);
148 void    OS_IrqHandler(void);
149 void    OS_IrqHandler_ThreadSwitch(void);
150 
151 //================================================================================
152 //              IRQ MASTER ENABLE
153 //================================================================================
154 /*---------------------------------------------------------------------------*
155   Name:         OS_EnableIrq
156 
157   Description:  enable master enable
158 
159   Arguments:    None
160 
161   Returns:      previous state of master enable.
162                 OS_IME_ENABLE or OS_IME_DISABLE.
163  *---------------------------------------------------------------------------*/
OS_EnableIrq(void)164 static inline BOOL OS_EnableIrq(void)
165 {
166     u16     prep = reg_OS_IME;
167     reg_OS_IME = OS_IME_ENABLE;
168     return (BOOL)prep;
169 }
170 
171 /*---------------------------------------------------------------------------*
172   Name:         OS_DisableIrq
173 
174   Description:  disable master enable
175 
176   Arguments:    None
177 
178   Returns:      previous status of master enable.
179                 OS_IME_ENABLE or OS_IME_DISABLE.
180  *---------------------------------------------------------------------------*/
OS_DisableIrq(void)181 static inline BOOL OS_DisableIrq(void)
182 {
183     u16     prep = reg_OS_IME;
184     reg_OS_IME = OS_IME_DISABLE;
185     return (BOOL)prep;
186 }
187 
188 /*---------------------------------------------------------------------------*
189   Name:         OS_RestoreIrq
190 
191   Description:  set master enable.
192                 this function is mainly used for restore previous state
193                 from OS_EnableIrq() or OS_DisableIrq().
194 
195   Arguments:    enable    OS_IME_ENABLE or OS_IME_DISABLE
196 
197   Returns:      previous state of master enable
198 
199  *---------------------------------------------------------------------------*/
OS_RestoreIrq(BOOL enable)200 static inline BOOL OS_RestoreIrq(BOOL enable)
201 {
202     u16     prep = reg_OS_IME;
203     reg_OS_IME = (u16)enable;
204     return (BOOL)prep;
205 }
206 
207 /*---------------------------------------------------------------------------*
208   Name:         OS_GetIrq
209 
210   Description:  get master enable.
211 
212   Arguments:    None
213 
214   Returns:      status of master enable.
215                 OS_IME_ENABLE or OS_IME_DISABLE.
216 
217  *---------------------------------------------------------------------------*/
OS_GetIrq(void)218 static inline BOOL OS_GetIrq(void)
219 {
220     return (BOOL)reg_OS_IME;
221 }
222 
223 //================================================================================
224 //              IRQ FACTORS
225 //================================================================================
226 /*---------------------------------------------------------------------------*
227   Name:         OS_SetIrqMask
228 
229   Description:  set irq factor
230 
231   Arguments:    intr        irq factor
232 
233   Returns:      previous factors
234  *---------------------------------------------------------------------------*/
235 OSIrqMask OS_SetIrqMask(OSIrqMask intr);
236 
237 /*---------------------------------------------------------------------------*
238   Name:         OS_GetIrqMask
239 
240   Description:  get irq factor
241 
242   Arguments:    None
243 
244   Returns:      irq factor which is set now
245  *---------------------------------------------------------------------------*/
OS_GetIrqMask(void)246 static inline OSIrqMask OS_GetIrqMask(void)
247 {
248     return reg_OS_IE;
249 }
250 
251 /*---------------------------------------------------------------------------*
252   Name:         OS_EnableIrqMask
253 
254   Description:  set specified irq factor
255 
256   Arguments:    intr        irq factor
257 
258   Returns:      previous factors
259  *---------------------------------------------------------------------------*/
260 OSIrqMask OS_EnableIrqMask(OSIrqMask intr);
261 
262 /*---------------------------------------------------------------------------*
263   Name:         OS_DisableIrqMask
264 
265   Description:  unset specified irq factor
266 
267   Arguments:    intr        irq factor
268 
269   Returns:      previous factors
270  *---------------------------------------------------------------------------*/
271 OSIrqMask OS_DisableIrqMask(OSIrqMask intr);
272 
273 //================================================================================
274 //              IF
275 //================================================================================
276 /*---------------------------------------------------------------------------*
277   Name:         OS_ResetRequestIrqMask
278 
279   Description:  reset IF bit
280                 (setting bit causes to clear bit for interrupt)
281 
282   Arguments:    intr        irq factor
283 
284   Returns:      previous factors
285  *---------------------------------------------------------------------------*/
286 OSIrqMask OS_ResetRequestIrqMask(OSIrqMask intr);
287 
288 /*---------------------------------------------------------------------------*
289   Name:         OS_GetReuestIrqMask
290 
291   Description:  get IF bit
292 
293   Arguments:    None
294 
295   Returns:      value of IF
296  *---------------------------------------------------------------------------*/
OS_GetRequestIrqMask(void)297 static inline OSIrqMask OS_GetRequestIrqMask(void)
298 {
299     return reg_OS_IF;
300 }
301 
302 //================================================================================
303 //              IRQ HANDLER
304 //================================================================================
305 /*---------------------------------------------------------------------------*
306   Name:         OS_InitIrqTable
307 
308   Description:  initialize irq table
309 
310   Arguments:    None
311 
312   Returns:      None
313  *---------------------------------------------------------------------------*/
314 void    OS_InitIrqTable(void);
315 
316 /*---------------------------------------------------------------------------*
317   Name:         OS_SetIrqFunction
318 
319   Description:  set irq handler for specified interrupt
320 
321   Arguments:    intrBit    irq factor
322                 function   irq handler for specified interrupt
323 
324   Returns:      None
325  *---------------------------------------------------------------------------*/
326 void    OS_SetIrqFunction(OSIrqMask intrBit, OSIrqFunction function);
327 
328 /*---------------------------------------------------------------------------*
329   Name:         OS_GetIrqFunction
330 
331   Description:  get irq handler for specified interrupt
332 
333   Arguments:    intrBit    irq factor
334 
335   Returns:      irq handler for specified interrupt
336  *---------------------------------------------------------------------------*/
337 OSIrqFunction OS_GetIrqFunction(OSIrqMask intrBit);
338 
339 
340 //================================================================================
341 //              IRQ CHEKE BUFFER
342 //================================================================================
343 /*---------------------------------------------------------------------------*
344   Name:         OS_SetIrqCheckFlag
345 
346   Description:  set irq flag to check being called
347 
348   Arguments:    irq factors to be set
349 
350   Returns:      None
351  *---------------------------------------------------------------------------*/
OS_SetIrqCheckFlag(OSIrqMask intr)352 static inline void OS_SetIrqCheckFlag(OSIrqMask intr)
353 {
354     *(vu32 *)HW_INTR_CHECK_BUF |= (u32)intr;
355 }
356 
357 /*---------------------------------------------------------------------------*
358   Name:         OS_ClearIrqCheckFlag
359 
360   Description:  clear irq flag stored in HW_INTR_CHECK_BUF
361 
362   Arguments:    irq factors to be cleared
363 
364   Returns:      None
365  *---------------------------------------------------------------------------*/
OS_ClearIrqCheckFlag(OSIrqMask intr)366 static inline void OS_ClearIrqCheckFlag(OSIrqMask intr)
367 {
368     *(vu32 *)HW_INTR_CHECK_BUF &= (u32)~intr;
369 }
370 
371 /*---------------------------------------------------------------------------*
372   Name:         OS_GetIrqCheckFlag
373 
374   Description:  get irq factors stored in HW_INTR_CHECK_BUF
375 
376   Arguments:    None
377 
378   Returns:      irq flags factors in HW_INTR_CHECK_BUG
379  *---------------------------------------------------------------------------*/
OS_GetIrqCheckFlag(void)380 static inline volatile OSIrqMask OS_GetIrqCheckFlag(void)
381 {
382     return *(volatile OSIrqMask *)HW_INTR_CHECK_BUF;
383 }
384 
385 
386 //================================================================================
387 //              WAIT IRQ
388 //================================================================================
389 /*---------------------------------------------------------------------------*
390   Name:         OS_WaitIrq
391 
392   Description:  wait specified interrupt
393                 the difference between OS_WaitIrq and OS_WaitInterrupt,
394                 in waiting interrupt
395                 OS_WaitIrq does switch thread,
396                 OS_WaitInterrupt doesn't switch thread.
397                 OS_WaitIrq wait by using OS_SleepThread() with threadQueue,
398                 OS_WaitInterrupt wait by using OS_Halt().
399                 if SDK_NO_THREAD defined, 2 functions become same.
400 
401   Arguments:    clear       TRUE if want to clear interrupt flag before wait
402                             FALSE if not
403                 irqFlags    bit of interrupts to wait for
404 
405   Returns:      None
406  *---------------------------------------------------------------------------*/
407 void    OS_WaitIrq(BOOL clear, OSIrqMask irqFlags);
408 
409 /*---------------------------------------------------------------------------*
410   Name:         OS_WaitAnyIrq
411 
412   Description:  wait any interrupt
413 
414   Arguments:    None
415 
416   Returns:      None
417  *---------------------------------------------------------------------------*/
418 void    OS_WaitAnyIrq(void);
419 
420 
421 //================================================================================
422 //              VBLANK COUNTER
423 //================================================================================
424 /*---------------------------------------------------------------------------*
425   Name:         OS_GetVBlankCount
426 
427   Description:  get VBlankCount
428 
429   Arguments:    None
430 
431   Returns:      VBlankCount
432  *---------------------------------------------------------------------------*/
OS_GetVBlankCount(void)433 static inline vu32 OS_GetVBlankCount(void)
434 {
435     return *(vu32 *)HW_VBLANK_COUNT_BUF;
436 }
437 
438 /*---------------------------------------------------------------------------*
439   Name:         OSi_SetVBlankCount
440 
441   Description:  set VBlankCount
442                 *** internal function. don't use this.
443 
444   Arguments:    count : VBlankCount
445 
446   Returns:      None
447  *---------------------------------------------------------------------------*/
OSi_SetVBlankCount(u32 count)448 static inline void OSi_SetVBlankCount(u32 count)
449 {
450     *(u32 *)HW_VBLANK_COUNT_BUF = count;
451 }
452 
453 //================================================================================
454 //              IRQ STACK CHECKER
455 //================================================================================
456 /*---------------------------------------------------------------------------*
457   Name:         OS_SetIrqStackWarningOffset
458 
459   Description:  Set warning level for irq stack checker
460 
461   Arguments:    offset     offset from stack top. must be multiple of 4
462 
463   Returns:      None
464  *---------------------------------------------------------------------------*/
465 extern void OS_SetIrqStackWarningOffset(u32 offset);
466 
467 /*---------------------------------------------------------------------------*
468   Name:         OS_GetIrqStackStatus
469 
470   Description:  check irq stack. check each CheckNUM.
471                 return result.
472 
473   Arguments:    None
474 
475   Returns:      0 (OS_STACK_NO_ERROR)        no error
476                 OS_STACK_OVERFLOW            overflow
477                 OS_STACK_ABOUT_TO_OVERFLOW   about to overflow
478                 OS_STACK_UNDERFLOW           underflow
479  *---------------------------------------------------------------------------*/
480 extern OSStackStatus OS_GetIrqStackStatus(void);
481 
482 /*---------------------------------------------------------------------------*
483   Name:         OS_SetIrqStackChecker
484 
485   Description:  set irq stack check number to irq stack
486 
487   Arguments:    None
488 
489   Returns:      None
490  *---------------------------------------------------------------------------*/
491 extern void OS_SetIrqStackChecker(void);
492 
493 /*---------------------------------------------------------------------------*
494   Name:         OS_CheckIrqStack
495 
496   Description:  check irq stack. check each CheckNum.
497                 if changed, display warning and halt.
498 
499   Arguments:    None
500 
501   Returns:      None.
502                 ( if error occurred, never return )
503  *---------------------------------------------------------------------------*/
504 void    OSi_CheckIrqStack(char *file, int line);
505 #if !defined(SDK_FINALROM) && !defined(SDK_NO_MESSAGE)
506 #define  OS_CheckIrqStack()  OSi_CheckIrqStack( __FILE__, __LINE__ );
507 #else
508 #define  OS_CheckIrqStack()  ((void)0)
509 #endif
510 
511 
512 #ifdef __cplusplus
513 } /* extern "C" */
514 #endif
515 
516 #endif
517 /* SDK_NITRO */
518 
519 /* NITRO_OS_INTERRUPT_H_ */
520 #endif
521