nkeynes@278 | 1 |
|
nkeynes@278 | 2 | #include <stdlib.h>
|
nkeynes@278 | 3 | #include "asic.h"
|
nkeynes@278 | 4 | #include "lib.h"
|
nkeynes@278 | 5 | #include "testdata.h"
|
nkeynes@278 | 6 |
|
nkeynes@278 | 7 | #define SPUBASE 0xA05F7800
|
nkeynes@278 | 8 | #define SPUBASERAM 0x00800000
|
nkeynes@278 | 9 | #define SPUWAIT (SPUBASE+0x90)
|
nkeynes@278 | 10 | #define SPUMAGIC (SPUBASE+0xBC)
|
nkeynes@278 | 11 |
|
nkeynes@278 | 12 |
|
nkeynes@278 | 13 | #define SPUDMAEXT(x) (SPUBASE+(0x20*(x)))
|
nkeynes@278 | 14 | #define SPUDMAHOST(x) (SPUBASE+(0x20*(x))+0x04)
|
nkeynes@278 | 15 | #define SPUDMASIZE(x) (SPUBASE+(0x20*(x))+0x08)
|
nkeynes@278 | 16 | #define SPUDMADIR(x) (SPUBASE+(0x20*(x))+0x0C)
|
nkeynes@278 | 17 | #define SPUDMAMODE(x) (SPUBASE+(0x20*(x))+0x10)
|
nkeynes@278 | 18 | #define SPUDMACTL1(x) (SPUBASE+(0x20*(x))+0x14)
|
nkeynes@278 | 19 | #define SPUDMACTL2(x) (SPUBASE+(0x20*(x))+0x18)
|
nkeynes@278 | 20 | #define SPUDMASTOP(x) (SPUBASE+(0x20*(x))+0x1C)
|
nkeynes@278 | 21 |
|
nkeynes@278 | 22 | void dump_spu_regs()
|
nkeynes@278 | 23 | {
|
nkeynes@278 | 24 | fwrite_dump( stderr, (char *)(0xA05F7800), 0x100 );
|
nkeynes@278 | 25 | }
|
nkeynes@278 | 26 |
|
nkeynes@278 | 27 | int dma_to_spu( int chan, uint32_t target, char *data, uint32_t size )
|
nkeynes@278 | 28 | {
|
nkeynes@278 | 29 | long_write( SPUWAIT, 0 );
|
nkeynes@278 | 30 | long_write( SPUMAGIC, 0x4659404f );
|
nkeynes@278 | 31 | long_write( SPUDMACTL1(chan), 0 );
|
nkeynes@278 | 32 | long_write( SPUDMACTL2(chan), 0 );
|
nkeynes@278 | 33 | long_write( SPUDMAHOST(chan), ((uint32_t)data)&0x1FFFFFE0 );
|
nkeynes@278 | 34 | long_write( SPUDMASIZE(chan), size | 0x80000000 );
|
nkeynes@278 | 35 | long_write( SPUDMAEXT(chan), target );
|
nkeynes@278 | 36 | long_write( SPUDMADIR(chan), 0 );
|
nkeynes@278 | 37 | long_write( SPUDMAMODE(chan), 0 );
|
nkeynes@278 | 38 |
|
nkeynes@278 | 39 | long_write( SPUDMACTL1(chan), 1 );
|
nkeynes@278 | 40 | long_write( SPUDMACTL2(chan), 1 );
|
nkeynes@278 | 41 | if( asic_wait( EVENT_SPU_DMA0 + chan ) != 0 ) {
|
nkeynes@278 | 42 | fprintf( stderr, "Timeout waiting for DMA event\n" );
|
nkeynes@278 | 43 | dump_spu_regs();
|
nkeynes@278 | 44 | return -1;
|
nkeynes@278 | 45 | }
|
nkeynes@278 | 46 | return 0;
|
nkeynes@278 | 47 | }
|
nkeynes@278 | 48 |
|
nkeynes@278 | 49 | int dma_from_spu( int chan, char *data, uint32_t src, uint32_t size )
|
nkeynes@278 | 50 | {
|
nkeynes@278 | 51 | long_write( SPUWAIT, 0 );
|
nkeynes@278 | 52 | long_write( SPUMAGIC, 0x4659404f );
|
nkeynes@278 | 53 | long_write( SPUDMACTL1(chan), 0 );
|
nkeynes@278 | 54 | long_write( SPUDMACTL2(chan), 0 );
|
nkeynes@278 | 55 | long_write( SPUDMAHOST(chan), ((uint32_t)data)&0x1FFFFFE0 );
|
nkeynes@278 | 56 | long_write( SPUDMASIZE(chan), size | 0x80000000 );
|
nkeynes@278 | 57 | long_write( SPUDMAEXT(chan), src );
|
nkeynes@278 | 58 | long_write( SPUDMADIR(chan), 1 );
|
nkeynes@278 | 59 | long_write( SPUDMAMODE(chan), 5 );
|
nkeynes@278 | 60 |
|
nkeynes@278 | 61 | long_write( SPUDMACTL1(chan), 1 );
|
nkeynes@278 | 62 | long_write( SPUDMACTL2(chan), 1 );
|
nkeynes@278 | 63 | if( asic_wait( EVENT_SPU_DMA0 + chan ) != 0 ) {
|
nkeynes@278 | 64 | fprintf( stderr, "Timeout waiting for DMA event\n" );
|
nkeynes@278 | 65 | dump_spu_regs();
|
nkeynes@278 | 66 | return -1;
|
nkeynes@278 | 67 | }
|
nkeynes@278 | 68 | return 0;
|
nkeynes@278 | 69 | }
|
nkeynes@278 | 70 |
|
nkeynes@278 | 71 | #define SPUTARGETADDR (SPUBASERAM+0x10000)
|
nkeynes@278 | 72 | #define SPUTARGET ((char *)(SPUTARGETADDR))
|
nkeynes@278 | 73 |
|
nkeynes@278 | 74 | int test_spu_dma_channel( int chan )
|
nkeynes@278 | 75 | {
|
nkeynes@278 | 76 | char sampledata1[256+32];
|
nkeynes@278 | 77 | char sampledata2[256+32];
|
nkeynes@278 | 78 | char resultdata[256+32];
|
nkeynes@278 | 79 |
|
nkeynes@278 | 80 | int i;
|
nkeynes@278 | 81 | char *p1 = DMA_ALIGN(sampledata1), *p2 = DMA_ALIGN(sampledata2);
|
nkeynes@278 | 82 | char *r = DMA_ALIGN(resultdata);
|
nkeynes@278 | 83 |
|
nkeynes@278 | 84 | for( i=0; i<256; i++ ) {
|
nkeynes@278 | 85 | p1[i] = (char)(i*i);
|
nkeynes@278 | 86 | p2[i] = 256 - i;
|
nkeynes@278 | 87 | }
|
nkeynes@278 | 88 |
|
nkeynes@278 | 89 | if( dma_to_spu( chan, SPUTARGETADDR, p1, 256 ) != 0 ) {
|
nkeynes@278 | 90 | return -1;
|
nkeynes@278 | 91 | }
|
nkeynes@278 | 92 |
|
nkeynes@278 | 93 | if( memcmp( p1, SPUTARGET, 256 ) != 0 ) {
|
nkeynes@278 | 94 | fprintf( stderr, "First data mismatch:\n" );
|
nkeynes@278 | 95 | fwrite_diff( stderr, p1, 256, SPUTARGET, 256 );
|
nkeynes@278 | 96 | return -1;
|
nkeynes@278 | 97 | }
|
nkeynes@278 | 98 |
|
nkeynes@278 | 99 | if( dma_to_spu( chan, SPUTARGETADDR, p2, 256 ) != 0 ) {
|
nkeynes@278 | 100 | return -1;
|
nkeynes@278 | 101 | }
|
nkeynes@278 | 102 |
|
nkeynes@278 | 103 | if( memcmp( p2, SPUTARGET, 256 ) != 0 ) {
|
nkeynes@278 | 104 | fprintf( stderr, "Second data mismatch:\n" );
|
nkeynes@278 | 105 | fwrite_diff( stderr, p2, 256, SPUTARGET, 256 );
|
nkeynes@278 | 106 | return -1;
|
nkeynes@278 | 107 | }
|
nkeynes@278 | 108 |
|
nkeynes@278 | 109 | memset( r, 0, 256 );
|
nkeynes@278 | 110 | if( dma_from_spu( chan, r, SPUTARGETADDR, 256 ) != 0 ) {
|
nkeynes@278 | 111 | return -1;
|
nkeynes@278 | 112 | }
|
nkeynes@278 | 113 |
|
nkeynes@278 | 114 | if( memcmp( p2, r, 256 ) != 0 ) {
|
nkeynes@278 | 115 | fprintf( stderr, "Read data mismatch:\n" );
|
nkeynes@278 | 116 | fwrite_diff( stderr, p2, 256, r, 256 );
|
nkeynes@278 | 117 | return -1;
|
nkeynes@278 | 118 | }
|
nkeynes@278 | 119 | }
|
nkeynes@278 | 120 |
|
nkeynes@278 | 121 |
|
nkeynes@278 | 122 | int test_spu_dma()
|
nkeynes@278 | 123 | {
|
nkeynes@278 | 124 | int i;
|
nkeynes@278 | 125 | for( i=0; i<4; i++ ) {
|
nkeynes@278 | 126 | if( test_spu_dma_channel(i) != 0 ) {
|
nkeynes@278 | 127 | return -1;
|
nkeynes@278 | 128 | }
|
nkeynes@278 | 129 | }
|
nkeynes@278 | 130 | }
|
nkeynes@278 | 131 |
|
nkeynes@278 | 132 | test_func_t tests[] = { test_spu_dma, NULL };
|
nkeynes@278 | 133 |
|
nkeynes@278 | 134 | int main()
|
nkeynes@278 | 135 | {
|
nkeynes@278 | 136 | return run_tests(tests);
|
nkeynes@278 | 137 | }
|