Search
lxdream.org :: lxdream/src/test/testsh4x86.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/test/testsh4x86.c
changeset 931:430048ea8b71
prev930:07e5b11419db
next934:3acd3b3ee6d1
author nkeynes
date Tue Dec 23 05:48:05 2008 +0000 (10 years ago)
branchlxdream-mem
permissions -rw-r--r--
last change More refactoring and general cleanup. Most things should be working again now.
Split off cache and start real implementation, breaking save states in the process
file annotate diff log raw
nkeynes@363
     1
/**
nkeynes@586
     2
 * $Id$
nkeynes@363
     3
 *
nkeynes@363
     4
 * Test cases for the SH4 => x86 translator core. Takes as
nkeynes@363
     5
 * input a binary SH4 object (and VMA), generates the
nkeynes@363
     6
 * corresponding x86 code, and outputs the disassembly.
nkeynes@363
     7
 *
nkeynes@363
     8
 * Copyright (c) 2005 Nathan Keynes.
nkeynes@363
     9
 *
nkeynes@363
    10
 * This program is free software; you can redistribute it and/or modify
nkeynes@363
    11
 * it under the terms of the GNU General Public License as published by
nkeynes@363
    12
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@363
    13
 * (at your option) any later version.
nkeynes@363
    14
 *
nkeynes@363
    15
 * This program is distributed in the hope that it will be useful,
nkeynes@363
    16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@363
    17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@363
    18
 * GNU General Public License for more details.
nkeynes@363
    19
 */
nkeynes@363
    20
nkeynes@363
    21
#include <stdio.h>
nkeynes@363
    22
#include <stdarg.h>
nkeynes@363
    23
#include <getopt.h>
nkeynes@365
    24
#include <sys/stat.h>
nkeynes@365
    25
#include "x86dasm/x86dasm.h"
nkeynes@363
    26
#include "sh4/sh4trans.h"
nkeynes@363
    27
#include "sh4/sh4core.h"
nkeynes@586
    28
#include "sh4/sh4mmio.h"
nkeynes@586
    29
nkeynes@820
    30
struct dreamcast_module sh4_module;
nkeynes@586
    31
struct mmio_region mmio_region_MMU;
nkeynes@820
    32
struct mmio_region mmio_region_PMM;
nkeynes@586
    33
struct breakpoint_struct sh4_breakpoints[MAX_BREAKPOINTS];
nkeynes@586
    34
int sh4_breakpoint_count = 0;
nkeynes@363
    35
nkeynes@363
    36
#define MAX_INS_SIZE 32
nkeynes@363
    37
nkeynes@930
    38
nkeynes@930
    39
struct mem_region_fn **sh4_address_space = (void *)0x12345432;
nkeynes@363
    40
char *option_list = "s:o:d:h";
nkeynes@363
    41
struct option longopts[1] = { { NULL, 0, 0, 0 } };
nkeynes@363
    42
nkeynes@363
    43
char *input_file = NULL;
nkeynes@363
    44
char *diff_file = NULL;
nkeynes@363
    45
char *output_file = NULL;
nkeynes@602
    46
gboolean sh4_starting;
nkeynes@363
    47
uint32_t start_addr = 0x8C010000;
nkeynes@365
    48
uint32_t sh4_cpu_period = 5;
nkeynes@586
    49
sh4ptr_t sh4_main_ram;
nkeynes@363
    50
FILE *in;
nkeynes@363
    51
nkeynes@363
    52
char *inbuf;
nkeynes@365
    53
nkeynes@365
    54
struct x86_symbol local_symbols[] = {
nkeynes@919
    55
    { "sh4r+128", ((char *)&sh4r)+128 },
nkeynes@919
    56
    { "sh4_cpu_period", &sh4_cpu_period },
nkeynes@919
    57
    { "mmu_vma_to_phys_read", mmu_vma_to_phys_read },
nkeynes@919
    58
    { "mmu_vma_to_phys_write", mmu_vma_to_phys_write },
nkeynes@930
    59
    { "sh4_address_space", 0x12345432 },
nkeynes@919
    60
    { "sh4_write_fpscr", sh4_write_fpscr },
nkeynes@919
    61
    { "sh4_write_sr", sh4_write_sr },
nkeynes@919
    62
    { "sh4_read_sr", sh4_read_sr },
nkeynes@919
    63
    { "sh4_sleep", sh4_sleep },
nkeynes@919
    64
    { "sh4_fsca", sh4_fsca },
nkeynes@919
    65
    { "sh4_ftrv", sh4_ftrv },
nkeynes@919
    66
    { "sh4_switch_fr_banks", sh4_switch_fr_banks },
nkeynes@919
    67
    { "sh4_execute_instruction", sh4_execute_instruction },
nkeynes@919
    68
    { "signsat48", signsat48 },
nkeynes@919
    69
    { "sh4_read_byte", sh4_read_byte },
nkeynes@919
    70
    { "sh4_read_word", sh4_read_word },
nkeynes@919
    71
    { "sh4_read_long", sh4_read_long },
nkeynes@919
    72
    { "sh4_write_byte", sh4_write_byte },
nkeynes@919
    73
    { "sh4_write_word", sh4_write_word },
nkeynes@919
    74
    { "sh4_write_long", sh4_write_long },
nkeynes@919
    75
    { "xlat_get_code_by_vma", xlat_get_code_by_vma },
nkeynes@919
    76
    { "xlat_get_code", xlat_get_code }
nkeynes@365
    77
};
nkeynes@363
    78
