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