1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - MI
3   File:     mi_dma.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-09-18#$
14   $Rev: 8573 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 #ifndef NITRO_COMMON_MI_DMA_H_
18 #define NITRO_COMMON_MI_DMA_H_
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 #include <nitro.h>
25 
26 //================================================================================
27 //          DMA system work
28 //================================================================================
29 #ifdef SDK_ARM9
30 # define MIi_DMA_CLEAR_DATA_BUF    REG_DMA0_CLR_DATA_ADDR      // ARM9-TS:  defined ARM9/ioreg_MI.h
31 #else  // ifdef SDK_ARM9
32 # define MIi_DMA_CLEAR_DATA_BUF     HW_PRV_WRAM_DMA_CLEAR_DATA_BUF      // ARM7:  defined ARM7/mmap_wram.h
33 #endif // ifdef SDK_ARM9
34 
35 typedef union
36 {
37     u32     b32;
38     u16     b16;
39 }
40 MIiDmaClearSrc;
41 
42 //================================================================================
43 //          setting DMA
44 //================================================================================
45 //---------------- set parameters
46 #define MIi_DMA_MODE_NOINT		1
47 #define MIi_DMA_MODE_WAIT		2
48 #define MIi_DMA_MODE_NOCLEAR	4
49 #define MIi_DMA_MODE_SRC32      0x10
50 #define MIi_DMA_MODE_SRC16      0x20
51 
52 void MIi_DmaSetParameters(u32 dmaNo, u32 src, u32 dest, u32 ctrl, u32 mode);
53 
54 //================================================================================
55 //          CALLBACK
56 //================================================================================
57 extern void OSi_EnterDmaCallback(u32 dmaNo, MIDmaCallback callback, void *arg);
58 
MIi_CallCallback(MIDmaCallback callback,void * arg)59 static inline void MIi_CallCallback(MIDmaCallback callback, void *arg)
60 {
61     if (callback)
62     {
63         (callback) (arg);
64     }
65 }
66 
67 //================================================================================
68 //          WAIT
69 //================================================================================
70 //----------------------------------------------------------------
71 //     for waiting DMA busy
72 #define MIi_Wait_BeforeDMA( dmaCntp, dmaNo )                  \
73     do {                                                      \
74       dmaCntp = &((vu32*)REG_DMA0SAD_ADDR)[dmaNo * 3 + 2];    \
75       MIi_ASSERT_DMANO( dmaNo );                              \
76       while ( *dmaCntp & REG_MI_DMA0CNT_E_MASK ) {}           \
77     }while(0)
78 
79 #define MIi_Wait_AfterDMA( dmaCntp )                          \
80     do {                                                      \
81       while ( *dmaCntp & REG_MI_DMA0CNT_E_MASK ) {}           \
82     }while(0)
83 
84 
85 //================================================================================
86 //         ASSERT
87 //================================================================================
88 #define MIi_ASSERT_DMANO( dmaNo )        SDK_ASSERTMSG( (dmaNo) <= MI_DMA_MAX_NUM, "illegal DMA No." )
89 #define MIi_ASSERT_MUL2( size )          SDK_ASSERTMSG( ((size) & 1) == 0, "size & 1 must be 0" )
90 #define MIi_ASSERT_MUL4( size )          SDK_ASSERTMSG( ((size) & 3) == 0, "size & 3 must be 0" )
91 #define MIi_ASSERT_SRC_ALIGN512( src )   SDK_ASSERTMSG( ((u32)(src) & 511) == 0, "source address must be in 512-byte alignment" )
92 #define MIi_ASSERT_SRC_ALIGN4( src )     SDK_ASSERTMSG( ((u32)(src) & 3) == 0, "source address must be in 4-byte alignment" )
93 #define MIi_ASSERT_SRC_ALIGN2( src )     SDK_ASSERTMSG( ((u32)(src) & 1) == 0, "source address must be in 2-byte alignment" )
94 #define MIi_ASSERT_DEST_ALIGN4( dest )   SDK_ASSERTMSG( ((u32)(dest) & 3) == 0, "destination address must be in 4-byte alignment" )
95 #define MIi_ASSERT_DEST_ALIGN2( dest )   SDK_ASSERTMSG( ((u32)(dest) & 1) == 0, "destination address must be in 2-byte alignment" )
96 
97 #ifdef SDK_ARM9
98 #  define MIi_ASSERT_SIZE( dmaNo, size ) SDK_ASSERTMSG( (size) <= 0x1fffff, "size too large" );
99 #else  //SDK_ARM7
100 #  define MIi_ASSERT_SIZE( dmaNo, size )                        \
101     do{                                                         \
102         if ( dmaNo <= 2 )                                       \
103         {                                                       \
104             SDK_ASSERTMSG( (size) <= 0x3fff, "size too large" );\
105         }                                                       \
106         else                                                    \
107         {                                                       \
108             SDK_ASSERTMSG( (size) <= 0xffff, "size too large" );\
109         }                                                       \
110     } while(0)
111 #endif
112 
113 
114 //================================================================================
115 //         CHECK
116 //================================================================================
117 //----------------------------------------------------------------
118 //      Check if specified area is in ITCM/DTCM.
119 //
120 #if defined( SDK_ARM9 ) && defined( SDK_DEBUG )
121 void    MIi_CheckAddressInTCM(u32 addr, u32 size);
122 #define MIi_WARNING_ADDRINTCM( addr, size )  MIi_CheckAddressInTCM( (u32)addr, (u32)size )
123 #else
124 #define MIi_WARNING_ADDRINTCM( addr, size )  ((void)0)
125 #endif
126 
127 
128 //----------------------------------------------------------------
129 //      for DMA check
130 //      (must avoid multiple auto start DMA)
131 //
132 #ifdef SDK_ARM9
133 void    MIi_CheckAnotherAutoDMA(u32 dmaNo, u32 dmaType);
134 #endif
135 
136 //----------------------------------------------------------------
137 //      for DMA0 check
138 //       Source address which is in I/O register or cartridge bus
139 //       is not available.
140 void    MIi_CheckDma0SourceAddress(u32 dmaNo, u32 src, u32 size, u32 dir);
141 
142 //================================================================================
143 //           dummy DMA for multi DMA problem
144 //================================================================================
145 #define MIi_DUMMY_DMA_NO   0
146 #define MIi_DUMMY_SRC      0
147 #define MIi_DUMMY_DEST     0
148 #define MIi_DUMMY_CNT      ( MI_DMA_ENABLE | MI_DMA_SRC_FIX | MI_DMA_DEST_FIX | MI_DMA_16BIT_BUS | 1 )
149 
150 #ifdef __cplusplus
151 } /* extern "C" */
152 #endif
153 
154 /* MI_COMMON_MI_DMA_H_ */
155 #endif
156