added yours sincerely for files where I feel that I've made non-trivial contributions.
[openocd.git] / src / target / target_request.c
1 /***************************************************************************
2 * Copyright (C) 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2007,2008 Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "replacements.h"
28 #include "log.h"
29 #include "target.h"
30 #include "target_request.h"
31 #include "binarybuffer.h"
32 #include "command.h"
33 #include "trace.h"
34
35 #include <stdlib.h>
36 #include <string.h>
37
38 command_t *target_request_cmd = NULL;
39
40 int target_asciimsg(target_t *target, u32 length)
41 {
42 char *msg = malloc(CEIL(length + 1, 4) * 4);
43 debug_msg_receiver_t *c = target->dbgmsg;
44
45 target->type->target_request_data(target, CEIL(length, 4), (u8*)msg);
46 msg[length] = 0;
47
48 LOG_DEBUG("%s", msg);
49
50 while (c)
51 {
52 command_print(c->cmd_ctx, "%s", msg);
53 c = c->next;
54 }
55
56 return ERROR_OK;
57 }
58
59 int target_charmsg(target_t *target, u8 msg)
60 {
61 LOG_USER_N("%c", msg);
62
63 return ERROR_OK;
64 }
65
66 int target_hexmsg(target_t *target, int size, u32 length)
67 {
68 u8 *data = malloc(CEIL(length * size, 4) * 4);
69 char line[128];
70 int line_len;
71 debug_msg_receiver_t *c = target->dbgmsg;
72 int i;
73
74 LOG_DEBUG("size: %i, length: %i", size, length);
75
76 target->type->target_request_data(target, CEIL(length * size, 4), (u8*)data);
77
78 line_len = 0;
79 for (i = 0; i < length; i++)
80 {
81 switch (size)
82 {
83 case 4:
84 line_len += snprintf(line + line_len, 128 - line_len, "%8.8x ", le_to_h_u32(data + (4*i)));
85 break;
86 case 2:
87 line_len += snprintf(line + line_len, 128 - line_len, "%4.4x ", le_to_h_u16(data + (2*i)));
88 break;
89 case 1:
90 line_len += snprintf(line + line_len, 128 - line_len, "%2.2x ", data[i]);
91 break;
92 }
93
94 if ((i%8 == 7) || (i == length - 1))
95 {
96 LOG_DEBUG("%s", line);
97
98 while (c)
99 {
100 command_print(c->cmd_ctx, "%s", line);
101 c = c->next;
102 }
103 c = target->dbgmsg;
104 line_len = 0;
105 }
106 }
107
108 free(data);
109
110 return ERROR_OK;
111 }
112
113 /* handle requests from the target received by a target specific
114 * side-band channel (e.g. ARM7/9 DCC)
115 */
116 int target_request(target_t *target, u32 request)
117 {
118 target_req_cmd_t target_req_cmd = request & 0xff;
119
120 switch (target_req_cmd)
121 {
122 case TARGET_REQ_TRACEMSG:
123 trace_point(target, (request & 0xffffff00) >> 8);
124 break;
125 case TARGET_REQ_DEBUGMSG:
126 if (((request & 0xff00) >> 8) == 0)
127 {
128 target_asciimsg(target, (request & 0xffff0000) >> 16);
129 }
130 else
131 {
132 target_hexmsg(target, (request & 0xff00) >> 8, (request & 0xffff0000) >> 16);
133 }
134 break;
135 case TARGET_REQ_DEBUGCHAR:
136 target_charmsg(target, (request & 0x00ff0000) >> 16);
137 break;
138 /* case TARGET_REQ_SEMIHOSTING:
139 * break;
140 */
141 default:
142 LOG_ERROR("unknown target request: %2.2x", target_req_cmd);
143 break;
144 }
145
146 return ERROR_OK;
147 }
148
149 int add_debug_msg_receiver(struct command_context_s *cmd_ctx, target_t *target)
150 {
151 debug_msg_receiver_t **p = &target->dbgmsg;
152
153 if (target == NULL)
154 return ERROR_INVALID_ARGUMENTS;
155
156 /* see if there's already a list */
157 if (*p)
158 {
159 /* find end of linked list */
160 p = &target->dbgmsg;
161 while ((*p)->next)
162 p = &((*p)->next);
163 p = &((*p)->next);
164 }
165
166 /* add new debug message receiver */
167 (*p) = malloc(sizeof(debug_msg_receiver_t));
168 (*p)->cmd_ctx = cmd_ctx;
169 (*p)->next = NULL;
170
171 /* enable callback */
172 target->dbg_msg_enabled = 1;
173
174 return ERROR_OK;
175 }
176
177 debug_msg_receiver_t* find_debug_msg_receiver(struct command_context_s *cmd_ctx, target_t *target)
178 {
179 int all_targets = 0;
180 debug_msg_receiver_t **p = &target->dbgmsg;
181
182 /* if no target has been specified search all of them */
183 if (target == NULL)
184 {
185 /* if no targets haven been specified */
186 if (targets == NULL)
187 return NULL;
188
189 target = targets;
190 all_targets = 1;
191 }
192
193 do
194 {
195 while (*p)
196 {
197 if ((*p)->cmd_ctx == cmd_ctx)
198 {
199 return *p;
200 }
201 p = &((*p)->next);
202 }
203
204 target = target->next;
205 } while (target && all_targets);
206
207 return NULL;
208 }
209
210 int delete_debug_msg_receiver(struct command_context_s *cmd_ctx, target_t *target)
211 {
212 debug_msg_receiver_t **p;
213 debug_msg_receiver_t *c;
214 int all_targets = 0;
215
216 /* if no target has been specified search all of them */
217 if (target == NULL)
218 {
219 /* if no targets haven been specified */
220 if (targets == NULL)
221 return ERROR_OK;
222
223 target = targets;
224 all_targets = 1;
225 }
226
227 do
228 {
229 p = &target->dbgmsg;
230 c = *p;
231 while (c)
232 {
233 debug_msg_receiver_t *next = c->next;
234 if (c->cmd_ctx == cmd_ctx)
235 {
236 *p = next;
237 free(c);
238 if (*p == NULL)
239 {
240 /* disable callback */
241 target->dbg_msg_enabled = 0;
242 }
243 return ERROR_OK;
244 }
245 else
246 p = &(c->next);
247 c = next;
248 }
249
250 target = target->next;
251 } while (target && all_targets);
252
253 return ERROR_OK;
254 }
255
256 int handle_target_request_debugmsgs_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
257 {
258 target_t *target = get_current_target(cmd_ctx);
259
260 int receiving = 0;
261
262 /* see if reciever is already registered */
263 if (find_debug_msg_receiver(cmd_ctx, target) != NULL)
264 receiving = 1;
265
266 if (argc > 0)
267 {
268 if (!strcmp(args[0], "enable"))
269 {
270 /* don't register if this command context is already receiving */
271 if (!receiving)
272 {
273 receiving = 1;
274 add_debug_msg_receiver(cmd_ctx, target);
275 }
276 }
277 else if (!strcmp(args[0], "disable"))
278 {
279 /* no need to delete a receiver if none is registered */
280 if (receiving)
281 {
282 receiving = 0;
283 delete_debug_msg_receiver(cmd_ctx, target);
284 }
285 }
286 else
287 {
288 command_print(cmd_ctx, "usage: target_request debugmsgs ['enable'|'disable']");
289 }
290 }
291
292 command_print(cmd_ctx, "receiving debug messages from current target %s",
293 (receiving) ? "enabled" : "disabled");
294
295 return ERROR_OK;
296 }
297
298 int target_request_register_commands(struct command_context_s *cmd_ctx)
299 {
300 target_request_cmd =
301 register_command(cmd_ctx, NULL, "target_request", NULL, COMMAND_ANY, "target_request commands");
302
303 register_command(cmd_ctx, target_request_cmd, "debugmsgs", handle_target_request_debugmsgs_command,
304 COMMAND_EXEC, "enable/disable reception of debug messgages from target");
305
306 return ERROR_OK;
307 }

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)