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 */
155 if (jtag_init(cmd_ctx
) == ERROR_OK
)
157 LOG_DEBUG("jtag init complete");
158 if (target_examine(cmd_ctx
) == ERROR_OK
)
160 LOG_DEBUG("jtag examine complete");
164 if (flash_init_drivers(cmd_ctx
) != ERROR_OK
)
166 LOG_DEBUG("flash init complete");
168 if (nand_init(cmd_ctx
) != ERROR_OK
)
170 LOG_DEBUG("NAND init complete");
172 if (pld_init(cmd_ctx
) != ERROR_OK
)
174 LOG_DEBUG("pld init complete");
176 /* initialize tcp server */
179 /* initialize telnet subsystem */
180 telnet_init("Open On-Chip Debugger");
182 tcl_init(); /* allows tcl to just connect without going thru telnet */
188 command_context_t
*active_cmd_ctx
;
190 static int new_int_array_element(Jim_Interp
* interp
, const char *varname
, int idx
, u32 val
)
193 Jim_Obj
*nameObjPtr
, *valObjPtr
;
196 namebuf
= alloc_printf("%s(%d)", varname
, idx
);
200 nameObjPtr
= Jim_NewStringObj(interp
, namebuf
, -1);
201 valObjPtr
= Jim_NewIntObj(interp
, val
);
202 if (!nameObjPtr
|| !valObjPtr
)
208 Jim_IncrRefCount(nameObjPtr
);
209 Jim_IncrRefCount(valObjPtr
);
210 result
= Jim_SetVariable(interp
, nameObjPtr
, valObjPtr
);
211 Jim_DecrRefCount(interp
, nameObjPtr
);
212 Jim_DecrRefCount(interp
, valObjPtr
);
214 /* printf("%s(%d) <= 0%08x\n", varname, idx, val); */
218 static int Jim_Command_mem2array(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
231 /* argv[1] = name of array to receive the data
232 * argv[2] = desired width
233 * argv[3] = memory address
234 * argv[4] = count of times to read
237 Jim_WrongNumArgs(interp
, 1, argv
, "varname width addr nelems");
240 varname
= Jim_GetString(argv
[1], &len
);
241 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
243 e
= Jim_GetLong(interp
, argv
[2], &l
);
249 e
= Jim_GetLong(interp
, argv
[3], &l
);
254 e
= Jim_GetLong(interp
, argv
[4], &l
);
270 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
271 Jim_AppendStrings( interp
, Jim_GetResult(interp
), "Invalid width param, must be 8/16/32", NULL
);
275 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
276 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: zero width read?", NULL
);
279 if ((addr
+ (len
* width
)) < addr
) {
280 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
281 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: addr + len - wraps to zero?", NULL
);
284 /* absurd transfer size? */
286 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
287 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: absurd > 64K item request", NULL
);
292 ((width
== 2) && ((addr
& 1) == 0)) ||
293 ((width
== 4) && ((addr
& 3) == 0))) {
297 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
298 sprintf(buf
, "mem2array address: 0x%08x is not aligned for %d byte reads", addr
, width
);
299 Jim_AppendStrings(interp
, Jim_GetResult(interp
), buf
, NULL
);
303 target
= get_current_target(active_cmd_ctx
);
312 /* Slurp... in buffer size chunks */
314 count
= len
; /* in objects.. */
315 if (count
> (sizeof(buffer
)/width
)) {
316 count
= (sizeof(buffer
)/width
);
319 retval
= target
->type
->read_memory( target
, addr
, width
, count
, buffer
);
320 if (retval
!= ERROR_OK
) {
322 LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed", addr
, width
, count
);
323 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
324 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: cannot read memory", NULL
);
328 v
= 0; /* shut up gcc */
329 for (i
= 0 ;i
< count
;i
++, n
++) {
332 v
= target_buffer_get_u32(target
, &buffer
[i
*width
]);
335 v
= target_buffer_get_u16(target
, &buffer
[i
*width
]);
338 v
= buffer
[i
] & 0x0ff;
341 new_int_array_element(interp
, varname
, n
, v
);
347 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
352 static int get_int_array_element(Jim_Interp
* interp
, const char *varname
, int idx
, u32
*val
)
355 Jim_Obj
*nameObjPtr
, *valObjPtr
;
359 namebuf
= alloc_printf("%s(%d)", varname
, idx
);
363 nameObjPtr
= Jim_NewStringObj(interp
, namebuf
, -1);
370 Jim_IncrRefCount(nameObjPtr
);
371 valObjPtr
= Jim_GetVariable(interp
, nameObjPtr
, JIM_ERRMSG
);
372 Jim_DecrRefCount(interp
, nameObjPtr
);
374 if (valObjPtr
== NULL
)
377 result
= Jim_GetLong(interp
, valObjPtr
, &l
);
378 /* printf("%s(%d) => 0%08x\n", varname, idx, val); */
383 static int Jim_Command_array2mem(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
396 /* argv[1] = name of array to get the data
397 * argv[2] = desired width
398 * argv[3] = memory address
399 * argv[4] = count to write
402 Jim_WrongNumArgs(interp
, 1, argv
, "varname width addr nelems");
405 varname
= Jim_GetString(argv
[1], &len
);
406 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
408 e
= Jim_GetLong(interp
, argv
[2], &l
);
414 e
= Jim_GetLong(interp
, argv
[3], &l
);
419 e
= Jim_GetLong(interp
, argv
[4], &l
);
435 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
436 Jim_AppendStrings( interp
, Jim_GetResult(interp
), "Invalid width param, must be 8/16/32", NULL
);
440 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
441 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: zero width read?", NULL
);
444 if ((addr
+ (len
* width
)) < addr
) {
445 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
446 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: addr + len - wraps to zero?", NULL
);
449 /* absurd transfer size? */
451 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
452 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: absurd > 64K item request", NULL
);
457 ((width
== 2) && ((addr
& 1) == 0)) ||
458 ((width
== 4) && ((addr
& 3) == 0))) {
462 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
463 sprintf(buf
, "array2mem address: 0x%08x is not aligned for %d byte reads", addr
, width
);
464 Jim_AppendStrings(interp
, Jim_GetResult(interp
), buf
, NULL
);
468 target
= get_current_target(active_cmd_ctx
);
477 /* Slurp... in buffer size chunks */
479 count
= len
; /* in objects.. */
480 if (count
> (sizeof(buffer
)/width
)) {
481 count
= (sizeof(buffer
)/width
);
484 v
= 0; /* shut up gcc */
485 for (i
= 0 ;i
< count
;i
++, n
++) {
486 get_int_array_element(interp
, varname
, n
, &v
);
489 target_buffer_set_u32(target
, &buffer
[i
*width
], v
);
492 target_buffer_set_u16(target
, &buffer
[i
*width
], v
);
495 buffer
[i
] = v
& 0x0ff;
501 retval
= target
->type
->write_memory(target
, addr
, width
, count
, buffer
);
502 if (retval
!= ERROR_OK
) {
504 LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed", addr
, width
, count
);
505 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
506 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: cannot read memory", NULL
);
512 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
517 static void tcl_output(void *privData
, const char *file
, int line
, const char *function
, const char *string
)
519 Jim_Obj
*tclOutput
=(Jim_Obj
*)privData
;
521 Jim_AppendString(interp
, tclOutput
, string
, strlen(string
));
524 /* try to execute as Jim command, otherwise fall back to standard command.
525 * Note that even if the Jim command caused an error, then we succeeded
526 * to execute it, hence this fn pretty much always returns ERROR_OK. */
527 int jim_command(command_context_t
*context
, char *line
)
530 int retcode
=Jim_Eval(interp
, line
);
532 if (retcode
== JIM_ERR
) {
533 Jim_PrintErrorMessage(interp
);
535 Jim_Obj
*openocd_result
=Jim_GetVariableStr(interp
, "openocd_result", JIM_ERRMSG
);
538 if (Jim_GetLong(interp
, openocd_result
, &t
)==JIM_OK
)
547 result
= Jim_GetString(Jim_GetResult(interp
), &reslen
);
549 if (retcode
== JIM_EXIT
) {
551 /* exit(Jim_GetExitCode(interp)); */
556 for (i
= 0; i
< reslen
; i
+= 256)
562 strncpy(buff
, result
+i
, chunk
);
564 LOG_USER_N("%s", buff
);
566 LOG_USER_N("%s", "\n");
574 static int Jim_Command_openocd_ignore(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
, int ignore
)
577 char *cmd
= (char*)Jim_GetString(argv
[1], NULL
);
579 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
583 /* We don't know whether or not the telnet/gdb server is running... */
584 target_call_timer_callbacks_now();
587 log_add_callback(tcl_output
, tclOutput
);
588 retval
=command_run_line_internal(active_cmd_ctx
, cmd
);
590 /* we need to be able to get at the retval, so we store in a variable
592 Jim_Obj
*resultvar
=Jim_NewIntObj(interp
, retval
);
593 Jim_IncrRefCount(resultvar
);
594 Jim_SetGlobalVariableStr(interp
, "openocd_result", resultvar
);
595 Jim_DecrRefCount(interp
, resultvar
);
599 target_call_timer_callbacks_now();
601 log_remove_callback(tcl_output
, tclOutput
);
603 Jim_SetResult(interp
, tclOutput
);
605 return (ignore
||(retval
==ERROR_OK
))?JIM_OK
:JIM_ERR
;
608 static int Jim_Command_openocd(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
610 return Jim_Command_openocd_ignore(interp
, argc
, argv
, 1);
613 static int Jim_Command_openocd_throw(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
615 return Jim_Command_openocd_ignore(interp
, argc
, argv
, 0);
618 /* find full path to file */
619 static int Jim_Command_find(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
623 char *file
= (char*)Jim_GetString(argv
[1], NULL
);
624 char *full_path
= find_file(file
);
625 if (full_path
== NULL
)
627 Jim_Obj
*result
= Jim_NewStringObj(interp
, full_path
, strlen(full_path
));
630 Jim_SetResult(interp
, result
);
634 static int Jim_Command_echo(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
638 char *str
= (char*)Jim_GetString(argv
[1], NULL
);
643 static size_t openocd_jim_fwrite(const void *_ptr
, size_t size
, size_t n
, void *cookie
)
648 /* make it a char easier to read code */
656 if (!active_cmd_ctx
) {
657 /* TODO: Where should this go? */
661 /* do we have to chunk it? */
662 if (ptr
[nbytes
] == 0) {
663 /* no it is a C style string */
664 command_output_text(active_cmd_ctx
, ptr
);
667 /* GRR we must chunk - not null terminated */
677 memcpy(chunk
, ptr
, x
);
681 command_output_text(active_cmd_ctx
, chunk
);
689 static size_t openocd_jim_fread(void *ptr
, size_t size
, size_t n
, void *cookie
)
691 /* TCL wants to read... tell him no */
695 static int openocd_jim_vfprintf(void *cookie
, const char *fmt
, va_list ap
)
701 if (active_cmd_ctx
) {
702 cp
= alloc_vprintf(fmt
, ap
);
704 command_output_text(active_cmd_ctx
, cp
);
712 static int openocd_jim_fflush(void *cookie
)
714 /* nothing to flush */
718 static char* openocd_jim_fgets(char *s
, int size
, void *cookie
)
727 Jim_CreateCommand(interp
, "openocd", Jim_Command_openocd
, NULL
, NULL
);
728 Jim_CreateCommand(interp
, "openocd_throw", Jim_Command_openocd_throw
, NULL
, NULL
);
729 Jim_CreateCommand(interp
, "find", Jim_Command_find
, NULL
, NULL
);
730 Jim_CreateCommand(interp
, "echo", Jim_Command_echo
, NULL
, NULL
);
731 Jim_CreateCommand(interp
, "mem2array", Jim_Command_mem2array
, NULL
, NULL
);
732 Jim_CreateCommand(interp
, "array2mem", Jim_Command_array2mem
, NULL
, NULL
);
734 /* Set Jim's STDIO */
735 interp
->cookie_stdin
= NULL
;
736 interp
->cookie_stdout
= NULL
;
737 interp
->cookie_stderr
= NULL
;
738 interp
->cb_fwrite
= openocd_jim_fwrite
;
739 interp
->cb_fread
= openocd_jim_fread
;
740 interp
->cb_vfprintf
= openocd_jim_vfprintf
;
741 interp
->cb_fflush
= openocd_jim_fflush
;
742 interp
->cb_fgets
= openocd_jim_fgets
;
745 /* after command line parsing */
748 if (Jim_Eval(interp
, "source [find tcl/commands.tcl]")==JIM_ERR
)
750 LOG_ERROR("Can not find tcl/commands.tcl - check installation");
755 command_context_t
*setup_command_handler(void)
757 command_context_t
*cmd_ctx
;
759 cmd_ctx
= command_init();
761 register_command(cmd_ctx
, NULL
, "version", handle_version_command
,
762 COMMAND_EXEC
, "show OpenOCD version");
763 register_command(cmd_ctx
, NULL
, "daemon_startup", handle_daemon_startup_command
, COMMAND_CONFIG
,
764 "deprecated - use \"init\" and \"reset\" at end of startup script instead");
766 /* register subsystem commands */
767 server_register_commands(cmd_ctx
);
768 telnet_register_commands(cmd_ctx
);
769 gdb_register_commands(cmd_ctx
);
770 tcl_register_commands(cmd_ctx
); /* tcl server commands */
771 log_register_commands(cmd_ctx
);
772 jtag_register_commands(cmd_ctx
);
773 interpreter_register_commands(cmd_ctx
);
774 xsvf_register_commands(cmd_ctx
);
775 target_register_commands(cmd_ctx
);
776 flash_register_commands(cmd_ctx
);
777 nand_register_commands(cmd_ctx
);
778 pld_register_commands(cmd_ctx
);
780 if (log_init(cmd_ctx
) != ERROR_OK
)
784 LOG_DEBUG("log init complete");
786 LOG_OUTPUT( OPENOCD_VERSION
"\n" );
789 register_command(cmd_ctx
, NULL
, "init", handle_init_command
,
790 COMMAND_ANY
, "initializes target and servers - nop on subsequent invocations");
795 /* normally this is the main() function entry, but if OpenOCD is linked
796 * into application, then this fn will not be invoked, but rather that
797 * application will have it's own implementation of main(). */
798 int openocd_main(int argc
, char *argv
[])
802 /* Create an interpreter */
803 interp
= Jim_CreateInterp();
804 /* Add all the Jim core commands */
805 Jim_RegisterCoreCommands(interp
);
810 /* initialize commandline interface */
811 command_context_t
*cmd_ctx
;
812 cmd_ctx
=setup_command_handler();
814 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
815 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
816 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
817 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
818 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
819 LOG_OUTPUT( "$URL$\n");
820 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
821 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
822 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
823 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
824 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
826 command_context_t
*cfg_cmd_ctx
;
827 cfg_cmd_ctx
= copy_command_context(cmd_ctx
);
828 cfg_cmd_ctx
->mode
= COMMAND_CONFIG
;
829 command_set_output_handler(cfg_cmd_ctx
, configuration_output_handler
, NULL
);
831 active_cmd_ctx
=cfg_cmd_ctx
;
837 if (parse_cmdline_args(cfg_cmd_ctx
, argc
, argv
) != ERROR_OK
)
840 if (parse_config_file(cfg_cmd_ctx
) != ERROR_OK
)
843 active_cmd_ctx
=cmd_ctx
;
845 command_done(cfg_cmd_ctx
);
847 if (command_run_line(cmd_ctx
, "init")!=ERROR_OK
)
851 command_run_line(cmd_ctx
, "reset");
855 /* handle network connections */
856 server_loop(cmd_ctx
);
858 /* shut server down */
861 unregister_all_commands(cmd_ctx
);
863 /* free commandline interface */
864 command_done(cmd_ctx
);
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)