nkeynes@905
    79
int32_t FASTCALL sh4_read_byte( uint32_t addr ) 
nkeynes@363
    80
{
nkeynes@363
    81
    return *(uint8_t *)(inbuf+(addr-start_addr));
nkeynes@363
    82
}
nkeynes@905
    83
int32_t FASTCALL sh4_read_word( uint32_t addr ) 
nkeynes@363
    84
{
nkeynes@363
    85
    return *(uint16_t *)(inbuf+(addr-start_addr));
nkeynes@363
    86
}
nkeynes@905
    87
int32_t FASTCALL sh4_read_long( uint32_t addr ) 
nkeynes@363
    88
{
nkeynes@363
    89
    return *(uint32_t *)(inbuf+(addr-start_addr));
nkeynes@363
    90
}
nkeynes@929
    91
nkeynes@363
    92
// Stubs
nkeynes@802
    93
gboolean sh4_execute_instruction( ) { return TRUE; }
nkeynes@363
    94
void sh4_accept_interrupt() {}
nkeynes@586
    95
void sh4_set_breakpoint( uint32_t pc, breakpoint_type_t type ) { }
nkeynes@802
    96
gboolean sh4_clear_breakpoint( uint32_t pc, breakpoint_type_t type ) { return TRUE; }
nkeynes@775
    97
gboolean dreamcast_is_running() { return FALSE; }
nkeynes@802
    98
int sh4_get_breakpoint( uint32_t pc ) { return 0; }
nkeynes@740
    99
void sh4_core_exit( int exit_code ){}
nkeynes@740
   100
void sh4_flush_icache(){}
nkeynes@363
   101
void event_execute() {}
nkeynes@363
   102
void TMU_run_slice( uint32_t nanos ) {}
nkeynes@931
   103
void CCN_set_cache_control( uint32_t val ) { }
nkeynes@884
   104
void PMM_write_control( int ctr, uint32_t val ) { }
nkeynes@363
   105
void SCIF_run_slice( uint32_t nanos ) {}
nkeynes@905
   106
void FASTCALL sh4_write_byte( uint32_t addr, uint32_t val ) {}
nkeynes@905
   107
void FASTCALL sh4_write_word( uint32_t addr, uint32_t val ) {}
nkeynes@905
   108
void FASTCALL sh4_write_long( uint32_t addr, uint32_t val ) {}
nkeynes@905
   109
void FASTCALL sh4_write_fpscr( uint32_t val ) { }
nkeynes@905
   110
void FASTCALL sh4_write_sr( uint32_t val ) { }
nkeynes@905
   111
uint32_t FASTCALL sh4_read_sr( void ) { return 0; }
nkeynes@905
   112
void FASTCALL sh4_sleep() { }
nkeynes@905
   113
void FASTCALL sh4_fsca( uint32_t angle, float *fr ) { }
nkeynes@905
   114
void FASTCALL sh4_ftrv( float *fv ) { }
nkeynes@905
   115
void FASTCALL signsat48(void) { }
nkeynes@669
   116
void sh4_switch_fr_banks() { }
nkeynes@918
   117
void mem_copy_to_sh4( sh4addr_t addr, sh4ptr_t src, size_t size ) { }
nkeynes@602
   118
gboolean sh4_has_page( sh4vma_t vma ) { return TRUE; }
nkeynes@385
   119
void syscall_invoke( uint32_t val ) { }
nkeynes@586
   120
void dreamcast_stop() {} 
nkeynes@586
   121
void dreamcast_reset() {}
nkeynes@905
   122
gboolean FASTCALL sh4_raise_reset( int exc ) { return TRUE; }
nkeynes@905
   123
gboolean FASTCALL sh4_raise_exception( int exc ) { return TRUE; }
nkeynes@905
   124
gboolean FASTCALL sh4_raise_tlb_exception( int exc ) { return TRUE; }
nkeynes@905
   125
gboolean FASTCALL sh4_raise_trap( int exc ) { return TRUE; }
nkeynes@802
   126
uint32_t sh4_sleep_run_slice(uint32_t nanosecs) { return nanosecs; }
nkeynes@802
   127
gboolean gui_error_dialog( const char *fmt, ... ) { return TRUE; }
nkeynes@586
   128
struct sh4_icache_struct sh4_icache;
nkeynes@930
   129
struct mem_region_fn mem_region_unmapped;
nkeynes@363
   130
nkeynes@363
   131
