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.
 
 
 
 
 
 

222 lines
5.7 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. #ifdef HAVE_CONFIG_H
  21. #include "config.h"
  22. #endif
  23. #include <stdlib.h>
  24. #include "binarybuffer.h"
  25. #include "target.h"
  26. #include "log.h"
  27. #include "types.h"
  28. #include "breakpoints.h"
  29. char *breakpoint_type_strings[] =
  30. {
  31. "hardware",
  32. "software"
  33. };
  34. char *watchpoint_rw_strings[] =
  35. {
  36. "read",
  37. "write",
  38. "access"
  39. };
  40. int breakpoint_add(target_t *target, u32 address, u32 length, enum breakpoint_type type)
  41. {
  42. breakpoint_t *breakpoint = target->breakpoints;
  43. breakpoint_t **breakpoint_p = &target->breakpoints;
  44. int retval;
  45. while (breakpoint)
  46. {
  47. if (breakpoint->address == address)
  48. return ERROR_OK;
  49. breakpoint_p = &breakpoint->next;
  50. breakpoint = breakpoint->next;
  51. }
  52. if ((retval = target->type->add_breakpoint(target, address, length, type)) != ERROR_OK)
  53. {
  54. switch (retval)
  55. {
  56. case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
  57. INFO("can't add %s breakpoint, resource not available", breakpoint_type_strings[type]);
  58. return retval;
  59. break;
  60. case ERROR_TARGET_NOT_HALTED:
  61. INFO("can't add breakpoint while target is running");
  62. return retval;
  63. break;
  64. default:
  65. ERROR("unknown error");
  66. exit(-1);
  67. break;
  68. }
  69. }
  70. (*breakpoint_p) = malloc(sizeof(breakpoint_t));
  71. (*breakpoint_p)->address = address;
  72. (*breakpoint_p)->length = length;
  73. (*breakpoint_p)->type = type;
  74. (*breakpoint_p)->set = 0;
  75. (*breakpoint_p)->orig_instr = malloc(CEIL(length, 8));
  76. (*breakpoint_p)->next = NULL;
  77. DEBUG("added %s breakpoint at 0x%8.8x of length 0x%8.8x", breakpoint_type_strings[type], address, length);
  78. return ERROR_OK;
  79. }
  80. int breakpoint_remove(target_t *target, u32 address)
  81. {
  82. breakpoint_t *breakpoint = target->breakpoints;
  83. breakpoint_t **breakpoint_p = &target->breakpoints;
  84. int retval;
  85. while (breakpoint)
  86. {
  87. if (breakpoint->address == address)
  88. break;
  89. breakpoint_p = &breakpoint->next;
  90. breakpoint = breakpoint->next;
  91. }
  92. if (breakpoint)
  93. {
  94. if ((retval = target->type->remove_breakpoint(target, breakpoint)) != ERROR_OK)
  95. {
  96. switch (retval)
  97. {
  98. case ERROR_TARGET_NOT_HALTED:
  99. INFO("can't remove breakpoint while target is running");
  100. return retval;
  101. break;
  102. default:
  103. ERROR("unknown error");
  104. exit(-1);
  105. break;
  106. }
  107. }
  108. (*breakpoint_p) = breakpoint->next;
  109. free(breakpoint->orig_instr);
  110. free(breakpoint);
  111. }
  112. else
  113. {
  114. ERROR("no breakpoint at address 0x%8.8x found", address);
  115. }
  116. return ERROR_OK;
  117. }
  118. breakpoint_t* breakpoint_find(target_t *target, u32 address)
  119. {
  120. breakpoint_t *breakpoint = target->breakpoints;
  121. while (breakpoint)
  122. {
  123. if (breakpoint->address == address)
  124. return breakpoint;
  125. breakpoint = breakpoint->next;
  126. }
  127. return NULL;
  128. }
  129. int watchpoint_add(target_t *target, u32 address, u32 length, enum watchpoint_rw rw, u32 value, u32 mask)
  130. {
  131. watchpoint_t *watchpoint = target->watchpoints;
  132. watchpoint_t **watchpoint_p = &target->watchpoints;
  133. int retval;
  134. while (watchpoint)
  135. {
  136. if (watchpoint->address == address)
  137. return ERROR_OK;
  138. watchpoint_p = &watchpoint->next;
  139. watchpoint = watchpoint->next;
  140. }
  141. if ((retval = target->type->add_watchpoint(target, address, length, rw)) != ERROR_OK)
  142. {
  143. switch (retval)
  144. {
  145. case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
  146. INFO("can't add %s watchpoint, resource not available", watchpoint_rw_strings[rw]);
  147. return retval;
  148. break;
  149. default:
  150. ERROR("unknown error");
  151. exit(-1);
  152. break;
  153. }
  154. }
  155. (*watchpoint_p) = malloc(sizeof(watchpoint_t));
  156. (*watchpoint_p)->address = address;
  157. (*watchpoint_p)->length = length;
  158. (*watchpoint_p)->value = value;
  159. (*watchpoint_p)->mask = mask;
  160. (*watchpoint_p)->rw = rw;
  161. (*watchpoint_p)->set = 0;
  162. (*watchpoint_p)->next = NULL;
  163. DEBUG("added %s watchpoint at 0x%8.8x of length 0x%8.8x", watchpoint_rw_strings[rw], address, length);
  164. return ERROR_OK;
  165. }
  166. int watchpoint_remove(target_t *target, u32 address)
  167. {
  168. watchpoint_t *watchpoint = target->watchpoints;
  169. watchpoint_t **watchpoint_p = &target->watchpoints;
  170. int retval;
  171. while (watchpoint)
  172. {
  173. if (watchpoint->address == address)
  174. break;
  175. watchpoint_p = &watchpoint->next;
  176. watchpoint = watchpoint->next;
  177. }
  178. if (watchpoint)
  179. {
  180. if ((retval = target->type->remove_watchpoint(target, watchpoint)) != ERROR_OK)
  181. {
  182. ERROR("BUG: can't remove watchpoint");
  183. exit(-1);
  184. }
  185. (*watchpoint_p) = watchpoint->next;
  186. free(watchpoint);
  187. }
  188. else
  189. {
  190. ERROR("no watchpoint at address 0x%8.8x found", address);
  191. }
  192. return ERROR_OK;
  193. }