]> git.sur5r.net Git - openocd/blob - src/target/breakpoints.c
- rename log functions to stop conflicts under win32 (wingdi)
[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(length);
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                                 LOG_INFO("can't add %s breakpoint, resource not available", breakpoint_type_strings[(*breakpoint_p)->type]);
74                                 free((*breakpoint_p)->orig_instr);
75                                 free(*breakpoint_p);
76                                 *breakpoint_p = NULL;
77                                 return retval;
78                                 break;
79                         case ERROR_TARGET_NOT_HALTED:
80                                 LOG_INFO("can't add breakpoint while target is running");
81                                 free((*breakpoint_p)->orig_instr);
82                                 free(*breakpoint_p);
83                                 *breakpoint_p = NULL;
84                                 return retval;
85                                 break;
86                         default:
87                                 LOG_ERROR("unknown error");
88                                 exit(-1);
89                                 break;
90                 }
91         }
92         
93         LOG_DEBUG("added %s breakpoint at 0x%8.8x of length 0x%8.8x", 
94                 breakpoint_type_strings[(*breakpoint_p)->type],
95                 (*breakpoint_p)->address, (*breakpoint_p)->length);
96         
97         return ERROR_OK;
98 }
99
100 int breakpoint_remove(target_t *target, u32 address)
101 {
102         breakpoint_t *breakpoint = target->breakpoints;
103         breakpoint_t **breakpoint_p = &target->breakpoints;
104         int retval;
105         
106         while (breakpoint)
107         {
108                 if (breakpoint->address == address)
109                         break;
110                 breakpoint_p = &breakpoint->next;
111                 breakpoint = breakpoint->next;
112         }
113         
114         if (breakpoint)
115         {
116                 if ((retval = target->type->remove_breakpoint(target, breakpoint)) != ERROR_OK)
117                 {
118                         switch (retval)
119                         {
120                                 case ERROR_TARGET_NOT_HALTED:
121                                         LOG_INFO("can't remove breakpoint while target is running");
122                                         return retval;
123                                         break;
124                                 default:
125                                         LOG_ERROR("unknown error");
126                                         exit(-1);
127                                         break;
128                         }
129                 }
130                 (*breakpoint_p) = breakpoint->next;
131                 free(breakpoint->orig_instr);
132                 free(breakpoint);
133         }
134         else
135         {
136                 LOG_ERROR("no breakpoint at address 0x%8.8x found", address);
137         }
138         
139         return ERROR_OK;
140 }
141
142 breakpoint_t* breakpoint_find(target_t *target, u32 address)
143 {
144         breakpoint_t *breakpoint = target->breakpoints;
145         
146         while (breakpoint)
147         {
148                 if (breakpoint->address == address)
149                         return breakpoint;
150                 breakpoint = breakpoint->next;
151         }
152         
153         return NULL;
154 }
155
156 int watchpoint_add(target_t *target, u32 address, u32 length, enum watchpoint_rw rw, u32 value, u32 mask)
157 {
158         watchpoint_t *watchpoint = target->watchpoints;
159         watchpoint_t **watchpoint_p = &target->watchpoints;
160         int retval;
161                 
162         while (watchpoint)
163         {
164                 if (watchpoint->address == address)
165                         return ERROR_OK;
166                 watchpoint_p = &watchpoint->next;
167                 watchpoint = watchpoint->next;
168         }
169         
170         (*watchpoint_p) = malloc(sizeof(watchpoint_t));
171         (*watchpoint_p)->address = address;
172         (*watchpoint_p)->length = length;
173         (*watchpoint_p)->value = value;
174         (*watchpoint_p)->mask = mask;
175         (*watchpoint_p)->rw = rw;
176         (*watchpoint_p)->set = 0;
177         (*watchpoint_p)->next = NULL;
178                 
179         if ((retval = target->type->add_watchpoint(target, *watchpoint_p)) != ERROR_OK)
180         {
181                 switch (retval)
182                 {
183                         case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
184                                 LOG_INFO("can't add %s watchpoint, resource not available", watchpoint_rw_strings[(*watchpoint_p)->rw]);
185                                 free (*watchpoint_p);
186                                 *watchpoint_p = NULL;
187                                 return retval;
188                                 break;
189                         case ERROR_TARGET_NOT_HALTED:
190                                 LOG_INFO("can't add watchpoint while target is running");
191                                 free (*watchpoint_p);
192                                 *watchpoint_p = NULL;
193                                 return retval;
194                                 break;
195                         default:
196                                 LOG_ERROR("unknown error");
197                                 exit(-1);
198                                 break;
199                 }
200         }
201         
202         LOG_DEBUG("added %s watchpoint at 0x%8.8x of length 0x%8.8x",
203                 watchpoint_rw_strings[(*watchpoint_p)->rw],
204                 (*watchpoint_p)->address, (*watchpoint_p)->length);
205         
206         return ERROR_OK;
207 }
208
209 int watchpoint_remove(target_t *target, u32 address)
210 {
211         watchpoint_t *watchpoint = target->watchpoints;
212         watchpoint_t **watchpoint_p = &target->watchpoints;
213         int retval;
214         
215         while (watchpoint)
216         {
217                 if (watchpoint->address == address)
218                         break;
219                 watchpoint_p = &watchpoint->next;
220                 watchpoint = watchpoint->next;
221         }
222         
223         if (watchpoint)
224         {
225                 if ((retval = target->type->remove_watchpoint(target, watchpoint)) != ERROR_OK)
226                 {
227                         switch (retval)
228                         {
229                                 case ERROR_TARGET_NOT_HALTED:
230                                         LOG_INFO("can't remove watchpoint while target is running");
231                                         return retval;
232                                         break;
233                                 default:
234                                         LOG_ERROR("unknown error");
235                                         exit(-1);
236                                         break;
237                         }
238                 }
239                 (*watchpoint_p) = watchpoint->next;
240                 free(watchpoint);
241         }
242         else
243         {
244                 LOG_ERROR("no watchpoint at address 0x%8.8x found", address);
245         }
246         
247         return ERROR_OK;
248 }