nkeynes@278: nkeynes@278: #include nkeynes@278: #include "asic.h" nkeynes@278: #include "lib.h" nkeynes@278: #include "testdata.h" nkeynes@278: nkeynes@278: #define SPUBASE 0xA05F7800 nkeynes@278: #define SPUBASERAM 0x00800000 nkeynes@278: #define SPUWAIT (SPUBASE+0x90) nkeynes@278: #define SPUMAGIC (SPUBASE+0xBC) nkeynes@278: nkeynes@278: nkeynes@278: #define SPUDMAEXT(x) (SPUBASE+(0x20*(x))) nkeynes@278: #define SPUDMAHOST(x) (SPUBASE+(0x20*(x))+0x04) nkeynes@278: #define SPUDMASIZE(x) (SPUBASE+(0x20*(x))+0x08) nkeynes@278: #define SPUDMADIR(x) (SPUBASE+(0x20*(x))+0x0C) nkeynes@278: #define SPUDMAMODE(x) (SPUBASE+(0x20*(x))+0x10) nkeynes@278: #define SPUDMACTL1(x) (SPUBASE+(0x20*(x))+0x14) nkeynes@278: #define SPUDMACTL2(x) (SPUBASE+(0x20*(x))+0x18) nkeynes@278: #define SPUDMASTOP(x) (SPUBASE+(0x20*(x))+0x1C) nkeynes@278: nkeynes@278: void dump_spu_regs() nkeynes@278: { nkeynes@278: fwrite_dump( stderr, (char *)(0xA05F7800), 0x100 ); nkeynes@278: } nkeynes@278: nkeynes@278: int dma_to_spu( int chan, uint32_t target, char *data, uint32_t size ) nkeynes@278: { nkeynes@278: long_write( SPUWAIT, 0 ); nkeynes@278: long_write( SPUMAGIC, 0x4659404f ); nkeynes@278: long_write( SPUDMACTL1(chan), 0 ); nkeynes@278: long_write( SPUDMACTL2(chan), 0 ); nkeynes@278: long_write( SPUDMAHOST(chan), ((uint32_t)data)&0x1FFFFFE0 ); nkeynes@278: long_write( SPUDMASIZE(chan), size | 0x80000000 ); nkeynes@278: long_write( SPUDMAEXT(chan), target ); nkeynes@278: long_write( SPUDMADIR(chan), 0 ); nkeynes@278: long_write( SPUDMAMODE(chan), 0 ); nkeynes@278: nkeynes@278: long_write( SPUDMACTL1(chan), 1 ); nkeynes@278: long_write( SPUDMACTL2(chan), 1 ); nkeynes@278: if( asic_wait( EVENT_SPU_DMA0 + chan ) != 0 ) { nkeynes@278: fprintf( stderr, "Timeout waiting for DMA event\n" ); nkeynes@278: dump_spu_regs(); nkeynes@278: return -1; nkeynes@278: } nkeynes@278: return 0; nkeynes@278: } nkeynes@278: nkeynes@278: int dma_from_spu( int chan, char *data, uint32_t src, uint32_t size ) nkeynes@278: { nkeynes@278: long_write( SPUWAIT, 0 ); nkeynes@278: long_write( SPUMAGIC, 0x4659404f ); nkeynes@278: long_write( SPUDMACTL1(chan), 0 ); nkeynes@278: long_write( SPUDMACTL2(chan), 0 ); nkeynes@278: long_write( SPUDMAHOST(chan), ((uint32_t)data)&0x1FFFFFE0 ); nkeynes@278: long_write( SPUDMASIZE(chan), size | 0x80000000 ); nkeynes@278: long_write( SPUDMAEXT(chan), src ); nkeynes@278: long_write( SPUDMADIR(chan), 1 ); nkeynes@278: long_write( SPUDMAMODE(chan), 5 ); nkeynes@278: nkeynes@278: long_write( SPUDMACTL1(chan), 1 ); nkeynes@278: long_write( SPUDMACTL2(chan), 1 ); nkeynes@278: if( asic_wait( EVENT_SPU_DMA0 + chan ) != 0 ) { nkeynes@278: fprintf( stderr, "Timeout waiting for DMA event\n" ); nkeynes@278: dump_spu_regs(); nkeynes@278: return -1; nkeynes@278: } nkeynes@278: return 0; nkeynes@278: } nkeynes@278: nkeynes@278: #define SPUTARGETADDR (SPUBASERAM+0x10000) nkeynes@278: #define SPUTARGET ((char *)(SPUTARGETADDR)) nkeynes@278: nkeynes@278: int test_spu_dma_channel( int chan ) nkeynes@278: { nkeynes@278: char sampledata1[256+32]; nkeynes@278: char sampledata2[256+32]; nkeynes@278: char resultdata[256+32]; nkeynes@278: nkeynes@278: int i; nkeynes@278: char *p1 = DMA_ALIGN(sampledata1), *p2 = DMA_ALIGN(sampledata2); nkeynes@278: char *r = DMA_ALIGN(resultdata); nkeynes@278: nkeynes@278: for( i=0; i<256; i++ ) { nkeynes@278: p1[i] = (char)(i*i); nkeynes@278: p2[i] = 256 - i; nkeynes@278: } nkeynes@278: nkeynes@278: if( dma_to_spu( chan, SPUTARGETADDR, p1, 256 ) != 0 ) { nkeynes@278: return -1; nkeynes@278: } nkeynes@278: nkeynes@278: if( memcmp( p1, SPUTARGET, 256 ) != 0 ) { nkeynes@278: fprintf( stderr, "First data mismatch:\n" ); nkeynes@278: fwrite_diff( stderr, p1, 256, SPUTARGET, 256 ); nkeynes@278: return -1; nkeynes@278: } nkeynes@278: nkeynes@278: if( dma_to_spu( chan, SPUTARGETADDR, p2, 256 ) != 0 ) { nkeynes@278: return -1; nkeynes@278: } nkeynes@278: nkeynes@278: if( memcmp( p2, SPUTARGET, 256 ) != 0 ) { nkeynes@278: fprintf( stderr, "Second data mismatch:\n" ); nkeynes@278: fwrite_diff( stderr, p2, 256, SPUTARGET, 256 ); nkeynes@278: return -1; nkeynes@278: } nkeynes@278: nkeynes@278: memset( r, 0, 256 ); nkeynes@278: if( dma_from_spu( chan, r, SPUTARGETADDR, 256 ) != 0 ) { nkeynes@278: return -1; nkeynes@278: } nkeynes@278: nkeynes@278: if( memcmp( p2, r, 256 ) != 0 ) { nkeynes@278: fprintf( stderr, "Read data mismatch:\n" ); nkeynes@278: fwrite_diff( stderr, p2, 256, r, 256 ); nkeynes@278: return -1; nkeynes@278: } nkeynes@278: } nkeynes@278: nkeynes@278: nkeynes@278: int test_spu_dma() nkeynes@278: { nkeynes@278: int i; nkeynes@278: for( i=0; i<4; i++ ) { nkeynes@278: if( test_spu_dma_channel(i) != 0 ) { nkeynes@278: return -1; nkeynes@278: } nkeynes@278: } nkeynes@278: } nkeynes@278: nkeynes@278: test_func_t tests[] = { test_spu_dma, NULL }; nkeynes@278: nkeynes@278: int main() nkeynes@278: { nkeynes@278: return run_tests(tests); nkeynes@278: }