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.
 
 
 
 
 
 

271 lines
6.5 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2007 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. #ifdef HAVE_CONFIG_H
  21. #include "config.h"
  22. #endif
  23. #include "replacements.h"
  24. #include "log.h"
  25. #include "target.h"
  26. #include "target_request.h"
  27. #include "binarybuffer.h"
  28. #include "command.h"
  29. #include <stdlib.h>
  30. #include <string.h>
  31. command_t *target_request_cmd = NULL;
  32. int target_asciimsg(target_t *target, u32 length)
  33. {
  34. char *msg = malloc(CEIL(length + 1, 4) * 4);
  35. debug_msg_receiver_t *c = target->dbgmsg;
  36. target->type->target_request_data(target, CEIL(length, 4), (u8*)msg);
  37. msg[length] = 0;
  38. DEBUG("%s", msg);
  39. while (c)
  40. {
  41. command_print(c->cmd_ctx, "%s", msg);
  42. c = c->next;
  43. }
  44. return ERROR_OK;
  45. }
  46. int target_hexmsg(target_t *target, int size, u32 length)
  47. {
  48. if (size == 1)
  49. {
  50. u8 *data = malloc(CEIL(length * sizeof(u8), 4) * 4);
  51. target->type->target_request_data(target, CEIL(length * sizeof(u8), 4), (u8*)data);
  52. free(data);
  53. }
  54. else if (size == 2)
  55. {
  56. u16 *data = malloc(CEIL(length * sizeof(u16), 4) * 4);
  57. target->type->target_request_data(target, CEIL(length * sizeof(u16), 4), (u8*)data);
  58. free(data);
  59. }
  60. else if (size == 4)
  61. {
  62. u32 *data = malloc(CEIL(length * sizeof(u32), 4) * 4);
  63. target->type->target_request_data(target, CEIL(length * sizeof(u32), 4), (u8*)data);
  64. free(data);
  65. }
  66. else
  67. {
  68. ERROR("invalid debug message type");
  69. }
  70. return ERROR_OK;
  71. }
  72. /* handle requests from the target received by a target specific
  73. * side-band channel (e.g. ARM7/9 DCC)
  74. */
  75. int target_request(target_t *target, u32 request)
  76. {
  77. target_req_cmd_t target_req_cmd = request & 0xff;
  78. switch (target_req_cmd)
  79. {
  80. case TARGET_REQ_TRACEMSG:
  81. DEBUG("tracepoint: %i", (request & 0xffffff00) >> 8);
  82. break;
  83. case TARGET_REQ_DEBUGMSG:
  84. if (((request & 0xff00) >> 8) == 0)
  85. {
  86. target_asciimsg(target, (request & 0xffff0000) >> 16);
  87. }
  88. else
  89. {
  90. target_hexmsg(target, (request & 0xff00) >> 8, (request & 0xffff0000) >> 16);
  91. }
  92. break;
  93. /* case TARGET_REQ_SEMIHOSTING:
  94. * break;
  95. */
  96. default:
  97. ERROR("unknown target request: %2.2x", target_req_cmd);
  98. break;
  99. }
  100. return ERROR_OK;
  101. }
  102. int add_debug_msg_receiver(struct command_context_s *cmd_ctx, target_t *target)
  103. {
  104. debug_msg_receiver_t **p = &target->dbgmsg;
  105. if (target == NULL)
  106. return ERROR_INVALID_ARGUMENTS;
  107. /* see if there's already a list */
  108. if (*p)
  109. {
  110. /* find end of linked list */
  111. p = &target->dbgmsg;
  112. while ((*p)->next)
  113. p = &((*p)->next);
  114. p = &((*p)->next);
  115. }
  116. /* add new debug message receiver */
  117. (*p) = malloc(sizeof(debug_msg_receiver_t));
  118. (*p)->cmd_ctx = cmd_ctx;
  119. (*p)->next = NULL;
  120. return ERROR_OK;
  121. }
  122. debug_msg_receiver_t* find_debug_msg_receiver(struct command_context_s *cmd_ctx, target_t *target)
  123. {
  124. int all_targets = 0;
  125. debug_msg_receiver_t **p = &target->dbgmsg;
  126. /* if no target has been specified search all of them */
  127. if (target == NULL)
  128. {
  129. /* if no targets haven been specified */
  130. if (targets == NULL)
  131. return NULL;
  132. target = targets;
  133. all_targets = 1;
  134. }
  135. do
  136. {
  137. while (*p)
  138. {
  139. if ((*p)->cmd_ctx == cmd_ctx)
  140. {
  141. return *p;
  142. }
  143. p = &((*p)->next);
  144. }
  145. target = target->next;
  146. } while (target && all_targets);
  147. return NULL;
  148. }
  149. int delete_debug_msg_receiver(struct command_context_s *cmd_ctx, target_t *target)
  150. {
  151. debug_msg_receiver_t **p;
  152. debug_msg_receiver_t *c;
  153. int all_targets = 0;
  154. /* if no target has been specified search all of them */
  155. if (target == NULL)
  156. {
  157. /* if no targets haven been specified */
  158. if (targets == NULL)
  159. return ERROR_OK;
  160. target = targets;
  161. all_targets = 1;
  162. }
  163. do
  164. {
  165. while (c)
  166. {
  167. debug_msg_receiver_t *next = c->next;
  168. if (c->cmd_ctx == cmd_ctx)
  169. {
  170. *p = next;
  171. free(c);
  172. return ERROR_OK;
  173. }
  174. else
  175. p = &(c->next);
  176. c = next;
  177. }
  178. target = target->next;
  179. } while (target && all_targets);
  180. return ERROR_OK;
  181. }
  182. int handle_target_request_debugmsgs_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  183. {
  184. target_t *target = get_current_target(cmd_ctx);
  185. int receiving = 0;
  186. /* see if reciever is already registered */
  187. if (find_debug_msg_receiver(cmd_ctx, target) != NULL)
  188. receiving = 1;
  189. if (argc > 0)
  190. {
  191. if (!strcmp(args[0], "enable"))
  192. {
  193. /* don't register if this command context is already receiving */
  194. if (!receiving)
  195. {
  196. receiving = 1;
  197. add_debug_msg_receiver(cmd_ctx, target);
  198. }
  199. }
  200. else if (!strcmp(args[0], "disable"))
  201. {
  202. /* no need to delete a receiver if none is registered */
  203. if (receiving)
  204. {
  205. receiving = 0;
  206. delete_debug_msg_receiver(cmd_ctx, target);
  207. }
  208. }
  209. else
  210. {
  211. command_print(cmd_ctx, "usage: target_request debugmsgs ['enable'|'disable']");
  212. }
  213. }
  214. command_print(cmd_ctx, "receiving debug messages from current target %s",
  215. (receiving) ? "enabled" : "disabled");
  216. return ERROR_OK;
  217. }
  218. int target_request_register_commands(struct command_context_s *cmd_ctx)
  219. {
  220. target_request_cmd =
  221. register_command(cmd_ctx, NULL, "target_request", NULL, COMMAND_ANY, "target_request commands");
  222. register_command(cmd_ctx, target_request_cmd, "debugmsgs", handle_target_request_debugmsgs_command,
  223. COMMAND_EXEC, "enable/disable reception of debug messgages from target");
  224. return ERROR_OK;
  225. }