e84090205bc603f2bd6f290a1dbba381eee83f33
[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
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 }

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)