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