1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
21 #define OPENOCD_VERSION "Open On-Chip Debugger " VERSION " (" PKGBLDDATE ") svn:" PKGBLDREV
30 #include "configuration.h"
31 #include "interpreter.h"
40 #include "telnet_server.h"
41 #include "gdb_server.h"
42 #include "tcl_server.h"
45 #include <sys/types.h>
60 /* Jim is provied by eCos */
61 #include <cyg/jimtcl/jim.h>
67 #include "replacements.h"
69 int launchTarget(struct command_context_s
*cmd_ctx
)
72 /* Try to examine & validate jtag chain, though this may require a reset first
73 * in which case we continue setup */
76 /* try to examine target at this point. If it fails, perhaps a reset will
77 * bring it up later on via a telnet/gdb session */
78 target_examine(cmd_ctx
);
80 retval
=flash_init_drivers(cmd_ctx
);
83 LOG_DEBUG("flash init complete");
85 retval
=nand_init(cmd_ctx
);
88 LOG_DEBUG("NAND init complete");
90 retval
=pld_init(cmd_ctx
);
93 LOG_DEBUG("pld init complete");
97 /* Give TELNET a way to find out what version this is */
98 int handle_version_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
100 command_print(cmd_ctx
, OPENOCD_VERSION
);
105 static int daemon_startup
= 0;
107 int handle_daemon_startup_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
112 return ERROR_COMMAND_SYNTAX_ERROR
;
114 daemon_startup
= strcmp("reset", args
[0])==0;
116 command_print(cmd_ctx
, OPENOCD_VERSION
);
121 void exit_handler(void)
123 /* close JTAG interface */
124 if (jtag
&& jtag
->quit
)
128 /* OpenOCD can't really handle failure of this command. Patches welcome! :-) */
129 int handle_init_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
132 static int initialized
=0;
138 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
140 atexit(exit_handler
);
142 if (target_init(cmd_ctx
) != ERROR_OK
)
144 LOG_DEBUG("target init complete");
146 if ((retval
=jtag_interface_init(cmd_ctx
)) != ERROR_OK
)
148 /* we must be able to set up the jtag interface */
151 LOG_DEBUG("jtag interface init complete");
153 /* Try to initialize & examine the JTAG chain at this point, but
154 * continue startup regardless
156 if (jtag_init(cmd_ctx
) == ERROR_OK
)
158 LOG_DEBUG("jtag init complete");
159 if (target_examine(cmd_ctx
) == ERROR_OK
)
161 LOG_DEBUG("jtag examine complete");
165 if (flash_init_drivers(cmd_ctx
) != ERROR_OK
)
167 LOG_DEBUG("flash init complete");
169 if (nand_init(cmd_ctx
) != ERROR_OK
)
171 LOG_DEBUG("NAND init complete");
173 if (pld_init(cmd_ctx
) != ERROR_OK
)
175 LOG_DEBUG("pld init complete");
177 /* initialize tcp server */
180 /* initialize telnet subsystem */
181 telnet_init("Open On-Chip Debugger");
183 tcl_init(); /* allows tcl to just connect without going thru telnet */
189 void unlockBigLock();
192 command_context_t
*active_cmd_ctx
;
194 static int new_int_array_element(Jim_Interp
* interp
, const char *varname
, int idx
, u32 val
)
197 Jim_Obj
*nameObjPtr
, *valObjPtr
;
200 namebuf
= alloc_printf("%s(%d)", varname
, idx
);
202 nameObjPtr
= Jim_NewStringObj(interp
, namebuf
, -1);
203 valObjPtr
= Jim_NewIntObj(interp
, val
);
204 Jim_IncrRefCount(nameObjPtr
);
205 Jim_IncrRefCount(valObjPtr
);
206 result
= Jim_SetVariable(interp
, nameObjPtr
, valObjPtr
);
207 Jim_DecrRefCount(interp
, nameObjPtr
);
208 Jim_DecrRefCount(interp
, valObjPtr
);
210 // printf( "%s = 0%08x\n", namebuf, val );
214 static int Jim_Command_mem2array(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
227 /* argv[1] = name of array to receive the data
228 * argv[2] = desired width
229 * argv[3] = memory address
230 * argv[4] = length in bytes to read
233 Jim_WrongNumArgs( interp
, 1, argv
, "varname width addr nelems" );
236 varname
= Jim_GetString( argv
[1], &len
);
237 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
239 e
= Jim_GetLong( interp
, argv
[2], &l
);
245 e
= Jim_GetLong( interp
, argv
[3], &l
);
250 e
= Jim_GetLong( interp
, argv
[4], &l
);
266 Jim_SetResult(interp
,
267 Jim_NewEmptyStringObj(interp
));
268 Jim_AppendStrings( interp
, Jim_GetResult(interp
),
269 "Invalid width param, must be 8/16/32", NULL
);
273 Jim_SetResult(interp
,
274 Jim_NewEmptyStringObj(interp
));
275 Jim_AppendStrings( interp
, Jim_GetResult(interp
),
276 "mem2array: zero width read?", NULL
);
279 if( (addr
+ (len
* width
)) < addr
){
280 Jim_SetResult(interp
,
281 Jim_NewEmptyStringObj(interp
));
282 Jim_AppendStrings( interp
, Jim_GetResult(interp
),
283 "mem2array: addr + len - wraps to zero?", NULL
);
286 /* absurd transfer size? */
288 Jim_SetResult(interp
,
289 Jim_NewEmptyStringObj(interp
));
290 Jim_AppendStrings( interp
, Jim_GetResult(interp
),
291 "mem2array: absurd > 64K item request", NULL
);
296 ((width
== 2) && ((addr
& 1) == 0)) ||
297 ((width
== 4) && ((addr
& 3) == 0)) ){
301 Jim_SetResult(interp
,
302 Jim_NewEmptyStringObj(interp
));
304 "mem2array address: 0x%08x is not aligned for %d byte reads",
307 Jim_AppendStrings( interp
, Jim_GetResult(interp
),
312 target
= get_current_target( active_cmd_ctx
);
322 /* Slurp... in buffer size chunks */
324 count
= len
; /* in objects.. */
325 if( count
> (sizeof(buffer
)/width
)){
326 count
= (sizeof(buffer
)/width
);
329 retval
= target
->type
->read_memory( target
,
335 if( retval
!= ERROR_OK
){
337 LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed",
338 addr
, width
, count
);
339 Jim_SetResult(interp
,
340 Jim_NewEmptyStringObj(interp
));
341 Jim_AppendStrings( interp
, Jim_GetResult(interp
),
342 "mem2array: cannot read memory", NULL
);
346 v
= 0; /* shut up gcc */
347 for( i
= 0 ; i
< count
; i
++, n
++ ){
350 v
= target_buffer_get_u32( target
, &buffer
[i
*width
] );
353 v
= target_buffer_get_u16( target
, &buffer
[i
*width
] );
356 v
= buffer
[i
] & 0x0ff;
359 new_int_array_element( interp
, varname
, n
, v
);
364 Jim_SetResult(interp
,
365 Jim_NewEmptyStringObj(interp
));
370 static void tcl_output(void *privData
, const char *file
, int line
, const char *function
, const char *string
)
372 Jim_Obj
*tclOutput
=(Jim_Obj
*)privData
;
374 Jim_AppendString(interp
, tclOutput
, string
, strlen(string
));
377 /* try to execute as Jim command, otherwise fall back to standard command.
379 Note that even if the Jim command caused an error, then we succeeded
380 to execute it, hence this fn pretty much always returns ERROR_OK.
383 int jim_command(command_context_t
*context
, char *line
)
386 /* FIX!!!! in reality there is only one cmd_ctx handler, but consider
387 what might happen here if there are multiple handlers w/reentrant callback
389 active_cmd_ctx
=context
;
390 int retcode
=Jim_Eval(interp
, line
);
394 result
= Jim_GetString(Jim_GetResult(interp
), &reslen
);
395 if (retcode
== JIM_ERR
) {
398 LOG_USER_N("Runtime error, file \"%s\", line %d:" JIM_NL
,
399 interp
->errorFileName
, interp
->errorLine
);
400 LOG_USER_N(" %s" JIM_NL
,
401 Jim_GetString(interp
->result
, NULL
));
402 Jim_ListLength(interp
, interp
->stackTrace
, &len
);
403 for (i
= 0; i
< len
; i
+= 3) {
405 const char *proc
, *file
, *line
;
407 Jim_ListIndex(interp
, interp
->stackTrace
, i
, &objPtr
, JIM_NONE
);
408 proc
= Jim_GetString(objPtr
, NULL
);
409 Jim_ListIndex(interp
, interp
->stackTrace
, i
+1, &objPtr
,
411 file
= Jim_GetString(objPtr
, NULL
);
412 Jim_ListIndex(interp
, interp
->stackTrace
, i
+2, &objPtr
,
414 line
= Jim_GetString(objPtr
, NULL
);
415 LOG_USER_N("In procedure '%s' called at file \"%s\", line %s" JIM_NL
,
418 } else if (retcode
== JIM_EXIT
) {
420 //exit(Jim_GetExitCode(interp));
425 for (i
=0; i
<reslen
; i
+=256)
431 strncpy(buff
, result
, chunk
);
433 LOG_USER_N("%s", buff
);
435 LOG_USER_N("%s", "\n");
443 static int Jim_Command_openocd_ignore(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
, int ignore
)
446 char *cmd
= (char*)Jim_GetString(argv
[1], NULL
);
450 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
454 // We don't know whether or not the telnet/gdb server is running...
455 target_call_timer_callbacks_now();
458 log_add_callback(tcl_output
, tclOutput
);
459 retval
=command_run_line_internal(active_cmd_ctx
, cmd
);
463 target_call_timer_callbacks_now();
465 log_remove_callback(tcl_output
, tclOutput
);
467 Jim_SetResult(interp
, tclOutput
);
470 return (ignore
||(retval
==ERROR_OK
))?JIM_OK
:JIM_ERR
;
473 static int Jim_Command_openocd(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
475 return Jim_Command_openocd_ignore(interp
, argc
, argv
, 1);
478 static int Jim_Command_openocd_throw(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
480 return Jim_Command_openocd_ignore(interp
, argc
, argv
, 0);
483 /* find full path to file */
484 static int Jim_Command_find(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
488 char *file
= (char*)Jim_GetString(argv
[1], NULL
);
489 char *full_path
=find_file(file
);
492 Jim_Obj
*result
= Jim_NewStringObj(interp
, full_path
, strlen(full_path
));
495 Jim_SetResult(interp
, result
);
499 static int Jim_Command_echo(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
503 char *str
= (char*)Jim_GetString(argv
[1], NULL
);
508 static size_t openocd_jim_fwrite(const void *_ptr
, size_t size
, size_t n
, void *cookie
)
513 /* make it a char easier to read code */
521 if( !active_cmd_ctx
){
522 /* FIXME: Where should this go? */
526 /* do we have to chunk it? */
527 if( ptr
[ nbytes
] == 0 ){
528 /* no it is a C style string */
529 command_output_text( active_cmd_ctx
, ptr
);
532 /* GRR we must chunk - not null terminated */
542 memcpy( chunk
, ptr
, x
);
546 command_output_text( active_cmd_ctx
, chunk
);
554 static size_t openocd_jim_fread(void *ptr
, size_t size
, size_t n
, void *cookie
)
556 /* TCL wants to read... tell him no */
560 static int openocd_jim_vfprintf(void *cookie
, const char *fmt
, va_list ap
)
566 if( active_cmd_ctx
){
567 cp
= alloc_vprintf( fmt
, ap
);
569 command_output_text( active_cmd_ctx
, cp
);
577 static int openocd_jim_fflush(void *cookie
)
579 /* nothing to flush */
583 static char* openocd_jim_fgets(char *s
, int size
, void *cookie
)
592 Jim_CreateCommand(interp
, "openocd", Jim_Command_openocd
, NULL
, NULL
);
593 Jim_CreateCommand(interp
, "openocd_throw", Jim_Command_openocd_throw
, NULL
, NULL
);
594 Jim_CreateCommand(interp
, "find", Jim_Command_find
, NULL
, NULL
);
595 Jim_CreateCommand(interp
, "echo", Jim_Command_echo
, NULL
, NULL
);
596 Jim_CreateCommand(interp
, "mem2array", Jim_Command_mem2array
, NULL
, NULL
);
598 /* Set Jim's STDIO */
599 interp
->cookie_stdin
= NULL
;
600 interp
->cookie_stdout
= NULL
;
601 interp
->cookie_stderr
= NULL
;
602 interp
->cb_fwrite
= openocd_jim_fwrite
;
603 interp
->cb_fread
= openocd_jim_fread
;
604 interp
->cb_vfprintf
= openocd_jim_vfprintf
;
605 interp
->cb_fflush
= openocd_jim_fflush
;
606 interp
->cb_fgets
= openocd_jim_fgets
;
609 /* after command line parsing */
612 Jim_Eval(interp
, "source [find tcl/commands.tcl]");
615 command_context_t
*setup_command_handler()
617 command_context_t
*cmd_ctx
;
619 cmd_ctx
= command_init();
621 register_command(cmd_ctx
, NULL
, "version", handle_version_command
,
622 COMMAND_EXEC
, "show OpenOCD version");
623 register_command(cmd_ctx
, NULL
, "daemon_startup", handle_daemon_startup_command
, COMMAND_CONFIG
,
624 "deprecated - use \"init\" and \"reset\" at end of startup script instead");
626 /* register subsystem commands */
627 server_register_commands(cmd_ctx
);
628 telnet_register_commands(cmd_ctx
);
629 gdb_register_commands(cmd_ctx
);
630 tcl_register_commands(cmd_ctx
); /* tcl server commands */
631 log_register_commands(cmd_ctx
);
632 jtag_register_commands(cmd_ctx
);
633 interpreter_register_commands(cmd_ctx
);
634 xsvf_register_commands(cmd_ctx
);
635 target_register_commands(cmd_ctx
);
636 flash_register_commands(cmd_ctx
);
637 nand_register_commands(cmd_ctx
);
638 pld_register_commands(cmd_ctx
);
640 if (log_init(cmd_ctx
) != ERROR_OK
)
644 LOG_DEBUG("log init complete");
646 LOG_OUTPUT( OPENOCD_VERSION
"\n" );
649 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
650 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
651 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
652 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
653 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
654 LOG_OUTPUT( "$URL$\n");
655 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
656 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
657 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
658 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
659 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
661 register_command(cmd_ctx
, NULL
, "init", handle_init_command
,
662 COMMAND_ANY
, "initializes target and servers - nop on subsequent invocations");
668 normally this is the main() function entry, but if OpenOCD is linked
669 into application, then this fn will not be invoked, but rather that
670 application will have it's own implementation of main().
672 int openocd_main(int argc
, char *argv
[])
676 /* Create an interpreter */
677 interp
= Jim_CreateInterp();
678 /* Add all the Jim core commands */
679 Jim_RegisterCoreCommands(interp
);
684 /* initialize commandline interface */
685 command_context_t
*cmd_ctx
;
686 cmd_ctx
=setup_command_handler();
688 command_context_t
*cfg_cmd_ctx
;
689 cfg_cmd_ctx
= copy_command_context(cmd_ctx
);
690 cfg_cmd_ctx
->mode
= COMMAND_CONFIG
;
691 command_set_output_handler(cfg_cmd_ctx
, configuration_output_handler
, NULL
);
693 if (parse_cmdline_args(cfg_cmd_ctx
, argc
, argv
) != ERROR_OK
)
698 if (parse_config_file(cfg_cmd_ctx
) != ERROR_OK
)
701 command_done(cfg_cmd_ctx
);
703 if (command_run_line(cmd_ctx
, "init")!=ERROR_OK
)
707 command_run_line(cmd_ctx
, "reset");
711 /* handle network connections */
712 server_loop(cmd_ctx
);
714 /* shut server down */
717 unregister_all_commands(cmd_ctx
);
719 /* free commandline interface */
720 command_done(cmd_ctx
);