Search
lxdream.org :: lxdream/test/testspu.c
lxdream 0.9.1
released Jun 29
Download Now
filename test/testspu.c
changeset 278:a66aaa522d31
next812:8cc61d5ea1f8
author nkeynes
date Thu Jan 25 10:18:42 2007 +0000 (17 years ago)
permissions -rw-r--r--
last change Increase SH4 speed to 100Mips
file annotate diff log raw
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
}
.