You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

861 lines
22 KiB

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