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.
 
 
 
 
 
 

338 lines
8.5 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2007 by Dominic Rath *
  3. * Dominic.Rath@gmx.de *
  4. * *
  5. * Copyright (C) 2007,2008 Øyvind Harboe *
  6. * oyvind.harboe@zylin.com *
  7. * *
  8. * Copyright (C) 2008 by Spencer Oliver *
  9. * spen@spen-soft.co.uk *
  10. * *
  11. * This program is free software; you can redistribute it and/or modify *
  12. * it under the terms of the GNU General Public License as published by *
  13. * the Free Software Foundation; either version 2 of the License, or *
  14. * (at your option) any later version. *
  15. * *
  16. * This program is distributed in the hope that it will be useful, *
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  19. * GNU General Public License for more details. *
  20. * *
  21. * You should have received a copy of the GNU General Public License *
  22. * along with this program; if not, write to the *
  23. * Free Software Foundation, Inc., *
  24. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  25. ***************************************************************************/
  26. #ifdef HAVE_CONFIG_H
  27. #include "config.h"
  28. #endif
  29. #include <helper/log.h>
  30. #include <helper/binarybuffer.h>
  31. #include "target.h"
  32. #include "target_request.h"
  33. #include "target_type.h"
  34. #include "trace.h"
  35. static bool got_message = false;
  36. bool target_got_message(void)
  37. {
  38. bool t = got_message;
  39. got_message = false;
  40. return t;
  41. }
  42. static int charmsg_mode = 0;
  43. static int target_asciimsg(struct target *target, uint32_t length)
  44. {
  45. char *msg = malloc(DIV_ROUND_UP(length + 1, 4) * 4);
  46. struct debug_msg_receiver *c = target->dbgmsg;
  47. target->type->target_request_data(target, DIV_ROUND_UP(length, 4), (uint8_t*)msg);
  48. msg[length] = 0;
  49. LOG_DEBUG("%s", msg);
  50. while (c)
  51. {
  52. command_print(c->cmd_ctx, "%s", msg);
  53. c = c->next;
  54. }
  55. return ERROR_OK;
  56. }
  57. static int target_charmsg(struct target *target, uint8_t msg)
  58. {
  59. LOG_USER_N("%c", msg);
  60. return ERROR_OK;
  61. }
  62. static int target_hexmsg(struct target *target, int size, uint32_t length)
  63. {
  64. uint8_t *data = malloc(DIV_ROUND_UP(length * size, 4) * 4);
  65. char line[128];
  66. int line_len;
  67. struct debug_msg_receiver *c = target->dbgmsg;
  68. uint32_t i;
  69. LOG_DEBUG("size: %i, length: %i", (int)size, (int)length);
  70. target->type->target_request_data(target, DIV_ROUND_UP(length * size, 4), (uint8_t*)data);
  71. line_len = 0;
  72. for (i = 0; i < length; i++)
  73. {
  74. switch (size)
  75. {
  76. case 4:
  77. line_len += snprintf(line + line_len, 128 - line_len, "%8.8" PRIx32 " ", le_to_h_u32(data + (4*i)));
  78. break;
  79. case 2:
  80. line_len += snprintf(line + line_len, 128 - line_len, "%4.4x ", le_to_h_u16(data + (2*i)));
  81. break;
  82. case 1:
  83. line_len += snprintf(line + line_len, 128 - line_len, "%2.2x ", data[i]);
  84. break;
  85. }
  86. if ((i%8 == 7) || (i == length - 1))
  87. {
  88. LOG_DEBUG("%s", line);
  89. while (c)
  90. {
  91. command_print(c->cmd_ctx, "%s", line);
  92. c = c->next;
  93. }
  94. c = target->dbgmsg;
  95. line_len = 0;
  96. }
  97. }
  98. free(data);
  99. return ERROR_OK;
  100. }
  101. /* handle requests from the target received by a target specific
  102. * side-band channel (e.g. ARM7/9 DCC)
  103. */
  104. int target_request(struct target *target, uint32_t request)
  105. {
  106. target_req_cmd_t target_req_cmd = request & 0xff;
  107. /* Record that we got a target message for back-off algorithm */
  108. got_message = true;
  109. if (charmsg_mode) {
  110. target_charmsg(target, target_req_cmd);
  111. return ERROR_OK;
  112. }
  113. switch (target_req_cmd)
  114. {
  115. case TARGET_REQ_TRACEMSG:
  116. trace_point(target, (request & 0xffffff00) >> 8);
  117. break;
  118. case TARGET_REQ_DEBUGMSG:
  119. if (((request & 0xff00) >> 8) == 0)
  120. {
  121. target_asciimsg(target, (request & 0xffff0000) >> 16);
  122. }
  123. else
  124. {
  125. target_hexmsg(target, (request & 0xff00) >> 8, (request & 0xffff0000) >> 16);
  126. }
  127. break;
  128. case TARGET_REQ_DEBUGCHAR:
  129. target_charmsg(target, (request & 0x00ff0000) >> 16);
  130. break;
  131. /* case TARGET_REQ_SEMIHOSTING:
  132. * break;
  133. */
  134. default:
  135. LOG_ERROR("unknown target request: %2.2x", target_req_cmd);
  136. break;
  137. }
  138. return ERROR_OK;
  139. }
  140. static int add_debug_msg_receiver(struct command_context *cmd_ctx, struct target *target)
  141. {
  142. struct debug_msg_receiver **p = &target->dbgmsg;
  143. if (target == NULL)
  144. return ERROR_INVALID_ARGUMENTS;
  145. /* see if there's already a list */
  146. if (*p)
  147. {
  148. /* find end of linked list */
  149. p = &target->dbgmsg;
  150. while ((*p)->next)
  151. p = &((*p)->next);
  152. p = &((*p)->next);
  153. }
  154. /* add new debug message receiver */
  155. (*p) = malloc(sizeof(struct debug_msg_receiver));
  156. (*p)->cmd_ctx = cmd_ctx;
  157. (*p)->next = NULL;
  158. /* enable callback */
  159. target->dbg_msg_enabled = 1;
  160. return ERROR_OK;
  161. }
  162. static struct debug_msg_receiver* find_debug_msg_receiver(struct command_context *cmd_ctx, struct target *target)
  163. {
  164. int do_all_targets = 0;
  165. /* if no target has been specified search all of them */
  166. if (target == NULL) {
  167. /* if no targets haven been specified */
  168. if (all_targets == NULL)
  169. return NULL;
  170. target = all_targets;
  171. do_all_targets = 1;
  172. }
  173. /* so we target != null */
  174. struct debug_msg_receiver **p = &target->dbgmsg;
  175. do {
  176. while (*p)
  177. {
  178. if ((*p)->cmd_ctx == cmd_ctx)
  179. {
  180. return *p;
  181. }
  182. p = &((*p)->next);
  183. }
  184. target = target->next;
  185. } while (target && do_all_targets);
  186. return NULL;
  187. }
  188. int delete_debug_msg_receiver(struct command_context *cmd_ctx, struct target *target)
  189. {
  190. struct debug_msg_receiver **p;
  191. struct debug_msg_receiver *c;
  192. int do_all_targets = 0;
  193. /* if no target has been specified search all of them */
  194. if (target == NULL)
  195. {
  196. /* if no targets haven been specified */
  197. if (all_targets == NULL)
  198. return ERROR_OK;
  199. target = all_targets;
  200. do_all_targets = 1;
  201. }
  202. do
  203. {
  204. p = &target->dbgmsg;
  205. c = *p;
  206. while (c)
  207. {
  208. struct debug_msg_receiver *next = c->next;
  209. if (c->cmd_ctx == cmd_ctx)
  210. {
  211. *p = next;
  212. free(c);
  213. if (*p == NULL)
  214. {
  215. /* disable callback */
  216. target->dbg_msg_enabled = 0;
  217. }
  218. return ERROR_OK;
  219. }
  220. else
  221. p = &(c->next);
  222. c = next;
  223. }
  224. target = target->next;
  225. } while (target && do_all_targets);
  226. return ERROR_OK;
  227. }
  228. COMMAND_HANDLER(handle_target_request_debugmsgs_command)
  229. {
  230. struct target *target = get_current_target(CMD_CTX);
  231. int receiving = 0;
  232. /* see if reciever is already registered */
  233. if (find_debug_msg_receiver(CMD_CTX, target) != NULL)
  234. receiving = 1;
  235. if (CMD_ARGC > 0)
  236. {
  237. if (!strcmp(CMD_ARGV[0], "enable") || !strcmp(CMD_ARGV[0], "charmsg"))
  238. {
  239. /* don't register if this command context is already receiving */
  240. if (!receiving)
  241. {
  242. receiving = 1;
  243. add_debug_msg_receiver(CMD_CTX, target);
  244. }
  245. charmsg_mode = !strcmp(CMD_ARGV[0], "charmsg");
  246. }
  247. else if (!strcmp(CMD_ARGV[0], "disable"))
  248. {
  249. /* no need to delete a receiver if none is registered */
  250. if (receiving)
  251. {
  252. receiving = 0;
  253. delete_debug_msg_receiver(CMD_CTX, target);
  254. }
  255. }
  256. else
  257. {
  258. command_print(CMD_CTX, "usage: target_request debugmsgs ['enable'|'disable'|'charmsg']");
  259. }
  260. }
  261. command_print(CMD_CTX, "receiving debug messages from current target %s",
  262. (receiving) ? (charmsg_mode?"charmsg":"enabled") : "disabled");
  263. return ERROR_OK;
  264. }
  265. static const struct command_registration target_req_exec_command_handlers[] = {
  266. {
  267. .name = "debugmsgs",
  268. .handler = handle_target_request_debugmsgs_command,
  269. .mode = COMMAND_EXEC,
  270. .help = "display and/or modify reception of debug messages from target",
  271. .usage = "['enable'|'charmsg'|'disable']",
  272. },
  273. COMMAND_REGISTRATION_DONE
  274. };
  275. static const struct command_registration target_req_command_handlers[] = {
  276. {
  277. .name = "target_request",
  278. .mode = COMMAND_ANY,
  279. .help = "target request command group",
  280. .chain = target_req_exec_command_handlers,
  281. },
  282. COMMAND_REGISTRATION_DONE
  283. };
  284. int target_request_register_commands(struct command_context *cmd_ctx)
  285. {
  286. return register_commands(cmd_ctx, NULL, target_req_command_handlers);
  287. }