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.
 
 
 
 
 
 

327 lines
8.2 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 int charmsg_mode = 0;
  36. static int target_asciimsg(struct target *target, uint32_t length)
  37. {
  38. char *msg = malloc(DIV_ROUND_UP(length + 1, 4) * 4);
  39. struct debug_msg_receiver *c = target->dbgmsg;
  40. target->type->target_request_data(target, DIV_ROUND_UP(length, 4), (uint8_t*)msg);
  41. msg[length] = 0;
  42. LOG_DEBUG("%s", msg);
  43. while (c)
  44. {
  45. command_print(c->cmd_ctx, "%s", msg);
  46. c = c->next;
  47. }
  48. return ERROR_OK;
  49. }
  50. static int target_charmsg(struct target *target, uint8_t msg)
  51. {
  52. LOG_USER_N("%c", msg);
  53. return ERROR_OK;
  54. }
  55. static int target_hexmsg(struct target *target, int size, uint32_t length)
  56. {
  57. uint8_t *data = malloc(DIV_ROUND_UP(length * size, 4) * 4);
  58. char line[128];
  59. int line_len;
  60. struct debug_msg_receiver *c = target->dbgmsg;
  61. uint32_t i;
  62. LOG_DEBUG("size: %i, length: %i", (int)size, (int)length);
  63. target->type->target_request_data(target, DIV_ROUND_UP(length * size, 4), (uint8_t*)data);
  64. line_len = 0;
  65. for (i = 0; i < length; i++)
  66. {
  67. switch (size)
  68. {
  69. case 4:
  70. line_len += snprintf(line + line_len, 128 - line_len, "%8.8" PRIx32 " ", le_to_h_u32(data + (4*i)));
  71. break;
  72. case 2:
  73. line_len += snprintf(line + line_len, 128 - line_len, "%4.4x ", le_to_h_u16(data + (2*i)));
  74. break;
  75. case 1:
  76. line_len += snprintf(line + line_len, 128 - line_len, "%2.2x ", data[i]);
  77. break;
  78. }
  79. if ((i%8 == 7) || (i == length - 1))
  80. {
  81. LOG_DEBUG("%s", line);
  82. while (c)
  83. {
  84. command_print(c->cmd_ctx, "%s", line);
  85. c = c->next;
  86. }
  87. c = target->dbgmsg;
  88. line_len = 0;
  89. }
  90. }
  91. free(data);
  92. return ERROR_OK;
  93. }
  94. /* handle requests from the target received by a target specific
  95. * side-band channel (e.g. ARM7/9 DCC)
  96. */
  97. int target_request(struct target *target, uint32_t request)
  98. {
  99. target_req_cmd_t target_req_cmd = request & 0xff;
  100. if (charmsg_mode) {
  101. target_charmsg(target, target_req_cmd);
  102. return ERROR_OK;
  103. }
  104. switch (target_req_cmd)
  105. {
  106. case TARGET_REQ_TRACEMSG:
  107. trace_point(target, (request & 0xffffff00) >> 8);
  108. break;
  109. case TARGET_REQ_DEBUGMSG:
  110. if (((request & 0xff00) >> 8) == 0)
  111. {
  112. target_asciimsg(target, (request & 0xffff0000) >> 16);
  113. }
  114. else
  115. {
  116. target_hexmsg(target, (request & 0xff00) >> 8, (request & 0xffff0000) >> 16);
  117. }
  118. break;
  119. case TARGET_REQ_DEBUGCHAR:
  120. target_charmsg(target, (request & 0x00ff0000) >> 16);
  121. break;
  122. /* case TARGET_REQ_SEMIHOSTING:
  123. * break;
  124. */
  125. default:
  126. LOG_ERROR("unknown target request: %2.2x", target_req_cmd);
  127. break;
  128. }
  129. return ERROR_OK;
  130. }
  131. static int add_debug_msg_receiver(struct command_context *cmd_ctx, struct target *target)
  132. {
  133. struct debug_msg_receiver **p = &target->dbgmsg;
  134. if (target == NULL)
  135. return ERROR_INVALID_ARGUMENTS;
  136. /* see if there's already a list */
  137. if (*p)
  138. {
  139. /* find end of linked list */
  140. p = &target->dbgmsg;
  141. while ((*p)->next)
  142. p = &((*p)->next);
  143. p = &((*p)->next);
  144. }
  145. /* add new debug message receiver */
  146. (*p) = malloc(sizeof(struct debug_msg_receiver));
  147. (*p)->cmd_ctx = cmd_ctx;
  148. (*p)->next = NULL;
  149. /* enable callback */
  150. target->dbg_msg_enabled = 1;
  151. return ERROR_OK;
  152. }
  153. static struct debug_msg_receiver* find_debug_msg_receiver(struct command_context *cmd_ctx, struct target *target)
  154. {
  155. int do_all_targets = 0;
  156. struct debug_msg_receiver **p = &target->dbgmsg;
  157. /* if no target has been specified search all of them */
  158. if (target == NULL)
  159. {
  160. /* if no targets haven been specified */
  161. if (all_targets == NULL)
  162. return NULL;
  163. target = all_targets;
  164. do_all_targets = 1;
  165. }
  166. do
  167. {
  168. while (*p)
  169. {
  170. if ((*p)->cmd_ctx == cmd_ctx)
  171. {
  172. return *p;
  173. }
  174. p = &((*p)->next);
  175. }
  176. target = target->next;
  177. } while (target && do_all_targets);
  178. return NULL;
  179. }
  180. int delete_debug_msg_receiver(struct command_context *cmd_ctx, struct target *target)
  181. {
  182. struct debug_msg_receiver **p;
  183. struct debug_msg_receiver *c;
  184. int do_all_targets = 0;
  185. /* if no target has been specified search all of them */
  186. if (target == NULL)
  187. {
  188. /* if no targets haven been specified */
  189. if (all_targets == NULL)
  190. return ERROR_OK;
  191. target = all_targets;
  192. do_all_targets = 1;
  193. }
  194. do
  195. {
  196. p = &target->dbgmsg;
  197. c = *p;
  198. while (c)
  199. {
  200. struct debug_msg_receiver *next = c->next;
  201. if (c->cmd_ctx == cmd_ctx)
  202. {
  203. *p = next;
  204. free(c);
  205. if (*p == NULL)
  206. {
  207. /* disable callback */
  208. target->dbg_msg_enabled = 0;
  209. }
  210. return ERROR_OK;
  211. }
  212. else
  213. p = &(c->next);
  214. c = next;
  215. }
  216. target = target->next;
  217. } while (target && do_all_targets);
  218. return ERROR_OK;
  219. }
  220. COMMAND_HANDLER(handle_target_request_debugmsgs_command)
  221. {
  222. struct target *target = get_current_target(CMD_CTX);
  223. int receiving = 0;
  224. /* see if reciever is already registered */
  225. if (find_debug_msg_receiver(CMD_CTX, target) != NULL)
  226. receiving = 1;
  227. if (CMD_ARGC > 0)
  228. {
  229. if (!strcmp(CMD_ARGV[0], "enable") || !strcmp(CMD_ARGV[0], "charmsg"))
  230. {
  231. /* don't register if this command context is already receiving */
  232. if (!receiving)
  233. {
  234. receiving = 1;
  235. add_debug_msg_receiver(CMD_CTX, target);
  236. }
  237. charmsg_mode = !strcmp(CMD_ARGV[0], "charmsg");
  238. }
  239. else if (!strcmp(CMD_ARGV[0], "disable"))
  240. {
  241. /* no need to delete a receiver if none is registered */
  242. if (receiving)
  243. {
  244. receiving = 0;
  245. delete_debug_msg_receiver(CMD_CTX, target);
  246. }
  247. }
  248. else
  249. {
  250. command_print(CMD_CTX, "usage: target_request debugmsgs ['enable'|'disable'|'charmsg']");
  251. }
  252. }
  253. command_print(CMD_CTX, "receiving debug messages from current target %s",
  254. (receiving) ? (charmsg_mode?"charmsg":"enabled") : "disabled");
  255. return ERROR_OK;
  256. }
  257. static const struct command_registration target_req_exec_command_handlers[] = {
  258. {
  259. .name = "debugmsgs",
  260. .handler = handle_target_request_debugmsgs_command,
  261. .mode = COMMAND_EXEC,
  262. .help = "display and/or modify reception of debug messages from target",
  263. .usage = "['enable'|'charmsg'|'disable']",
  264. },
  265. COMMAND_REGISTRATION_DONE
  266. };
  267. static const struct command_registration target_req_command_handlers[] = {
  268. {
  269. .name = "target_request",
  270. .mode = COMMAND_ANY,
  271. .help = "target request command group",
  272. .chain = target_req_exec_command_handlers,
  273. },
  274. COMMAND_REGISTRATION_DONE
  275. };
  276. int target_request_register_commands(struct command_context *cmd_ctx)
  277. {
  278. return register_commands(cmd_ctx, NULL, target_req_command_handlers);
  279. }