a3b0fe181eed2c088f85cc73fff8307f11a6927f
[openocd.git] / src / openocd.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
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. *
9 * *
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. *
14 * *
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 ***************************************************************************/
20
21 #define OPENOCD_VERSION "Open On-Chip Debugger " VERSION " (" PKGBLDDATE ") svn:" PKGBLDREV
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "log.h"
28 #include "types.h"
29 #include "jtag.h"
30 #include "configuration.h"
31 #include "xsvf.h"
32 #include "target.h"
33 #include "flash.h"
34 #include "nand.h"
35 #include "pld.h"
36
37 #include "command.h"
38 #include "server.h"
39 #include "telnet_server.h"
40 #include "gdb_server.h"
41 #include "tcl_server.h"
42
43 #include <sys/time.h>
44 #include <sys/types.h>
45 #include <strings.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <string.h>
49 #include <unistd.h>
50 #include <errno.h>
51
52 #ifdef _WIN32
53 #include <malloc.h>
54 #else
55 #include <alloca.h>
56 #endif
57
58 #ifdef __ECOS
59 /* Jim is provied by eCos */
60 #include <cyg/jimtcl/jim.h>
61 #else
62 #define JIM_EMBEDDED
63 #include "jim.h"
64 #endif
65
66 #include "replacements.h"
67
68
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)
71 {
72 command_print(cmd_ctx, OPENOCD_VERSION);
73
74 return ERROR_OK;
75 }
76
77 static int daemon_startup = 0;
78
79 int handle_daemon_startup_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
80 {
81 if (argc==0)
82 return ERROR_OK;
83 if (argc > 1 )
84 return ERROR_COMMAND_SYNTAX_ERROR;
85
86 daemon_startup = strcmp("reset", args[0])==0;
87
88 command_print(cmd_ctx, OPENOCD_VERSION);
89
90 return ERROR_OK;
91 }
92
93 void exit_handler(void)
94 {
95 /* close JTAG interface */
96 if (jtag && jtag->quit)
97 jtag->quit();
98 }
99
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)
102 {
103 int retval;
104 static int initialized=0;
105 if (initialized)
106 return ERROR_OK;
107
108 initialized=1;
109
110 atexit(exit_handler);
111
112 if (target_init(cmd_ctx) != ERROR_OK)
113 return ERROR_FAIL;
114 LOG_DEBUG("target init complete");
115
116 if ((retval=jtag_interface_init(cmd_ctx)) != ERROR_OK)
117 {
118 /* we must be able to set up the jtag interface */
119 return retval;
120 }
121 LOG_DEBUG("jtag interface init complete");
122
123 /* Try to initialize & examine the JTAG chain at this point, but
124 * continue startup regardless */
125 if (jtag_init(cmd_ctx) == ERROR_OK)
126 {
127 LOG_DEBUG("jtag init complete");
128 if (target_examine(cmd_ctx) == ERROR_OK)
129 {
130 LOG_DEBUG("jtag examine complete");
131 }
132 }
133
134 if (flash_init_drivers(cmd_ctx) != ERROR_OK)
135 return ERROR_FAIL;
136 LOG_DEBUG("flash init complete");
137
138 if (nand_init(cmd_ctx) != ERROR_OK)
139 return ERROR_FAIL;
140 LOG_DEBUG("NAND init complete");
141
142 if (pld_init(cmd_ctx) != ERROR_OK)
143 return ERROR_FAIL;
144 LOG_DEBUG("pld init complete");
145
146 /* initialize tcp server */
147 server_init();
148
149 /* initialize telnet subsystem */
150 telnet_init("Open On-Chip Debugger");
151 gdb_init();
152 tcl_init(); /* allows tcl to just connect without going thru telnet */
153
154 return ERROR_OK;
155 }
156
157 Jim_Interp *interp;
158 command_context_t *active_cmd_ctx;
159
160 static int new_int_array_element(Jim_Interp * interp, const char *varname, int idx, u32 val)
161 {
162 char *namebuf;
163 Jim_Obj *nameObjPtr, *valObjPtr;
164 int result;
165
166 namebuf = alloc_printf("%s(%d)", varname, idx);
167 if (!namebuf)
168 return JIM_ERR;
169
170 nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);
171 valObjPtr = Jim_NewIntObj(interp, val);
172 if (!nameObjPtr || !valObjPtr)
173 {
174 free(namebuf);
175 return JIM_ERR;
176 }
177
178 Jim_IncrRefCount(nameObjPtr);
179 Jim_IncrRefCount(valObjPtr);
180 result = Jim_SetVariable(interp, nameObjPtr, valObjPtr);
181 Jim_DecrRefCount(interp, nameObjPtr);
182 Jim_DecrRefCount(interp, valObjPtr);
183 free(namebuf);
184 /* printf("%s(%d) <= 0%08x\n", varname, idx, val); */
185 return result;
186 }
187
188 static int Jim_Command_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
189 {
190 target_t *target;
191 long l;
192 u32 width;
193 u32 len;
194 u32 addr;
195 u32 count;
196 u32 v;
197 const char *varname;
198 u8 buffer[4096];
199 int i, n, e, retval;
200
201 /* argv[1] = name of array to receive the data
202 * argv[2] = desired width
203 * argv[3] = memory address
204 * argv[4] = count of times to read
205 */
206 if (argc != 5) {
207 Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");
208 return JIM_ERR;
209 }
210 varname = Jim_GetString(argv[1], &len);
211 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
212
213 e = Jim_GetLong(interp, argv[2], &l);
214 width = l;
215 if (e != JIM_OK) {
216 return e;
217 }
218
219 e = Jim_GetLong(interp, argv[3], &l);
220 addr = l;
221 if (e != JIM_OK) {
222 return e;
223 }
224 e = Jim_GetLong(interp, argv[4], &l);
225 len = l;
226 if (e != JIM_OK) {
227 return e;
228 }
229 switch (width) {
230 case 8:
231 width = 1;
232 break;
233 case 16:
234 width = 2;
235 break;
236 case 32:
237 width = 4;
238 break;
239 default:
240 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
241 Jim_AppendStrings( interp, Jim_GetResult(interp), "Invalid width param, must be 8/16/32", NULL );
242 return JIM_ERR;
243 }
244 if (len == 0) {
245 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
246 Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: zero width read?", NULL);
247 return JIM_ERR;
248 }
249 if ((addr + (len * width)) < addr) {
250 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
251 Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: addr + len - wraps to zero?", NULL);
252 return JIM_ERR;
253 }
254 /* absurd transfer size? */
255 if (len > 65536) {
256 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
257 Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: absurd > 64K item request", NULL);
258 return JIM_ERR;
259 }
260
261 if ((width == 1) ||
262 ((width == 2) && ((addr & 1) == 0)) ||
263 ((width == 4) && ((addr & 3) == 0))) {
264 /* all is well */
265 } else {
266 char buf[100];
267 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
268 sprintf(buf, "mem2array address: 0x%08x is not aligned for %d byte reads", addr, width);
269 Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);
270 return JIM_ERR;
271 }
272
273 target = get_current_target(active_cmd_ctx);
274
275 /* Transfer loop */
276
277 /* index counter */
278 n = 0;
279 /* assume ok */
280 e = JIM_OK;
281 while (len) {
282 /* Slurp... in buffer size chunks */
283
284 count = len; /* in objects.. */
285 if (count > (sizeof(buffer)/width)) {
286 count = (sizeof(buffer)/width);
287 }
288
289 retval = target->type->read_memory( target, addr, width, count, buffer );
290 if (retval != ERROR_OK) {
291 /* BOO !*/
292 LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed", addr, width, count);
293 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
294 Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: cannot read memory", NULL);
295 e = JIM_ERR;
296 len = 0;
297 } else {
298 v = 0; /* shut up gcc */
299 for (i = 0 ;i < count ;i++, n++) {
300 switch (width) {
301 case 4:
302 v = target_buffer_get_u32(target, &buffer[i*width]);
303 break;
304 case 2:
305 v = target_buffer_get_u16(target, &buffer[i*width]);
306 break;
307 case 1:
308 v = buffer[i] & 0x0ff;
309 break;
310 }
311 new_int_array_element(interp, varname, n, v);
312 }
313 len -= count;
314 }
315 }
316
317 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
318
319 return JIM_OK;
320 }
321
322 static int get_int_array_element(Jim_Interp * interp, const char *varname, int idx, u32 *val)
323 {
324 char *namebuf;
325 Jim_Obj *nameObjPtr, *valObjPtr;
326 int result;
327 long l;
328
329 namebuf = alloc_printf("%s(%d)", varname, idx);
330 if (!namebuf)
331 return JIM_ERR;
332
333 nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);
334 if (!nameObjPtr)
335 {
336 free(namebuf);
337 return JIM_ERR;
338 }
339
340 Jim_IncrRefCount(nameObjPtr);
341 valObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_ERRMSG);
342 Jim_DecrRefCount(interp, nameObjPtr);
343 free(namebuf);
344 if (valObjPtr == NULL)
345 return JIM_ERR;
346
347 result = Jim_GetLong(interp, valObjPtr, &l);
348 /* printf("%s(%d) => 0%08x\n", varname, idx, val); */
349 *val = l;
350 return result;
351 }
352
353 static int Jim_Command_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
354 {
355 target_t *target;
356 long l;
357 u32 width;
358 u32 len;
359 u32 addr;
360 u32 count;
361 u32 v;
362 const char *varname;
363 u8 buffer[4096];
364 int i, n, e, retval;
365
366 /* argv[1] = name of array to get the data
367 * argv[2] = desired width
368 * argv[3] = memory address
369 * argv[4] = count to write
370 */
371 if (argc != 5) {
372 Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");
373 return JIM_ERR;
374 }
375 varname = Jim_GetString(argv[1], &len);
376 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
377
378 e = Jim_GetLong(interp, argv[2], &l);
379 width = l;
380 if (e != JIM_OK) {
381 return e;
382 }
383
384 e = Jim_GetLong(interp, argv[3], &l);
385 addr = l;
386 if (e != JIM_OK) {
387 return e;
388 }
389 e = Jim_GetLong(interp, argv[4], &l);
390 len = l;
391 if (e != JIM_OK) {
392 return e;
393 }
394 switch (width) {
395 case 8:
396 width = 1;
397 break;
398 case 16:
399 width = 2;
400 break;
401 case 32:
402 width = 4;
403 break;
404 default:
405 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
406 Jim_AppendStrings( interp, Jim_GetResult(interp), "Invalid width param, must be 8/16/32", NULL );
407 return JIM_ERR;
408 }
409 if (len == 0) {
410 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
411 Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: zero width read?", NULL);
412 return JIM_ERR;
413 }
414 if ((addr + (len * width)) < addr) {
415 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
416 Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: addr + len - wraps to zero?", NULL);
417 return JIM_ERR;
418 }
419 /* absurd transfer size? */
420 if (len > 65536) {
421 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
422 Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: absurd > 64K item request", NULL);
423 return JIM_ERR;
424 }
425
426 if ((width == 1) ||
427 ((width == 2) && ((addr & 1) == 0)) ||
428 ((width == 4) && ((addr & 3) == 0))) {
429 /* all is well */
430 } else {
431 char buf[100];
432 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
433 sprintf(buf, "array2mem address: 0x%08x is not aligned for %d byte reads", addr, width);
434 Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);
435 return JIM_ERR;
436 }
437
438 target = get_current_target(active_cmd_ctx);
439
440 /* Transfer loop */
441
442 /* index counter */
443 n = 0;
444 /* assume ok */
445 e = JIM_OK;
446 while (len) {
447 /* Slurp... in buffer size chunks */
448
449 count = len; /* in objects.. */
450 if (count > (sizeof(buffer)/width)) {
451 count = (sizeof(buffer)/width);
452 }
453
454 v = 0; /* shut up gcc */
455 for (i = 0 ;i < count ;i++, n++) {
456 get_int_array_element(interp, varname, n, &v);
457 switch (width) {
458 case 4:
459 target_buffer_set_u32(target, &buffer[i*width], v);
460 break;
461 case 2:
462 target_buffer_set_u16(target, &buffer[i*width], v);
463 break;
464 case 1:
465 buffer[i] = v & 0x0ff;
466 break;
467 }
468 }
469 len -= count;
470
471 retval = target->type->write_memory(target, addr, width, count, buffer);
472 if (retval != ERROR_OK) {
473 /* BOO !*/
474 LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed", addr, width, count);
475 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
476 Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: cannot read memory", NULL);
477 e = JIM_ERR;
478 len = 0;
479 }
480 }
481
482 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
483
484 return JIM_OK;
485 }
486
487
488 static int openocd_retval;
489
490 /* try to execute as Jim command, otherwise fall back to standard command.
491 * Note that even if the Jim command caused an error, then we succeeded
492 * to execute it, hence this fn pretty much always returns ERROR_OK. */
493 int jim_command(command_context_t *context, char *line)
494 {
495 int retval=ERROR_OK;
496 int retcode;
497
498 active_cmd_ctx = context;
499 openocd_retval=ERROR_OK;
500 retcode = Jim_Eval(interp, line);
501
502 if (retcode == JIM_ERR) {
503 if (openocd_retval!=ERROR_COMMAND_CLOSE_CONNECTION)
504 {
505 /* We do not print the connection closed error message */
506 Jim_PrintErrorMessage(interp);
507 }
508 if (openocd_retval==ERROR_OK)
509 {
510 /* It wasn't a low level OpenOCD command that failed */
511 return ERROR_FAIL;
512 }
513 return openocd_retval;
514 }
515 const char *result;
516 int reslen;
517 result = Jim_GetString(Jim_GetResult(interp), &reslen);
518
519 if (retcode == JIM_EXIT) {
520 /* ignore. */
521 /* exit(Jim_GetExitCode(interp)); */
522 } else {
523 if (reslen) {
524 int i;
525 char buff[256+1];
526 for (i = 0; i < reslen; i += 256)
527 {
528 int chunk;
529 chunk = reslen - i;
530 if (chunk > 256)
531 chunk = 256;
532 strncpy(buff, result+i, chunk);
533 buff[chunk] = 0;
534 LOG_USER_N("%s", buff);
535 }
536 LOG_USER_N("%s", "\n");
537 }
538 }
539 return retval;
540 }
541
542 /* find full path to file */
543 static int Jim_Command_find(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
544 {
545 if (argc != 2)
546 return JIM_ERR;
547 const char *file = Jim_GetString(argv[1], NULL);
548 char *full_path = find_file(file);
549 if (full_path == NULL)
550 return JIM_ERR;
551 Jim_Obj *result = Jim_NewStringObj(interp, full_path, strlen(full_path));
552 free(full_path);
553
554 Jim_SetResult(interp, result);
555 return JIM_OK;
556 }
557
558 static int Jim_Command_echo(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
559 {
560 if (argc != 2)
561 return JIM_ERR;
562 char *str = (char*)Jim_GetString(argv[1], NULL);
563 LOG_USER("%s", str);
564 return JIM_OK;
565 }
566
567
568
569 static size_t openocd_jim_fwrite(const void *_ptr, size_t size, size_t n, void *cookie)
570 {
571 size_t nbytes;
572 const char *ptr;
573
574 /* make it a char easier to read code */
575 ptr = _ptr;
576
577 nbytes = size * n;
578 if (nbytes == 0) {
579 return 0;
580 }
581
582 if (!active_cmd_ctx) {
583 /* TODO: Where should this go? */
584 return n;
585 }
586
587 /* do we have to chunk it? */
588 if (ptr[nbytes] == 0) {
589 /* no it is a C style string */
590 command_output_text(active_cmd_ctx, ptr);
591 return strlen(ptr);
592 }
593 /* GRR we must chunk - not null terminated */
594 while (nbytes) {
595 char chunk[128+1];
596 int x;
597
598 x = nbytes;
599 if (x > 128) {
600 x = 128;
601 }
602 /* copy it */
603 memcpy(chunk, ptr, x);
604 /* terminate it */
605 chunk[n] = 0;
606 /* output it */
607 command_output_text(active_cmd_ctx, chunk);
608 ptr += x;
609 nbytes -= x;
610 }
611
612 return n;
613 }
614
615 static size_t openocd_jim_fread(void *ptr, size_t size, size_t n, void *cookie )
616 {
617 /* TCL wants to read... tell him no */
618 return 0;
619 }
620
621 static int openocd_jim_vfprintf(void *cookie, const char *fmt, va_list ap)
622 {
623 char *cp;
624 int n;
625
626 n = -1;
627 if (active_cmd_ctx) {
628 cp = alloc_vprintf(fmt, ap);
629 if (cp) {
630 command_output_text(active_cmd_ctx, cp);
631 n = strlen(cp);
632 free(cp);
633 }
634 }
635 return n;
636 }
637
638 static int openocd_jim_fflush(void *cookie)
639 {
640 /* nothing to flush */
641 return 0;
642 }
643
644 static char* openocd_jim_fgets(char *s, int size, void *cookie)
645 {
646 /* not supported */
647 errno = ENOTSUP;
648 return NULL;
649 }
650
651 void add_jim(const char *name, int (*cmd)(Jim_Interp *interp, int argc, Jim_Obj *const *argv), const char *help)
652 {
653 Jim_CreateCommand(interp, name, cmd, NULL, NULL);
654
655 /* FIX!!! it would be prettier to invoke add_help_text...
656 accumulate help text in Tcl helptext list. */
657 Jim_Obj *helptext=Jim_GetGlobalVariableStr(interp, "ocd_helptext", JIM_ERRMSG);
658 if (Jim_IsShared(helptext))
659 helptext = Jim_DuplicateObj(interp, helptext);
660
661 Jim_Obj *cmd_entry=Jim_NewListObj(interp, NULL, 0);
662
663 Jim_Obj *cmd_list=Jim_NewListObj(interp, NULL, 0);
664 Jim_ListAppendElement(interp, cmd_list, Jim_NewStringObj(interp, name, -1));
665
666 Jim_ListAppendElement(interp, cmd_entry, cmd_list);
667 Jim_ListAppendElement(interp, cmd_entry, Jim_NewStringObj(interp, help, -1));
668 Jim_ListAppendElement(interp, helptext, cmd_entry);
669 }
670
671 extern unsigned const char startup_tcl[];
672
673 void initJim(void)
674 {
675 Jim_CreateCommand(interp, "openocd_find", Jim_Command_find, NULL, NULL);
676 Jim_CreateCommand(interp, "echo", Jim_Command_echo, NULL, NULL);
677 Jim_CreateCommand(interp, "mem2array", Jim_Command_mem2array, NULL, NULL );
678 Jim_CreateCommand(interp, "array2mem", Jim_Command_array2mem, NULL, NULL );
679
680 /* Set Jim's STDIO */
681 interp->cookie_stdin = NULL;
682 interp->cookie_stdout = NULL;
683 interp->cookie_stderr = NULL;
684 interp->cb_fwrite = openocd_jim_fwrite;
685 interp->cb_fread = openocd_jim_fread ;
686 interp->cb_vfprintf = openocd_jim_vfprintf;
687 interp->cb_fflush = openocd_jim_fflush;
688 interp->cb_fgets = openocd_jim_fgets;
689
690 add_default_dirs();
691
692 if (Jim_Eval(interp, startup_tcl)==JIM_ERR)
693 {
694 LOG_ERROR("Failed to run startup.tcl (embedded into OpenOCD compile time)");
695 Jim_PrintErrorMessage(interp);
696 exit(-1);
697 }
698 }
699
700 command_context_t *setup_command_handler(void)
701 {
702 command_context_t *cmd_ctx;
703
704 cmd_ctx = command_init();
705
706 register_command(cmd_ctx, NULL, "version", handle_version_command,
707 COMMAND_EXEC, "show OpenOCD version");
708 register_command(cmd_ctx, NULL, "daemon_startup", handle_daemon_startup_command, COMMAND_CONFIG,
709 "deprecated - use \"init\" and \"reset\" at end of startup script instead");
710
711 /* register subsystem commands */
712 server_register_commands(cmd_ctx);
713 telnet_register_commands(cmd_ctx);
714 gdb_register_commands(cmd_ctx);
715 tcl_register_commands(cmd_ctx); /* tcl server commands */
716 log_register_commands(cmd_ctx);
717 jtag_register_commands(cmd_ctx);
718 xsvf_register_commands(cmd_ctx);
719 target_register_commands(cmd_ctx);
720 flash_register_commands(cmd_ctx);
721 nand_register_commands(cmd_ctx);
722 pld_register_commands(cmd_ctx);
723
724 if (log_init(cmd_ctx) != ERROR_OK)
725 {
726 exit(-1);
727 }
728 LOG_DEBUG("log init complete");
729
730 LOG_OUTPUT( OPENOCD_VERSION "\n" );
731
732
733 register_command(cmd_ctx, NULL, "init", handle_init_command,
734 COMMAND_ANY, "initializes target and servers - nop on subsequent invocations");
735
736 return cmd_ctx;
737 }
738
739 /* normally this is the main() function entry, but if OpenOCD is linked
740 * into application, then this fn will not be invoked, but rather that
741 * application will have it's own implementation of main(). */
742 int openocd_main(int argc, char *argv[])
743 {
744 #ifdef JIM_EMBEDDED
745 Jim_InitEmbedded();
746 /* Create an interpreter */
747 interp = Jim_CreateInterp();
748 /* Add all the Jim core commands */
749 Jim_RegisterCoreCommands(interp);
750 #endif
751
752 initJim();
753
754 /* initialize commandline interface */
755 command_context_t *cmd_ctx;
756 cmd_ctx=setup_command_handler();
757
758 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
759 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
760 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
761 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
762 /* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
763 LOG_OUTPUT( "$URL$\n");
764 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
765 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
766 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
767 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
768 /* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
769
770 command_context_mode(cmd_ctx, COMMAND_CONFIG);
771 command_set_output_handler(cmd_ctx, configuration_output_handler, NULL);
772
773 if (parse_cmdline_args(cmd_ctx, argc, argv) != ERROR_OK)
774 return EXIT_FAILURE;
775
776 if (parse_config_file(cmd_ctx) != ERROR_OK)
777 return EXIT_FAILURE;
778
779 command_context_mode(cmd_ctx, COMMAND_EXEC);
780 if (command_run_line(cmd_ctx, "init")!=ERROR_OK)
781 return EXIT_FAILURE;
782
783 if (daemon_startup)
784 command_run_line(cmd_ctx, "reset");
785
786 /* handle network connections */
787 server_loop(cmd_ctx);
788
789 /* shut server down */
790 server_quit();
791
792 unregister_all_commands(cmd_ctx);
793
794 /* free commandline interface */
795 command_done(cmd_ctx);
796
797 return EXIT_SUCCESS;
798 }

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)