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