void usage()
nkeynes@363
   132
{
nkeynes@363
   133
    fprintf( stderr, "Usage: testsh4x86 [options] <input bin file>\n");
nkeynes@363
   134
    fprintf( stderr, "Options:\n");
nkeynes@363
   135
    fprintf( stderr, "  -d <filename>  Diff results against contents of file\n" );
nkeynes@363
   136
    fprintf( stderr, "  -h             Display this help message\n" );
nkeynes@363
   137
    fprintf( stderr, "  -o <filename>  Output disassembly to file [stdout]\n" );
nkeynes@363
   138
    fprintf( stderr, "  -s <addr>      Specify start address of binary [8C010000]\n" );
nkeynes@363
   139
}
nkeynes@363
   140
nkeynes@363
   141
void emit( void *ptr, int level, const gchar *source, const char *msg, ... )
nkeynes@363
   142
{
nkeynes@363
   143
    va_list ap;
nkeynes@363
   144
    va_start( ap, msg );
nkeynes@363
   145
    vfprintf( stderr, msg, ap );
nkeynes@363
   146
    fprintf( stderr, "\n" );
nkeynes@363
   147
    va_end(ap);
nkeynes@363
   148
}
nkeynes@363
   149
nkeynes@363
   150
nkeynes@363
   151
struct sh4_registers sh4r;
nkeynes@363
   152
nkeynes@363
   153
nkeynes@363
   154
int main( int argc, char *argv[] )
nkeynes@363
   155
{
nkeynes@363
   156
    struct stat st;
nkeynes@363
   157
    int opt;
nkeynes@363
   158
    while( (opt = getopt_long( argc, argv, option_list, longopts, NULL )) != -1 ) {
nkeynes@363
   159
	switch( opt ) {
nkeynes@363
   160
	case 'd':
nkeynes@363
   161
	    diff_file = optarg;
nkeynes@363
   162
	    break;
nkeynes@363
   163
	case 'o':
nkeynes@363
   164
	    output_file = optarg;
nkeynes@363
   165
	    break;
nkeynes@363
   166
	case 's':
nkeynes@363
   167
	    start_addr = strtoul(optarg, NULL, 0);
nkeynes@363
   168
	    break;
nkeynes@363
   169
	case 'h':
nkeynes@363
   170
	    usage();
nkeynes@363
   171
	    exit(0);
nkeynes@363
   172
	}
nkeynes@363
   173
    }
nkeynes@363
   174
    if( optind < argc ) {
nkeynes@363
   175
	input_file = argv[optind++];
nkeynes@363
   176
    } else {
nkeynes@363
   177
	usage();
nkeynes@363
   178
	exit(1);
nkeynes@363
   179
    }
nkeynes@363
   180
nkeynes@919
   181
    mmio_region_MMU.mem = malloc(4096);
nkeynes@919
   182
    memset( mmio_region_MMU.mem, 0, 4096 );
nkeynes@919
   183
nkeynes@929
   184
    ((uint32_t *)mmio_region_MMU.mem)[4] = 1;
nkeynes@929
   185
nkeynes@363
   186
    in = fopen( input_file, "ro" );
nkeynes@363
   187
    if( in == NULL ) {
nkeynes@363
   188
	perror( "Unable to open input file" );
nkeynes@363
   189
	exit(2);
nkeynes@363
   190
    }
nkeynes@363
   191
    fstat( fileno(in), &st );
nkeynes@363
   192
    inbuf = malloc( st.st_size );
nkeynes@363
   193
    fread( inbuf, st.st_size, 1, in );
nkeynes@919
   194
    sh4_icache.mask = 0xFFFFF000;
nkeynes@919
   195
    sh4_icache.page_vma = start_addr & 0xFFFFF000;
nkeynes@919
   196
    sh4_icache.page = (unsigned char *)(inbuf - (sh4_icache.page_vma&0xFFF));
nkeynes@919
   197
    sh4_icache.page_ppa = start_addr & 0xFFFFF000;
nkeynes@363
   198
nkeynes@365
   199
    xlat_cache_init();
nkeynes@925
   200
    uintptr_t pc;
nkeynes@365
   201
    uint8_t *buf = sh4_translate_basic_block( start_addr );
nkeynes@919
   202
    uint32_t buflen = xlat_get_code_size(buf);
nkeynes@925
   203
    x86_disasm_init( buf, buf, buflen );
nkeynes@919
   204
    x86_set_symtab( local_symbols, sizeof(local_symbols)/sizeof(struct x86_symbol) );
nkeynes@925
   205
    for( pc = buf; pc < buf + buflen;  ) {
nkeynes@363
   206
	char buf[256];
nkeynes@363
   207
	char op[256];
nkeynes@925
   208
	uintptr_t pc2 = x86_disasm_instruction( pc, buf, sizeof(buf), op );
nkeynes@929
   209
	fprintf( stdout, "%08x: %s\n", pc, buf );
nkeynes@363
   210
	pc = pc2;
nkeynes@363
   211
    }
nkeynes@802
   212
    return 0;
nkeynes@363
   213
}
.