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

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)