@ -28,6 +28,8 @@
# include <stdio.h>
# include <stdlib.h>
# include <sys/stat.h>
# include <sys/types.h>
# include <readline/readline.h>
# include <readline/history.h>
@ -39,7 +41,7 @@
# include "bus.h"
cable_driver_t * cable = NULL ;
parts * ps = NULL ;
bus_driver_t * bus_driver = NULL ;
static char *
@ -57,46 +59,103 @@ void help( const char *cmd );
void discovery ( const char * filename ) ;
int
main ( void )
int jtag_parse_file ( const char * filename ) ;
# define JTAGDIR ".jtag"
# define HISTORYFILE "history"
# define RCFILE "rc"
void
jtag_create_jtagdir ( void )
{
char * line = NULL ;
parts * ps = NULL ;
char * home = getenv ( " HOME " ) ;
char * jdir ;
printf (
" %s \n "
" Copyright (C) 2002, 2003 ETC s.r.o. \n "
" %s is free software, covered by the GNU General Public License, and you are \n "
" welcome to change it and/or distribute copies of it under certain conditions. \n "
" There is absolutely no warranty for %s. \n \n " , PACKAGE_STRING , PACKAGE , PACKAGE
) ;
if ( ! home )
return ;
printf ( " Warning: %s may damage your hardware! Type \" quit \" for exit! \n \n " , PACKAGE ) ;
printf ( " Type \" help \" for help. \n \n " ) ;
jdir = malloc ( strlen ( home ) + strlen ( JTAGDIR ) + 2 ) ; /* "/" and trailing \0 */
if ( ! jdir )
return ;
strcpy ( jdir , home ) ;
strcat ( jdir , " / " ) ;
strcat ( jdir , JTAGDIR ) ;
/* Create the directory if it doesn't exists. */
mkdir ( jdir , 0755 ) ;
free ( jdir ) ;
}
void
jtag_load_history ( void )
{
char * home = getenv ( " HOME " ) ;
char * file ;
using_history ( ) ;
read_history ( " .jtag_history " ) ;
for ( ; ; ) {
char * t ;
if ( ! home )
return ;
free ( line ) ;
line = readline ( " jtag> " ) ;
file = malloc ( strlen ( home ) + strlen ( JTAGDIR ) + strlen ( HISTORYFILE ) + 3 ) ; /* 2 x "/" and trailing \0 */
if ( ! file )
return ;
strcpy ( file , home ) ;
strcat ( file , " / " ) ;
strcat ( file , JTAGDIR ) ;
strcat ( file , " / " ) ;
strcat ( file , HISTORYFILE ) ;
read_history ( file ) ;
if ( ! line | | ! * line )
continue ;
add_history ( line ) ;
free ( file ) ;
}
void
jtag_save_history ( void )
{
char * home = getenv ( " HOME " ) ;
char * file ;
if ( ! home )
return ;
file = malloc ( strlen ( home ) + strlen ( JTAGDIR ) + strlen ( HISTORYFILE ) + 3 ) ; /* 2 x "/" and trailing \0 */
if ( ! file )
return ;
strcpy ( file , home ) ;
strcat ( file , " / " ) ;
strcat ( file , JTAGDIR ) ;
strcat ( file , " / " ) ;
strcat ( file , HISTORYFILE ) ;
write_history ( file ) ;
free ( file ) ;
}
int
jtag_parse_line ( char * line )
{
char * t ;
if ( ! line | | ! ( strlen ( line ) > 0 ) )
return 1 ;
t = get_token ( line ) ;
if ( ! t )
continue ;
return 1 ;
if ( strcmp ( t , " quit " ) = = 0 ) {
if ( get_token ( NULL ) ) {
printf ( " quit: syntax error \n \n Type \" help \" for help. \n \n " ) ;
continue ;
return 1 ;
}
break ;
return 0 ;
}
if ( strcmp ( t , " help " ) = = 0 ) {
@ -105,7 +164,7 @@ main( void )
printf ( " help: Syntax error! \n " ) ;
else
help ( t ) ;
continue ;
return 1 ;
}
if ( strcmp ( t , " frequency " ) = = 0 ) {
@ -114,22 +173,22 @@ main( void )
t = get_token ( NULL ) ;
if ( ! t ) {
printf ( " Missing argument(s) \n " ) ;
continue ;
return 1 ;
}
if ( ( sscanf ( t , " 0x%x " , & freq ) ! = 1 ) & & ( sscanf ( t , " %u " , & freq ) ! = 1 ) ) {
printf ( " syntax error \n " ) ;
continue ;
return 1 ;
}
if ( get_token ( NULL ) ) {
printf ( " frequency: syntax error \n " ) ;
continue ;
return 1 ;
}
printf ( " Setting TCK frequency to %u Hz \n " , freq ) ;
frequency = freq ;
continue ;
return 1 ;
}
if ( strcmp ( t , " cable " ) = = 0 ) {
@ -139,38 +198,38 @@ main( void )
t = get_token ( NULL ) ;
if ( ! t ) {
printf ( " Missing argument(s) \n " ) ;
continue ;
return 1 ;
}
if ( strcmp ( t , " parallel " ) ! = 0 ) {
printf ( " syntax error! \n " ) ;
continue ;
return 1 ;
}
t = get_token ( NULL ) ;
if ( ! t ) {
printf ( " Missing argument(s) \n " ) ;
continue ;
return 1 ;
}
if ( ( sscanf ( t , " 0x%x " , & port ) ! = 1 ) & & ( sscanf ( t , " %d " , & port ) ! = 1 ) ) {
printf ( " syntax error \n " ) ;
continue ;
return 1 ;
}
t = get_token ( NULL ) ;
if ( ! t ) {
printf ( " Missing argument(s) \n " ) ;
continue ;
return 1 ;
}
if ( get_token ( NULL ) ) {
printf ( " syntax error! \n " ) ;
continue ;
return 1 ;
}
if ( strcmp ( t , " none " ) = = 0 ) {
printf ( " Changed cable to 'none' \n " ) ;
cable = NULL ;
continue ;
return 1 ;
}
for ( i = 0 ; cable_drivers [ i ] ; i + + )
@ -179,7 +238,7 @@ main( void )
if ( ! cable_drivers [ i ] ) {
printf ( " Unknown cable: %s \n " , t ) ;
continue ;
return 1 ;
}
cable = cable_drivers [ i ] ;
@ -187,44 +246,44 @@ main( void )
if ( ! cable - > init ( port ) ) {
printf ( " Error: Cable driver initialization failed! \n " ) ;
cable = NULL ;
continue ;
return 1 ;
}
cable - > set_trst ( 0 ) ;
cable - > set_trst ( 1 ) ;
tap_reset ( ) ;
continue ;
return 1 ;
}
if ( strcmp ( t , " discovery " ) = = 0 ) {
if ( ! cable ) {
printf ( " Error: Cable not configured. Use 'cable' command first! \n " ) ;
continue ;
return 1 ;
}
t = get_token ( NULL ) ;
if ( ! t ) {
printf ( " discovery: missing filename \n " ) ;
continue ;
return 1 ;
}
if ( get_token ( NULL ) ) {
printf ( " syntax error! \n " ) ;
continue ;
return 1 ;
}
discovery ( t ) ;
continue ;
return 1 ;
}
if ( strcmp ( t , " detect " ) = = 0 ) {
if ( ! cable ) {
printf ( " Error: Cable not configured. Use 'cable' command first! \n " ) ;
continue ;
return 1 ;
}
if ( get_token ( NULL ) ) {
printf ( " detect: syntax error \n " ) ;
continue ;
return 1 ;
}
parts_free ( ps ) ;
@ -232,7 +291,7 @@ main( void )
if ( ! ps - > len ) {
parts_free ( ps ) ;
ps = NULL ;
continue ;
return 1 ;
}
parts_set_instruction ( ps , " SAMPLE/PRELOAD " ) ;
parts_shift_instructions ( ps ) ;
@ -245,7 +304,7 @@ main( void )
bus_driver = & pxa250_bus_driver ;
if ( strcmp ( ps - > parts [ 0 ] - > part , " IXP425 " ) = = 0 )
bus_driver = & ixp425_bus_driver ;
continue ;
return 1 ;
}
if ( strcmp ( t , " flashmem " ) = = 0 ) {
@ -255,23 +314,23 @@ main( void )
if ( ! cable ) {
printf ( " Error: Cable not configured. Use 'cable' command first! \n " ) ;
continue ;
return 1 ;
}
if ( ! ps ) {
printf ( " Run \" detect \" first. \n " ) ;
continue ;
return 1 ;
}
t = get_token ( NULL ) ;
if ( ! t ) {
printf ( " flashmem: Missing argument(s) \n " ) ;
continue ;
return 1 ;
}
if ( strcmp ( t , " msbin " ) ! = 0 ) {
if ( ( sscanf ( t , " 0x%x " , & addr ) ! = 1 ) & & ( sscanf ( t , " %d " , & addr ) ! = 1 ) ) {
printf ( " error \n " ) ;
continue ;
return 1 ;
}
printf ( " 0x%08X \n " , addr ) ;
} else
@ -280,23 +339,23 @@ main( void )
t = get_token ( NULL ) ;
if ( ! t ) {
printf ( " flashmem: missing filename \n " ) ;
continue ;
return 1 ;
}
if ( get_token ( NULL ) ) {
printf ( " syntax error! \n " ) ;
continue ;
return 1 ;
}
f = fopen ( t , " r " ) ;
if ( ! f ) {
printf ( " Unable to open file `%s'! \n " , t ) ;
continue ;
return 1 ;
}
if ( msbin )
flashmsbin ( ps , f ) ;
else
flashmem ( ps , f , addr ) ;
fclose ( f ) ;
continue ;
return 1 ;
}
if ( strcmp ( t , " readmem " ) = = 0 ) {
@ -306,89 +365,89 @@ main( void )
if ( ! cable ) {
printf ( " Error: Cable not configured. Use 'cable' command first! \n " ) ;
continue ;
return 1 ;
}
if ( ! ps ) {
printf ( " Run \" detect \" first. \n " ) ;
continue ;
return 1 ;
}
t = get_token ( NULL ) ;
if ( ! t ) {
printf ( " flashmem: Missing argument(s) \n " ) ;
continue ;
return 1 ;
}
if ( ( sscanf ( t , " 0x%x " , & addr ) ! = 1 ) & & ( sscanf ( t , " %d " , & addr ) ! = 1 ) ) {
printf ( " syntax error \n " ) ;
continue ;
return 1 ;
}
t = get_token ( NULL ) ;
if ( ! t ) {
printf ( " flashmem: Missing argument(s) \n " ) ;
continue ;
return 1 ;
}
if ( ( sscanf ( t , " 0x%x " , & len ) ! = 1 ) & & ( sscanf ( t , " %d " , & len ) ! = 1 ) ) {
printf ( " syntax error \n " ) ;
continue ;
return 1 ;
}
/* filename */
t = get_token ( NULL ) ;
if ( ! t ) {
printf ( " flashmem: missing filename \n " ) ;
continue ;
return 1 ;
}
if ( get_token ( NULL ) ) {
printf ( " syntax error! \n " ) ;
continue ;
return 1 ;
}
f = fopen ( t , " w " ) ;
if ( ! f ) {
printf ( " Unable to create file `%s'! \n " , t ) ;
continue ;
return 1 ;
}
readmem ( ps , f , addr , len ) ;
fclose ( f ) ;
continue ;
return 1 ;
}
if ( strcmp ( t , " detectflash " ) = = 0 ) {
if ( get_token ( NULL ) ) {
printf ( " detectflash: syntax error \n " ) ;
continue ;
return 1 ;
}
if ( ! cable ) {
printf ( " Error: Cable not configured. Use 'cable' command first! \n " ) ;
continue ;
return 1 ;
}
if ( ! ps ) {
printf ( " Run \" detect \" first. \n " ) ;
continue ;
return 1 ;
}
detectflash ( ps ) ;
continue ;
return 1 ;
}
if ( strcmp ( t , " print " ) = = 0 ) {
if ( get_token ( NULL ) ) {
printf ( " print: syntax error \n " ) ;
continue ;
return 1 ;
}
if ( ! cable ) {
printf ( " Error: Cable not configured. Use 'cable' command first! \n " ) ;
continue ;
return 1 ;
}
parts_print ( ps , 1 ) ;
continue ;
return 1 ;
}
if ( strcmp ( t , " instruction " ) = = 0 ) {
@ -396,69 +455,69 @@ main( void )
if ( ! cable ) {
printf ( " Error: Cable not configured. Use 'cable' command first! \n " ) ;
continue ;
return 1 ;
}
if ( ! ps ) {
printf ( " Run \" detect \" first. \n " ) ;
continue ;
return 1 ;
}
t = get_token ( NULL ) ;
if ( ! t ) {
printf ( " instruction: syntax error \n " ) ;
continue ;
return 1 ;
}
n = strtol ( t , & t , 10 ) ;
if ( t & & * t ) {
printf ( " instruction: syntax error \n " ) ;
continue ;
return 1 ;
}
if ( ( n < 0 ) | | ( n > = ps - > len ) ) {
printf ( " instruction: invalid part number \n " ) ;
continue ;
return 1 ;
}
t = get_token ( NULL ) ;
if ( ! t ) {
printf ( " instruction: missing instruction name \n " ) ;
continue ;
return 1 ;
}
if ( get_token ( NULL ) ) {
printf ( " instruction: syntax error \n " ) ;
continue ;
return 1 ;
}
part_set_instruction ( ps - > parts [ n ] , t ) ;
if ( ps - > parts [ n ] - > active_instruction = = NULL )
printf ( " instruction: unknown instruction %s \n " , t ) ;
continue ;
return 1 ;
}
if ( strcmp ( t , " shift " ) = = 0 ) {
if ( ! cable ) {
printf ( " Error: Cable not configured. Use 'cable' command first! \n " ) ;
continue ;
return 1 ;
}
t = get_token ( NULL ) ;
if ( t & & ( strcmp ( t , " ir " ) = = 0 ) ) {
parts_shift_instructions ( ps ) ;
continue ;
return 1 ;
}
if ( t & & ( strcmp ( t , " dr " ) = = 0 ) ) {
parts_shift_data_registers ( ps ) ;
continue ;
return 1 ;
}
printf ( " shift: syntax error \n " ) ;
continue ;
return 1 ;
}
if ( strcmp ( t , " dr " ) = = 0 ) {
@ -468,29 +527,29 @@ main( void )
if ( ! cable ) {
printf ( " Error: Cable not configured. Use 'cable' command first! \n " ) ;
continue ;
return 1 ;
}
if ( ! ps ) {
printf ( " Run \" detect \" first. \n " ) ;
continue ;
return 1 ;
}
t = get_token ( NULL ) ;
if ( ! t ) {
printf ( " dr: syntax error \n " ) ;
continue ;
return 1 ;
}
n = strtol ( t , & t , 10 ) ;
if ( t & & * t ) {
printf ( " dr: syntax error \n " ) ;
continue ;
return 1 ;
}
if ( ( n < 0 ) | | ( n > = ps - > len ) ) {
printf ( " dr: invalid part number \n " ) ;
continue ;
return 1 ;
}
t = get_token ( NULL ) ;
@ -503,12 +562,12 @@ main( void )
dir = 1 ;
else {
printf ( " dr: syntax error \n " ) ;
continue ;
return 1 ;
}
if ( get_token ( NULL ) ) {
printf ( " dr: syntax error \n " ) ;
continue ;
return 1 ;
}
}
@ -518,7 +577,7 @@ main( void )
r = ps - > parts [ n ] - > active_instruction - > data_register - > in ;
printf ( " %s \n " , register_get_string ( r ) ) ;
continue ;
return 1 ;
}
if ( strcmp ( t , " set " ) = = 0 ) {
@ -529,46 +588,46 @@ main( void )
if ( ! cable ) {
printf ( " Error: Cable not configured. Use 'cable' command first! \n " ) ;
continue ;
return 1 ;
}
if ( ! ps ) {
printf ( " Run \" detect \" first. \n " ) ;
continue ;
return 1 ;
}
t = get_token ( NULL ) ;
if ( ! t | | strcmp ( t , " signal " ) ! = 0 ) {
printf ( " set: syntax error \n " ) ;
continue ;
return 1 ;
}
t = get_token ( NULL ) ;
if ( ! t ) {
printf ( " set: syntax error \n " ) ;
continue ;
return 1 ;
}
n = strtol ( t , & t , 10 ) ;
if ( t & & * t ) {
printf ( " set: syntax error \n " ) ;
continue ;
return 1 ;
}
if ( ( n < 0 ) | | ( n > = ps - > len ) ) {
printf ( " set: invalid part number \n " ) ;
continue ;
return 1 ;
}
s = get_token ( NULL ) ; /* signal name */
if ( ! s ) {
printf ( " set: syntax error \n " ) ;
continue ;
return 1 ;
}
t = get_token ( NULL ) ; /* direction */
if ( ! t | | ( strcmp ( t , " in " ) ! = 0 & & strcmp ( t , " out " ) ! = 0 ) ) {
printf ( " set: syntax error \n " ) ;
continue ;
return 1 ;
}
dir = ( strcmp ( t , " in " ) = = 0 ) ? 0 : 1 ;
@ -577,27 +636,140 @@ main( void )
data = strtol ( t , & t , 10 ) ;
if ( t & & * t ) {
printf ( " set: syntax error \n " ) ;
continue ;
return 1 ;
}
if ( ( data < 0 ) | | ( data > 1 ) ) {
printf ( " set: invalid data value \n " ) ;
continue ;
return 1 ;
}
} else
data = 0 ;
part_set_signal ( ps - > parts [ n ] , s , dir , data ) ;
continue ;
return 1 ;
}
if ( strcmp ( t , " script " ) = = 0 ) {
t = get_token ( NULL ) ; /* filename */
if ( ! t ) {
printf ( " script: missing filename \n " ) ;
return 1 ;
}
if ( get_token ( NULL ) ) {
printf ( " script: syntax error \n " ) ;
return 1 ;
}
jtag_parse_file ( t ) ;
return 1 ;
}
printf ( " %s: unknown command \n " , t ) ;
}
return 1 ;
}
void
jtag_readline_loop ( const char * prompt )
{
char * line = NULL ;
/* Iterate */
while ( jtag_parse_line ( line ) ) {
free ( line ) ;
/* Read a line from the terminal */
line = readline ( prompt ) ;
/* Check if we actually got something */
if ( line & & ( strlen ( line ) > 0 ) )
add_history ( line ) ;
}
free ( line ) ;
parts_free ( ps ) ;
}
int
jtag_parse_file ( const char * filename )
{
FILE * f ;
int go = 1 ;
char * line = NULL ;
int n ;
f = fopen ( filename , " r " ) ;
if ( ! f ) {
printf ( " Unable to open file `%s'! \n " , filename ) ;
return 1 ;
}
while ( getline ( & line , & n , f ) ! = - 1 )
if ( strlen ( line ) > 0 )
go = jtag_parse_line ( line ) ;
free ( line ) ;
fclose ( f ) ;
return go ;
}
void
jtag_parse_rc ( void )
{
char * home = getenv ( " HOME " ) ;
char * file ;
if ( ! home )
return ;
file = malloc ( strlen ( home ) + strlen ( JTAGDIR ) + strlen ( RCFILE ) + 3 ) ; /* 2 x "/" and trailing \0 */
if ( ! file )
return ;
strcpy ( file , home ) ;
strcat ( file , " / " ) ;
strcat ( file , JTAGDIR ) ;
strcat ( file , " / " ) ;
strcat ( file , RCFILE ) ;
jtag_parse_file ( file ) ;
free ( file ) ;
}
int
main ( void )
{
printf (
" %s \n "
" Copyright (C) 2002, 2003 ETC s.r.o. \n "
" %s is free software, covered by the GNU General Public License, and you are \n "
" welcome to change it and/or distribute copies of it under certain conditions. \n "
" There is absolutely no warranty for %s. \n \n " , PACKAGE_STRING , PACKAGE , PACKAGE
) ;
printf ( " Warning: %s may damage your hardware! Type \" quit \" for exit! \n \n " , PACKAGE ) ;
printf ( " Type \" help \" for help. \n \n " ) ;
/* Create ~/.jtag */
jtag_create_jtagdir ( ) ;
/* Parse and execute the RC file */
jtag_parse_rc ( ) ;
/* Load history */
jtag_load_history ( ) ;
/* main loop */
jtag_readline_loop ( " jtag> " ) ;
/* Save history */
jtag_save_history ( ) ;
parts_free ( ps ) ;
if ( cable ) {
cable - > set_trst ( 0 ) ;
cable - > set_trst ( 1 ) ;
@ -607,6 +779,5 @@ main( void )
cable = NULL ;
}
write_history ( " .jtag_history " ) ;
return 0 ;
}