diff options
| author | lameguy64 <lameguy64@github.com> | 2024-05-04 18:55:05 +0800 |
|---|---|---|
| committer | lameguy64 <lameguy64@github.com> | 2024-05-04 18:55:05 +0800 |
| commit | 702bb601fb5712e2ae962a34b89204c646fe98f5 (patch) | |
| tree | 765f400d1535d37c5ff4df61d01229a7dc7d8207 /indev/psn00bdbg-mk2/testutil/comms.c | |
| parent | 00abe5963fbead092f91935b90390aa5a9111c43 (diff) | |
| download | psn00bsdk-702bb601fb5712e2ae962a34b89204c646fe98f5.tar.gz | |
Included PSn00bDBG-mk2 monitor and test utility
Diffstat (limited to 'indev/psn00bdbg-mk2/testutil/comms.c')
| -rw-r--r-- | indev/psn00bdbg-mk2/testutil/comms.c | 817 |
1 files changed, 817 insertions, 0 deletions
diff --git a/indev/psn00bdbg-mk2/testutil/comms.c b/indev/psn00bdbg-mk2/testutil/comms.c new file mode 100644 index 0000000..46ec1f3 --- /dev/null +++ b/indev/psn00bdbg-mk2/testutil/comms.c @@ -0,0 +1,817 @@ +#include <stdio.h>
+#include <string.h>
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <unistd.h>
+#endif /* _WIN32 */
+#include "cmdefs.h"
+#include "main.h"
+#include "mips_disassembler.h"
+
+#ifdef _WIN32 /* platform specific macros */
+
+#define SIO_DELAY() ( Sleep( 10 ) )
+
+#else
+
+#define SIO_DELAY() ( usleep( 10000 ) )
+
+#endif /* _WIN32 */
+
+static const char *msg_sendfail = "Failed to send command.\n";
+static const char *msg_recfail = "Error on receive.\n";
+static const char *msg_noack = "No acknowledgement from target.\n";
+
+static char *regnames_param[] =
+{
+ "r0", "at", "v0", "v1",
+ "a0", "a1", "a2", "a3",
+ "t0", "t1", "t2", "t3",
+ "t4", "t5", "t6", "t7",
+ "s0", "s1", "s2", "s3",
+ "s4", "s5", "s6", "s7",
+ "t8", "t9", "k0", "k1",
+ "gp", "sp", "fp", "ra",
+ "pc", "hi", "lo", "sr"
+};
+
+int dbGetInfo( void )
+{
+ int i;
+
+ if( commWriteByte( CMD_DB_GETINFO ) > 0 )
+ {
+ printf( "Debug monitor info string: " );
+ while( i = commReadByte() )
+ {
+ if( i < 0 )
+ {
+ puts( msg_recfail );
+ return( 1 );
+ }
+ putchar( i );
+ }
+ putchar( '\n' );
+ }
+ else
+ {
+ puts( msg_sendfail );
+ return( 1 );
+ }
+
+ return( 0 );
+
+} /* dbGetInfo */
+
+void dbGetStatus( void )
+{
+ int i;
+
+ if( commWriteByte( CMD_DB_GETSTAT ) > 0 )
+ {
+ if( (i = commReadByte()) < 0 )
+ {
+ puts( msg_recfail );
+ }
+ else
+ {
+ printf( "Target status: %d (", i );
+
+ switch( i )
+ {
+ case DB_STAT_STOP:
+ printf( "stopped" );
+ break;
+ case DB_STAT_BREAK:
+ printf( "breakpoint" );
+ break;
+ case DB_STAT_EXCEPT:
+ printf( "unhandled exception" );
+ break;
+ case DB_STAT_RUN:
+ printf( "running" );
+ break;
+ default:
+ printf( "undefined" );
+ }
+ printf( ")\n" );
+ }
+ }
+ else
+ {
+ puts( msg_sendfail );
+ }
+
+} /* dbGetStatus */
+
+int dbGetStatusPoll(void)
+{
+ int i;
+
+ if( commWriteByte( CMD_DB_GETSTAT ) > 0 )
+ {
+ if( (i = commReadByte()) < 0 )
+ {
+ return(-1);
+ }
+ }
+ else
+ {
+ return(-1);
+ }
+
+ return(i);
+
+} /* dbGetStatus */
+
+int dbSetExec( int exec )
+{
+ if( commWriteByte( CMD_DB_SETEXEC ) < 0 ) /* send command */
+ {
+ puts( msg_sendfail );
+ return(1);
+ }
+
+ if( commWriteByte( exec) < 0 ) /* send exec value */
+ {
+ puts( msg_sendfail );
+ return(1);
+ }
+
+ if( commReadByte() < 0 ) /* check for acknowledgment */
+ {
+ puts( msg_noack );
+ return(1);
+ }
+
+ return(0);
+
+} /* dbSetExec */
+
+void dbRunTo(unsigned int addr, int flag)
+{
+ if( commWriteByte(CMD_DB_RUNTO) < 0 ) /* send command */
+ {
+ puts( msg_sendfail );
+ return;
+ }
+
+ if( commWriteByte(flag) < 0 ) /* send flag */
+ {
+ puts( msg_sendfail );
+ return;
+ }
+
+ if( commWriteBytes( &addr, 4 ) < 4 ) /* send runto address */
+ {
+ puts( msg_sendfail );
+ return;
+ }
+
+ if( commReadByte() < 0 ) /* check for acknowledgment */
+ {
+ puts( msg_noack );
+ return;
+ }
+
+} /* dbRunTo */
+
+void dbSetBreak(unsigned int addr, unsigned int flag, int count)
+{
+ int ret;
+
+ if( commWriteByte(CMD_DB_SETBRK) < 0 ) /* send command */
+ {
+ puts(msg_sendfail);
+ return;
+ }
+
+ if( commWriteBytes(&addr, 4) < 4 ) /* send breakpoint address */
+ {
+ puts(msg_sendfail);
+ return;
+ }
+
+ SIO_DELAY(); /* delay otherwise last byte doesn't get sent somehow */
+
+ ret = (flag&0xFF) | (count<<16); /* send flag value */
+ if( commWriteBytes(&ret, 4) < 4 )
+ {
+ puts(msg_sendfail);
+ return;
+ }
+
+ SIO_DELAY();
+
+ if( (ret = commReadByte()) < 0 ) /* check for acknowledgment */
+ {
+ puts( msg_noack );
+ return;
+ }
+
+ if( ret == 0 )
+ {
+ printf("Bad breakpoint address.\n");
+ }
+ else if( ret == 1 )
+ {
+ printf("Breakpoint set/update.\n");
+ }
+ else
+ {
+ printf("Unknown response value: %d\n", ret);
+ }
+
+} /* dbSetBreak */
+
+void dbClearBreaks()
+{
+ int ret;
+
+ if( commWriteByte(CMD_DB_CLRBRK) < 0 ) /* send command */
+ {
+ puts(msg_sendfail);
+ return;
+ }
+
+ if( (ret = commReadByte()) < 0 ) /* check for acknowledgment */
+ {
+ puts( msg_noack );
+ return;
+ }
+
+} /* dbClearBreaks */
+
+void dbReboot( void )
+{
+ if( commWriteByte( CMD_REBOOT ) < 0 ) /* send command */
+ {
+ puts( msg_sendfail );
+ return;
+ }
+
+} /* dbReboot */
+
+void dbUploadMemFile( unsigned int addr, const char *infile, size_t len )
+{
+ FILE *fp;
+ int i,progress,olen;
+ unsigned char buffer[100];
+ size_t file_sz;
+
+ fp = fopen( infile, "rb" );
+
+ if( !fp )
+ {
+ printf( "File not found.\n" );
+ return;
+ }
+
+ fseek( fp, 0, SEEK_END ); /* determine file size */
+ file_sz = ftell( fp );
+ fseek( fp, 0, SEEK_SET );
+
+ if( len > file_sz )
+ len = file_sz;
+
+ if( commWriteByte( CMD_DB_GETMEM ) < 0 ) /* send getmem command */
+ {
+ puts( msg_sendfail );
+ fclose( fp );
+ return;
+ }
+
+ if( commWriteByte( 1 ) < 1 ) /* send operation */
+ {
+ puts( msg_sendfail );
+ fclose( fp );
+ return;
+ }
+
+ SIO_DELAY();
+
+ if( commWriteBytes( &addr, 4 ) < 4 ) /* send write address */
+ {
+ puts( msg_sendfail );
+ fclose( fp );
+ return;
+ }
+
+ SIO_DELAY();
+
+ if( commWriteBytes( &len, 4 ) < 4 ) /* send write length */
+ {
+ puts( msg_sendfail );
+ fclose( fp );
+ return;
+ }
+
+ putchar( ' ' ); /* draw a progress bar */
+ for( i=0; i<70; i++ )
+ {
+ putchar( '.' );
+ }
+ putchar( ']' );
+ putchar( '\r' );
+ putchar( '[' );
+ fflush( stdout );
+
+ progress = 0;
+ olen = len;
+
+ while( len > 0 ) /* send the incoming bytes */
+ {
+ i = len;
+ if( i > 10 )
+ i = 10;
+
+ i = fread( buffer, 1, i, fp );
+ if( i <= 0 )
+ {
+ break;
+ }
+
+ if( ( i = commWriteBytes( buffer, i ) ) < 0 )
+ {
+ puts( msg_recfail );
+ break;
+ }
+ len -= i;
+
+ i = (70*((1024*((olen-len)>>2))/ /* draw out progress */
+ (olen>>2)))/1024;
+ if( i > progress )
+ {
+ progress = i;
+ putchar( '#' );
+ fflush( stdout );
+ }
+ }
+
+ for( i=0; i<(70-progress); i++ )
+ putchar( '#' );
+
+ putchar( '\n' );
+
+ fclose( fp );
+
+} /* dbUploadMemFile */
+
+int dbUploadMem( unsigned int addr, char *buff, size_t len )
+{
+ int i,progress,olen;
+
+ if( commWriteByte( CMD_DB_GETMEM ) < 0 ) /* send getmem command */
+ {
+ puts( msg_sendfail );
+ return(1);
+ }
+
+ if( commWriteByte( 1 ) < 1 ) /* send operation */
+ {
+ puts( msg_sendfail );
+ return(1);
+ }
+
+ SIO_DELAY();
+
+ if( commWriteBytes( &addr, 4 ) < 4 ) /* send write address */
+ {
+ puts( msg_sendfail );
+ return(1);
+ }
+
+ SIO_DELAY();
+
+ if( commWriteBytes( &len, 4 ) < 4 ) /* send write length */
+ {
+ puts( msg_sendfail );
+ return(1);
+ }
+
+ putchar( ' ' ); /* draw a progress bar */
+ for( i=0; i<70; i++ )
+ {
+ putchar( '.' );
+ }
+ putchar( ']' );
+ putchar( '\r' );
+ putchar( '[' );
+ fflush( stdout );
+
+ progress = 0;
+ olen = len;
+
+ while( len > 0 ) /* send the incoming bytes */
+ {
+ i = len;
+ if( i > 10 )
+ i = 10;
+
+ if( ( i = commWriteBytes( buff, i ) ) < 0 )
+ {
+ puts( msg_recfail );
+ break;
+ }
+ len -= i;
+ buff += i;
+
+ i = (70*((1024*((olen-len)>>2))/ /* draw out progress */
+ (olen>>2)))/1024;
+ if( i > progress )
+ {
+ progress = i;
+ putchar( '#' );
+ fflush( stdout );
+ }
+ }
+
+ for( i=0; i<(70-progress); i++ )
+ putchar( '#' );
+
+ putchar( '\n' );
+
+ return(0);
+
+} /* dbUploadMem */
+
+void dbGetMem( unsigned int addr, int len, const char *outfile )
+{
+ FILE *fp;
+ int i,progress,olen;
+ unsigned char buffer[100];
+
+ fp = fopen( outfile, "wb" );
+
+ if( !fp )
+ {
+ printf( "Cannot create output file.\n" );
+ return;
+ }
+
+ if( commWriteByte( CMD_DB_GETMEM ) < 0 ) /* send getmem command */
+ {
+ puts( msg_sendfail );
+ fclose( fp );
+ return;
+ }
+
+ if( commWriteByte( 0 ) < 1 ) /* send operation */
+ {
+ puts( msg_sendfail );
+ fclose( fp );
+ return;
+ }
+
+ SIO_DELAY();
+
+ if( commWriteBytes( &addr, 4 ) < 4 ) /* send read address */
+ {
+ puts( msg_sendfail );
+ fclose( fp );
+ return;
+ }
+
+ SIO_DELAY();
+
+ if( commWriteBytes( &len, 4 ) < 4 ) /* send read length */
+ {
+ puts( msg_sendfail );
+ fclose( fp );
+ return;
+ }
+
+ putchar( ' ' ); /* draw a progress bar */
+ for( i=0; i<70; i++ )
+ {
+ putchar( '.' );
+ }
+ putchar( ']' );
+ putchar( '\r' );
+ putchar( '[' );
+ fflush( stdout );
+
+ progress = 0;
+ olen = len;
+
+ while( len > 0 ) /* receive the incoming bytes */
+ {
+ i = len;
+ if( i > 10 )
+ i = 10;
+
+ if( ( i = commReadBytes( buffer, i ) ) < 0 )
+ {
+ puts( msg_recfail );
+ break;
+ }
+
+ fwrite( buffer, 1, i, fp );
+ len -= i;
+
+ i = (70*((1024*((olen-len)>>2))/ /* draw out progress */
+ (olen>>2)))/1024;
+ if( i > progress )
+ {
+ progress = i;
+ putchar( '#' );
+ fflush( stdout );
+ }
+ }
+
+ for( i=0; i<(70-progress); i++ )
+ putchar( '#' );
+
+ putchar( '\n' );
+
+ fclose( fp );
+
+} /* dbGetMem */
+
+unsigned int dbReadValue( int wordsz, unsigned int addr )
+{
+ unsigned int val;
+
+ if( commWriteByte( CMD_DB_WORD ) < 0 ) /* send value command */
+ {
+ puts( msg_sendfail );
+ return( 0 );
+ }
+
+ if( commWriteByte( 0 ) < 0 ) /* perform read operation */
+ {
+ puts( msg_sendfail );
+ return( 0 );
+ }
+
+ if( commWriteByte( wordsz ) < 0 ) /* send word size */
+ {
+ puts( msg_sendfail );
+ return( 0 );
+ }
+
+ if( commWriteBytes( &addr, 4 ) < 4 ) /* send address */
+ {
+ puts( msg_sendfail );
+ return( 0 );
+ }
+
+ if( commReadBytes( &val, 4 ) < 4 ) /* retrieve value */
+ {
+ puts( msg_recfail );
+ return( 0 );
+ }
+
+ return( val );
+
+} /* dbReadValue */
+
+void dbWriteValue( int wordsz, unsigned int addr, unsigned int val )
+{
+ if( commWriteByte( CMD_DB_WORD ) < 0 ) /* send value command */
+ {
+ puts( msg_sendfail );
+ return;
+ }
+
+ if( commWriteByte( 1 ) < 0 ) /* perform write operation */
+ {
+ puts( msg_sendfail );
+ return;
+ }
+
+ if( commWriteByte( wordsz ) < 0 ) /* send word size */
+ {
+ puts( msg_sendfail );
+ return;
+ }
+
+ if( commWriteBytes( &addr, 4 ) < 4 ) /* send address */
+ {
+ puts( msg_sendfail );
+ return;
+ }
+
+ SIO_DELAY();
+
+ if( commWriteBytes( &val, 4 ) < 4 ) /* send value */
+ {
+ puts( msg_sendfail );
+ return;
+ }
+
+ if( commReadByte() < 0 )
+ {
+ puts( msg_noack );
+ }
+
+} /* dbWriteValue */
+
+static const char *regnames[] =
+{
+ "r0=","at=","v0=","v1=",
+ "a0=","a1=","a2=","a3=",
+ "t0=","t1=","t2=","t3=",
+ "t4=","t5=","t6=","t7=",
+ "s0=","s1=","s2=","s3=",
+ "s4=","s5=","s6=","s7=",
+ "t8=","t9=","k0=","k1=",
+ "gp=","sp=","fp=","ra=",
+ "pc=","hi=","lo="
+};
+
+static const char *cop0names[] =
+{
+ "SR =",
+ "CAUSE =",
+ "BADVADDR =",
+ "JUMPDEST =",
+ "DCIC =",
+ "OPCODE[0] =",
+ "OPCODE[1] ="
+};
+
+void dbGetRegs( void )
+{
+ int i;
+ unsigned int regval;
+ unsigned int pc;
+ char textbuff[32];
+
+ if( commWriteByte( CMD_DB_GETREGS ) < 0 ) /* send getmem command */
+ {
+ puts( msg_sendfail );
+ return;
+ }
+
+ for( i=0; i<35; i++ )
+ {
+ if( commReadBytes( ®val, 4 ) < 4 )
+ {
+ puts( msg_recfail );
+ return;
+ }
+
+ printf( "%s%08X ", regnames[i], regval );
+ if( (i&0x3) == 3 )
+ printf( "\n" );
+
+ if( i == 32 )
+ pc = regval;
+ }
+
+ printf( "\n\n" );
+
+ for( i=0; i<7; i++ )
+ {
+ if( commReadBytes( ®val, 4 ) < 4 )
+ {
+ puts( msg_recfail );
+ return;
+ }
+ printf( "%s%08X", cop0names[i], regval );
+ if( i < 5 )
+ putchar( '\n' );
+ if( i >= 5 )
+ {
+ mips_Decode( regval, pc+((i>5)?4:0), textbuff, 0 );
+ printf( " %s\n", textbuff );
+ }
+ }
+
+ printf( "\n" );
+
+} /* dbGetRegs */
+
+void dbGetBreaks(void)
+{
+ unsigned int regval;
+
+ if( commWriteByte(CMD_DB_GETBRK) < 0 ) /* send get breaks command */
+ {
+ puts(msg_sendfail);
+ return;
+ }
+
+ while(1)
+ {
+ if( commReadBytes(®val, 4) < 4 )
+ {
+ puts(msg_recfail);
+ return;
+ }
+
+ if( regval == 0xFFFFFFFF )
+ {
+ break;
+ }
+
+ printf("PC=%08X ", regval);
+
+ if( commReadBytes(®val, 4) < 4 )
+ {
+ puts(msg_recfail);
+ return;
+ }
+
+ printf("FLAG=%08X ", regval);
+
+ if( commReadBytes(®val, 4) < 4 )
+ {
+ puts(msg_recfail);
+ return;
+ }
+
+ printf("CNT=%08X\n", regval);
+ }
+
+} /* dbGetBreaks */
+
+int dbSetReg(const char *regname, unsigned int value)
+{
+ int regnum;
+ int found;
+
+ found = 0;
+ for(regnum=0; regnum<36; regnum++)
+ {
+ if( strcmp(regname, regnames_param[regnum]) == 0 )
+ {
+ found = 1;
+ break;
+ }
+ }
+
+ if( found == 0 )
+ {
+ printf("Invalid register name.\n");
+ return(1);
+ }
+
+ if( commWriteByte(CMD_DB_SETREG) < 0 ) /* send set register command */
+ {
+ puts(msg_sendfail);
+ return(1);
+ }
+
+ if( commWriteByte(regnum) < 0 ) /* send register byte */
+ {
+ puts(msg_sendfail);
+ return(1);
+ }
+
+ if( commWriteBytes(&value, 4) < 4 ) /* send new register value */
+ {
+ puts(msg_sendfail);
+ return(1);
+ }
+
+ SIO_DELAY();
+
+ if( commReadByte() < 0 )
+ {
+ puts(msg_noack);
+ }
+
+ return(0);
+
+} /* dbSetReg */
+
+int dbSetBDregs(unsigned int addr, unsigned int mask, unsigned char flags)
+{
+ /* send set data break command */
+ if( commWriteByte(CMD_DB_SETBDREG) < 0 )
+ {
+ puts(msg_sendfail);
+ return 1;
+ }
+
+ if( commWriteBytes(&addr, 4) < 4 )
+ {
+ puts(msg_sendfail);
+ return 1;
+ }
+
+ if( commWriteBytes(&mask, 4) < 4 )
+ {
+ puts(msg_sendfail);
+ return 1;
+ }
+
+ if( commWriteByte(flags) < 0 )
+ {
+ puts(msg_sendfail);
+ return 1;
+ }
+
+ SIO_DELAY();
+
+ if( commReadByte() < 0 )
+ {
+ puts(msg_noack);
+ }
+
+ return 0;
+
+} /* dbSetDBregs */
|
