types: write memory now uses const
[openocd/jflash.git] / src / target / breakpoints.c
blob917dfc7897cf0aa4c6fc4873f7c4054572a7b211
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
24 #include "target.h"
25 #include <helper/log.h>
26 #include "breakpoints.h"
29 static char *breakpoint_type_strings[] =
31 "hardware",
32 "software"
35 static char *watchpoint_rw_strings[] =
37 "read",
38 "write",
39 "access"
42 // monotonic counter/id-number for breakpoints and watch points
43 static int bpwp_unique_id;
45 int breakpoint_add(struct target *target, uint32_t address, uint32_t length, enum breakpoint_type type)
47 struct breakpoint *breakpoint = target->breakpoints;
48 struct breakpoint **breakpoint_p = &target->breakpoints;
49 int retval;
50 int n;
52 n = 0;
53 while (breakpoint)
55 n++;
56 if (breakpoint->address == address) {
57 /* FIXME don't assume "same address" means "same
58 * breakpoint" ... check all the parameters before
59 * succeeding.
61 LOG_DEBUG("Duplicate Breakpoint address: 0x%08" PRIx32 " (BP %d)",
62 address, breakpoint->unique_id );
63 return ERROR_OK;
65 breakpoint_p = &breakpoint->next;
66 breakpoint = breakpoint->next;
69 (*breakpoint_p) = malloc(sizeof(struct breakpoint));
70 (*breakpoint_p)->address = address;
71 (*breakpoint_p)->length = length;
72 (*breakpoint_p)->type = type;
73 (*breakpoint_p)->set = 0;
74 (*breakpoint_p)->orig_instr = malloc(length);
75 (*breakpoint_p)->next = NULL;
76 (*breakpoint_p)->unique_id = bpwp_unique_id++;
78 retval = target_add_breakpoint(target, *breakpoint_p);
79 if (retval != ERROR_OK)
81 LOG_ERROR("could not add breakpoint");
82 free((*breakpoint_p)->orig_instr);
83 free(*breakpoint_p);
84 *breakpoint_p = NULL;
85 return retval;
88 LOG_DEBUG("added %s breakpoint at 0x%8.8" PRIx32 " of length 0x%8.8x, (BPID: %d)",
89 breakpoint_type_strings[(*breakpoint_p)->type],
90 (*breakpoint_p)->address, (*breakpoint_p)->length,
91 (*breakpoint_p)->unique_id );
93 return ERROR_OK;
96 /* free up a breakpoint */
97 static void breakpoint_free(struct target *target, struct breakpoint *breakpoint_to_remove)
99 struct breakpoint *breakpoint = target->breakpoints;
100 struct breakpoint **breakpoint_p = &target->breakpoints;
101 int retval;
103 while (breakpoint)
105 if (breakpoint == breakpoint_to_remove)
106 break;
107 breakpoint_p = &breakpoint->next;
108 breakpoint = breakpoint->next;
111 if (breakpoint == NULL)
112 return;
114 retval = target_remove_breakpoint(target, breakpoint);
116 LOG_DEBUG("free BPID: %d --> %d", breakpoint->unique_id, retval);
117 (*breakpoint_p) = breakpoint->next;
118 free(breakpoint->orig_instr);
119 free(breakpoint);
122 void breakpoint_remove(struct target *target, uint32_t address)
124 struct breakpoint *breakpoint = target->breakpoints;
125 struct breakpoint **breakpoint_p = &target->breakpoints;
127 while (breakpoint)
129 if (breakpoint->address == address)
130 break;
131 breakpoint_p = &breakpoint->next;
132 breakpoint = breakpoint->next;
135 if (breakpoint)
137 breakpoint_free(target, breakpoint);
139 else
141 LOG_ERROR("no breakpoint at address 0x%8.8" PRIx32 " found", address);
145 void breakpoint_clear_target(struct target *target)
147 struct breakpoint *breakpoint;
149 LOG_DEBUG("Delete all breakpoints for target: %s",
150 target_name(target));
151 while ((breakpoint = target->breakpoints) != NULL)
153 breakpoint_free(target, breakpoint);
157 struct breakpoint* breakpoint_find(struct target *target, uint32_t address)
159 struct breakpoint *breakpoint = target->breakpoints;
161 while (breakpoint)
163 if (breakpoint->address == address)
164 return breakpoint;
165 breakpoint = breakpoint->next;
168 return NULL;
171 int watchpoint_add(struct target *target, uint32_t address, uint32_t length,
172 enum watchpoint_rw rw, uint32_t value, uint32_t mask)
174 struct watchpoint *watchpoint = target->watchpoints;
175 struct watchpoint **watchpoint_p = &target->watchpoints;
176 int retval;
178 while (watchpoint)
180 if (watchpoint->address == address) {
181 if (watchpoint->length != length
182 || watchpoint->value != value
183 || watchpoint->mask != mask
184 || watchpoint->rw != rw) {
185 LOG_ERROR("address 0x%8.8" PRIx32
186 "already has watchpoint %d",
187 address, watchpoint->unique_id);
188 return ERROR_FAIL;
191 /* ignore duplicate watchpoint */
192 return ERROR_OK;
194 watchpoint_p = &watchpoint->next;
195 watchpoint = watchpoint->next;
198 (*watchpoint_p) = calloc(1, sizeof(struct watchpoint));
199 (*watchpoint_p)->address = address;
200 (*watchpoint_p)->length = length;
201 (*watchpoint_p)->value = value;
202 (*watchpoint_p)->mask = mask;
203 (*watchpoint_p)->rw = rw;
204 (*watchpoint_p)->unique_id = bpwp_unique_id++;
206 retval = target_add_watchpoint(target, *watchpoint_p);
207 if (retval != ERROR_OK)
209 LOG_ERROR("can't add %s watchpoint at 0x%8.8" PRIx32,
210 watchpoint_rw_strings[(*watchpoint_p)->rw],
211 address);
212 free (*watchpoint_p);
213 *watchpoint_p = NULL;
214 return retval;
217 LOG_DEBUG("added %s watchpoint at 0x%8.8" PRIx32
218 " of length 0x%8.8" PRIx32 " (WPID: %d)",
219 watchpoint_rw_strings[(*watchpoint_p)->rw],
220 (*watchpoint_p)->address,
221 (*watchpoint_p)->length,
222 (*watchpoint_p)->unique_id );
224 return ERROR_OK;
227 static void watchpoint_free(struct target *target, struct watchpoint *watchpoint_to_remove)
229 struct watchpoint *watchpoint = target->watchpoints;
230 struct watchpoint **watchpoint_p = &target->watchpoints;
231 int retval;
233 while (watchpoint)
235 if (watchpoint == watchpoint_to_remove)
236 break;
237 watchpoint_p = &watchpoint->next;
238 watchpoint = watchpoint->next;
241 if (watchpoint == NULL)
242 return;
243 retval = target_remove_watchpoint(target, watchpoint);
244 LOG_DEBUG("free WPID: %d --> %d", watchpoint->unique_id, retval);
245 (*watchpoint_p) = watchpoint->next;
246 free(watchpoint);
249 void watchpoint_remove(struct target *target, uint32_t address)
251 struct watchpoint *watchpoint = target->watchpoints;
252 struct watchpoint **watchpoint_p = &target->watchpoints;
254 while (watchpoint)
256 if (watchpoint->address == address)
257 break;
258 watchpoint_p = &watchpoint->next;
259 watchpoint = watchpoint->next;
262 if (watchpoint)
264 watchpoint_free(target, watchpoint);
266 else
268 LOG_ERROR("no watchpoint at address 0x%8.8" PRIx32 " found", address);
272 void watchpoint_clear_target(struct target *target)
274 struct watchpoint *watchpoint;
276 LOG_DEBUG("Delete all watchpoints for target: %s",
277 target_name(target));
278 while ((watchpoint = target->watchpoints) != NULL)
280 watchpoint_free(target, watchpoint);