Search
lxdream.org :: lxdream/test/testspu.c
lxdream 0.9.1
released Jun 29
Download Now
filename test/testspu.c
changeset 812:8cc61d5ea1f8
prev278:a66aaa522d31
author nkeynes
date Wed Dec 02 10:36:49 2009 +1000 (14 years ago)
permissions -rw-r--r--
last change Add missing SUBV instruction to the emulation core (translation core is ok),
along with test cases. Thanks to D. Jeff Dionne for pointing this out.
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@812
    41
    if( asic_wait( EVENT_G2_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@812
    63
    if( asic_wait( EVENT_G2_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
}
.