]> git.sur5r.net Git - openocd/blob - src/target/breakpoints.c
- added support for the oocd-link (http://www.joernonline.de/dw/doku.php?id=en:projec...
[openocd] / src / target / breakpoints.c
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
24 #include <stdlib.h>
25
26 #include "binarybuffer.h"
27 #include "target.h"
28 #include "log.h"
29 #include "types.h"
30
31 #include "breakpoints.h"
32
33 char *breakpoint_type_strings[] =
34 {
35         "hardware",
36         "software"
37 };
38
39 char *watchpoint_rw_strings[] =
40 {
41         "read",
42         "write",
43         "access"
44 };
45
46 int breakpoint_add(target_t *target, u32 address, u32 length, enum breakpoint_type type)
47 {
48         breakpoint_t *breakpoint = target->breakpoints;
49         breakpoint_t **breakpoint_p = &target->breakpoints;
50         int retval;
51                 
52         while (breakpoint)
53         {
54                 if (breakpoint->address == address)
55                         return ERROR_OK;
56                 breakpoint_p = &breakpoint->next;
57                 breakpoint = breakpoint->next;
58         }
59                 
60         (*breakpoint_p) = malloc(sizeof(breakpoint_t));
61         (*breakpoint_p)->address = address;
62         (*breakpoint_p)->length = length;
63         (*breakpoint_p)->type = type;
64         (*breakpoint_p)->set = 0;
65         (*breakpoint_p)->orig_instr = malloc(CEIL(length, 8));
66         (*breakpoint_p)->next = NULL;
67         
68         if ((retval = target->type->add_breakpoint(target, *breakpoint_p)) != ERROR_OK)
69         {
70                 switch (retval)
71                 {
72                         case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
73                                 INFO("can't add %s breakpoint, resource not available", breakpoint_type_strings[(*breakpoint_p)->type]);
74                                 free (*breakpoint_p);
75                                 *breakpoint_p = NULL;
76                                 return retval;
77                                 break;
78                         case ERROR_TARGET_NOT_HALTED:
79                                 INFO("can't add breakpoint while target is running");
80                                 free (*breakpoint_p);
81                                 *breakpoint_p = NULL;
82                                 return retval;
83                                 break;
84                         default:
85                                 ERROR("unknown error");
86                                 exit(-1);
87                                 break;
88                 }
89         }
90         
91         DEBUG("added %s breakpoint at 0x%8.8x of length 0x%8.8x", 
92                 breakpoint_type_strings[(*breakpoint_p)->type],
93                 (*breakpoint_p)->address, (*breakpoint_p)->length);
94         
95         return ERROR_OK;
96 }
97
98 int breakpoint_remove(target_t *target, u32 address)
99 {
100         breakpoint_t *breakpoint = target->breakpoints;
101         breakpoint_t **breakpoint_p = &target->breakpoints;
102         int retval;
103         
104         while (breakpoint)
105         {
106                 if (breakpoint->address == address)
107                         break;
108                 breakpoint_p = &breakpoint->next;
109                 breakpoint = breakpoint->next;
110         }
111         
112         if (breakpoint)
113         {
114                 if ((retval = target->type->remove_breakpoint(target, breakpoint)) != ERROR_OK)
115                 {
116                         switch (retval)
117                         {
118                                 case ERROR_TARGET_NOT_HALTED:
119                                         INFO("can't remove breakpoint while target is running");
120                                         return retval;
121                                         break;
122                                 default:
123                                         ERROR("unknown error");
124                                         exit(-1);
125                                         break;
126                         }
127                 }
128                 (*breakpoint_p) = breakpoint->next;
129                 free(breakpoint->orig_instr);
130                 free(breakpoint);
131         }
132         else
133         {
134                 ERROR("no breakpoint at address 0x%8.8x found", address);
135         }
136         
137         return ERROR_OK;
138 }
139
140 breakpoint_t* breakpoint_find(target_t *target, u32 address)
141 {
142         breakpoint_t *breakpoint = target->breakpoints;
143         
144         while (breakpoint)
145         {
146                 if (breakpoint->address == address)
147                         return breakpoint;
148                 breakpoint = breakpoint->next;
149         }
150         
151         return NULL;
152 }
153
154 int watchpoint_add(target_t *target, u32 address, u32 length, enum watchpoint_rw rw, u32 value, u32 mask)
155 {
156         watchpoint_t *watchpoint = target->watchpoints;
157         watchpoint_t **watchpoint_p = &target->watchpoints;
158         int retval;
159                 
160         while (watchpoint)
161         {
162                 if (watchpoint->address == address)
163                         return ERROR_OK;
164                 watchpoint_p = &watchpoint->next;
165                 watchpoint = watchpoint->next;
166         }
167         
168         (*watchpoint_p) = malloc(sizeof(watchpoint_t));
169         (*watchpoint_p)->address = address;
170         (*watchpoint_p)->length = length;
171         (*watchpoint_p)->value = value;
172         (*watchpoint_p)->mask = mask;
173         (*watchpoint_p)->rw = rw;
174         (*watchpoint_p)->set = 0;
175         (*watchpoint_p)->next = NULL;
176                 
177         if ((retval = target->type->add_watchpoint(target, *watchpoint_p)) != ERROR_OK)
178         {
179                 switch (retval)
180                 {
181                         case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
182                                 INFO("can't add %s watchpoint, resource not available", watchpoint_rw_strings[(*watchpoint_p)->rw]);
183                                 free (*watchpoint_p);
184                                 *watchpoint_p = NULL;
185                                 return retval;
186                                 break;
187                         case ERROR_TARGET_NOT_HALTED:
188                                 INFO("can't add watchpoint while target is running");
189                                 free (*watchpoint_p);
190                                 *watchpoint_p = NULL;
191                                 return retval;
192                                 break;
193                         default:
194                                 ERROR("unknown error");
195                                 exit(-1);
196                                 break;
197                 }
198         }
199         
200         DEBUG("added %s watchpoint at 0x%8.8x of length 0x%8.8x",
201                 watchpoint_rw_strings[(*watchpoint_p)->rw],
202                 (*watchpoint_p)->address, (*watchpoint_p)->length);
203         
204         return ERROR_OK;
205 }
206
207 int watchpoint_remove(target_t *target, u32 address)
208 {
209         watchpoint_t *watchpoint = target->watchpoints;
210         watchpoint_t **watchpoint_p = &target->watchpoints;
211         int retval;
212         
213         while (watchpoint)
214         {
215                 if (watchpoint->address == address)
216                         break;
217                 watchpoint_p = &watchpoint->next;
218                 watchpoint = watchpoint->next;
219         }
220         
221         if (watchpoint)
222         {
223                 if ((retval = target->type->remove_watchpoint(target, watchpoint)) != ERROR_OK)
224                 {
225                         ERROR("BUG: can't remove watchpoint");
226                         exit(-1);
227                 }
228                 (*watchpoint_p) = watchpoint->next;
229                 free(watchpoint);
230         }
231         else
232         {
233                 ERROR("no watchpoint at address 0x%8.8x found", address);
234         }
235         
236         return ERROR_OK;
237 }