arm9 MI_dma

This commit is contained in:
red031000
2020-06-29 22:37:12 +01:00
parent a0d97c8515
commit 32fee85569
6 changed files with 369 additions and 492 deletions
+1
View File
@@ -971,6 +971,7 @@ SECTIONS {
SDK_AUTOLOAD.ITCM.START = .;
OS_irqHandler.o (.itcm)
OS_reset.o (.itcm)
MI_dma.o (.itcm)
arm9_itcm.o (.text)
. = ALIGN(32);
SDK_AUTOLOAD.ITCM.END = .;
-385
View File
@@ -1,385 +0,0 @@
.include "asm/macros.inc"
.include "global.inc"
.text
arm_func_start MIi_CheckDma0SourceAddress
MIi_CheckDma0SourceAddress:
stmdb sp!, {lr}
sub sp, sp, #0x4
cmp r0, #0x0
addne sp, sp, #0x4
ldmneia sp!, {lr}
bxne lr
cmp r3, #0x0
and r0, r1, #0xff000000
beq _020CD8A4
cmp r3, #0x800000
subeq r1, r1, r2
b _020CD8A8
_020CD8A4:
add r1, r1, r2
_020CD8A8:
cmp r0, #0x4000000
beq _020CD8D4
cmp r0, #0x8000000
bhs _020CD8D4
and r0, r1, #0xff000000
cmp r0, #0x4000000
beq _020CD8D4
cmp r0, #0x8000000
addcc sp, sp, #0x4
ldmccia sp!, {lr}
bxcc lr
_020CD8D4:
bl OS_Terminate
add sp, sp, #0x4
ldmia sp!, {lr}
bx lr
arm_func_start MIi_CheckAnotherAutoDMA
MIi_CheckAnotherAutoDMA: ; 0x020CD8E4
stmdb sp!, {r4-r7,lr}
sub sp, sp, #0x4
ldr r4, _020CD994 ; =0x040000B8
mov r7, r0
mov r6, r1
mov r5, #0x0
_020CD8FC:
cmp r5, r7
beq _020CD978
ldr r1, [r4, #0x0]
ands r0, r1, #0x80000000
beq _020CD978
and r0, r1, #0x38000000
cmp r0, r6
beq _020CD978
cmp r0, #0x8000000
bne _020CD92C
cmp r6, #0x10000000
beq _020CD978
_020CD92C:
cmp r0, #0x10000000
bne _020CD93C
cmp r6, #0x8000000
beq _020CD978
_020CD93C:
cmp r0, #0x18000000
beq _020CD974
cmp r0, #0x20000000
beq _020CD974
cmp r0, #0x28000000
beq _020CD974
cmp r0, #0x30000000
beq _020CD974
cmp r0, #0x38000000
beq _020CD974
cmp r0, #0x8000000
beq _020CD974
cmp r0, #0x10000000
bne _020CD978
_020CD974:
bl OS_Terminate
_020CD978:
add r5, r5, #0x1
cmp r5, #0x3
add r4, r4, #0xc
blt _020CD8FC
add sp, sp, #0x4
ldmia sp!, {r4-r7,lr}
bx lr
.balign 4
_020CD994: .word 0x040000B8
arm_func_start MI_StopDma
MI_StopDma: ; 0x020CD998
stmdb sp!, {r4,lr}
mov r4, r0
bl OS_DisableInterrupts
mov r1, #0x6
mul r1, r4, r1
add r1, r1, #0x5
mov r1, r1, lsl #0x1
add r1, r1, #0x4000000
ldrh r2, [r1, #0xb0]
cmp r4, #0x0
bic r2, r2, #0x3a00
strh r2, [r1, #0xb0]
ldrh r2, [r1, #0xb0]
bic r2, r2, #0x8000
strh r2, [r1, #0xb0]
ldrh r2, [r1, #0xb0]
ldrh r1, [r1, #0xb0]
bne _020CDA08
mov r1, #0xc
mul r12, r4, r1
ldr r1, _020CDA14 ; =0x040000B0
add r2, r12, #0x4000000
mov r3, #0x0
str r3, [r2, #0xb0]
add r2, r12, r1
ldr r1, _020CDA18 ; =0x81400001
str r3, [r2, #0x4]
str r1, [r2, #0x8]
_020CDA08:
bl OS_RestoreInterrupts
ldmia sp!, {r4,lr}
bx lr
.balign 4
_020CDA14: .word 0x040000B0
_020CDA18: .word 0x81400001
arm_func_start MI_WaitDma
MI_WaitDma:
stmdb sp!, {r4,lr}
mov r4, r0
bl OS_DisableInterrupts
mov r1, #0x3
mul r2, r4, r1
ldr r1, _020CDA84 ; =0x040000B0
add r2, r2, #0x2
add r2, r1, r2, lsl #0x2
_020CDA3C:
ldr r1, [r2, #0x0]
ands r1, r1, #0x80000000
bne _020CDA3C
cmp r4, #0x0
bne _020CDA78
mov r1, #0xc
mul r12, r4, r1
ldr r1, _020CDA84 ; =0x040000B0
add r2, r12, #0x4000000
mov r3, #0x0
str r3, [r2, #0xb0]
add r2, r12, r1
ldr r1, _020CDA88 ; =0x81400001
str r3, [r2, #0x4]
str r1, [r2, #0x8]
_020CDA78:
bl OS_RestoreInterrupts
ldmia sp!, {r4,lr}
bx lr
.balign 4
_020CDA84: .word 0x040000B0
_020CDA88: .word 0x81400001
arm_func_start MI_DmaCopy32Async
MI_DmaCopy32Async: ; 0x020CDA8C
stmdb sp!, {r4-r8,lr}
mov r5, r3
mov r6, r2
mov r2, r5
mov r3, #0x0
mov r8, r0
mov r7, r1
ldr r4, [sp, #0x18]
bl MIi_CheckDma0SourceAddress
_020CDAB0:
cmp r5, #0x0
bne _020CDAD4
cmp r4, #0x0
ldmeqia sp!, {r4-r8, lr}
bxeq lr
ldr r0, [sp, #0x1C]
blx r4
ldmia sp!, {r4-r8, lr}
bx lr
_020CDAD4:
mov r0, r8
bl MI_WaitDma
cmp r4, #0x0
beq _020CDB14
ldr r2, [sp, #0x1C]
mov r0, r8
mov r1, r4
bl OSi_EnterDmaCallback
mov r3, r5, lsr #0x2
mov r0, r8
mov r1, r7
mov r2, r6
orr r3, r3, #0xc4000000
bl MIi_DmaSetParams
ldmia sp!, {r4-r8, lr}
bx lr
_020CDB14:
mov r3, r5, lsr #0x2
mov r0, r8
mov r1, r7
mov r2, r6
orr r3, r3, #0x84000000
bl MIi_DmaSetParams
ldmia sp!, {r4-r8, lr}
bx lr
arm_func_start MI_DmaFill32Async
MI_DmaFill32Async: ; 0x020CDB34
stmdb sp!, {r4-r8,lr}
movs r4, r3
mov r7, r0
mov r6, r1
mov r5, r2
ldr r8, [sp, #0x18]
bne _020CDB6C
cmp r8, #0x0
ldmeqia sp!, {r4-r8,lr}
bxeq lr
ldr r0, [sp, #0x1c]
blx r8
ldmia sp!, {r4-r8,lr}
bx lr
_020CDB6C:
bl MI_WaitDma
_020CDB70:
cmp r8, #0x0
beq _020CDBC8
ldr r2, [sp, #0x1C]
mov r0, r7
mov r1, r8
bl OSi_EnterDmaCallback
bl OS_DisableInterrupts
mov r3, r4, lsr #2
ldr r1, _20CDC08
mov r2, r7, lsl #2
add r2, r2, #0x4000000
str r5, [r2, #0xE0]
mov r4, r0
add r1, r1, r7, lsl #0x2
mov r0, r7
mov r2, r6
orr r3, r3, #0xc5000000
bl MIi_DmaSetParams_noInt
mov r0, r4
bl OS_RestoreInterrupts
ldmia sp!, {r4-r8,lr}
bx lr
_020CDBC8:
bl OS_DisableInterrupts
ldr r1, _20CDC08
mov r2, r7, lsl #0x2
mov r3, r4, lsr #0x2
mov r4, r0
add ip, r2, #0x4000000
mov r0, r7
mov r2, r6
add r1, r1, r7, lsl #0x2
orr r3, r3, #0x85000000
str r5, [ip, #0xE0]
bl MIi_DmaSetParams_noInt
mov r0, r4
bl OS_RestoreInterrupts
ldmia sp!, {r4-r8,lr}
bx lr
_20CDC08: .word 0x040000E0
arm_func_start MI_DmaCopy16
MI_DmaCopy16: ; 0x020CDC0C
stmdb sp!, {r4-r8,lr}
movs r5, r3
mov r8, r0
mov r7, r1
mov r6, r2
ldmeqia sp!, {r4-r8,lr}
bxeq lr
mov r2, r5
mov r3, #0x0
bl MIi_CheckDma0SourceAddress
mov r0, #0x3
mul r1, r8, r0
ldr r0, _020CDC80 ; =0x040000B0
add r1, r1, #0x2
add r4, r0, r1, lsl #0x2
_020CDC48:
ldr r0, [r4, #0x0]
ands r0, r0, #0x80000000
bne _020CDC48
mov r3, r5, lsr #0x1
mov r0, r8
mov r1, r7
mov r2, r6
orr r3, r3, #0x80000000
bl MIi_DmaSetParams_wait
_020CDC6C:
ldr r0, [r4]
ands r0, r0, #0x80000000
bne _020CDC6C
ldmia sp!, {r4-r8,lr}
bx lr
_020CDC80: .word 0x040000B0
arm_func_start MI_DmaCopy32
MI_DmaCopy32: ; 0x020CDC84
stmdb sp!, {r4-r8,lr}
mov r5, r3
mov r6, r2
mov r2, r5
mov r3, #0x0
mov r8, r0
mov r7, r1
bl MIi_CheckDma0SourceAddress
_020CDCA4:
cmp r5, #0x0
ldmeqia sp!, {r4-r8,lr}
bxeq lr
mov r0, #0x3
mul r1, r8, r0
ldr r0, _020CDCFC
add r1, r1, #0x2
add r4, r0, r1, lsl #0x2
_020CDCC4:
ldr r0, [r4]
ands r0, r0, #0x80000000
bne _020CDCC4
mov r3, r5, lsr #0x2
mov r0, r8
mov r1, r7
mov r2, r6
orr r3, r3, #0x84000000
bl MIi_DmaSetParams_wait
_020CDCE8:
ldr r0, [r4]
ands r0, r0, #0x80000000
bne _020CDCE8
ldmia sp!, {r4-r8,lr}
bx lr
_020CDCFC: .word 0x040000B0
arm_func_start MI_DmaFill32
MI_DmaFill32: ; 0x020CDD00
stmdb sp!, {r4-r8,lr}
movs r4, r3
mov r8, r0
mov r7, r1
mov r6, r2
ldmeqia sp!, {r4-r8,lr}
bxeq lr
mov r0, #0x3
mul r1, r8, r0
ldr r0, _020CDD88 ; =0x040000B0
add r1, r1, #0x2
add r5, r0, r1, lsl #0x2
_020CDD30:
ldr r0, [r5, #0x0]
ands r0, r0, #0x80000000
bne _020CDD30
bl OS_DisableInterrupts
ldr r1, _020CDD8C ; =0x040000E0
mov r2, r8, lsl #0x2
mov r3, r4, lsr #0x2
mov r4, r0
add r12, r2, #0x4000000
mov r0, r8
mov r2, r7
add r1, r1, r8, lsl #0x2
orr r3, r3, #0x85000000
str r6, [r12, #0xe0]
bl MIi_DmaSetParams_wait_noInt
mov r0, r4
bl OS_RestoreInterrupts
_020CDD74:
ldr r0, [r5]
ands r0, r0, #0x80000000
bne _020CDD74
ldmia sp!, {r4-r8,lr}
bx lr
_020CDD88: .word 0x040000B0
_020CDD8C: .word 0x040000E0
-99
View File
@@ -3,105 +3,6 @@
.section .text
; MI
arm_func_start MIi_DmaSetParams_wait_noInt
MIi_DmaSetParams_wait_noInt: ; 0x01FF84E4
stmdb sp!, {r4, lr}
mov ip, #12
mul r4, r0, ip
add ip, r4, #67108864 ; 0x4000000
ldr lr, [pc, #64] ; 0x10b4dc
str r1, [ip, #176] ; 0xb0
add r4, r4, lr
str r2, [r4, #4]
str r3, [r4, #8]
ldr r1, [lr]
cmp r0, #0
ldr r0, [lr]
moveq r1, #0
streq r1, [r4]
streq r1, [r4, #4]
ldreq r0, _01FF8540
ldr r1, _01FF853C
streq r0, [r4, #8]
ldr r0, [r1]
ldr r0, [r1]
ldmia sp!, {r4, lr}
bx lr
_01FF853C: .word 0x040000B0
_01FF8540: .word 0x81400001
arm_func_start MIi_DmaSetParams_noInt
MIi_DmaSetParams_noInt: ; 01FF8544
stmfd sp!, {lr}
sub sp, sp, #4
mov ip, #12
mul lr, r0, ip
ldr r0, _01FF8578
add ip, lr, #67108864 ; 0x4000000
str r1, [ip, #176] ; 0xb0
add r0, lr, r0
str r2, [r0, #4]
str r3, [r0, #8]
add sp, sp, #4
ldmfd sp!, {lr}
bx lr
_01FF8578: .word 0x040000B0
arm_func_start MIi_DmaSetParams_wait
MIi_DmaSetParams_wait: ; 01FF857C
stmdb sp!, {r4, r5, r6, r7, lr}
sub sp, sp, #4
mov r7, r0
mov r6, r1
mov r5, r2
mov r4, r3
bl OS_DisableInterrupts
mov r1, #12
mul r3, r7, r1
add r1, r3, #67108864 ; 0x4000000
ldr r2, _01FF85E8
str r6, [r1, #176] ; 0xb0
add r3, r3, r2
str r5, [r3, #4]
str r4, [r3, #8]
ldr r1, [r2]
cmp r7, #0
ldr r1, [r2]
moveq r2, #0
streq r2, [r3]
ldreq r1, _01FF85EC
streq r2, [r3, #4]
streq r1, [r3, #8]
bl OS_RestoreInterrupts
add sp, sp, #4
ldmia sp!, {r4, r5, r6, r7, lr}
bx lr
_01FF85E8: .word 0x040000B0
_01FF85EC: .word 0x81400001
arm_func_start MIi_DmaSetParams
MIi_DmaSetParams: ; 01FF85F0
stmdb sp!, {r4, r5, r6, r7, lr}
sub sp, sp, #4
mov r7, r0
mov r6, r1
mov r5, r2
mov r4, r3
bl OS_DisableInterrupts
mov r1, #12
mul r3, r7, r1
ldr r1, _01FF863C
add r2, r3, #67108864 ; 0x4000000
str r6, [r2, #176] ; 0xb0
add r1, r3, r1
str r5, [r1, #4]
str r4, [r1, #8]
bl OS_RestoreInterrupts
add sp, sp, #4
ldmia sp!, {r4, r5, r6, r7, lr}
bx lr
_01FF863C: .word 0x040000B0
arm_func_start MI_SendGXCommand
MI_SendGXCommand: ; 0x01FF8640
stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
+61
View File
@@ -2,7 +2,68 @@
#define POKEDIAMOND_ARM9_MI_DMA_H
#include "nitro/MI_dma_shared.h"
#include "consts.h"
#include "OS_system.h"
typedef void (*MIDmaCallback)(void *);
#define REG_ADDR_DMA0CNT 0x40000b8
#define REG_ADDR_DMA0_CLR_DATA 0x40000e0
#define MI_CNT_CLEAR32(size) (0x85000000 | ((size)/4))
#define MI_CNT_CLEAR32_IF(size) (0xc5000000 | ((size)/4))
#define MI_CNT_COPY32(size) (0x84000000 | ((size)/4))
#define MI_CNT_COPY32_IF(size) (0xc4000000 | ((size)/4))
#define MI_CNT_COPY16(size) (0x80000000 | ((size)/2))
typedef union
{
u32 b32;
u16 b16;
} MIiDmaClearSrc;
void MI_DmaFill32(u32 dmaNo, void *dest, u32 data, u32 size);
void MI_DmaCopy32(u32 dmaNo, const void *src, void *dest, u32 size);
void MI_DmaCopy16(u32 dmaNo, const void *src, void *dest, u32 size);
void MI_DmaFill32Async(u32 dmaNo, void *dest, u32 data, u32 size, MIDmaCallback callback, void *arg);
void MI_DmaCopy32Async(u32 dmaNo, const void *src, void *dest, u32 size, MIDmaCallback callback, void *arg);
void MI_WaitDma(u32 dmaNo);
void MI_StopDma(u32 dmaNo);
void MIi_CheckAnotherAutoDMA(u32 dmaNo, u32 dmaType);
void MIi_CheckDma0SourceAddress(u32 dmaNo, u32 src, u32 size, u32 dir);
void MIi_DmaSetParams(u32 dmaNo, u32 src, u32 dest, u32 ctrl);
void MIi_DmaSetParams_wait(u32 dmaNo, u32 src, u32 dest, u32 ctrl);
void MIi_DmaSetParams_noInt(u32 dmaNo, u32 src, u32 dest, u32 ctrl);
void MIi_DmaSetParams_wait_noInt(u32 dmaNo, u32 src, u32 dest, u32 ctrl);
static inline void MIi_DmaSetParams_wait_src32(u32 dmaNo, u32 data, u32 dest, u32 ctrl)
{
OSIntrMode lastIntrMode = OS_DisableInterrupts();
MIiDmaClearSrc *scrp = (MIiDmaClearSrc *) ((u32)REG_ADDR_DMA0_CLR_DATA + dmaNo * 4);
scrp->b32 = data;
MIi_DmaSetParams_wait_noInt(dmaNo, (u32)scrp, dest, ctrl);
(void)OS_RestoreInterrupts(lastIntrMode);
}
static inline void MIi_DmaSetParams_src32(u32 dmaNo, u32 data, u32 dest, u32 ctrl)
{
OSIntrMode lastIntrMode = OS_DisableInterrupts();
MIiDmaClearSrc *srcp = (MIiDmaClearSrc *) ((u32)REG_ADDR_DMA0_CLR_DATA + dmaNo * 4);
srcp->b32 = data;
MIi_DmaSetParams_noInt(dmaNo, (u32)srcp, dest, ctrl);
(void)OS_RestoreInterrupts(lastIntrMode);
}
static inline void MIi_CallCallback(MIDmaCallback callback, void *arg)
{
if (callback)
{
(callback) (arg);
}
}
#endif //POKEDIAMOND_ARM9_MI_DMA_H
-8
View File
@@ -9,17 +9,9 @@
void GXi_NopClearFifo128_(void *);
void MI_Copy16B(const void *, void *);
void MI_DmaFill32Async(u32, void *, u32, u32, u32, u32);
void MI_DmaFill32(u32, void *, u32, u32);
void MIi_CpuClear32(u32, void *, u32);
void MI_Copy64B(void *src, void *dst);
void MI_WaitDma(u32);
void MI_DmaCopy32Async(u32, const void *, void *, u32, void *, void *);
void MI_DmaCopy16(u32 unk, const void *src, void *dst, u32 size);
void MI_DmaCopy32(u32 unk, const void *src, void *dst, u32 size);
void MIi_CpuCopy32(const void *src, void *dst, u32 size);
void OSi_UnlockVram(u16, u16);
void MIi_CpuClear32(u32, void *, u32);
#include "GXcommon.h"
#include "GX_struct_2d.h"
+307
View File
@@ -0,0 +1,307 @@
#include "MI_dma.h"
#include "function_target.h"
#include "OS_interrupt.h"
#include "OS_terminate_proc.h"
#include "sections.h"
#pragma section ITCM begin
ARM_FUNC void MIi_DmaSetParams(u32 dmaNo, u32 src, u32 dest, u32 ctrl)
{
OSIntrMode lastIntrMode = OS_DisableInterrupts();
vu32 *p = (vu32 *)((u32)REG_ADDR_DMA0SAD + dmaNo * 12);
*p = (vu32)src;
*(p + 1) = (vu32)dest;
*(p + 2) = (vu32)ctrl;
(void)OS_RestoreInterrupts(lastIntrMode);
}
ARM_FUNC void MIi_DmaSetParams_wait(u32 dmaNo, u32 src, u32 dest, u32 ctrl)
{
OSIntrMode enabled = OS_DisableInterrupts();
vu32 *p = (vu32 *)((u32)REG_ADDR_DMA0SAD + dmaNo * 12);
*p = (vu32)src;
*(p + 1) = (vu32)dest;
*(p + 2) = (vu32)ctrl;
//delay cycles
{
u32 delay = reg_MI_DMA0SAD;
}
{
u32 delay = reg_MI_DMA0SAD;
}
if (!dmaNo)
{
*p = (vu32)0;
*(p + 1) = (vu32)0;
*(p + 2) = (vu32)0x81400001;
}
(void)OS_RestoreInterrupts(enabled);
}
ARM_FUNC void MIi_DmaSetParams_noInt(u32 dmaNo, u32 src, u32 dest, u32 ctrl)
{
vu32 *p = (vu32 *)((u32)REG_ADDR_DMA0SAD + dmaNo * 12);
*p = (vu32)src;
*(p + 1) = (vu32)dest;
*(p + 2) = (vu32)ctrl;
}
ARM_FUNC void MIi_DmaSetParams_wait_noInt(u32 dmaNo, u32 src, u32 dest, u32 ctrl)
{
vu32 *p = (vu32 *)((u32)REG_ADDR_DMA0SAD + dmaNo * 12);
*p = (vu32)src;
*(p + 1) = (vu32)dest;
*(p + 2) = (vu32)ctrl;
//delay cycles
{
u32 delay = reg_MI_DMA0SAD;
}
{
u32 delay = reg_MI_DMA0SAD;
}
if (!dmaNo)
{
*p = (vu32)0;
*(p + 1) = (vu32)0;
*(p + 2) = (vu32)0x81400001;
}
//delay cycles
{
u32 delay = reg_MI_DMA0SAD;
}
{
u32 delay = reg_MI_DMA0SAD;
}
}
#pragma section ITCM end
ARM_FUNC void MI_DmaFill32(u32 dmaNo, void *dest, u32 data, u32 size)
{
vu32 *dmaCntp;
if (!size)
{
return;
}
do
{
dmaCntp = &((vu32 *)REG_ADDR_DMA0SAD)[dmaNo * 3 + 2];
while (*dmaCntp & 0x80000000) {}
} while(0);
MIi_DmaSetParams_wait_src32(dmaNo, data, (u32)dest, MI_CNT_CLEAR32(size));
do
{
while (*dmaCntp & 0x80000000) {}
} while(0);
}
ARM_FUNC void MI_DmaCopy32(u32 dmaNo, const void *src, void *dest, u32 size)
{
vu32 *dmaCntp;
MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, DMA_SRC_INC);
if (!size)
{
return;
}
do
{
dmaCntp = &((vu32 *)REG_ADDR_DMA0SAD)[dmaNo * 3 + 2];
while (*dmaCntp & 0x80000000) {}
} while(0);
MIi_DmaSetParams_wait(dmaNo, (u32)src, (u32)dest, MI_CNT_COPY32(size));
do
{
while (*dmaCntp & 0x80000000) {}
} while(0);
}
ARM_FUNC void MI_DmaCopy16(u32 dmaNo, const void *src, void *dest, u32 size)
{
vu32 *dmaCntp;
if (!size)
{
return;
}
MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, DMA_SRC_INC);
do
{
dmaCntp = &((vu32 *)REG_ADDR_DMA0SAD)[dmaNo * 3 + 2];
while (*dmaCntp & 0x80000000) {}
} while(0);
MIi_DmaSetParams_wait(dmaNo, (u32)src, (u32)dest, MI_CNT_COPY16(size));
do
{
while (*dmaCntp & 0x80000000) {}
} while(0);
}
ARM_FUNC void MI_DmaFill32Async(u32 dmaNo, void *dest, u32 data, u32 size, MIDmaCallback callback, void *arg)
{
if (!size)
{
MIi_CallCallback(callback, arg);
}
else
{
MI_WaitDma(dmaNo);
if (callback)
{
OSi_EnterDmaCallback(dmaNo, callback, arg);
MIi_DmaSetParams_src32(dmaNo, data, (u32)dest, MI_CNT_CLEAR32_IF(size));
}
else
{
MIi_DmaSetParams_src32(dmaNo, data, (u32)dest, MI_CNT_CLEAR32(size));
}
}
}
ARM_FUNC void MI_DmaCopy32Async(u32 dmaNo, const void *src, void *dest, u32 size, MIDmaCallback callback, void *arg)
{
MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, DMA_SRC_INC);
if (!size)
{
MIi_CallCallback(callback, arg);
}
else
{
MI_WaitDma(dmaNo);
if (callback)
{
OSi_EnterDmaCallback(dmaNo, callback, arg);
MIi_DmaSetParams(dmaNo, (u32)src, (u32)dest, MI_CNT_COPY32_IF(size));
}
else
{
MIi_DmaSetParams(dmaNo, (u32)src, (u32)dest, MI_CNT_COPY32(size));
}
}
}
ARM_FUNC void MI_WaitDma(u32 dmaNo)
{
OSIntrMode lastIntrMode = OS_DisableInterrupts();
vu32 *dmaCntp = &((vu32 *)REG_ADDR_DMA0SAD)[dmaNo * 3 + 2];
while (*dmaCntp & 0x80000000) {}
if (!dmaNo)
{
vu32 *p = (vu32 *)((u32)REG_ADDR_DMA0SAD + dmaNo * 12);
*p = (vu32)0;
*(p + 1) = (vu32)0;
*(p + 2) = (vu32)0x81400001;
}
(void)OS_RestoreInterrupts(lastIntrMode);
}
ARM_FUNC void MI_StopDma(u32 dmaNo)
{
OSIntrMode lastIntrMode = OS_DisableInterrupts();
vu16 *dmaCntp = &((vu16 *)REG_ADDR_DMA0SAD)[dmaNo * 6 + 5];
*dmaCntp &= ~0x3a00;
*dmaCntp &= ~0x8000;
//delay cycles
{
s32 delay = dmaCntp[0];
}
{
s32 delay = dmaCntp[0];
}
if (!dmaNo)
{
vu32 *p = (vu32 *)((u32)REG_ADDR_DMA0SAD + dmaNo * 12);
*p = (vu32)0;
*(p + 1) = (vu32)0;
*(p + 2) = (vu32)0x81400001;
}
(void)OS_RestoreInterrupts(lastIntrMode);
}
ARM_FUNC void MIi_CheckAnotherAutoDMA(u32 dmaNo, u32 dmaType)
{
u32 dmaCnt;
u32 timing;
for (int i = 0; i < 3; i++)
{
if (i == dmaNo) continue;
dmaCnt = *(REGType32v *)(REG_ADDR_DMA0CNT + i * 12);
if (!(dmaCnt & 0x80000000)) continue;
timing = dmaCnt & 0x38000000;
if (timing == dmaType
|| (timing == 0x8000000 && dmaType == 0x10000000)
|| (timing == 0x10000000 && dmaType == 0x8000000))
{
continue;
}
if (timing == 0x18000000
|| timing == 0x20000000
|| timing == 0x28000000
|| timing == 0x30000000
|| timing == 0x38000000
|| timing == 0x8000000
|| timing == 0x10000000)
{
OS_Terminate();
}
}
}
ARM_FUNC void MIi_CheckDma0SourceAddress(u32 dmaNo, u32 src, u32 size, u32 dir)
{
if (!dmaNo)
{
u32 addStart = src & 0xff000000;
u32 addEnd;
switch (dir)
{
case 0: //dma_src_inc
addEnd = src + size;
break;
case 0x800000: //dma_src_dec
addEnd = src - size;
break;
default:
addEnd = src;
break;
}
addEnd &= 0xff000000;
if (addStart == 0x04000000 || addStart >= 0x08000000 ||
addEnd == 0x04000000 || addEnd >= 0x08000000)
{
OS_Terminate();
}
}
}