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.
 
 
 
 
 
 

389 lines
9.4 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2016 by Matthias Welwarsky *
  3. * *
  4. * This program is free software; you can redistribute it and/or modify *
  5. * it under the terms of the GNU General Public License as published by *
  6. * the Free Software Foundation; either version 2 of the License, or *
  7. * (at your option) any later version. *
  8. * *
  9. * This program is distributed in the hope that it will be useful, *
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  12. * GNU General Public License for more details. *
  13. * *
  14. * You should have received a copy of the GNU General Public License *
  15. * along with this program; if not, write to the *
  16. * Free Software Foundation, Inc., *
  17. * *
  18. ***************************************************************************/
  19. #ifdef HAVE_CONFIG_H
  20. #include "config.h"
  21. #endif
  22. #include <stdlib.h>
  23. #include <stdint.h>
  24. #include "target/arm_adi_v5.h"
  25. #include "target/arm.h"
  26. #include "helper/list.h"
  27. #include "helper/command.h"
  28. #include "transport/transport.h"
  29. #include "jtag/interface.h"
  30. static LIST_HEAD(all_dap);
  31. extern const struct dap_ops swd_dap_ops;
  32. extern const struct dap_ops jtag_dp_ops;
  33. extern struct adapter_driver *adapter_driver;
  34. #define ADI_BAD_CFG 0xBAD00000
  35. /* DAP command support */
  36. struct arm_dap_object {
  37. struct list_head lh;
  38. struct adiv5_dap dap;
  39. char *name;
  40. const struct swd_driver *swd;
  41. };
  42. static void dap_instance_init(struct adiv5_dap *dap)
  43. {
  44. int i;
  45. /* Set up with safe defaults */
  46. for (i = 0; i <= DP_APSEL_MAX; i++) {
  47. dap->ap[i].dap = dap;
  48. dap->ap[i].ap_num = i;
  49. /* memaccess_tck max is 255 */
  50. dap->ap[i].memaccess_tck = 255;
  51. /* Number of bits for tar autoincrement, impl. dep. at least 10 */
  52. dap->ap[i].tar_autoincr_block = (1<<10);
  53. /* default CSW value */
  54. dap->ap[i].csw_default = CSW_AHB_DEFAULT;
  55. dap->ap[i].cfg_reg = ADI_BAD_CFG; /* mem_ap configuration reg (large physical addr, etc.) */
  56. }
  57. INIT_LIST_HEAD(&dap->cmd_journal);
  58. INIT_LIST_HEAD(&dap->cmd_pool);
  59. }
  60. const char *adiv5_dap_name(struct adiv5_dap *self)
  61. {
  62. struct arm_dap_object *obj = container_of(self, struct arm_dap_object, dap);
  63. return obj->name;
  64. }
  65. const struct swd_driver *adiv5_dap_swd_driver(struct adiv5_dap *self)
  66. {
  67. struct arm_dap_object *obj = container_of(self, struct arm_dap_object, dap);
  68. return obj->swd;
  69. }
  70. struct adiv5_dap *adiv5_get_dap(struct arm_dap_object *obj)
  71. {
  72. return &obj->dap;
  73. }
  74. struct adiv5_dap *dap_instance_by_jim_obj(Jim_Interp *interp, Jim_Obj *o)
  75. {
  76. struct arm_dap_object *obj = NULL;
  77. const char *name;
  78. bool found = false;
  79. name = Jim_GetString(o, NULL);
  80. list_for_each_entry(obj, &all_dap, lh) {
  81. if (!strcmp(name, obj->name)) {
  82. found = true;
  83. break;
  84. }
  85. }
  86. if (found)
  87. return &obj->dap;
  88. return NULL;
  89. }
  90. static int dap_init_all(void)
  91. {
  92. struct arm_dap_object *obj;
  93. int retval;
  94. LOG_DEBUG("Initializing all DAPs ...");
  95. list_for_each_entry(obj, &all_dap, lh) {
  96. struct adiv5_dap *dap = &obj->dap;
  97. /* with hla, dap is just a dummy */
  98. if (transport_is_hla())
  99. continue;
  100. /* skip taps that are disabled */
  101. if (!dap->tap->enabled)
  102. continue;
  103. if (transport_is_swd()) {
  104. dap->ops = &swd_dap_ops;
  105. obj->swd = adapter_driver->swd_ops;
  106. } else if (transport_is_dapdirect_swd()) {
  107. dap->ops = adapter_driver->dap_swd_ops;
  108. } else if (transport_is_dapdirect_jtag()) {
  109. dap->ops = adapter_driver->dap_jtag_ops;
  110. } else
  111. dap->ops = &jtag_dp_ops;
  112. retval = dap->ops->connect(dap);
  113. if (retval != ERROR_OK)
  114. return retval;
  115. }
  116. return ERROR_OK;
  117. }
  118. int dap_cleanup_all(void)
  119. {
  120. struct arm_dap_object *obj, *tmp;
  121. struct adiv5_dap *dap;
  122. list_for_each_entry_safe(obj, tmp, &all_dap, lh) {
  123. dap = &obj->dap;
  124. if (dap->ops && dap->ops->quit)
  125. dap->ops->quit(dap);
  126. free(obj->name);
  127. free(obj);
  128. }
  129. return ERROR_OK;
  130. }
  131. enum dap_cfg_param {
  132. CFG_CHAIN_POSITION,
  133. CFG_IGNORE_SYSPWRUPACK,
  134. };
  135. static const struct jim_nvp nvp_config_opts[] = {
  136. { .name = "-chain-position", .value = CFG_CHAIN_POSITION },
  137. { .name = "-ignore-syspwrupack", .value = CFG_IGNORE_SYSPWRUPACK },
  138. { .name = NULL, .value = -1 }
  139. };
  140. static int dap_configure(struct jim_getopt_info *goi, struct arm_dap_object *dap)
  141. {
  142. struct jtag_tap *tap = NULL;
  143. struct jim_nvp *n;
  144. int e;
  145. /* parse config or cget options ... */
  146. while (goi->argc > 0) {
  147. Jim_SetEmptyResult(goi->interp);
  148. e = jim_getopt_nvp(goi, nvp_config_opts, &n);
  149. if (e != JIM_OK) {
  150. jim_getopt_nvp_unknown(goi, nvp_config_opts, 0);
  151. return e;
  152. }
  153. switch (n->value) {
  154. case CFG_CHAIN_POSITION: {
  155. Jim_Obj *o_t;
  156. e = jim_getopt_obj(goi, &o_t);
  157. if (e != JIM_OK)
  158. return e;
  159. tap = jtag_tap_by_jim_obj(goi->interp, o_t);
  160. if (!tap) {
  161. Jim_SetResultString(goi->interp, "-chain-position is invalid", -1);
  162. return JIM_ERR;
  163. }
  164. /* loop for more */
  165. break;
  166. }
  167. case CFG_IGNORE_SYSPWRUPACK:
  168. dap->dap.ignore_syspwrupack = true;
  169. break;
  170. default:
  171. break;
  172. }
  173. }
  174. if (!tap) {
  175. Jim_SetResultString(goi->interp, "-chain-position required when creating DAP", -1);
  176. return JIM_ERR;
  177. }
  178. dap_instance_init(&dap->dap);
  179. dap->dap.tap = tap;
  180. return JIM_OK;
  181. }
  182. static int dap_create(struct jim_getopt_info *goi)
  183. {
  184. struct command_context *cmd_ctx;
  185. static struct arm_dap_object *dap;
  186. Jim_Obj *new_cmd;
  187. Jim_Cmd *cmd;
  188. const char *cp;
  189. int e;
  190. cmd_ctx = current_command_context(goi->interp);
  191. assert(cmd_ctx);
  192. if (goi->argc < 3) {
  193. Jim_WrongNumArgs(goi->interp, 1, goi->argv, "?name? ..options...");
  194. return JIM_ERR;
  195. }
  196. /* COMMAND */
  197. jim_getopt_obj(goi, &new_cmd);
  198. /* does this command exist? */
  199. cmd = Jim_GetCommand(goi->interp, new_cmd, JIM_ERRMSG);
  200. if (cmd) {
  201. cp = Jim_GetString(new_cmd, NULL);
  202. Jim_SetResultFormatted(goi->interp, "Command: %s Exists", cp);
  203. return JIM_ERR;
  204. }
  205. /* Create it */
  206. dap = calloc(1, sizeof(struct arm_dap_object));
  207. if (!dap)
  208. return JIM_ERR;
  209. e = dap_configure(goi, dap);
  210. if (e != JIM_OK) {
  211. free(dap);
  212. return e;
  213. }
  214. cp = Jim_GetString(new_cmd, NULL);
  215. dap->name = strdup(cp);
  216. struct command_registration dap_commands[] = {
  217. {
  218. .name = cp,
  219. .mode = COMMAND_ANY,
  220. .help = "dap instance command group",
  221. .usage = "",
  222. .chain = dap_instance_commands,
  223. },
  224. COMMAND_REGISTRATION_DONE
  225. };
  226. /* don't expose the instance commands when using hla */
  227. if (transport_is_hla())
  228. dap_commands[0].chain = NULL;
  229. e = register_commands_with_data(cmd_ctx, NULL, dap_commands, dap);
  230. if (e != ERROR_OK)
  231. return JIM_ERR;
  232. list_add_tail(&dap->lh, &all_dap);
  233. return JIM_OK;
  234. }
  235. static int jim_dap_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
  236. {
  237. struct jim_getopt_info goi;
  238. jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
  239. if (goi.argc < 2) {
  240. Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
  241. "<name> [<dap_options> ...]");
  242. return JIM_ERR;
  243. }
  244. return dap_create(&goi);
  245. }
  246. static int jim_dap_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
  247. {
  248. struct arm_dap_object *obj;
  249. if (argc != 1) {
  250. Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");
  251. return JIM_ERR;
  252. }
  253. Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0));
  254. list_for_each_entry(obj, &all_dap, lh) {
  255. Jim_ListAppendElement(interp, Jim_GetResult(interp),
  256. Jim_NewStringObj(interp, obj->name, -1));
  257. }
  258. return JIM_OK;
  259. }
  260. COMMAND_HANDLER(handle_dap_init)
  261. {
  262. return dap_init_all();
  263. }
  264. COMMAND_HANDLER(handle_dap_info_command)
  265. {
  266. struct target *target = get_current_target(CMD_CTX);
  267. struct arm *arm = target_to_arm(target);
  268. struct adiv5_dap *dap = arm->dap;
  269. uint32_t apsel;
  270. if (!dap) {
  271. LOG_ERROR("DAP instance not available. Probably a HLA target...");
  272. return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
  273. }
  274. switch (CMD_ARGC) {
  275. case 0:
  276. apsel = dap->apsel;
  277. break;
  278. case 1:
  279. COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
  280. if (apsel > DP_APSEL_MAX)
  281. return ERROR_COMMAND_SYNTAX_ERROR;
  282. break;
  283. default:
  284. return ERROR_COMMAND_SYNTAX_ERROR;
  285. }
  286. return dap_info_command(CMD, &dap->ap[apsel]);
  287. }
  288. static const struct command_registration dap_subcommand_handlers[] = {
  289. {
  290. .name = "create",
  291. .mode = COMMAND_ANY,
  292. .jim_handler = jim_dap_create,
  293. .usage = "name '-chain-position' name",
  294. .help = "Creates a new DAP instance",
  295. },
  296. {
  297. .name = "names",
  298. .mode = COMMAND_ANY,
  299. .jim_handler = jim_dap_names,
  300. .usage = "",
  301. .help = "Lists all registered DAP instances by name",
  302. },
  303. {
  304. .name = "init",
  305. .mode = COMMAND_ANY,
  306. .handler = handle_dap_init,
  307. .usage = "",
  308. .help = "Initialize all registered DAP instances"
  309. },
  310. {
  311. .name = "info",
  312. .handler = handle_dap_info_command,
  313. .mode = COMMAND_EXEC,
  314. .help = "display ROM table for MEM-AP of current target "
  315. "(default currently selected AP)",
  316. .usage = "[ap_num]",
  317. },
  318. COMMAND_REGISTRATION_DONE
  319. };
  320. static const struct command_registration dap_commands[] = {
  321. {
  322. .name = "dap",
  323. .mode = COMMAND_CONFIG,
  324. .help = "DAP commands",
  325. .chain = dap_subcommand_handlers,
  326. .usage = "",
  327. },
  328. COMMAND_REGISTRATION_DONE
  329. };
  330. int dap_register_commands(struct command_context *cmd_ctx)
  331. {
  332. return register_commands(cmd_ctx, NULL, dap_commands);
  333. }