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"
39 #include "telnet_server.h"
40 #include "gdb_server.h"
41 #include "tcl_server.h"
44 #include <sys/types.h>
59 /* Jim is provied by eCos */
60 #include <cyg/jimtcl/jim.h>
66 #include "replacements.h"
69 /* Give TELNET a way to find out what version this is */
70 int handle_version_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
72 command_print(cmd_ctx
, OPENOCD_VERSION
);
77 static int daemon_startup
= 0;
79 int handle_daemon_startup_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
84 return ERROR_COMMAND_SYNTAX_ERROR
;
86 daemon_startup
= strcmp("reset", args
[0])==0;
88 command_print(cmd_ctx
, OPENOCD_VERSION
);
93 void exit_handler(void)
95 /* close JTAG interface */
96 if (jtag
&& jtag
->quit
)
100 /* OpenOCD can't really handle failure of this command. Patches welcome! :-) */
101 int handle_init_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
104 static int initialized
=0;
110 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
112 atexit(exit_handler
);
114 if (target_init(cmd_ctx
) != ERROR_OK
)
116 LOG_DEBUG("target init complete");
118 if ((retval
=jtag_interface_init(cmd_ctx
)) != ERROR_OK
)
120 /* we must be able to set up the jtag interface */
123 LOG_DEBUG("jtag interface init complete");
125 /* Try to initialize & examine the JTAG chain at this point, but
126 * continue startup regardless */
127 if (jtag_init(cmd_ctx
) == ERROR_OK
)
129 LOG_DEBUG("jtag init complete");
130 if (target_examine(cmd_ctx
) == ERROR_OK
)
132 LOG_DEBUG("jtag examine complete");
136 if (flash_init_drivers(cmd_ctx
) != ERROR_OK
)
138 LOG_DEBUG("flash init complete");
140 if (nand_init(cmd_ctx
) != ERROR_OK
)
142 LOG_DEBUG("NAND init complete");
144 if (pld_init(cmd_ctx
) != ERROR_OK
)
146 LOG_DEBUG("pld init complete");
148 /* initialize tcp server */
151 /* initialize telnet subsystem */
152 telnet_init("Open On-Chip Debugger");
154 tcl_init(); /* allows tcl to just connect without going thru telnet */
160 command_context_t
*active_cmd_ctx
;
162 static int new_int_array_element(Jim_Interp
* interp
, const char *varname
, int idx
, u32 val
)
165 Jim_Obj
*nameObjPtr
, *valObjPtr
;
168 namebuf
= alloc_printf("%s(%d)", varname
, idx
);
172 nameObjPtr
= Jim_NewStringObj(interp
, namebuf
, -1);
173 valObjPtr
= Jim_NewIntObj(interp
, val
);
174 if (!nameObjPtr
|| !valObjPtr
)
180 Jim_IncrRefCount(nameObjPtr
);
181 Jim_IncrRefCount(valObjPtr
);
182 result
= Jim_SetVariable(interp
, nameObjPtr
, valObjPtr
);
183 Jim_DecrRefCount(interp
, nameObjPtr
);
184 Jim_DecrRefCount(interp
, valObjPtr
);
186 /* printf("%s(%d) <= 0%08x\n", varname, idx, val); */
190 static int Jim_Command_mem2array(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
203 /* argv[1] = name of array to receive the data
204 * argv[2] = desired width
205 * argv[3] = memory address
206 * argv[4] = count of times to read
209 Jim_WrongNumArgs(interp
, 1, argv
, "varname width addr nelems");
212 varname
= Jim_GetString(argv
[1], &len
);
213 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
215 e
= Jim_GetLong(interp
, argv
[2], &l
);
221 e
= Jim_GetLong(interp
, argv
[3], &l
);
226 e
= Jim_GetLong(interp
, argv
[4], &l
);
242 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
243 Jim_AppendStrings( interp
, Jim_GetResult(interp
), "Invalid width param, must be 8/16/32", NULL
);
247 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
248 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: zero width read?", NULL
);
251 if ((addr
+ (len
* width
)) < addr
) {
252 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
253 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: addr + len - wraps to zero?", NULL
);
256 /* absurd transfer size? */
258 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
259 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: absurd > 64K item request", NULL
);
264 ((width
== 2) && ((addr
& 1) == 0)) ||
265 ((width
== 4) && ((addr
& 3) == 0))) {
269 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
270 sprintf(buf
, "mem2array address: 0x%08x is not aligned for %d byte reads", addr
, width
);
271 Jim_AppendStrings(interp
, Jim_GetResult(interp
), buf
, NULL
);
275 target
= get_current_target(active_cmd_ctx
);
284 /* Slurp... in buffer size chunks */
286 count
= len
; /* in objects.. */
287 if (count
> (sizeof(buffer
)/width
)) {
288 count
= (sizeof(buffer
)/width
);
291 retval
= target
->type
->read_memory( target
, addr
, width
, count
, buffer
);
292 if (retval
!= ERROR_OK
) {
294 LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed", addr
, width
, count
);
295 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
296 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: cannot read memory", NULL
);
300 v
= 0; /* shut up gcc */
301 for (i
= 0 ;i
< count
;i
++, n
++) {
304 v
= target_buffer_get_u32(target
, &buffer
[i
*width
]);
307 v
= target_buffer_get_u16(target
, &buffer
[i
*width
]);
310 v
= buffer
[i
] & 0x0ff;
313 new_int_array_element(interp
, varname
, n
, v
);
319 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
324 static int get_int_array_element(Jim_Interp
* interp
, const char *varname
, int idx
, u32
*val
)
327 Jim_Obj
*nameObjPtr
, *valObjPtr
;
331 namebuf
= alloc_printf("%s(%d)", varname
, idx
);
335 nameObjPtr
= Jim_NewStringObj(interp
, namebuf
, -1);
342 Jim_IncrRefCount(nameObjPtr
);
343 valObjPtr
= Jim_GetVariable(interp
, nameObjPtr
, JIM_ERRMSG
);
344 Jim_DecrRefCount(interp
, nameObjPtr
);
346 if (valObjPtr
== NULL
)
349 result
= Jim_GetLong(interp
, valObjPtr
, &l
);
350 /* printf("%s(%d) => 0%08x\n", varname, idx, val); */
355 static int Jim_Command_array2mem(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
368 /* argv[1] = name of array to get the data
369 * argv[2] = desired width
370 * argv[3] = memory address
371 * argv[4] = count to write
374 Jim_WrongNumArgs(interp
, 1, argv
, "varname width addr nelems");
377 varname
= Jim_GetString(argv
[1], &len
);
378 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
380 e
= Jim_GetLong(interp
, argv
[2], &l
);
386 e
= Jim_GetLong(interp
, argv
[3], &l
);
391 e
= Jim_GetLong(interp
, argv
[4], &l
);
407 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
408 Jim_AppendStrings( interp
, Jim_GetResult(interp
), "Invalid width param, must be 8/16/32", NULL
);
412 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
413 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: zero width read?", NULL
);
416 if ((addr
+ (len
* width
)) < addr
) {
417 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
418 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: addr + len - wraps to zero?", NULL
);
421 /* absurd transfer size? */
423 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
424 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: absurd > 64K item request", NULL
);
429 ((width
== 2) && ((addr
& 1) == 0)) ||
430 ((width
== 4) && ((addr
& 3) == 0))) {
434 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
435 sprintf(buf
, "array2mem address: 0x%08x is not aligned for %d byte reads", addr
, width
);
436 Jim_AppendStrings(interp
, Jim_GetResult(interp
), buf
, NULL
);
440 target
= get_current_target(active_cmd_ctx
);
449 /* Slurp... in buffer size chunks */
451 count
= len
; /* in objects.. */
452 if (count
> (sizeof(buffer
)/width
)) {
453 count
= (sizeof(buffer
)/width
);
456 v
= 0; /* shut up gcc */
457 for (i
= 0 ;i
< count
;i
++, n
++) {
458 get_int_array_element(interp
, varname
, n
, &v
);
461 target_buffer_set_u32(target
, &buffer
[i
*width
], v
);
464 target_buffer_set_u16(target
, &buffer
[i
*width
], v
);
467 buffer
[i
] = v
& 0x0ff;
473 retval
= target
->type
->write_memory(target
, addr
, width
, count
, buffer
);
474 if (retval
!= ERROR_OK
) {
476 LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed", addr
, width
, count
);
477 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
478 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: cannot read memory", NULL
);
484 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
489 static void tcl_output(void *privData
, const char *file
, int line
, const char *function
, const char *string
)
491 Jim_Obj
*tclOutput
=(Jim_Obj
*)privData
;
493 Jim_AppendString(interp
, tclOutput
, string
, strlen(string
));
496 /* try to execute as Jim command, otherwise fall back to standard command.
497 * Note that even if the Jim command caused an error, then we succeeded
498 * to execute it, hence this fn pretty much always returns ERROR_OK. */
499 int jim_command(command_context_t
*context
, char *line
)
502 int retcode
=Jim_Eval(interp
, line
);
504 if (retcode
== JIM_ERR
) {
505 Jim_PrintErrorMessage(interp
);
507 Jim_Obj
*openocd_result
=Jim_GetVariableStr(interp
, "openocd_result", JIM_ERRMSG
);
510 if (Jim_GetLong(interp
, openocd_result
, &t
)==JIM_OK
)
519 result
= Jim_GetString(Jim_GetResult(interp
), &reslen
);
521 if (retcode
== JIM_EXIT
) {
523 /* exit(Jim_GetExitCode(interp)); */
528 for (i
= 0; i
< reslen
; i
+= 256)
534 strncpy(buff
, result
+i
, chunk
);
536 LOG_USER_N("%s", buff
);
538 LOG_USER_N("%s", "\n");
546 static int Jim_Command_openocd_ignore(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
, int ignore
)
549 char *cmd
= (char*)Jim_GetString(argv
[1], NULL
);
551 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
555 /* We don't know whether or not the telnet/gdb server is running... */
556 target_call_timer_callbacks_now();
559 log_add_callback(tcl_output
, tclOutput
);
560 retval
=command_run_line_internal(active_cmd_ctx
, cmd
);
562 /* we need to be able to get at the retval, so we store in a variable
564 Jim_Obj
*resultvar
=Jim_NewIntObj(interp
, retval
);
565 Jim_IncrRefCount(resultvar
);
566 Jim_SetGlobalVariableStr(interp
, "openocd_result", resultvar
);
567 Jim_DecrRefCount(interp
, resultvar
);
571 target_call_timer_callbacks_now();
573 log_remove_callback(tcl_output
, tclOutput
);
575 Jim_SetResult(interp
, tclOutput
);
577 return (ignore
||(retval
==ERROR_OK
))?JIM_OK
:JIM_ERR
;
580 static int Jim_Command_openocd(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
582 return Jim_Command_openocd_ignore(interp
, argc
, argv
, 1);
585 static int Jim_Command_openocd_throw(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
587 return Jim_Command_openocd_ignore(interp
, argc
, argv
, 0);
590 /* find full path to file */
591 static int Jim_Command_find(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
595 char *file
= (char*)Jim_GetString(argv
[1], NULL
);
596 char *full_path
= find_file(file
);
597 if (full_path
== NULL
)
599 Jim_Obj
*result
= Jim_NewStringObj(interp
, full_path
, strlen(full_path
));
602 Jim_SetResult(interp
, result
);
606 static int Jim_Command_echo(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
610 char *str
= (char*)Jim_GetString(argv
[1], NULL
);
615 static size_t openocd_jim_fwrite(const void *_ptr
, size_t size
, size_t n
, void *cookie
)
620 /* make it a char easier to read code */
628 if (!active_cmd_ctx
) {
629 /* TODO: Where should this go? */
633 /* do we have to chunk it? */
634 if (ptr
[nbytes
] == 0) {
635 /* no it is a C style string */
636 command_output_text(active_cmd_ctx
, ptr
);
639 /* GRR we must chunk - not null terminated */
649 memcpy(chunk
, ptr
, x
);
653 command_output_text(active_cmd_ctx
, chunk
);
661 static size_t openocd_jim_fread(void *ptr
, size_t size
, size_t n
, void *cookie
)
663 /* TCL wants to read... tell him no */
667 static int openocd_jim_vfprintf(void *cookie
, const char *fmt
, va_list ap
)
673 if (active_cmd_ctx
) {
674 cp
= alloc_vprintf(fmt
, ap
);
676 command_output_text(active_cmd_ctx
, cp
);
684 static int openocd_jim_fflush(void *cookie
)
686 /* nothing to flush */
690 static char* openocd_jim_fgets(char *s
, int size
, void *cookie
)
697 void add_jim(const char *name
, int (*cmd
)(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
), const char *help
)
699 Jim_CreateCommand(interp
, name
, cmd
, NULL
, NULL
);
701 /* FIX!!! it would be prettier to invoke add_help_text...
702 accumulate help text in Tcl helptext list. */
703 Jim_Obj
*helptext
=Jim_GetGlobalVariableStr(interp
, "ocd_helptext", JIM_ERRMSG
);
704 Jim_Obj
*cmd_entry
=Jim_NewListObj(interp
, NULL
, 0);
706 Jim_Obj
*cmd_list
=Jim_NewListObj(interp
, NULL
, 0);
707 Jim_ListAppendElement(interp
, cmd_list
, Jim_NewStringObj(interp
, name
, -1));
709 Jim_ListAppendElement(interp
, cmd_entry
, cmd_list
);
710 Jim_ListAppendElement(interp
, cmd_entry
, Jim_NewStringObj(interp
, help
, -1));
711 Jim_ListAppendElement(interp
, helptext
, cmd_entry
);
714 extern char binary_startup_tcl_start
;
715 extern char binary_startup_tcl_size
;
722 Jim_CreateCommand(interp
, "openocd", Jim_Command_openocd
, NULL
, NULL
);
723 Jim_CreateCommand(interp
, "openocd_throw", Jim_Command_openocd_throw
, NULL
, NULL
);
724 Jim_CreateCommand(interp
, "find", Jim_Command_find
, NULL
, NULL
);
725 Jim_CreateCommand(interp
, "echo", Jim_Command_echo
, NULL
, NULL
);
726 Jim_CreateCommand(interp
, "mem2array", Jim_Command_mem2array
, NULL
, NULL
);
727 Jim_CreateCommand(interp
, "array2mem", Jim_Command_array2mem
, NULL
, NULL
);
729 /* Set Jim's STDIO */
730 interp
->cookie_stdin
= NULL
;
731 interp
->cookie_stdout
= NULL
;
732 interp
->cookie_stderr
= NULL
;
733 interp
->cb_fwrite
= openocd_jim_fwrite
;
734 interp
->cb_fread
= openocd_jim_fread
;
735 interp
->cb_vfprintf
= openocd_jim_vfprintf
;
736 interp
->cb_fflush
= openocd_jim_fflush
;
737 interp
->cb_fgets
= openocd_jim_fgets
;
741 script_len
= (int)&binary_startup_tcl_size
;
742 script
= malloc(script_len
+ sizeof(char));
743 memcpy(script
, &binary_startup_tcl_start
, script_len
);
746 script
[script_len
] = 0;
748 if (Jim_Eval(interp
, script
)==JIM_ERR
)
750 LOG_ERROR("Failed to run startup.tcl (embedded into OpenOCD compile time)");
751 Jim_PrintErrorMessage(interp
);
758 int handle_script_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
761 return ERROR_COMMAND_SYNTAX_ERROR
;
763 /* Run a tcl script file */
764 return command_run_linef(cmd_ctx
, "source [find {%s}]", args
[0]);
767 command_context_t
*setup_command_handler(void)
769 command_context_t
*cmd_ctx
;
771 cmd_ctx
= command_init();
773 register_command(cmd_ctx
, NULL
, "version", handle_version_command
,
774 COMMAND_EXEC
, "show OpenOCD version");
775 register_command(cmd_ctx
, NULL
, "daemon_startup", handle_daemon_startup_command
, COMMAND_CONFIG
,
776 "deprecated - use \"init\" and \"reset\" at end of startup script instead");
778 /* register subsystem commands */
779 server_register_commands(cmd_ctx
);
780 telnet_register_commands(cmd_ctx
);
781 gdb_register_commands(cmd_ctx
);
782 tcl_register_commands(cmd_ctx
); /* tcl server commands */
783 log_register_commands(cmd_ctx
);
784 jtag_register_commands(cmd_ctx
);
785 register_command(cmd_ctx
, NULL
, "script", handle_script_command
, COMMAND_ANY
, "execute commands from <file>");
786 xsvf_register_commands(cmd_ctx
);
787 target_register_commands(cmd_ctx
);
788 flash_register_commands(cmd_ctx
);
789 nand_register_commands(cmd_ctx
);
790 pld_register_commands(cmd_ctx
);
792 if (log_init(cmd_ctx
) != ERROR_OK
)
796 LOG_DEBUG("log init complete");
798 LOG_OUTPUT( OPENOCD_VERSION
"\n" );
801 register_command(cmd_ctx
, NULL
, "init", handle_init_command
,
802 COMMAND_ANY
, "initializes target and servers - nop on subsequent invocations");
807 /* normally this is the main() function entry, but if OpenOCD is linked
808 * into application, then this fn will not be invoked, but rather that
809 * application will have it's own implementation of main(). */
810 int openocd_main(int argc
, char *argv
[])
814 /* Create an interpreter */
815 interp
= Jim_CreateInterp();
816 /* Add all the Jim core commands */
817 Jim_RegisterCoreCommands(interp
);
822 /* initialize commandline interface */
823 command_context_t
*cmd_ctx
;
824 cmd_ctx
=setup_command_handler();
826 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
827 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
828 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
829 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
830 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
831 LOG_OUTPUT( "$URL$\n");
832 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
833 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
834 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
835 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
836 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
838 command_context_t
*cfg_cmd_ctx
;
839 cfg_cmd_ctx
= copy_command_context(cmd_ctx
);
840 cfg_cmd_ctx
->mode
= COMMAND_CONFIG
;
841 command_set_output_handler(cfg_cmd_ctx
, configuration_output_handler
, NULL
);
843 active_cmd_ctx
=cfg_cmd_ctx
;
846 if (parse_cmdline_args(cfg_cmd_ctx
, argc
, argv
) != ERROR_OK
)
849 if (parse_config_file(cfg_cmd_ctx
) != ERROR_OK
)
852 active_cmd_ctx
=cmd_ctx
;
854 command_done(cfg_cmd_ctx
);
856 if (command_run_line(cmd_ctx
, "init")!=ERROR_OK
)
860 command_run_line(cmd_ctx
, "reset");
864 /* handle network connections */
865 server_loop(cmd_ctx
);
867 /* shut server down */
870 unregister_all_commands(cmd_ctx
);
872 /* free commandline interface */
873 command_done(cmd_ctx
);