b65d4715288cd3eacdb340f2481bd2dddb6d7567
[fw/openocd] / src / openocd.c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 /***************************************************************************
4  *   Copyright (C) 2005 by Dominic Rath                                    *
5  *   Dominic.Rath@gmx.de                                                   *
6  *                                                                         *
7  *   Copyright (C) 2007-2010 Ã˜yvind Harboe                                 *
8  *   oyvind.harboe@zylin.com                                               *
9  *                                                                         *
10  *   Copyright (C) 2008 Richard Missenden                                  *
11  *   richard.missenden@googlemail.com                                      *
12  ***************************************************************************/
13
14 #ifdef HAVE_CONFIG_H
15 #include "config.h"
16 #endif
17
18 #include "openocd.h"
19 #include <jtag/adapter.h>
20 #include <jtag/jtag.h>
21 #include <transport/transport.h>
22 #include <helper/util.h>
23 #include <helper/configuration.h>
24 #include <flash/nor/core.h>
25 #include <flash/nand/core.h>
26 #include <pld/pld.h>
27 #include <target/arm_cti.h>
28 #include <target/arm_adi_v5.h>
29 #include <target/arm_tpiu_swo.h>
30 #include <rtt/rtt.h>
31
32 #include <server/server.h>
33 #include <server/gdb_server.h>
34 #include <server/rtt_server.h>
35
36 #ifdef HAVE_STRINGS_H
37 #include <strings.h>
38 #endif
39
40 #ifdef PKGBLDDATE
41 #define OPENOCD_VERSION \
42         "Open On-Chip Debugger " VERSION RELSTR " (" PKGBLDDATE ")"
43 #else
44 #define OPENOCD_VERSION \
45         "Open On-Chip Debugger " VERSION RELSTR
46 #endif
47
48 static const char openocd_startup_tcl[] = {
49 #include "startup_tcl.inc"
50 0 /* Terminate with zero */
51 };
52
53 /* Give scripts and TELNET a way to find out what version this is */
54 static int jim_version_command(Jim_Interp *interp, int argc,
55         Jim_Obj * const *argv)
56 {
57         if (argc > 2)
58                 return JIM_ERR;
59         const char *str = "";
60         char *version_str;
61         version_str = OPENOCD_VERSION;
62
63         if (argc == 2)
64                 str = Jim_GetString(argv[1], NULL);
65
66         if (strcmp("git", str) == 0)
67                 version_str = GITVERSION;
68
69         Jim_SetResult(interp, Jim_NewStringObj(interp, version_str, -1));
70
71         return JIM_OK;
72 }
73
74 static int log_target_callback_event_handler(struct target *target,
75         enum target_event event,
76         void *priv)
77 {
78         switch (event) {
79                 case TARGET_EVENT_GDB_START:
80                         target->verbose_halt_msg = false;
81                         break;
82                 case TARGET_EVENT_GDB_END:
83                         target->verbose_halt_msg = true;
84                         break;
85                 case TARGET_EVENT_HALTED:
86                         if (target->verbose_halt_msg) {
87                                 /* do not display information when debugger caused the halt */
88                                 target_arch_state(target);
89                         }
90                         break;
91                 default:
92                         break;
93         }
94
95         return ERROR_OK;
96 }
97
98 static bool init_at_startup = true;
99
100 COMMAND_HANDLER(handle_noinit_command)
101 {
102         if (CMD_ARGC != 0)
103                 return ERROR_COMMAND_SYNTAX_ERROR;
104         init_at_startup = false;
105         return ERROR_OK;
106 }
107
108 /* OpenOCD can't really handle failure of this command. Patches welcome! :-) */
109 COMMAND_HANDLER(handle_init_command)
110 {
111
112         if (CMD_ARGC != 0)
113                 return ERROR_COMMAND_SYNTAX_ERROR;
114
115         int retval;
116         static int initialized;
117         if (initialized)
118                 return ERROR_OK;
119
120         initialized = 1;
121
122         bool save_poll_mask = jtag_poll_mask();
123
124         retval = command_run_line(CMD_CTX, "target init");
125         if (retval != ERROR_OK)
126                 return ERROR_FAIL;
127
128         retval = adapter_init(CMD_CTX);
129         if (retval != ERROR_OK) {
130                 /* we must be able to set up the debug adapter */
131                 return retval;
132         }
133
134         LOG_DEBUG("Debug Adapter init complete");
135
136         /* "transport init" verifies the expected devices are present;
137          * for JTAG, it checks the list of configured TAPs against
138          * what's discoverable, possibly with help from the platform's
139          * JTAG event handlers.  (which require COMMAND_EXEC)
140          */
141         command_context_mode(CMD_CTX, COMMAND_EXEC);
142
143         retval = command_run_line(CMD_CTX, "transport init");
144         if (retval != ERROR_OK)
145                 return ERROR_FAIL;
146
147         retval = command_run_line(CMD_CTX, "dap init");
148         if (retval != ERROR_OK)
149                 return ERROR_FAIL;
150
151         LOG_DEBUG("Examining targets...");
152         if (target_examine() != ERROR_OK)
153                 LOG_DEBUG("target examination failed");
154
155         command_context_mode(CMD_CTX, COMMAND_CONFIG);
156
157         if (command_run_line(CMD_CTX, "flash init") != ERROR_OK)
158                 return ERROR_FAIL;
159
160         if (command_run_line(CMD_CTX, "nand init") != ERROR_OK)
161                 return ERROR_FAIL;
162
163         if (command_run_line(CMD_CTX, "pld init") != ERROR_OK)
164                 return ERROR_FAIL;
165         command_context_mode(CMD_CTX, COMMAND_EXEC);
166
167         /* in COMMAND_EXEC, after target_examine(), only tpiu or only swo */
168         if (command_run_line(CMD_CTX, "tpiu init") != ERROR_OK)
169                 return ERROR_FAIL;
170
171         jtag_poll_unmask(save_poll_mask);
172
173         /* initialize telnet subsystem */
174         gdb_target_add_all(all_targets);
175
176         target_register_event_callback(log_target_callback_event_handler, CMD_CTX);
177
178         if (command_run_line(CMD_CTX, "_run_post_init_commands") != ERROR_OK)
179                 return ERROR_FAIL;
180
181         return ERROR_OK;
182 }
183
184 COMMAND_HANDLER(handle_add_script_search_dir_command)
185 {
186         if (CMD_ARGC != 1)
187                 return ERROR_COMMAND_SYNTAX_ERROR;
188
189         add_script_search_dir(CMD_ARGV[0]);
190
191         return ERROR_OK;
192 }
193
194 static const struct command_registration openocd_command_handlers[] = {
195         {
196                 .name = "version",
197                 .jim_handler = jim_version_command,
198                 .mode = COMMAND_ANY,
199                 .help = "show program version",
200         },
201         {
202                 .name = "noinit",
203                 .handler = &handle_noinit_command,
204                 .mode = COMMAND_CONFIG,
205                 .help = "Prevent 'init' from being called at startup.",
206                 .usage = ""
207         },
208         {
209                 .name = "init",
210                 .handler = &handle_init_command,
211                 .mode = COMMAND_ANY,
212                 .help = "Initializes configured targets and servers.  "
213                         "Changes command mode from CONFIG to EXEC.  "
214                         "Unless 'noinit' is called, this command is "
215                         "called automatically at the end of startup.",
216                 .usage = ""
217         },
218         {
219                 .name = "add_script_search_dir",
220                 .handler = &handle_add_script_search_dir_command,
221                 .mode = COMMAND_ANY,
222                 .help = "dir to search for config files and scripts",
223                 .usage = "<directory>"
224         },
225         COMMAND_REGISTRATION_DONE
226 };
227
228 static int openocd_register_commands(struct command_context *cmd_ctx)
229 {
230         return register_commands(cmd_ctx, NULL, openocd_command_handlers);
231 }
232
233 /*
234  * TODO: to be removed after v0.12.0
235  * workaround for syntax change of "expr" in jimtcl 0.81
236  * replace "expr" with openocd version that prints the deprecated msg
237  */
238 struct jim_scriptobj {
239         void *token;
240         Jim_Obj *filename_obj;
241         int len;
242         int subst_flags;
243         int in_use;
244         int firstline;
245         int linenr;
246         int missing;
247 };
248
249 static int jim_expr_command(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
250 {
251         if (argc == 2)
252                 return Jim_EvalExpression(interp, argv[1]);
253
254         if (argc > 2) {
255                 Jim_Obj *obj = Jim_ConcatObj(interp, argc - 1, argv + 1);
256                 Jim_IncrRefCount(obj);
257                 const char *s = Jim_String(obj);
258                 struct jim_scriptobj *script = Jim_GetIntRepPtr(interp->currentScriptObj);
259                 if (interp->currentScriptObj == interp->emptyObj ||
260                                 strcmp(interp->currentScriptObj->typePtr->name, "script") ||
261                                 script->subst_flags ||
262                                 script->filename_obj == interp->emptyObj)
263                         LOG_WARNING("DEPRECATED! use 'expr { %s }' not 'expr %s'", s, s);
264                 else
265                         LOG_WARNING("DEPRECATED! (%s:%d) use 'expr { %s }' not 'expr %s'",
266                                                 Jim_String(script->filename_obj), script->linenr, s, s);
267                 int retcode = Jim_EvalExpression(interp, obj);
268                 Jim_DecrRefCount(interp, obj);
269                 return retcode;
270         }
271
272         Jim_WrongNumArgs(interp, 1, argv, "expression ?...?");
273         return JIM_ERR;
274 }
275
276 static const struct command_registration expr_handler[] = {
277         {
278                 .name = "expr",
279                 .jim_handler = jim_expr_command,
280                 .mode = COMMAND_ANY,
281                 .help = "",
282                 .usage = "",
283         },
284         COMMAND_REGISTRATION_DONE
285 };
286
287 static int workaround_for_jimtcl_expr(struct command_context *cmd_ctx)
288 {
289         return register_commands(cmd_ctx, NULL, expr_handler);
290 }
291
292 struct command_context *global_cmd_ctx;
293
294 static struct command_context *setup_command_handler(Jim_Interp *interp)
295 {
296         log_init();
297         LOG_DEBUG("log_init: complete");
298
299         struct command_context *cmd_ctx = command_init(openocd_startup_tcl, interp);
300
301         /* register subsystem commands */
302         typedef int (*command_registrant_t)(struct command_context *cmd_ctx_value);
303         static const command_registrant_t command_registrants[] = {
304                 &workaround_for_jimtcl_expr,
305                 &openocd_register_commands,
306                 &server_register_commands,
307                 &gdb_register_commands,
308                 &log_register_commands,
309                 &rtt_server_register_commands,
310                 &transport_register_commands,
311                 &adapter_register_commands,
312                 &target_register_commands,
313                 &flash_register_commands,
314                 &nand_register_commands,
315                 &pld_register_commands,
316                 &cti_register_commands,
317                 &dap_register_commands,
318                 &arm_tpiu_swo_register_commands,
319                 NULL
320         };
321         for (unsigned i = 0; command_registrants[i]; i++) {
322                 int retval = (*command_registrants[i])(cmd_ctx);
323                 if (retval != ERROR_OK) {
324                         command_done(cmd_ctx);
325                         return NULL;
326                 }
327         }
328         LOG_DEBUG("command registration: complete");
329
330         LOG_OUTPUT(OPENOCD_VERSION "\n"
331                 "Licensed under GNU GPL v2\n");
332
333         global_cmd_ctx = cmd_ctx;
334
335         return cmd_ctx;
336 }
337
338 /** OpenOCD runtime meat that can become single-thread in future. It parse
339  * commandline, reads configuration, sets up the target and starts server loop.
340  * Commandline arguments are passed into this function from openocd_main().
341  */
342 static int openocd_thread(int argc, char *argv[], struct command_context *cmd_ctx)
343 {
344         int ret;
345
346         if (parse_cmdline_args(cmd_ctx, argc, argv) != ERROR_OK)
347                 return ERROR_FAIL;
348
349         if (server_preinit() != ERROR_OK)
350                 return ERROR_FAIL;
351
352         ret = parse_config_file(cmd_ctx);
353         if (ret == ERROR_COMMAND_CLOSE_CONNECTION) {
354                 server_quit(); /* gdb server may be initialized by -c init */
355                 return ERROR_OK;
356         } else if (ret != ERROR_OK) {
357                 server_quit(); /* gdb server may be initialized by -c init */
358                 return ERROR_FAIL;
359         }
360
361         ret = server_init(cmd_ctx);
362         if (ret != ERROR_OK)
363                 return ERROR_FAIL;
364
365         if (init_at_startup) {
366                 ret = command_run_line(cmd_ctx, "init");
367                 if (ret != ERROR_OK) {
368                         server_quit();
369                         return ERROR_FAIL;
370                 }
371         }
372
373         ret = server_loop(cmd_ctx);
374
375         int last_signal = server_quit();
376         if (last_signal != ERROR_OK)
377                 return last_signal;
378
379         if (ret != ERROR_OK)
380                 return ERROR_FAIL;
381         return ERROR_OK;
382 }
383
384 /* normally this is the main() function entry, but if OpenOCD is linked
385  * into application, then this fn will not be invoked, but rather that
386  * application will have it's own implementation of main(). */
387 int openocd_main(int argc, char *argv[])
388 {
389         int ret;
390
391         /* initialize commandline interface */
392         struct command_context *cmd_ctx;
393
394         cmd_ctx = setup_command_handler(NULL);
395
396         if (util_init(cmd_ctx) != ERROR_OK)
397                 return EXIT_FAILURE;
398
399         if (rtt_init() != ERROR_OK)
400                 return EXIT_FAILURE;
401
402         LOG_OUTPUT("For bug reports, read\n\t"
403                 "http://openocd.org/doc/doxygen/bugs.html"
404                 "\n");
405
406         command_context_mode(cmd_ctx, COMMAND_CONFIG);
407         command_set_output_handler(cmd_ctx, configuration_output_handler, NULL);
408
409         server_host_os_entry();
410
411         /* Start the executable meat that can evolve into thread in future. */
412         ret = openocd_thread(argc, argv, cmd_ctx);
413
414         flash_free_all_banks();
415         gdb_service_free();
416         arm_tpiu_swo_cleanup_all();
417         server_free();
418
419         unregister_all_commands(cmd_ctx, NULL);
420         help_del_all_commands(cmd_ctx);
421
422         /* free all DAP and CTI objects */
423         arm_cti_cleanup_all();
424         dap_cleanup_all();
425
426         adapter_quit();
427
428         server_host_os_close();
429
430         /* Shutdown commandline interface */
431         command_exit(cmd_ctx);
432
433         rtt_exit();
434         free_config();
435
436         log_exit();
437
438         if (ret == ERROR_FAIL)
439                 return EXIT_FAILURE;
440         else if (ret != ERROR_OK)
441                 exit_on_signal(ret);
442
443         return ret;
444 }