1 /*---------------------------------------------------------------------------* 2 Project: TwlSDK - MI - 3 File: dma_red.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 *---------------------------------------------------------------------------*/ 18 19 #ifndef NITRO_MI_DMA_RED_H_ 20 #define NITRO_MI_DMA_RED_H_ 21 22 #ifdef __cplusplus 23 extern "C" { 24 #endif 25 26 #include <nitro/misc.h> 27 #include <nitro/types.h> 28 #include <nitro/memorymap.h> 29 #include <nitro/os/systemCall.h> 30 #include <nitro/mi/dma.h> 31 32 //---------------------------------------------------------------- 33 // Interface created by Research & Engineering 34 // Kept by request. 35 // Comes here without being included in nitro-sdk/include/nitro/mi/dma.h. 36 // 37 38 //---------------------------------------------------------------------- 39 // DMA Setting 40 //---------------------------------------------------------------------- 41 //#define SIMULATOR 42 #ifndef SIMULATOR 43 #define __MI_DmaSet(dmaNo, srcp, destp, dmaCntData) \ 44 { \ 45 vu32 *dmaCntp = &((vu32 *)REG_DMA0SAD_ADDR)[dmaNo * 3]; \ 46 dmaCntp[0] = (vu32 )(srcp); \ 47 dmaCntp[1] = (vu32 )(destp); \ 48 dmaCntp[2] = (vu32 )(dmaCntData); \ 49 {u32 dummy = dmaCntp[2];} \ 50 {u32 dummy = dmaCntp[2];} \ 51 } 52 #define __MI_DmaSetAsync(dmaNo, srcp, destp, dmaCntData) \ 53 { \ 54 vu32 *dmaCntp = &((vu32 *)REG_DMA0SAD_ADDR)[dmaNo * 3]; \ 55 dmaCntp[0] = (vu32 )(srcp); \ 56 dmaCntp[1] = (vu32 )(destp); \ 57 dmaCntp[2] = (vu32 )(dmaCntData); \ 58 } 59 #else 60 #define __MI_DmaSet(dmaNo, srcp, destp, dmaCntData) \ 61 { \ 62 int i; \ 63 for (i=0; i<(dmaCntData & 0x1ffff); i++) \ 64 if ((dmaCntData) & MI_DMA_SRC_FIX) { \ 65 if ((dmaCntData) & MI_DMA_32BIT_BUS) \ 66 ((vu32 *)(destp))[i] = ((vu32 *)(srcp))[0]; \ 67 else ((vu16 *)(destp))[i] = ((vu16 *)(srcp))[0]; \ 68 } else { \ 69 if ((dmaCntData) & MI_DMA_32BIT_BUS) \ 70 ((vu32 *)(destp))[i] = ((vu32 *)(srcp))[i]; \ 71 else ((vu16 *)(destp))[i] = ((vu16 *)(srcp))[i]; \ 72 } \ 73 } 74 #define __MI_DmaSetAsync(dmaNo, srcp, destp, dmaCntData) \ 75 __MI_DmaSet( dmaNo, srcp, destp, dmaCntData) 76 #endif 77 78 //- Set parameter in DMA controller. 79 //- When SIMULATER is defined, then simulation occurs on the CPU. 80 // Enabled during situations such as debugging with GDB. 81 //- Finally, the "LDR" command is inserted to wait for DMA to start. 82 // 83 //Arguments: 84 // dmaNo: DMA number 85 // srcp: Source address 86 // destp: Destination address 87 // dmaCntData: Parameter data 88 // 89 //Note: When DMA is started by a program in the CPU internal RAM, the next instruction will be executed first 90 // 91 // Therefore, if an attempt is made to change the transfer destination in the CPU immediately after starting DMA, the DMA transfer destination data sometimes becomes an unintended value because DMA starts up during read/write 92 // 93 // 94 // In that case, the impact on subsequent code can be avoided by inserting WaitDma() immediately after, and checking if DMA has finished or not 95 // 96 97 98 //---------------------------------------------------------------------- 99 // DMA Clear 100 //---------------------------------------------------------------------- 101 102 #define __MI_DmaClear(dmaNo, data, destp, size, bit) \ 103 { \ 104 *(vu##bit *)HW_DMA_CLEAR_DATA_BUF = (vu##bit )(data); \ 105 __MI_DmaSet(dmaNo, HW_DMA_CLEAR_DATA_BUF, destp, ( \ 106 MI_DMA_ENABLE | MI_DMA_TIMING_IMM | \ 107 MI_DMA_SRC_FIX | MI_DMA_DEST_INC | \ 108 MI_DMA_##bit##BIT_BUS | ((size)/(bit/8)))); \ 109 } 110 111 #define __MI_DmaClearIf(dmaNo, data, destp, size, bit) \ 112 { \ 113 *(vu##bit *)DMA_CLEAR_DATA_BUF = (vu##bit )(data); \ 114 __MI_DmaSet(dmaNo, DMA_CLEAR_DATA_BUF, destp, ( \ 115 MI_DMA_ENABLE | MI_DMA_TIMING_IMM | \ 116 MI_DMA_IF_ENABLE | \ 117 MI_DMA_SRC_FIX | MI_DMA_DEST_INC | \ 118 MI_DMA_##bit##BIT_BUS | ((size)/(bit/8)))); \ 119 } 120 121 #define __MI_DmaClearArray( dmaNo, data, destp, bit) \ 122 __MI_DmaClear( dmaNo, data, destp, sizeof(destp), bit) 123 124 #define MI_DmaClearArrayIf(dmaNo, data, destp, bit) \ 125 __MI_DmaClearIf( dmaNo, data, destp, sizeof(destp), bit) 126 127 //- Clear RAM with DMA 128 //- Clear data is put in stack, and that is copied to the destination. 129 //- When MI_DmaClearIf or MI_DmaClearArrayIf ends, they generate an interrupt request. 130 //- MI_DmaClearArray/MI_DmaClearArrayIf clears entire destination array. 131 // 132 //Arguments: 133 // dmaNo: DMA number 134 // data: Clear data 135 // destp: Destination address 136 // size: Number of cleared bytes 137 // bit: Transfer bit width (16|32) 138 // 139 // 140 //Note: When DMA is started by a program in the CPU internal RAM, the next instruction will be executed first 141 // 142 // Therefore, if an attempt is made to change the transfer destination in the CPU immediately after starting DMA, the DMA transfer destination data sometimes becomes an unintended value because DMA starts up during read/write 143 // 144 // 145 // In that case, the impact on subsequent code can be avoided by inserting WaitDma() immediately after, and checking if DMA has finished or not 146 // 147 148 //---------------------------------------------------------------------- 149 // DMA Copy 150 //---------------------------------------------------------------------- 151 152 #define __MI_DmaCopy(dmaNo, srcp, destp, size, bit) \ 153 \ 154 __MI_DmaSet(dmaNo, srcp, destp, ( \ 155 MI_DMA_ENABLE | MI_DMA_TIMING_IMM | \ 156 MI_DMA_SRC_INC | MI_DMA_DEST_INC | \ 157 MI_DMA_##bit##BIT_BUS | ((size)/((bit)/8)))) 158 159 #define __MI_DmaCopyIf(dmaNo, srcp, destp, size, bit) \ 160 \ 161 __MI_DmaSet(dmaNo, srcp, destp, ( \ 162 MI_DMA_ENABLE | MI_DMA_TIMING_IMM | \ 163 MI_DMA_IF_ENABLE | \ 164 MI_DMA_SRC_INC | MI_DMA_DEST_INC | \ 165 MI_DMA_##bit##BIT_BUS | ((size)/(bit/8)))) 166 167 #define __MI_DmaCopyArray( dmaNo, srcp, destp, bit) \ 168 __MI_DmaCopy( dmaNo, srcp, destp, sizeof(srcp), bit) 169 170 #define __MI_DmaCopyArrayIf(dmaNo, srcp, destp, bit) \ 171 __MI_DmaCopyIf( dmaNo, srcp, destp, sizeof(srcp), bit) 172 173 //- Copy using DMA. 174 //- When MI_DmaCopyIf or MI_DmaCopyArrayIf ends, they generate an interrupt request. 175 //- MI_DmaCopyArray/MI_DmaCopyArrayIf copy the entire source array. 176 // 177 //Arguments: 178 // dmaNo: DMA number 179 // srcp: Source address 180 // destp: Destination address 181 // size: Number of transfer bytes 182 // bit: Transfer bit width (16|32) 183 // 184 // 185 //Note: When DMA is started by a program in the CPU internal RAM, the next instruction will be executed first 186 // 187 // Therefore, if an attempt is made to change the transfer destination in the CPU immediately after starting DMA, the DMA transfer destination data sometimes becomes an unintended value because DMA starts up during read/write 188 // 189 // 190 // In that case, the impact on subsequent code can be avoided by inserting WaitDma() immediately after, and checking if DMA has finished or not 191 // 192 193 //---------------------------------------------------------------------- 194 // H-Blank DMA Copy 195 //---------------------------------------------------------------------- 196 197 #define __MI_H_DmaCopy(dmaNo, srcp, destp, size, bit) \ 198 \ 199 __MI_DmaSet(dmaNo, srcp, destp, ( \ 200 MI_DMA_ENABLE | MI_DMA_TIMING_H_BLANK | \ 201 MI_DMA_SRC_INC | MI_DMA_DEST_RELOAD | \ 202 MI_DMA_CONTINUOUS_ON | \ 203 MI_DMA_##bit##BIT_BUS | ((size)/((bit)/8)))) 204 205 #define __MI_H_DmaCopyIf(dmaNo, srcp, destp, size, bit) \ 206 \ 207 __MI_DmaSet(dmaNo, srcp, destp, ( \ 208 MI_DMA_ENABLE | MI_DMA_TIMING_H_BLANK | \ 209 MI_DMA_IF_ENABLE | \ 210 MI_DMA_SRC_INC | MI_DMA_DEST_RELOAD | \ 211 MI_DMA_CONTINUOUS_ON | \ 212 MI_DMA_##bit##BIT_BUS | ((size)/(bit/8)))) 213 214 #define __MI_H_DmaCopyArray( dmaNo, srcp, destp, bit) \ 215 __MI_H_DmaCopy( dmaNo, srcp, destp, sizeof(srcp), bit) 216 217 #define __MI_H_DmaCopyArrayIf(dmaNo, srcp, destp, bit) \ 218 __MI_H_DmaCopyIf( dmaNo, srcp, destp, sizeof(srcp), bit) 219 220 //- Synchronizes with H-Blank and copies using DMA. 221 //- When MI_H_DmaCopyIf or MI_H_DmaCopyArrayIf ends, they generate an interrupt request. 222 //- MI_H_DmaCopyArray or MI_H_DmaCopyArrayIf copies the entire source array. 223 // 224 //Arguments: 225 // dmaNo: DMA number 226 // srcp: Source address 227 // destp: Destination address 228 // size: Number of transfer bytes 229 // bit: Transfer bit width (16|32) 230 231 //---------------------------------------------------------------------- 232 // V-Blank DMA Copy 233 //---------------------------------------------------------------------- 234 235 #define __MI_V_DmaCopy(dmaNo, srcp, destp, size, bit) \ 236 \ 237 __MI_DmaSet(dmaNo, srcp, destp, ( \ 238 MI_DMA_ENABLE | MI_DMA_TIMING_V_BLANK | \ 239 MI_DMA_SRC_INC | MI_DMA_DEST_INC | \ 240 MI_DMA_##bit##BIT_BUS | ((size)/(bit/8)))) 241 242 #define __MI_V_DmaCopyIf(dmaNo, srcp, destp, size, bit) \ 243 \ 244 __MI_DmaSet(dmaNo, srcp, destp, ( \ 245 MI_DMA_ENABLE | MI_DMA_TIMING_V_BLANK | \ 246 MI_DMA_IF_ENABLE | \ 247 MI_DMA_SRC_INC | MI_DMA_DEST_INC | \ 248 MI_DMA_##bit##BIT_BUS | ((size)/(bit/8)))) 249 250 #define __MI_V_DmaCopyArray( dmaNo, srcp, destp, bit) \ 251 __MI_V_DmaCopy( dmaNo, srcp, destp, sizeof(srcp), bit) 252 253 #define __MI_V_DmaCopyArrayIf(dmaNo, srcp, destp, bit) \ 254 __MI_V_DmaCopyIf( dmaNo, srcp, destp, sizeof(srcp), bit) 255 256 //- Synchronizes with V-Blank and copies using DMA. 257 //- When MI_V_DmaCopyIf or MI_V_DmaCopyArrayIf ends, they generate an interrupt request. 258 //- MI_V_DmaCopyArray or MI_V_DmaCopyArrayIf copies entire source array. 259 // 260 //Arguments: 261 // dmaNo: DMA number 262 // srcp: Source address 263 // destp: Destination address 264 // size: Number of transfer bytes 265 // bit: Transfer bit width (16|32) 266 267 //---------------------------------------------------------------------- 268 // Main Memory Display DMA 269 //---------------------------------------------------------------------- 270 271 #define __MI_DmaDispMainmem(dmaNo, srcp) \ 272 \ 273 __MI_DmaSet(dmaNo, srcp, REG_DISP_MMEM_FIFO_ADDR, ( \ 274 MI_DMA_ENABLE | MI_DMA_TIMING_DISP_MMEM | \ 275 MI_DMA_SRC_INC | MI_DMA_DEST_FIX | \ 276 MI_DMA_CONTINUOUS_ON | \ 277 MI_DMA_32BIT_BUS | (4))) 278 279 //- Performs a DMA transfer to display an image that is in main memory. 280 // 281 //Arguments: 282 // dmaNo: DMA number 283 // srcp: Source address 284 285 //---------------------------------------------------------------------- 286 // Geometry FIFO-DMA 287 //---------------------------------------------------------------------- 288 289 #define __MI_GX_Dma(dmaNo, srcp, length) \ 290 \ 291 __MI_DmaSetAsync(dmaNo, srcp, REG_GXFIFO_ADDR, ( \ 292 MI_DMA_ENABLE | MI_DMA_TIMING_GXFIFO | \ 293 MI_DMA_SRC_INC | MI_DMA_DEST_FIX | \ 294 MI_DMA_32BIT_BUS | (length))) 295 296 #define __MI_GX_DmaIf(dmaNo, srcp, length) \ 297 \ 298 __MI_DmaSetAsync(dmaNo, srcp, REG_GXFIFO_ADDR ( \ 299 MI_DMA_ENABLE | MI_DMA_TIMING_GXFIFO | \ 300 MI_DMA_IF_ENABLE | \ 301 MI_DMA_SRC_INC | MI_DMA_DEST_FIX | \ 302 MI_DMA_32BIT_BUS | (length))) 303 304 #define __MI_GX_DmaFast(dmaNo, srcp, length) \ 305 \ 306 __MI_DmaSetAsync(dmaNo, srcp, REG_GXFIFO_ADDR, ( \ 307 MI_DMA_ENABLE | MI_DMA_TIMING_IMM | \ 308 MI_DMA_SRC_INC | MI_DMA_DEST_FIX | \ 309 MI_DMA_32BIT_BUS | (length))) 310 311 #define __MI_GX_DmaFastIf(dmaNo, srcp, length) \ 312 \ 313 __MI_DmaSetAsync(dmaNo, srcp, REG_GXFIFO_ADDR, ( \ 314 DMA_ENABLE | DMA_TIMING_IMM | \ 315 DMA_IF_ENABLE | \ 316 DMA_SRC_INC | DMA_DEST_FIX | \ 317 DMA_32BIT_BUS | (length))) 318 319 #define __MI_GX_DmaArray( dmaNo, srcp, destp, bit) \ 320 __MI_GX_Dma( dmaNo, srcp, destp, sizeof(srcp), bit) 321 322 #define __MI_GX_DmaArrayIf(dmaNo, srcp, destp, bit) \ 323 __MI_GX_DmaIf(dmaNo, srcp, destp, sizeof(srcp), bit) 324 325 #define __MI_GX_DmaArrayFast( dmaNo, srcp, destp, bit) \ 326 __MI_GX_DmaFast( dmaNo, srcp, destp, sizeof(srcp), bit) 327 328 #define __MI_GX_DmaArrayFastIf(dmaNo, srcp, destp, bit) \ 329 __MI_GX_DmaFastIf(dmaNo, srcp, destp, sizeof(srcp), bit) 330 331 //- Copies using DMA by request from geometry FIFO. 332 //- MI_GX_DmaIf, MI_GX_DmaArrayIf, MI_GX_DmaFastIf, or MI_GX_DmaArrayFastIf generate interrupt requests when ending. 333 // 334 //- MI_GX_DmaArray, MI_GX_DmaArrayIf, MI_GX_DmaArrayFast, and MI_GX_DmaArrayFastIf copy the entire source array. 335 // 336 // 337 //Arguments: 338 // dmaNo: DMA number 339 // srcp: Source address 340 // size: Number of transfer bytes 341 342 343 //---------------------------------------------------------------------- 344 // Wait for DMA End 345 //---------------------------------------------------------------------- 346 347 #define __MI_WaitDma(dmaNo) \ 348 { \ 349 vu32 *(dmaCntp) = &((vu32 *)REG_DMA0SAD_ADDR)[dmaNo * 3]; \ 350 while (dmaCntp[2] & MI_DMA_ENABLE) ; \ 351 } 352 353 //- Wait for end of DMA 354 // 355 //Arguments: 356 // dmaNo: DMA number 357 358 359 //---------------------------------------------------------------------- 360 // DMA Stop 361 //---------------------------------------------------------------------- 362 363 #define __MI_StopDma(dmaNo) \ 364 { \ 365 vu16* dmaCntp = &((vu16 *)REG_DMA0SAD_ADDR)[dmaNo * 6]; \ 366 dmaCntp[5] &= ~((MI_DMA_TIMING_MASK | MI_DMA_CONTINUOUS_ON) \ 367 >> 16); \ 368 dmaCntp[5] &= ~( MI_DMA_ENABLE >> 16); \ 369 {u32 dummy = dmaCntp[5];} \ 370 {u32 dummy = dmaCntp[5];} \ 371 } 372 373 //- Stops DMA. 374 //- However, DMA runs only once if automatically started during processing. 375 // 376 //Arguments: 377 // dmaNo: DMA number 378 379 380 //---------------------------------------------------------------------- 381 // CPU Clear 382 //---------------------------------------------------------------------- 383 384 #define __MI_CpuClear(data, destp, size, bit) UTL_CpuClear##bit(data, (void *)(destp), size) 385 386 #define __MI_CpuClearArray(data, destp, bit) \ 387 __MI_CpuClear( data, destp, sizeof(destp), bit) 388 389 //- Calls system call that does RAM clear on CPU. 390 //- Clear data is put in stack, and that is copied to the destination. 391 //- CpuClearArray clears entire destination array. 392 // 393 //Arguments: 394 // data: Clear data 395 // destp: Destination address 396 // size: Number of cleared bytes 397 // bit: Transfer bit width (16|32) 398 399 //---------------------------------------------------------------------- 400 // CPU Copy 401 //---------------------------------------------------------------------- 402 403 #define __MI_CpuCopy(srcp, destp, size, bit) UTL_CpuCopy##bit((void *)(srcp), (void *)(destp), size) 404 405 #define __MI_CpuCopyArray(srcp, destp, bit) \ 406 __MI_CpuCopy( srcp, destp, sizeof(srcp), bit) 407 408 //- Calls system call that does copy on CPU. 409 //- CpuCopyArray copies entire source array. 410 // 411 //Arguments: 412 // srcp: Source address 413 // destp: Destination address 414 // size: Number of transfer bytes 415 // bit: Transfer bit width (16|32) 416 417 //---------------------------------------------------------------------- 418 // CPU High-Speed Clear (32-byte units) 419 //---------------------------------------------------------------------- 420 421 #define __MI_CpuClearFast(data, destp, size) UTL_CpuClearFast(data, (void *)(destp), size) 422 423 #define MI_CpuClearArrayFast(data, destp) \ 424 __MI_CpuClearFast( data, destp, sizeof(destp)) 425 426 //- Calls a system call that rapidly clears RAM in the CPU. 427 //- Clear data is put in stack, and that is copied to the destination. 428 //- CpuClearArrayFast clears entire destination array. 429 // 430 //Arguments: 431 // data: Clear data 432 // destp: Destination address 433 // size: Number of cleared bytes 434 435 //---------------------------------------------------------------------- 436 // CPU High-Speed Copy (32-byte unit) 437 //---------------------------------------------------------------------- 438 439 #define __MI_CpuCopyFast(srcp, destp, size) UTL_CpuCopyFast((void *)(srcp), (void *)(destp), size) 440 441 442 #define MI_CpuCopyArrayFast(srcp, destp) \ 443 __MI_CpuCopyFast( srcp, destp, sizeof(srcp)) 444 445 //- Calls a system call that rapidly copies in the CPU. 446 //- CpuCopyArrayFast copies entire source array. 447 // 448 //Arguments: 449 // srcp: Source address 450 // destp: Destination address 451 // size: Number of transfer bytes 452 453 454 455 456 457 #ifdef __cplusplus 458 } /* extern "C" */ 459 #endif 460 461 /* NITRO_MI_DMA_RED_H_ */ 462 #endif 463