From dc796a209113c3fdc27de0211edcaa67faed7b5f Mon Sep 17 00:00:00 2001 From: oharboe Date: Sun, 6 Jul 2008 19:17:43 +0000 Subject: src/helper/configuration.h - Log output handlers now get a "const char *line" - Added "const" to parameter. src/helper/command.c src/helper/command.h - New function: 'command_output_text()' - Log output handlers now get a "const char *line" src/helper/options.c - Log output handlers now get a "const char *line" src/server/telnet_server.c - DO not transmit NULL bytes via TELNET. - Log output handlers now get a "const char *line" src/server/gdb_server.c - Log output handlers now get a "const char *line" *** THIS INCLUDES PORTIONS OF A PATCH FROM Oyvind sent previously to the mailing list for TCL users try src/target/target.c *** THIS INCLUDES PORTIONS OF A PATCH FROM Oyvind sent previously to the mailing list for TCL users try src/target/target.h *** THIS INCLUDES PORTIONS OF A PATCH FROM Oyvind sent previously to the mailing list for TCL users try src/openocd.c - **MAJOR** Work: New TCL/Jim function: mem2array - **MAJOR** Work: Redirect Tcl/Jim stdio output to remote users. - Previously: TCL output did not go to GDB. - Previously: TCL output did not go to TELNET - Previously: TCL output only goes to control console. - This fixes that problem. + Created callbacks: +openocd_jim_fwrite() +openocd_jim_fread() +openocd_jim_vfprintf() +openocd_jim_fflush() +openocd_jim_fgets() src/Makefile.am - New TCL files. - Future note: This should be more automated. As the list of 'tcl' files grows maintaning this list will suck. src/Jim.c - ** THIS INCLUDES A PREVIOUS PATCH I SENT EARLIER ** - that impliments many [format] specifies JIM did not support. - Jim_FormatString() - **MAJOR** work. - Previously only supported "%s" "%d" and "%c" - And what support existed had bugs. - NEW: *MANY* formating parameters are now supported. - TODO: The "precision" specifier is not supported. ** NEW ** This patch. - Jim_StringToWide() test if no conversion occured. - Jim_StringToIndex() test if no conversion occured. - Jim_StringToDouble() test if no conversion occured. ** NEW ** This Patch. Major Work. - Previously output from JIM did not get sent to GDB - Ditto: Output to Telnet session. - Above items are now fixed - By introducing callbacks new function pointers in the "interp" structure. - Helpers that call the callbacks. - New function: Jim_fprintf() - New function: Jim_vfprintf() - New function: Jim_fwrite() - New function: Jim_fread() - New function: Jim_fflush() - New function: Jim_fgets() By default: the output is to STDIO as previous. The "openocd.c" - redirects the output as needed. - Jim_Panic() - Send panic to both STDERR and the interps specified STDERR output as a 2nd choice. - Now JIM's "stdin/stdout/stderr" paramters are "void *" and are no longer "FILE *". src/Jim.h - **MAJOR** - New JIM STDIO callbacks in the "interp" structure. - change: "stdin/stdout/stderr" are now "void *" cookies. - New JIM stdio helper functions. git-svn-id: svn://svn.berlios.de/openocd/trunk@755 b42882b7-edfa-0310-969c-e2dbd0fdcd60 --- src/openocd.c | 295 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 295 insertions(+) (limited to 'src/openocd.c') diff --git a/src/openocd.c b/src/openocd.c index 99ee6527..b6b217df 100644 --- a/src/openocd.c +++ b/src/openocd.c @@ -165,6 +165,191 @@ void unlockBigLock() Jim_Interp *interp; command_context_t *active_cmd_ctx; +static int +new_int_array_element( Jim_Interp * interp, + const char *varname, + int idx, + u32 val ) +{ + char *namebuf; + Jim_Obj *nameObjPtr, *valObjPtr; + int result; + + namebuf = alloca( strlen(varname) + 30 ); + sprintf( namebuf, "%s(%d)", varname, idx ); + + + nameObjPtr = Jim_NewStringObj(interp, namebuf, -1); + valObjPtr = Jim_NewIntObj(interp, val ); + Jim_IncrRefCount(nameObjPtr); + Jim_IncrRefCount(valObjPtr); + result = Jim_SetVariable(interp, nameObjPtr, valObjPtr); + Jim_DecrRefCount(interp, nameObjPtr); + Jim_DecrRefCount(interp, valObjPtr); + // printf( "%s = 0%08x\n", namebuf, val ); + return result; +} + +static int +Jim_Command_mem2array( Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + target_t *target; + long l; + u32 width; + u32 endian; + u32 len; + u32 addr; + u32 count; + u32 v; + const char *varname; + u8 buffer[4096]; + int i,n,e,retval; + + + /* argv[1] = name of array to receive the data + * argv[2] = desired width + * argv[3] = memory address + * argv[4] = length in bytes to read + */ + if( argc != 5 ){ + Jim_WrongNumArgs( interp, 1, argv, "varname width addr nelems" ); + return JIM_ERR; + } + varname = Jim_GetString( argv[1], &len ); + /* given "foo" get space for worse case "foo(%d)" .. add 20 */ + + + e = Jim_GetLong( interp, argv[2], &l ); + width = l; + if( e != JIM_OK ){ + return e; + } + + e = Jim_GetLong( interp, argv[3], &l ); + addr = l; + if( e != JIM_OK ){ + return e; + } + e = Jim_GetLong( interp, argv[4], &l ); + len = l; + if( e != JIM_OK ){ + return e; + } + switch(width){ + case 8: + width = 1; + break; + case 16: + width = 2; + break; + case 32: + width = 4; + break; + default: + Jim_SetResult(interp, + Jim_NewEmptyStringObj(interp)); + Jim_AppendStrings( interp, Jim_GetResult(interp), + "Invalid width param, must be 8/16/32", NULL ); + return JIM_ERR; + } + if( len == 0 ){ + Jim_SetResult(interp, + Jim_NewEmptyStringObj(interp)); + Jim_AppendStrings( interp, Jim_GetResult(interp), + "mem2array: zero width read?", NULL ); + return JIM_ERR; + } + if( (addr + (len * width)) < addr ){ + Jim_SetResult(interp, + Jim_NewEmptyStringObj(interp)); + Jim_AppendStrings( interp, Jim_GetResult(interp), + "mem2array: addr + len - wraps to zero?", NULL ); + return JIM_ERR; + } + /* absurd transfer size? */ + if( len > 65536 ){ + Jim_SetResult(interp, + Jim_NewEmptyStringObj(interp)); + Jim_AppendStrings( interp, Jim_GetResult(interp), + "mem2array: absurd > 64K item request", NULL ); + return JIM_ERR; + } + + if( (width == 1) || + ((width == 2) && ((addr & 1) == 0)) || + ((width == 4) && ((addr & 3) == 0)) ){ + /* all is well */ + } else { + char buf[100]; + Jim_SetResult(interp, + Jim_NewEmptyStringObj(interp)); + sprintf( buf, + "mem2array address: 0x%08x is not aligned for %d byte reads", + addr, width ); + + Jim_AppendStrings( interp, Jim_GetResult(interp), + buf , NULL ); + return JIM_ERR; + } + + target = get_current_target( active_cmd_ctx ); + + /* Transfer loop */ + + /* index counter */ + n = 0; + /* assume ok */ + e = JIM_OK; + while( len ){ + + /* Slurp... in buffer size chunks */ + + count = len; /* in objects.. */ + if( count > (sizeof(buffer)/width)){ + count = (sizeof(buffer)/width); + } + + retval = target->type->read_memory( target, + addr, + width, + count, + buffer ); + + if( retval != ERROR_OK ){ + /* BOO !*/ + LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed", + addr, width, count ); + Jim_SetResult(interp, + Jim_NewEmptyStringObj(interp)); + Jim_AppendStrings( interp, Jim_GetResult(interp), + "mem2array: cannot read memory", NULL ); + e = JIM_ERR; + len = 0; + } else { + v = 0; /* shut up gcc */ + for( i = 0 ; i < count ; i++, n++ ){ + switch(width){ + case 4: + v = target_buffer_get_u32( target, &buffer[i*width] ); + break; + case 2: + v = target_buffer_get_u16( target, &buffer[i*width] ); + break; + case 1: + v = buffer[i] & 0x0ff; + break; + } + new_int_array_element( interp, varname, n, v ); + } + len -= count; + } + } + Jim_SetResult(interp, + Jim_NewEmptyStringObj(interp)); + + return JIM_OK; +} + static void tcl_output(void *privData, const char *file, int line, const char *function, const char *string) { @@ -323,6 +508,97 @@ Jim_Command_echo(Jim_Interp *interp, return JIM_OK; } +static size_t +openocd_jim_fwrite( const void *_ptr, size_t size, size_t n, void *cookie ) +{ + size_t nbytes; + const char *ptr; + + /* make it a char easier to read code */ + ptr = _ptr; + + nbytes = size * n; + if( nbytes == 0 ){ + return 0; + } + + if( !active_cmd_ctx ){ + /* FIXME: Where should this go? */ + return n; + } + + + /* do we have to chunk it? */ + if( ptr[ nbytes ] == 0 ){ + /* no it is a C style string */ + command_output_text( active_cmd_ctx, ptr ); + return; + } + /* GRR we must chunk - not null terminated */ + while( nbytes ){ + char chunk[128+1]; + int x; + + x = nbytes; + if( x > 128 ){ + x = 128; + } + /* copy it */ + memcpy( chunk, ptr, x ); + /* terminate it */ + chunk[n] = 0; + /* output it */ + command_output_text( active_cmd_ctx, chunk ); + ptr += x; + nbytes -= x; + } + + return n; +} + +static size_t +openocd_jim_fread(void *ptr, size_t size, size_t n, void *cookie ) +{ + /* TCL wants to read... tell him no */ + return 0; +} + + +static int +openocd_jim_vfprintf( void *cookie, const char *fmt, va_list ap ) +{ + char *cp; + int n; + + n = -1; + if( active_cmd_ctx ){ + cp = alloc_vprintf( fmt, ap ); + if( cp ){ + command_output_text( active_cmd_ctx, cp ); + n = strlen(cp); + free(cp); + } + } + return n; +} + +static int +openocd_jim_fflush( void *cookie ) +{ + /* nothing to flush */ + return 0; +} + +static char * +openocd_jim_fgets( char *s, int size, void *cookie ) +{ + /* not supported */ + errno = ENOTSUP; + return NULL; +} + + + void initJim(void) { Jim_InitEmbedded(); @@ -335,6 +611,17 @@ void initJim(void) Jim_CreateCommand(interp, "openocd_throw", Jim_Command_openocd_throw, NULL, NULL); Jim_CreateCommand(interp, "find", Jim_Command_find, NULL, NULL); Jim_CreateCommand(interp, "echo", Jim_Command_echo, NULL, NULL); + Jim_CreateCommand(interp, "mem2array", Jim_Command_mem2array, NULL, NULL ); + + /* Set Jim's STDIO */ + interp->cookie_stdin = NULL; + interp->cookie_stdout = NULL; + interp->cookie_stderr = NULL; + interp->cb_fwrite = openocd_jim_fwrite; + interp->cb_fread = openocd_jim_fread ; + interp->cb_vfprintf = openocd_jim_vfprintf; + interp->cb_fflush = openocd_jim_fflush; + interp->cb_fgets = openocd_jim_fgets; } int main(int argc, char *argv[]) @@ -422,3 +709,11 @@ int main(int argc, char *argv[]) return EXIT_SUCCESS; } + +/* + * Local Variables: ** + * tab-width: 4 ** + * c-basic-offset: 4 ** + * End: ** + */ + -- cgit v1.2.3-18-g5258