Add target_write_memory wrapper:
[openocd.git] / src / target / target.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2007,2008 Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
7 * *
8 * Copyright (C) 2008, Duane Ellis *
9 * openocd@duaneeellis.com *
10 * *
11 * Copyright (C) 2008 by Spencer Oliver *
12 * spen@spen-soft.co.uk *
13 * *
14 * Copyright (C) 2008 by Rick Altherr *
15 * kc8apf@kc8apf.net> *
16 * *
17 * This program is free software; you can redistribute it and/or modify *
18 * it under the terms of the GNU General Public License as published by *
19 * the Free Software Foundation; either version 2 of the License, or *
20 * (at your option) any later version. *
21 * *
22 * This program is distributed in the hope that it will be useful, *
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
25 * GNU General Public License for more details. *
26 * *
27 * You should have received a copy of the GNU General Public License *
28 * along with this program; if not, write to the *
29 * Free Software Foundation, Inc., *
30 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
31 ***************************************************************************/
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include "target.h"
37 #include "target_request.h"
38 #include "time_support.h"
39 #include "register.h"
40 #include "trace.h"
41 #include "image.h"
42 #include "jtag.h"
43
44 #include <inttypes.h>
45
46
47 static int handle_targets_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
48
49 static int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
50 static int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
51 static int handle_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
52 static int handle_wait_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
53 static int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
54 static int handle_soft_reset_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
55 static int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
56 static int handle_step_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
57 static int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
58 static int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
59 static int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
60 static int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
61 static int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
62 static int handle_test_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
63 static int handle_bp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
64 static int handle_rbp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
65 static int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
66 static int handle_rwp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
67 static int handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc);
68 static int handle_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
69 static int handle_fast_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
70 static int handle_fast_load_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
71
72 static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
73 static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
74 static int jim_target( Jim_Interp *interp, int argc, Jim_Obj *const *argv);
75
76 static int target_array2mem(Jim_Interp *interp, target_t *target, int argc, Jim_Obj *const *argv);
77 static int target_mem2array(Jim_Interp *interp, target_t *target, int argc, Jim_Obj *const *argv);
78
79 /* targets */
80 extern target_type_t arm7tdmi_target;
81 extern target_type_t arm720t_target;
82 extern target_type_t arm9tdmi_target;
83 extern target_type_t arm920t_target;
84 extern target_type_t arm966e_target;
85 extern target_type_t arm926ejs_target;
86 extern target_type_t feroceon_target;
87 extern target_type_t xscale_target;
88 extern target_type_t cortexm3_target;
89 extern target_type_t cortexa8_target;
90 extern target_type_t arm11_target;
91 extern target_type_t mips_m4k_target;
92 extern target_type_t avr_target;
93
94 target_type_t *target_types[] =
95 {
96 &arm7tdmi_target,
97 &arm9tdmi_target,
98 &arm920t_target,
99 &arm720t_target,
100 &arm966e_target,
101 &arm926ejs_target,
102 &feroceon_target,
103 &xscale_target,
104 &cortexm3_target,
105 &cortexa8_target,
106 &arm11_target,
107 &mips_m4k_target,
108 &avr_target,
109 NULL,
110 };
111
112 target_t *all_targets = NULL;
113 target_event_callback_t *target_event_callbacks = NULL;
114 target_timer_callback_t *target_timer_callbacks = NULL;
115
116 const Jim_Nvp nvp_assert[] = {
117 { .name = "assert", NVP_ASSERT },
118 { .name = "deassert", NVP_DEASSERT },
119 { .name = "T", NVP_ASSERT },
120 { .name = "F", NVP_DEASSERT },
121 { .name = "t", NVP_ASSERT },
122 { .name = "f", NVP_DEASSERT },
123 { .name = NULL, .value = -1 }
124 };
125
126 const Jim_Nvp nvp_error_target[] = {
127 { .value = ERROR_TARGET_INVALID, .name = "err-invalid" },
128 { .value = ERROR_TARGET_INIT_FAILED, .name = "err-init-failed" },
129 { .value = ERROR_TARGET_TIMEOUT, .name = "err-timeout" },
130 { .value = ERROR_TARGET_NOT_HALTED, .name = "err-not-halted" },
131 { .value = ERROR_TARGET_FAILURE, .name = "err-failure" },
132 { .value = ERROR_TARGET_UNALIGNED_ACCESS , .name = "err-unaligned-access" },
133 { .value = ERROR_TARGET_DATA_ABORT , .name = "err-data-abort" },
134 { .value = ERROR_TARGET_RESOURCE_NOT_AVAILABLE , .name = "err-resource-not-available" },
135 { .value = ERROR_TARGET_TRANSLATION_FAULT , .name = "err-translation-fault" },
136 { .value = ERROR_TARGET_NOT_RUNNING, .name = "err-not-running" },
137 { .value = ERROR_TARGET_NOT_EXAMINED, .name = "err-not-examined" },
138 { .value = -1, .name = NULL }
139 };
140
141 const char *target_strerror_safe( int err )
142 {
143 const Jim_Nvp *n;
144
145 n = Jim_Nvp_value2name_simple( nvp_error_target, err );
146 if( n->name == NULL ){
147 return "unknown";
148 } else {
149 return n->name;
150 }
151 }
152
153 static const Jim_Nvp nvp_target_event[] = {
154 { .value = TARGET_EVENT_OLD_gdb_program_config , .name = "old-gdb_program_config" },
155 { .value = TARGET_EVENT_OLD_pre_resume , .name = "old-pre_resume" },
156
157 { .value = TARGET_EVENT_EARLY_HALTED, .name = "early-halted" },
158 { .value = TARGET_EVENT_HALTED, .name = "halted" },
159 { .value = TARGET_EVENT_RESUMED, .name = "resumed" },
160 { .value = TARGET_EVENT_RESUME_START, .name = "resume-start" },
161 { .value = TARGET_EVENT_RESUME_END, .name = "resume-end" },
162
163 { .name = "gdb-start", .value = TARGET_EVENT_GDB_START },
164 { .name = "gdb-end", .value = TARGET_EVENT_GDB_END },
165
166 /* historical name */
167
168 { .value = TARGET_EVENT_RESET_START, .name = "reset-start" },
169
170 { .value = TARGET_EVENT_RESET_ASSERT_PRE, .name = "reset-assert-pre" },
171 { .value = TARGET_EVENT_RESET_ASSERT_POST, .name = "reset-assert-post" },
172 { .value = TARGET_EVENT_RESET_DEASSERT_PRE, .name = "reset-deassert-pre" },
173 { .value = TARGET_EVENT_RESET_DEASSERT_POST, .name = "reset-deassert-post" },
174 { .value = TARGET_EVENT_RESET_HALT_PRE, .name = "reset-halt-pre" },
175 { .value = TARGET_EVENT_RESET_HALT_POST, .name = "reset-halt-post" },
176 { .value = TARGET_EVENT_RESET_WAIT_PRE, .name = "reset-wait-pre" },
177 { .value = TARGET_EVENT_RESET_WAIT_POST, .name = "reset-wait-post" },
178 { .value = TARGET_EVENT_RESET_INIT , .name = "reset-init" },
179 { .value = TARGET_EVENT_RESET_END, .name = "reset-end" },
180
181 { .value = TARGET_EVENT_EXAMINE_START, .name = "examine-start" },
182 { .value = TARGET_EVENT_EXAMINE_END, .name = "examine-end" },
183
184 { .value = TARGET_EVENT_DEBUG_HALTED, .name = "debug-halted" },
185 { .value = TARGET_EVENT_DEBUG_RESUMED, .name = "debug-resumed" },
186
187 { .value = TARGET_EVENT_GDB_ATTACH, .name = "gdb-attach" },
188 { .value = TARGET_EVENT_GDB_DETACH, .name = "gdb-detach" },
189
190 { .value = TARGET_EVENT_GDB_FLASH_WRITE_START, .name = "gdb-flash-write-start" },
191 { .value = TARGET_EVENT_GDB_FLASH_WRITE_END , .name = "gdb-flash-write-end" },
192
193 { .value = TARGET_EVENT_GDB_FLASH_ERASE_START, .name = "gdb-flash-erase-start" },
194 { .value = TARGET_EVENT_GDB_FLASH_ERASE_END , .name = "gdb-flash-erase-end" },
195
196 { .value = TARGET_EVENT_RESUME_START, .name = "resume-start" },
197 { .value = TARGET_EVENT_RESUMED , .name = "resume-ok" },
198 { .value = TARGET_EVENT_RESUME_END , .name = "resume-end" },
199
200 { .name = NULL, .value = -1 }
201 };
202
203 const Jim_Nvp nvp_target_state[] = {
204 { .name = "unknown", .value = TARGET_UNKNOWN },
205 { .name = "running", .value = TARGET_RUNNING },
206 { .name = "halted", .value = TARGET_HALTED },
207 { .name = "reset", .value = TARGET_RESET },
208 { .name = "debug-running", .value = TARGET_DEBUG_RUNNING },
209 { .name = NULL, .value = -1 },
210 };
211
212 const Jim_Nvp nvp_target_debug_reason [] = {
213 { .name = "debug-request" , .value = DBG_REASON_DBGRQ },
214 { .name = "breakpoint" , .value = DBG_REASON_BREAKPOINT },
215 { .name = "watchpoint" , .value = DBG_REASON_WATCHPOINT },
216 { .name = "watchpoint-and-breakpoint", .value = DBG_REASON_WPTANDBKPT },
217 { .name = "single-step" , .value = DBG_REASON_SINGLESTEP },
218 { .name = "target-not-halted" , .value = DBG_REASON_NOTHALTED },
219 { .name = "undefined" , .value = DBG_REASON_UNDEFINED },
220 { .name = NULL, .value = -1 },
221 };
222
223 const Jim_Nvp nvp_target_endian[] = {
224 { .name = "big", .value = TARGET_BIG_ENDIAN },
225 { .name = "little", .value = TARGET_LITTLE_ENDIAN },
226 { .name = "be", .value = TARGET_BIG_ENDIAN },
227 { .name = "le", .value = TARGET_LITTLE_ENDIAN },
228 { .name = NULL, .value = -1 },
229 };
230
231 const Jim_Nvp nvp_reset_modes[] = {
232 { .name = "unknown", .value = RESET_UNKNOWN },
233 { .name = "run" , .value = RESET_RUN },
234 { .name = "halt" , .value = RESET_HALT },
235 { .name = "init" , .value = RESET_INIT },
236 { .name = NULL , .value = -1 },
237 };
238
239 static int max_target_number(void)
240 {
241 target_t *t;
242 int x;
243
244 x = -1;
245 t = all_targets;
246 while( t ){
247 if( x < t->target_number ){
248 x = (t->target_number)+1;
249 }
250 t = t->next;
251 }
252 return x;
253 }
254
255 /* determine the number of the new target */
256 static int new_target_number(void)
257 {
258 target_t *t;
259 int x;
260
261 /* number is 0 based */
262 x = -1;
263 t = all_targets;
264 while(t){
265 if( x < t->target_number ){
266 x = t->target_number;
267 }
268 t = t->next;
269 }
270 return x+1;
271 }
272
273 static int target_continous_poll = 1;
274
275 /* read a u32 from a buffer in target memory endianness */
276 u32 target_buffer_get_u32(target_t *target, const u8 *buffer)
277 {
278 if (target->endianness == TARGET_LITTLE_ENDIAN)
279 return le_to_h_u32(buffer);
280 else
281 return be_to_h_u32(buffer);
282 }
283
284 /* read a u16 from a buffer in target memory endianness */
285 u16 target_buffer_get_u16(target_t *target, const u8 *buffer)
286 {
287 if (target->endianness == TARGET_LITTLE_ENDIAN)
288 return le_to_h_u16(buffer);
289 else
290 return be_to_h_u16(buffer);
291 }
292
293 /* read a u8 from a buffer in target memory endianness */
294 u8 target_buffer_get_u8(target_t *target, const u8 *buffer)
295 {
296 return *buffer & 0x0ff;
297 }
298
299 /* write a u32 to a buffer in target memory endianness */
300 void target_buffer_set_u32(target_t *target, u8 *buffer, u32 value)
301 {
302 if (target->endianness == TARGET_LITTLE_ENDIAN)
303 h_u32_to_le(buffer, value);
304 else
305 h_u32_to_be(buffer, value);
306 }
307
308 /* write a u16 to a buffer in target memory endianness */
309 void target_buffer_set_u16(target_t *target, u8 *buffer, u16 value)
310 {
311 if (target->endianness == TARGET_LITTLE_ENDIAN)
312 h_u16_to_le(buffer, value);
313 else
314 h_u16_to_be(buffer, value);
315 }
316
317 /* write a u8 to a buffer in target memory endianness */
318 void target_buffer_set_u8(target_t *target, u8 *buffer, u8 value)
319 {
320 *buffer = value;
321 }
322
323 /* return a pointer to a configured target; id is name or number */
324 target_t *get_target(const char *id)
325 {
326 target_t *target;
327 char *endptr;
328 int num;
329
330 /* try as tcltarget name */
331 for (target = all_targets; target; target = target->next) {
332 if (target->cmd_name == NULL)
333 continue;
334 if (strcmp(id, target->cmd_name) == 0)
335 return target;
336 }
337
338 /* no match, try as number */
339 num = strtoul(id, &endptr, 0);
340 if (*endptr != 0)
341 return NULL;
342
343 for (target = all_targets; target; target = target->next) {
344 if (target->target_number == num)
345 return target;
346 }
347
348 return NULL;
349 }
350
351 /* returns a pointer to the n-th configured target */
352 static target_t *get_target_by_num(int num)
353 {
354 target_t *target = all_targets;
355
356 while (target){
357 if( target->target_number == num ){
358 return target;
359 }
360 target = target->next;
361 }
362
363 return NULL;
364 }
365
366 int get_num_by_target(target_t *query_target)
367 {
368 return query_target->target_number;
369 }
370
371 target_t* get_current_target(command_context_t *cmd_ctx)
372 {
373 target_t *target = get_target_by_num(cmd_ctx->current_target);
374
375 if (target == NULL)
376 {
377 LOG_ERROR("BUG: current_target out of bounds");
378 exit(-1);
379 }
380
381 return target;
382 }
383
384 int target_poll(struct target_s *target)
385 {
386 /* We can't poll until after examine */
387 if (!target->type->examined)
388 {
389 /* Fail silently lest we pollute the log */
390 return ERROR_FAIL;
391 }
392 return target->type->poll(target);
393 }
394
395 int target_halt(struct target_s *target)
396 {
397 /* We can't poll until after examine */
398 if (!target->type->examined)
399 {
400 LOG_ERROR("Target not examined yet");
401 return ERROR_FAIL;
402 }
403 return target->type->halt(target);
404 }
405
406 int target_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution)
407 {
408 int retval;
409
410 /* We can't poll until after examine */
411 if (!target->type->examined)
412 {
413 LOG_ERROR("Target not examined yet");
414 return ERROR_FAIL;
415 }
416
417 /* note that resume *must* be asynchronous. The CPU can halt before we poll. The CPU can
418 * even halt at the current PC as a result of a software breakpoint being inserted by (a bug?)
419 * the application.
420 */
421 if ((retval = target->type->resume(target, current, address, handle_breakpoints, debug_execution)) != ERROR_OK)
422 return retval;
423
424 return retval;
425 }
426
427 int target_process_reset(struct command_context_s *cmd_ctx, enum target_reset_mode reset_mode)
428 {
429 char buf[100];
430 int retval;
431 Jim_Nvp *n;
432 n = Jim_Nvp_value2name_simple( nvp_reset_modes, reset_mode );
433 if( n->name == NULL ){
434 LOG_ERROR("invalid reset mode");
435 return ERROR_FAIL;
436 }
437
438 sprintf( buf, "ocd_process_reset %s", n->name );
439 retval = Jim_Eval( interp, buf );
440
441 if(retval != JIM_OK) {
442 Jim_PrintErrorMessage(interp);
443 return ERROR_FAIL;
444 }
445
446 /* We want any events to be processed before the prompt */
447 retval = target_call_timer_callbacks_now();
448
449 return retval;
450 }
451
452 static int default_virt2phys(struct target_s *target, u32 virtual, u32 *physical)
453 {
454 *physical = virtual;
455 return ERROR_OK;
456 }
457
458 static int default_mmu(struct target_s *target, int *enabled)
459 {
460 *enabled = 0;
461 return ERROR_OK;
462 }
463
464 static int default_examine(struct target_s *target)
465 {
466 target->type->examined = 1;
467 return ERROR_OK;
468 }
469
470 /* Targets that correctly implement init+examine, i.e.
471 * no communication with target during init:
472 *
473 * XScale
474 */
475 int target_examine(void)
476 {
477 int retval = ERROR_OK;
478 target_t *target = all_targets;
479 while (target)
480 {
481 if ((retval = target->type->examine(target))!=ERROR_OK)
482 return retval;
483 target = target->next;
484 }
485 return retval;
486 }
487
488 static int target_write_memory_imp(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
489 {
490 if (!target->type->examined)
491 {
492 LOG_ERROR("Target not examined yet");
493 return ERROR_FAIL;
494 }
495 return target->type->write_memory_imp(target, address, size, count, buffer);
496 }
497
498 static int target_read_memory_imp(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
499 {
500 if (!target->type->examined)
501 {
502 LOG_ERROR("Target not examined yet");
503 return ERROR_FAIL;
504 }
505 return target->type->read_memory_imp(target, address, size, count, buffer);
506 }
507
508 static int target_soft_reset_halt_imp(struct target_s *target)
509 {
510 if (!target->type->examined)
511 {
512 LOG_ERROR("Target not examined yet");
513 return ERROR_FAIL;
514 }
515 return target->type->soft_reset_halt_imp(target);
516 }
517
518 static int target_run_algorithm_imp(struct target_s *target, int num_mem_params, mem_param_t *mem_params, int num_reg_params, reg_param_t *reg_param, u32 entry_point, u32 exit_point, int timeout_ms, void *arch_info)
519 {
520 if (!target->type->examined)
521 {
522 LOG_ERROR("Target not examined yet");
523 return ERROR_FAIL;
524 }
525 return target->type->run_algorithm_imp(target, num_mem_params, mem_params, num_reg_params, reg_param, entry_point, exit_point, timeout_ms, arch_info);
526 }
527
528 int target_read_memory(struct target_s *target,
529 u32 address, u32 size, u32 count, u8 *buffer)
530 {
531 return target->type->read_memory(target, address, size, count, buffer);
532 }
533
534 int target_write_memory(struct target_s *target,
535 u32 address, u32 size, u32 count, u8 *buffer)
536 {
537 return target->type->write_memory(target, address, size, count, buffer);
538 }
539
540
541 int target_init(struct command_context_s *cmd_ctx)
542 {
543 target_t *target = all_targets;
544 int retval;
545
546 while (target)
547 {
548 target->type->examined = 0;
549 if (target->type->examine == NULL)
550 {
551 target->type->examine = default_examine;
552 }
553
554 if ((retval = target->type->init_target(cmd_ctx, target)) != ERROR_OK)
555 {
556 LOG_ERROR("target '%s' init failed", target->type->name);
557 return retval;
558 }
559
560 /* Set up default functions if none are provided by target */
561 if (target->type->virt2phys == NULL)
562 {
563 target->type->virt2phys = default_virt2phys;
564 }
565 target->type->virt2phys = default_virt2phys;
566 /* a non-invasive way(in terms of patches) to add some code that
567 * runs before the type->write/read_memory implementation
568 */
569 target->type->write_memory_imp = target->type->write_memory;
570 target->type->write_memory = target_write_memory_imp;
571 target->type->read_memory_imp = target->type->read_memory;
572 target->type->read_memory = target_read_memory_imp;
573 target->type->soft_reset_halt_imp = target->type->soft_reset_halt;
574 target->type->soft_reset_halt = target_soft_reset_halt_imp;
575 target->type->run_algorithm_imp = target->type->run_algorithm;
576 target->type->run_algorithm = target_run_algorithm_imp;
577
578 if (target->type->mmu == NULL)
579 {
580 target->type->mmu = default_mmu;
581 }
582 target = target->next;
583 }
584
585 if (all_targets)
586 {
587 if((retval = target_register_user_commands(cmd_ctx)) != ERROR_OK)
588 return retval;
589 if((retval = target_register_timer_callback(handle_target, 100, 1, NULL)) != ERROR_OK)
590 return retval;
591 }
592
593 return ERROR_OK;
594 }
595
596 int target_register_event_callback(int (*callback)(struct target_s *target, enum target_event event, void *priv), void *priv)
597 {
598 target_event_callback_t **callbacks_p = &target_event_callbacks;
599
600 if (callback == NULL)
601 {
602 return ERROR_INVALID_ARGUMENTS;
603 }
604
605 if (*callbacks_p)
606 {
607 while ((*callbacks_p)->next)
608 callbacks_p = &((*callbacks_p)->next);
609 callbacks_p = &((*callbacks_p)->next);
610 }
611
612 (*callbacks_p) = malloc(sizeof(target_event_callback_t));
613 (*callbacks_p)->callback = callback;
614 (*callbacks_p)->priv = priv;
615 (*callbacks_p)->next = NULL;
616
617 return ERROR_OK;
618 }
619
620 int target_register_timer_callback(int (*callback)(void *priv), int time_ms, int periodic, void *priv)
621 {
622 target_timer_callback_t **callbacks_p = &target_timer_callbacks;
623 struct timeval now;
624
625 if (callback == NULL)
626 {
627 return ERROR_INVALID_ARGUMENTS;
628 }
629
630 if (*callbacks_p)
631 {
632 while ((*callbacks_p)->next)
633 callbacks_p = &((*callbacks_p)->next);
634 callbacks_p = &((*callbacks_p)->next);
635 }
636
637 (*callbacks_p) = malloc(sizeof(target_timer_callback_t));
638 (*callbacks_p)->callback = callback;
639 (*callbacks_p)->periodic = periodic;
640 (*callbacks_p)->time_ms = time_ms;
641
642 gettimeofday(&now, NULL);
643 (*callbacks_p)->when.tv_usec = now.tv_usec + (time_ms % 1000) * 1000;
644 time_ms -= (time_ms % 1000);
645 (*callbacks_p)->when.tv_sec = now.tv_sec + (time_ms / 1000);
646 if ((*callbacks_p)->when.tv_usec > 1000000)
647 {
648 (*callbacks_p)->when.tv_usec = (*callbacks_p)->when.tv_usec - 1000000;
649 (*callbacks_p)->when.tv_sec += 1;
650 }
651
652 (*callbacks_p)->priv = priv;
653 (*callbacks_p)->next = NULL;
654
655 return ERROR_OK;
656 }
657
658 int target_unregister_event_callback(int (*callback)(struct target_s *target, enum target_event event, void *priv), void *priv)
659 {
660 target_event_callback_t **p = &target_event_callbacks;
661 target_event_callback_t *c = target_event_callbacks;
662
663 if (callback == NULL)
664 {
665 return ERROR_INVALID_ARGUMENTS;
666 }
667
668 while (c)
669 {
670 target_event_callback_t *next = c->next;
671 if ((c->callback == callback) && (c->priv == priv))
672 {
673 *p = next;
674 free(c);
675 return ERROR_OK;
676 }
677 else
678 p = &(c->next);
679 c = next;
680 }
681
682 return ERROR_OK;
683 }
684
685 int target_unregister_timer_callback(int (*callback)(void *priv), void *priv)
686 {
687 target_timer_callback_t **p = &target_timer_callbacks;
688 target_timer_callback_t *c = target_timer_callbacks;
689
690 if (callback == NULL)
691 {
692 return ERROR_INVALID_ARGUMENTS;
693 }
694
695 while (c)
696 {
697 target_timer_callback_t *next = c->next;
698 if ((c->callback == callback) && (c->priv == priv))
699 {
700 *p = next;
701 free(c);
702 return ERROR_OK;
703 }
704 else
705 p = &(c->next);
706 c = next;
707 }
708
709 return ERROR_OK;
710 }
711
712 int target_call_event_callbacks(target_t *target, enum target_event event)
713 {
714 target_event_callback_t *callback = target_event_callbacks;
715 target_event_callback_t *next_callback;
716
717 if (event == TARGET_EVENT_HALTED)
718 {
719 /* execute early halted first */
720 target_call_event_callbacks(target, TARGET_EVENT_EARLY_HALTED);
721 }
722
723 LOG_DEBUG("target event %i (%s)",
724 event,
725 Jim_Nvp_value2name_simple( nvp_target_event, event )->name );
726
727 target_handle_event( target, event );
728
729 while (callback)
730 {
731 next_callback = callback->next;
732 callback->callback(target, event, callback->priv);
733 callback = next_callback;
734 }
735
736 return ERROR_OK;
737 }
738
739 static int target_call_timer_callbacks_check_time(int checktime)
740 {
741 target_timer_callback_t *callback = target_timer_callbacks;
742 target_timer_callback_t *next_callback;
743 struct timeval now;
744
745 keep_alive();
746
747 gettimeofday(&now, NULL);
748
749 while (callback)
750 {
751 next_callback = callback->next;
752
753 if ((!checktime&&callback->periodic)||
754 (((now.tv_sec >= callback->when.tv_sec) && (now.tv_usec >= callback->when.tv_usec))
755 || (now.tv_sec > callback->when.tv_sec)))
756 {
757 if(callback->callback != NULL)
758 {
759 callback->callback(callback->priv);
760 if (callback->periodic)
761 {
762 int time_ms = callback->time_ms;
763 callback->when.tv_usec = now.tv_usec + (time_ms % 1000) * 1000;
764 time_ms -= (time_ms % 1000);
765 callback->when.tv_sec = now.tv_sec + time_ms / 1000;
766 if (callback->when.tv_usec > 1000000)
767 {
768 callback->when.tv_usec = callback->when.tv_usec - 1000000;
769 callback->when.tv_sec += 1;
770 }
771 }
772 else
773 {
774 int retval;
775 if((retval = target_unregister_timer_callback(callback->callback, callback->priv)) != ERROR_OK)
776 return retval;
777 }
778 }
779 }
780
781 callback = next_callback;
782 }
783
784 return ERROR_OK;
785 }
786
787 int target_call_timer_callbacks(void)
788 {
789 return target_call_timer_callbacks_check_time(1);
790 }
791
792 /* invoke periodic callbacks immediately */
793 int target_call_timer_callbacks_now(void)
794 {
795 return target_call_timer_callbacks_check_time(0);
796 }
797
798 int target_alloc_working_area(struct target_s *target, u32 size, working_area_t **area)
799 {
800 working_area_t *c = target->working_areas;
801 working_area_t *new_wa = NULL;
802
803 /* Reevaluate working area address based on MMU state*/
804 if (target->working_areas == NULL)
805 {
806 int retval;
807 int enabled;
808 retval = target->type->mmu(target, &enabled);
809 if (retval != ERROR_OK)
810 {
811 return retval;
812 }
813 if (enabled)
814 {
815 target->working_area = target->working_area_virt;
816 }
817 else
818 {
819 target->working_area = target->working_area_phys;
820 }
821 }
822
823 /* only allocate multiples of 4 byte */
824 if (size % 4)
825 {
826 LOG_ERROR("BUG: code tried to allocate unaligned number of bytes, padding");
827 size = CEIL(size, 4);
828 }
829
830 /* see if there's already a matching working area */
831 while (c)
832 {
833 if ((c->free) && (c->size == size))
834 {
835 new_wa = c;
836 break;
837 }
838 c = c->next;
839 }
840
841 /* if not, allocate a new one */
842 if (!new_wa)
843 {
844 working_area_t **p = &target->working_areas;
845 u32 first_free = target->working_area;
846 u32 free_size = target->working_area_size;
847
848 LOG_DEBUG("allocating new working area");
849
850 c = target->working_areas;
851 while (c)
852 {
853 first_free += c->size;
854 free_size -= c->size;
855 p = &c->next;
856 c = c->next;
857 }
858
859 if (free_size < size)
860 {
861 LOG_WARNING("not enough working area available(requested %d, free %d)", size, free_size);
862 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
863 }
864
865 new_wa = malloc(sizeof(working_area_t));
866 new_wa->next = NULL;
867 new_wa->size = size;
868 new_wa->address = first_free;
869
870 if (target->backup_working_area)
871 {
872 int retval;
873 new_wa->backup = malloc(new_wa->size);
874 if((retval = target_read_memory(target, new_wa->address, 4, new_wa->size / 4, new_wa->backup)) != ERROR_OK)
875 {
876 free(new_wa->backup);
877 free(new_wa);
878 return retval;
879 }
880 }
881 else
882 {
883 new_wa->backup = NULL;
884 }
885
886 /* put new entry in list */
887 *p = new_wa;
888 }
889
890 /* mark as used, and return the new (reused) area */
891 new_wa->free = 0;
892 *area = new_wa;
893
894 /* user pointer */
895 new_wa->user = area;
896
897 return ERROR_OK;
898 }
899
900 int target_free_working_area_restore(struct target_s *target, working_area_t *area, int restore)
901 {
902 if (area->free)
903 return ERROR_OK;
904
905 if (restore&&target->backup_working_area)
906 {
907 int retval;
908 if((retval = target_write_memory(target, area->address, 4, area->size / 4, area->backup)) != ERROR_OK)
909 return retval;
910 }
911
912 area->free = 1;
913
914 /* mark user pointer invalid */
915 *area->user = NULL;
916 area->user = NULL;
917
918 return ERROR_OK;
919 }
920
921 int target_free_working_area(struct target_s *target, working_area_t *area)
922 {
923 return target_free_working_area_restore(target, area, 1);
924 }
925
926 /* free resources and restore memory, if restoring memory fails,
927 * free up resources anyway
928 */
929 void target_free_all_working_areas_restore(struct target_s *target, int restore)
930 {
931 working_area_t *c = target->working_areas;
932
933 while (c)
934 {
935 working_area_t *next = c->next;
936 target_free_working_area_restore(target, c, restore);
937
938 if (c->backup)
939 free(c->backup);
940
941 free(c);
942
943 c = next;
944 }
945
946 target->working_areas = NULL;
947 }
948
949 void target_free_all_working_areas(struct target_s *target)
950 {
951 target_free_all_working_areas_restore(target, 1);
952 }
953
954 int target_register_commands(struct command_context_s *cmd_ctx)
955 {
956
957 register_command(cmd_ctx, NULL, "targets", handle_targets_command, COMMAND_EXEC, "change the current command line target (one parameter) or lists targets (with no parameter)");
958
959
960
961
962 register_jim(cmd_ctx, "target", jim_target, "configure target" );
963
964 return ERROR_OK;
965 }
966
967 int target_arch_state(struct target_s *target)
968 {
969 int retval;
970 if (target==NULL)
971 {
972 LOG_USER("No target has been configured");
973 return ERROR_OK;
974 }
975
976 LOG_USER("target state: %s",
977 Jim_Nvp_value2name_simple(nvp_target_state,target->state)->name);
978
979 if (target->state!=TARGET_HALTED)
980 return ERROR_OK;
981
982 retval=target->type->arch_state(target);
983 return retval;
984 }
985
986 /* Single aligned words are guaranteed to use 16 or 32 bit access
987 * mode respectively, otherwise data is handled as quickly as
988 * possible
989 */
990 int target_write_buffer(struct target_s *target, u32 address, u32 size, u8 *buffer)
991 {
992 int retval;
993 LOG_DEBUG("writing buffer of %i byte at 0x%8.8x", size, address);
994
995 if (!target->type->examined)
996 {
997 LOG_ERROR("Target not examined yet");
998 return ERROR_FAIL;
999 }
1000
1001 if (size == 0) {
1002 return ERROR_OK;
1003 }
1004
1005 if ((address + size - 1) < address)
1006 {
1007 /* GDB can request this when e.g. PC is 0xfffffffc*/
1008 LOG_ERROR("address+size wrapped(0x%08x, 0x%08x)", address, size);
1009 return ERROR_FAIL;
1010 }
1011
1012 if (((address % 2) == 0) && (size == 2))
1013 {
1014 return target_write_memory(target, address, 2, 1, buffer);
1015 }
1016
1017 /* handle unaligned head bytes */
1018 if (address % 4)
1019 {
1020 u32 unaligned = 4 - (address % 4);
1021
1022 if (unaligned > size)
1023 unaligned = size;
1024
1025 if ((retval = target_write_memory(target, address, 1, unaligned, buffer)) != ERROR_OK)
1026 return retval;
1027
1028 buffer += unaligned;
1029 address += unaligned;
1030 size -= unaligned;
1031 }
1032
1033 /* handle aligned words */
1034 if (size >= 4)
1035 {
1036 int aligned = size - (size % 4);
1037
1038 /* use bulk writes above a certain limit. This may have to be changed */
1039 if (aligned > 128)
1040 {
1041 if ((retval = target->type->bulk_write_memory(target, address, aligned / 4, buffer)) != ERROR_OK)
1042 return retval;
1043 }
1044 else
1045 {
1046 if ((retval = target_write_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK)
1047 return retval;
1048 }
1049
1050 buffer += aligned;
1051 address += aligned;
1052 size -= aligned;
1053 }
1054
1055 /* handle tail writes of less than 4 bytes */
1056 if (size > 0)
1057 {
1058 if ((retval = target_write_memory(target, address, 1, size, buffer)) != ERROR_OK)
1059 return retval;
1060 }
1061
1062 return ERROR_OK;
1063 }
1064
1065 /* Single aligned words are guaranteed to use 16 or 32 bit access
1066 * mode respectively, otherwise data is handled as quickly as
1067 * possible
1068 */
1069 int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffer)
1070 {
1071 int retval;
1072 LOG_DEBUG("reading buffer of %i byte at 0x%8.8x", size, address);
1073
1074 if (!target->type->examined)
1075 {
1076 LOG_ERROR("Target not examined yet");
1077 return ERROR_FAIL;
1078 }
1079
1080 if (size == 0) {
1081 return ERROR_OK;
1082 }
1083
1084 if ((address + size - 1) < address)
1085 {
1086 /* GDB can request this when e.g. PC is 0xfffffffc*/
1087 LOG_ERROR("address+size wrapped(0x%08x, 0x%08x)", address, size);
1088 return ERROR_FAIL;
1089 }
1090
1091 if (((address % 2) == 0) && (size == 2))
1092 {
1093 return target_read_memory(target, address, 2, 1, buffer);
1094 }
1095
1096 /* handle unaligned head bytes */
1097 if (address % 4)
1098 {
1099 u32 unaligned = 4 - (address % 4);
1100
1101 if (unaligned > size)
1102 unaligned = size;
1103
1104 if ((retval = target_read_memory(target, address, 1, unaligned, buffer)) != ERROR_OK)
1105 return retval;
1106
1107 buffer += unaligned;
1108 address += unaligned;
1109 size -= unaligned;
1110 }
1111
1112 /* handle aligned words */
1113 if (size >= 4)
1114 {
1115 int aligned = size - (size % 4);
1116
1117 if ((retval = target_read_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK)
1118 return retval;
1119
1120 buffer += aligned;
1121 address += aligned;
1122 size -= aligned;
1123 }
1124
1125 /* handle tail writes of less than 4 bytes */
1126 if (size > 0)
1127 {
1128 if ((retval = target_read_memory(target, address, 1, size, buffer)) != ERROR_OK)
1129 return retval;
1130 }
1131
1132 return ERROR_OK;
1133 }
1134
1135 int target_checksum_memory(struct target_s *target, u32 address, u32 size, u32* crc)
1136 {
1137 u8 *buffer;
1138 int retval;
1139 u32 i;
1140 u32 checksum = 0;
1141 if (!target->type->examined)
1142 {
1143 LOG_ERROR("Target not examined yet");
1144 return ERROR_FAIL;
1145 }
1146
1147 if ((retval = target->type->checksum_memory(target, address,
1148 size, &checksum)) != ERROR_OK)
1149 {
1150 buffer = malloc(size);
1151 if (buffer == NULL)
1152 {
1153 LOG_ERROR("error allocating buffer for section (%d bytes)", size);
1154 return ERROR_INVALID_ARGUMENTS;
1155 }
1156 retval = target_read_buffer(target, address, size, buffer);
1157 if (retval != ERROR_OK)
1158 {
1159 free(buffer);
1160 return retval;
1161 }
1162
1163 /* convert to target endianess */
1164 for (i = 0; i < (size/sizeof(u32)); i++)
1165 {
1166 u32 target_data;
1167 target_data = target_buffer_get_u32(target, &buffer[i*sizeof(u32)]);
1168 target_buffer_set_u32(target, &buffer[i*sizeof(u32)], target_data);
1169 }
1170
1171 retval = image_calculate_checksum( buffer, size, &checksum );
1172 free(buffer);
1173 }
1174
1175 *crc = checksum;
1176
1177 return retval;
1178 }
1179
1180 int target_blank_check_memory(struct target_s *target, u32 address, u32 size, u32* blank)
1181 {
1182 int retval;
1183 if (!target->type->examined)
1184 {
1185 LOG_ERROR("Target not examined yet");
1186 return ERROR_FAIL;
1187 }
1188
1189 if (target->type->blank_check_memory == 0)
1190 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1191
1192 retval = target->type->blank_check_memory(target, address, size, blank);
1193
1194 return retval;
1195 }
1196
1197 int target_read_u32(struct target_s *target, u32 address, u32 *value)
1198 {
1199 u8 value_buf[4];
1200 if (!target->type->examined)
1201 {
1202 LOG_ERROR("Target not examined yet");
1203 return ERROR_FAIL;
1204 }
1205
1206 int retval = target_read_memory(target, address, 4, 1, value_buf);
1207
1208 if (retval == ERROR_OK)
1209 {
1210 *value = target_buffer_get_u32(target, value_buf);
1211 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address, *value);
1212 }
1213 else
1214 {
1215 *value = 0x0;
1216 LOG_DEBUG("address: 0x%8.8x failed", address);
1217 }
1218
1219 return retval;
1220 }
1221
1222 int target_read_u16(struct target_s *target, u32 address, u16 *value)
1223 {
1224 u8 value_buf[2];
1225 if (!target->type->examined)
1226 {
1227 LOG_ERROR("Target not examined yet");
1228 return ERROR_FAIL;
1229 }
1230
1231 int retval = target_read_memory(target, address, 2, 1, value_buf);
1232
1233 if (retval == ERROR_OK)
1234 {
1235 *value = target_buffer_get_u16(target, value_buf);
1236 LOG_DEBUG("address: 0x%8.8x, value: 0x%4.4x", address, *value);
1237 }
1238 else
1239 {
1240 *value = 0x0;
1241 LOG_DEBUG("address: 0x%8.8x failed", address);
1242 }
1243
1244 return retval;
1245 }
1246
1247 int target_read_u8(struct target_s *target, u32 address, u8 *value)
1248 {
1249 int retval = target_read_memory(target, address, 1, 1, value);
1250 if (!target->type->examined)
1251 {
1252 LOG_ERROR("Target not examined yet");
1253 return ERROR_FAIL;
1254 }
1255
1256 if (retval == ERROR_OK)
1257 {
1258 LOG_DEBUG("address: 0x%8.8x, value: 0x%2.2x", address, *value);
1259 }
1260 else
1261 {
1262 *value = 0x0;
1263 LOG_DEBUG("address: 0x%8.8x failed", address);
1264 }
1265
1266 return retval;
1267 }
1268
1269 int target_write_u32(struct target_s *target, u32 address, u32 value)
1270 {
1271 int retval;
1272 u8 value_buf[4];
1273 if (!target->type->examined)
1274 {
1275 LOG_ERROR("Target not examined yet");
1276 return ERROR_FAIL;
1277 }
1278
1279 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address, value);
1280
1281 target_buffer_set_u32(target, value_buf, value);
1282 if ((retval = target_write_memory(target, address, 4, 1, value_buf)) != ERROR_OK)
1283 {
1284 LOG_DEBUG("failed: %i", retval);
1285 }
1286
1287 return retval;
1288 }
1289
1290 int target_write_u16(struct target_s *target, u32 address, u16 value)
1291 {
1292 int retval;
1293 u8 value_buf[2];
1294 if (!target->type->examined)
1295 {
1296 LOG_ERROR("Target not examined yet");
1297 return ERROR_FAIL;
1298 }
1299
1300 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address, value);
1301
1302 target_buffer_set_u16(target, value_buf, value);
1303 if ((retval = target_write_memory(target, address, 2, 1, value_buf)) != ERROR_OK)
1304 {
1305 LOG_DEBUG("failed: %i", retval);
1306 }
1307
1308 return retval;
1309 }
1310
1311 int target_write_u8(struct target_s *target, u32 address, u8 value)
1312 {
1313 int retval;
1314 if (!target->type->examined)
1315 {
1316 LOG_ERROR("Target not examined yet");
1317 return ERROR_FAIL;
1318 }
1319
1320 LOG_DEBUG("address: 0x%8.8x, value: 0x%2.2x", address, value);
1321
1322 if ((retval = target_write_memory(target, address, 1, 1, &value)) != ERROR_OK)
1323 {
1324 LOG_DEBUG("failed: %i", retval);
1325 }
1326
1327 return retval;
1328 }
1329
1330 int target_register_user_commands(struct command_context_s *cmd_ctx)
1331 {
1332 int retval = ERROR_OK;
1333
1334
1335 /* script procedures */
1336 register_command(cmd_ctx, NULL, "profile", handle_profile_command, COMMAND_EXEC, "profiling samples the CPU PC");
1337 register_jim(cmd_ctx, "ocd_mem2array", jim_mem2array, "read memory and return as a TCL array for script processing <ARRAYNAME> <WIDTH=32/16/8> <ADDRESS> <COUNT>");
1338 register_jim(cmd_ctx, "ocd_array2mem", jim_array2mem, "convert a TCL array to memory locations and write the values <ARRAYNAME> <WIDTH=32/16/8> <ADDRESS> <COUNT>");
1339
1340 register_command(cmd_ctx, NULL, "fast_load_image", handle_fast_load_image_command, COMMAND_ANY,
1341 "same args as load_image, image stored in memory - mainly for profiling purposes");
1342
1343 register_command(cmd_ctx, NULL, "fast_load", handle_fast_load_command, COMMAND_ANY,
1344 "loads active fast load image to current target - mainly for profiling purposes");
1345
1346
1347 register_command(cmd_ctx, NULL, "virt2phys", handle_virt2phys_command, COMMAND_ANY, "translate a virtual address into a physical address");
1348 register_command(cmd_ctx, NULL, "reg", handle_reg_command, COMMAND_EXEC, "display or set a register");
1349 register_command(cmd_ctx, NULL, "poll", handle_poll_command, COMMAND_EXEC, "poll target state");
1350 register_command(cmd_ctx, NULL, "wait_halt", handle_wait_halt_command, COMMAND_EXEC, "wait for target halt [time (s)]");
1351 register_command(cmd_ctx, NULL, "halt", handle_halt_command, COMMAND_EXEC, "halt target");
1352 register_command(cmd_ctx, NULL, "resume", handle_resume_command, COMMAND_EXEC, "resume target [addr]");
1353 register_command(cmd_ctx, NULL, "step", handle_step_command, COMMAND_EXEC, "step one instruction from current PC or [addr]");
1354 register_command(cmd_ctx, NULL, "reset", handle_reset_command, COMMAND_EXEC, "reset target [run|halt|init] - default is run");
1355 register_command(cmd_ctx, NULL, "soft_reset_halt", handle_soft_reset_halt_command, COMMAND_EXEC, "halt the target and do a soft reset");
1356
1357 register_command(cmd_ctx, NULL, "mdw", handle_md_command, COMMAND_EXEC, "display memory words <addr> [count]");
1358 register_command(cmd_ctx, NULL, "mdh", handle_md_command, COMMAND_EXEC, "display memory half-words <addr> [count]");
1359 register_command(cmd_ctx, NULL, "mdb", handle_md_command, COMMAND_EXEC, "display memory bytes <addr> [count]");
1360
1361 register_command(cmd_ctx, NULL, "mww", handle_mw_command, COMMAND_EXEC, "write memory word <addr> <value> [count]");
1362 register_command(cmd_ctx, NULL, "mwh", handle_mw_command, COMMAND_EXEC, "write memory half-word <addr> <value> [count]");
1363 register_command(cmd_ctx, NULL, "mwb", handle_mw_command, COMMAND_EXEC, "write memory byte <addr> <value> [count]");
1364
1365 register_command(cmd_ctx, NULL, "bp", handle_bp_command, COMMAND_EXEC, "set breakpoint <address> <length> [hw]");
1366 register_command(cmd_ctx, NULL, "rbp", handle_rbp_command, COMMAND_EXEC, "remove breakpoint <adress>");
1367 register_command(cmd_ctx, NULL, "wp", handle_wp_command, COMMAND_EXEC, "set watchpoint <address> <length> <r/w/a> [value] [mask]");
1368 register_command(cmd_ctx, NULL, "rwp", handle_rwp_command, COMMAND_EXEC, "remove watchpoint <adress>");
1369
1370 register_command(cmd_ctx, NULL, "load_image", handle_load_image_command, COMMAND_EXEC, "load_image <file> <address> ['bin'|'ihex'|'elf'|'s19'] [min_address] [max_length]");
1371 register_command(cmd_ctx, NULL, "dump_image", handle_dump_image_command, COMMAND_EXEC, "dump_image <file> <address> <size>");
1372 register_command(cmd_ctx, NULL, "verify_image", handle_verify_image_command, COMMAND_EXEC, "verify_image <file> [offset] [type]");
1373 register_command(cmd_ctx, NULL, "test_image", handle_test_image_command, COMMAND_EXEC, "test_image <file> [offset] [type]");
1374
1375 if((retval = target_request_register_commands(cmd_ctx)) != ERROR_OK)
1376 return retval;
1377 if((retval = trace_register_commands(cmd_ctx)) != ERROR_OK)
1378 return retval;
1379
1380 return retval;
1381 }
1382
1383 static int handle_targets_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1384 {
1385 target_t *target = all_targets;
1386
1387 if (argc == 1)
1388 {
1389 target = get_target(args[0]);
1390 if (target == NULL) {
1391 command_print(cmd_ctx,"Target: %s is unknown, try one of:\n", args[0] );
1392 goto DumpTargets;
1393 }
1394
1395 cmd_ctx->current_target = target->target_number;
1396 return ERROR_OK;
1397 }
1398 DumpTargets:
1399
1400 target = all_targets;
1401 command_print(cmd_ctx, " CmdName Type Endian AbsChainPos Name State ");
1402 command_print(cmd_ctx, "-- ---------- ---------- ---------- ----------- ------------- ----------");
1403 while (target)
1404 {
1405 /* XX: abcdefghij abcdefghij abcdefghij abcdefghij */
1406 command_print(cmd_ctx, "%2d: %-10s %-10s %-10s %10d %14s %s",
1407 target->target_number,
1408 target->cmd_name,
1409 target->type->name,
1410 Jim_Nvp_value2name_simple( nvp_target_endian, target->endianness )->name,
1411 target->tap->abs_chain_position,
1412 target->tap->dotted_name,
1413 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name );
1414 target = target->next;
1415 }
1416
1417 return ERROR_OK;
1418 }
1419
1420 /* every 300ms we check for reset & powerdropout and issue a "reset halt" if so. */
1421
1422 static int powerDropout;
1423 static int srstAsserted;
1424
1425 static int runPowerRestore;
1426 static int runPowerDropout;
1427 static int runSrstAsserted;
1428 static int runSrstDeasserted;
1429
1430 static int sense_handler(void)
1431 {
1432 static int prevSrstAsserted = 0;
1433 static int prevPowerdropout = 0;
1434
1435 int retval;
1436 if ((retval=jtag_power_dropout(&powerDropout))!=ERROR_OK)
1437 return retval;
1438
1439 int powerRestored;
1440 powerRestored = prevPowerdropout && !powerDropout;
1441 if (powerRestored)
1442 {
1443 runPowerRestore = 1;
1444 }
1445
1446 long long current = timeval_ms();
1447 static long long lastPower = 0;
1448 int waitMore = lastPower + 2000 > current;
1449 if (powerDropout && !waitMore)
1450 {
1451 runPowerDropout = 1;
1452 lastPower = current;
1453 }
1454
1455 if ((retval=jtag_srst_asserted(&srstAsserted))!=ERROR_OK)
1456 return retval;
1457
1458 int srstDeasserted;
1459 srstDeasserted = prevSrstAsserted && !srstAsserted;
1460
1461 static long long lastSrst = 0;
1462 waitMore = lastSrst + 2000 > current;
1463 if (srstDeasserted && !waitMore)
1464 {
1465 runSrstDeasserted = 1;
1466 lastSrst = current;
1467 }
1468
1469 if (!prevSrstAsserted && srstAsserted)
1470 {
1471 runSrstAsserted = 1;
1472 }
1473
1474 prevSrstAsserted = srstAsserted;
1475 prevPowerdropout = powerDropout;
1476
1477 if (srstDeasserted || powerRestored)
1478 {
1479 /* Other than logging the event we can't do anything here.
1480 * Issuing a reset is a particularly bad idea as we might
1481 * be inside a reset already.
1482 */
1483 }
1484
1485 return ERROR_OK;
1486 }
1487
1488 /* process target state changes */
1489 int handle_target(void *priv)
1490 {
1491 int retval = ERROR_OK;
1492
1493 /* we do not want to recurse here... */
1494 static int recursive = 0;
1495 if (! recursive)
1496 {
1497 recursive = 1;
1498 sense_handler();
1499 /* danger! running these procedures can trigger srst assertions and power dropouts.
1500 * We need to avoid an infinite loop/recursion here and we do that by
1501 * clearing the flags after running these events.
1502 */
1503 int did_something = 0;
1504 if (runSrstAsserted)
1505 {
1506 Jim_Eval( interp, "srst_asserted");
1507 did_something = 1;
1508 }
1509 if (runSrstDeasserted)
1510 {
1511 Jim_Eval( interp, "srst_deasserted");
1512 did_something = 1;
1513 }
1514 if (runPowerDropout)
1515 {
1516 Jim_Eval( interp, "power_dropout");
1517 did_something = 1;
1518 }
1519 if (runPowerRestore)
1520 {
1521 Jim_Eval( interp, "power_restore");
1522 did_something = 1;
1523 }
1524
1525 if (did_something)
1526 {
1527 /* clear detect flags */
1528 sense_handler();
1529 }
1530
1531 /* clear action flags */
1532
1533 runSrstAsserted=0;
1534 runSrstDeasserted=0;
1535 runPowerRestore=0;
1536 runPowerDropout=0;
1537
1538 recursive = 0;
1539 }
1540
1541 target_t *target = all_targets;
1542
1543 while (target)
1544 {
1545
1546 /* only poll target if we've got power and srst isn't asserted */
1547 if (target_continous_poll&&!powerDropout&&!srstAsserted)
1548 {
1549 /* polling may fail silently until the target has been examined */
1550 if((retval = target_poll(target)) != ERROR_OK)
1551 return retval;
1552 }
1553
1554 target = target->next;
1555 }
1556
1557 return retval;
1558 }
1559
1560 static int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1561 {
1562 target_t *target;
1563 reg_t *reg = NULL;
1564 int count = 0;
1565 char *value;
1566
1567 LOG_DEBUG("-");
1568
1569 target = get_current_target(cmd_ctx);
1570
1571 /* list all available registers for the current target */
1572 if (argc == 0)
1573 {
1574 reg_cache_t *cache = target->reg_cache;
1575
1576 count = 0;
1577 while(cache)
1578 {
1579 int i;
1580 for (i = 0; i < cache->num_regs; i++)
1581 {
1582 value = buf_to_str(cache->reg_list[i].value, cache->reg_list[i].size, 16);
1583 command_print(cmd_ctx, "(%i) %s (/%i): 0x%s (dirty: %i, valid: %i)", count++, cache->reg_list[i].name, cache->reg_list[i].size, value, cache->reg_list[i].dirty, cache->reg_list[i].valid);
1584 free(value);
1585 }
1586 cache = cache->next;
1587 }
1588
1589 return ERROR_OK;
1590 }
1591
1592 /* access a single register by its ordinal number */
1593 if ((args[0][0] >= '0') && (args[0][0] <= '9'))
1594 {
1595 int num = strtoul(args[0], NULL, 0);
1596 reg_cache_t *cache = target->reg_cache;
1597
1598 count = 0;
1599 while(cache)
1600 {
1601 int i;
1602 for (i = 0; i < cache->num_regs; i++)
1603 {
1604 if (count++ == num)
1605 {
1606 reg = &cache->reg_list[i];
1607 break;
1608 }
1609 }
1610 if (reg)
1611 break;
1612 cache = cache->next;
1613 }
1614
1615 if (!reg)
1616 {
1617 command_print(cmd_ctx, "%i is out of bounds, the current target has only %i registers (0 - %i)", num, count, count - 1);
1618 return ERROR_OK;
1619 }
1620 } else /* access a single register by its name */
1621 {
1622 reg = register_get_by_name(target->reg_cache, args[0], 1);
1623
1624 if (!reg)
1625 {
1626 command_print(cmd_ctx, "register %s not found in current target", args[0]);
1627 return ERROR_OK;
1628 }
1629 }
1630
1631 /* display a register */
1632 if ((argc == 1) || ((argc == 2) && !((args[1][0] >= '0') && (args[1][0] <= '9'))))
1633 {
1634 if ((argc == 2) && (strcmp(args[1], "force") == 0))
1635 reg->valid = 0;
1636
1637 if (reg->valid == 0)
1638 {
1639 reg_arch_type_t *arch_type = register_get_arch_type(reg->arch_type);
1640 arch_type->get(reg);
1641 }
1642 value = buf_to_str(reg->value, reg->size, 16);
1643 command_print(cmd_ctx, "%s (/%i): 0x%s", reg->name, reg->size, value);
1644 free(value);
1645 return ERROR_OK;
1646 }
1647
1648 /* set register value */
1649 if (argc == 2)
1650 {
1651 u8 *buf = malloc(CEIL(reg->size, 8));
1652 str_to_buf(args[1], strlen(args[1]), buf, reg->size, 0);
1653
1654 reg_arch_type_t *arch_type = register_get_arch_type(reg->arch_type);
1655 arch_type->set(reg, buf);
1656
1657 value = buf_to_str(reg->value, reg->size, 16);
1658 command_print(cmd_ctx, "%s (/%i): 0x%s", reg->name, reg->size, value);
1659 free(value);
1660
1661 free(buf);
1662
1663 return ERROR_OK;
1664 }
1665
1666 command_print(cmd_ctx, "usage: reg <#|name> [value]");
1667
1668 return ERROR_OK;
1669 }
1670
1671 static int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1672 {
1673 int retval = ERROR_OK;
1674 target_t *target = get_current_target(cmd_ctx);
1675
1676 if (argc == 0)
1677 {
1678 if((retval = target_poll(target)) != ERROR_OK)
1679 return retval;
1680 if((retval = target_arch_state(target)) != ERROR_OK)
1681 return retval;
1682
1683 }
1684 else if (argc==1)
1685 {
1686 if (strcmp(args[0], "on") == 0)
1687 {
1688 target_continous_poll = 1;
1689 }
1690 else if (strcmp(args[0], "off") == 0)
1691 {
1692 target_continous_poll = 0;
1693 }
1694 else
1695 {
1696 command_print(cmd_ctx, "arg is \"on\" or \"off\"");
1697 }
1698 } else
1699 {
1700 return ERROR_COMMAND_SYNTAX_ERROR;
1701 }
1702
1703 return retval;
1704 }
1705
1706 static int handle_wait_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1707 {
1708 int ms = 5000;
1709
1710 if (argc > 0)
1711 {
1712 char *end;
1713
1714 ms = strtoul(args[0], &end, 0) * 1000;
1715 if (*end)
1716 {
1717 command_print(cmd_ctx, "usage: %s [seconds]", cmd);
1718 return ERROR_OK;
1719 }
1720 }
1721 target_t *target = get_current_target(cmd_ctx);
1722
1723 return target_wait_state(target, TARGET_HALTED, ms);
1724 }
1725
1726 /* wait for target state to change. The trick here is to have a low
1727 * latency for short waits and not to suck up all the CPU time
1728 * on longer waits.
1729 *
1730 * After 500ms, keep_alive() is invoked
1731 */
1732 int target_wait_state(target_t *target, enum target_state state, int ms)
1733 {
1734 int retval;
1735 long long then=0, cur;
1736 int once=1;
1737
1738 for (;;)
1739 {
1740 if ((retval=target_poll(target))!=ERROR_OK)
1741 return retval;
1742 if (target->state == state)
1743 {
1744 break;
1745 }
1746 cur = timeval_ms();
1747 if (once)
1748 {
1749 once=0;
1750 then = timeval_ms();
1751 LOG_DEBUG("waiting for target %s...",
1752 Jim_Nvp_value2name_simple(nvp_target_state,state)->name);
1753 }
1754
1755 if (cur-then>500)
1756 {
1757 keep_alive();
1758 }
1759
1760 if ((cur-then)>ms)
1761 {
1762 LOG_ERROR("timed out while waiting for target %s",
1763 Jim_Nvp_value2name_simple(nvp_target_state,state)->name);
1764 return ERROR_FAIL;
1765 }
1766 }
1767
1768 return ERROR_OK;
1769 }
1770
1771 static int handle_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1772 {
1773 int retval;
1774 target_t *target = get_current_target(cmd_ctx);
1775
1776 LOG_DEBUG("-");
1777
1778 if ((retval = target_halt(target)) != ERROR_OK)
1779 {
1780 return retval;
1781 }
1782
1783 if (argc == 1)
1784 {
1785 int wait;
1786 char *end;
1787
1788 wait = strtoul(args[0], &end, 0);
1789 if (!*end && !wait)
1790 return ERROR_OK;
1791 }
1792
1793 return handle_wait_halt_command(cmd_ctx, cmd, args, argc);
1794 }
1795
1796 static int handle_soft_reset_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1797 {
1798 target_t *target = get_current_target(cmd_ctx);
1799
1800 LOG_USER("requesting target halt and executing a soft reset");
1801
1802 target->type->soft_reset_halt(target);
1803
1804 return ERROR_OK;
1805 }
1806
1807 static int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1808 {
1809 const Jim_Nvp *n;
1810 enum target_reset_mode reset_mode = RESET_RUN;
1811
1812 if (argc >= 1)
1813 {
1814 n = Jim_Nvp_name2value_simple( nvp_reset_modes, args[0] );
1815 if( (n->name == NULL) || (n->value == RESET_UNKNOWN) ){
1816 return ERROR_COMMAND_SYNTAX_ERROR;
1817 }
1818 reset_mode = n->value;
1819 }
1820
1821 /* reset *all* targets */
1822 return target_process_reset(cmd_ctx, reset_mode);
1823 }
1824
1825
1826 static int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1827 {
1828 int retval;
1829 target_t *target = get_current_target(cmd_ctx);
1830
1831 target_handle_event( target, TARGET_EVENT_OLD_pre_resume );
1832
1833 if (argc == 0)
1834 retval = target_resume(target, 1, 0, 1, 0); /* current pc, addr = 0, handle breakpoints, not debugging */
1835 else if (argc == 1)
1836 retval = target_resume(target, 0, strtoul(args[0], NULL, 0), 1, 0); /* addr = args[0], handle breakpoints, not debugging */
1837 else
1838 {
1839 retval = ERROR_COMMAND_SYNTAX_ERROR;
1840 }
1841
1842 return retval;
1843 }
1844
1845 static int handle_step_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1846 {
1847 target_t *target = get_current_target(cmd_ctx);
1848
1849 LOG_DEBUG("-");
1850
1851 if (argc == 0)
1852 return target->type->step(target, 1, 0, 1); /* current pc, addr = 0, handle breakpoints */
1853
1854 if (argc == 1)
1855 return target->type->step(target, 0, strtoul(args[0], NULL, 0), 1); /* addr = args[0], handle breakpoints */
1856
1857 return ERROR_OK;
1858 }
1859
1860 static void handle_md_output(struct command_context_s *cmd_ctx,
1861 struct target_s *target, u32 address, unsigned size,
1862 unsigned count, const u8 *buffer)
1863 {
1864 const unsigned line_bytecnt = 32;
1865 unsigned line_modulo = line_bytecnt / size;
1866
1867 char output[line_bytecnt * 4 + 1];
1868 unsigned output_len = 0;
1869
1870 const char *value_fmt;
1871 switch (size) {
1872 case 4: value_fmt = "%8.8x"; break;
1873 case 2: value_fmt = "%4.2x"; break;
1874 case 1: value_fmt = "%2.2x"; break;
1875 default:
1876 LOG_ERROR("invalid memory read size: %u", size);
1877 exit(-1);
1878 }
1879
1880 for (unsigned i = 0; i < count; i++)
1881 {
1882 if (i % line_modulo == 0)
1883 {
1884 output_len += snprintf(output + output_len,
1885 sizeof(output) - output_len,
1886 "0x%8.8x: ", address + (i*size));
1887 }
1888
1889 u32 value;
1890 const u8 *value_ptr = buffer + i * size;
1891 switch (size) {
1892 case 4: value = target_buffer_get_u32(target, value_ptr); break;
1893 case 2: value = target_buffer_get_u16(target, value_ptr); break;
1894 case 1: value = *value_ptr;
1895 }
1896 output_len += snprintf(output + output_len,
1897 sizeof(output) - output_len,
1898 value_fmt, value);
1899
1900 if ((i % line_modulo == line_modulo - 1) || (i == count - 1))
1901 {
1902 command_print(cmd_ctx, "%s", output);
1903 output_len = 0;
1904 }
1905 }
1906 }
1907
1908 static int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1909 {
1910 if (argc < 1)
1911 return ERROR_COMMAND_SYNTAX_ERROR;
1912
1913 unsigned size = 0;
1914 switch (cmd[2]) {
1915 case 'w': size = 4; break;
1916 case 'h': size = 2; break;
1917 case 'b': size = 1; break;
1918 default: return ERROR_COMMAND_SYNTAX_ERROR;
1919 }
1920
1921 u32 address = strtoul(args[0], NULL, 0);
1922
1923 unsigned count = 1;
1924 if (argc == 2)
1925 count = strtoul(args[1], NULL, 0);
1926
1927 u8 *buffer = calloc(count, size);
1928
1929 target_t *target = get_current_target(cmd_ctx);
1930 int retval = target_read_memory(target,
1931 address, size, count, buffer);
1932 if (ERROR_OK == retval)
1933 handle_md_output(cmd_ctx, target, address, size, count, buffer);
1934
1935 free(buffer);
1936
1937 return retval;
1938 }
1939
1940 static int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1941 {
1942 u32 address = 0;
1943 u32 value = 0;
1944 int count = 1;
1945 int i;
1946 int wordsize;
1947 target_t *target = get_current_target(cmd_ctx);
1948 u8 value_buf[4];
1949
1950 if ((argc < 2) || (argc > 3))
1951 return ERROR_COMMAND_SYNTAX_ERROR;
1952
1953 address = strtoul(args[0], NULL, 0);
1954 value = strtoul(args[1], NULL, 0);
1955 if (argc == 3)
1956 count = strtoul(args[2], NULL, 0);
1957
1958 switch (cmd[2])
1959 {
1960 case 'w':
1961 wordsize = 4;
1962 target_buffer_set_u32(target, value_buf, value);
1963 break;
1964 case 'h':
1965 wordsize = 2;
1966 target_buffer_set_u16(target, value_buf, value);
1967 break;
1968 case 'b':
1969 wordsize = 1;
1970 value_buf[0] = value;
1971 break;
1972 default:
1973 return ERROR_COMMAND_SYNTAX_ERROR;
1974 }
1975 for (i=0; i<count; i++)
1976 {
1977 int retval = target_write_memory(target,
1978 address + i * wordsize, wordsize, 1, value_buf);
1979 if (ERROR_OK != retval)
1980 return retval;
1981 keep_alive();
1982 }
1983
1984 return ERROR_OK;
1985
1986 }
1987
1988 static int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1989 {
1990 u8 *buffer;
1991 u32 buf_cnt;
1992 u32 image_size;
1993 u32 min_address=0;
1994 u32 max_address=0xffffffff;
1995 int i;
1996 int retval, retvaltemp;
1997
1998 image_t image;
1999
2000 duration_t duration;
2001 char *duration_text;
2002
2003 target_t *target = get_current_target(cmd_ctx);
2004
2005 if ((argc < 1)||(argc > 5))
2006 {
2007 return ERROR_COMMAND_SYNTAX_ERROR;
2008 }
2009
2010 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
2011 if (argc >= 2)
2012 {
2013 image.base_address_set = 1;
2014 image.base_address = strtoul(args[1], NULL, 0);
2015 }
2016 else
2017 {
2018 image.base_address_set = 0;
2019 }
2020
2021
2022 image.start_address_set = 0;
2023
2024 if (argc>=4)
2025 {
2026 min_address=strtoul(args[3], NULL, 0);
2027 }
2028 if (argc>=5)
2029 {
2030 max_address=strtoul(args[4], NULL, 0)+min_address;
2031 }
2032
2033 if (min_address>max_address)
2034 {
2035 return ERROR_COMMAND_SYNTAX_ERROR;
2036 }
2037
2038 duration_start_measure(&duration);
2039
2040 if (image_open(&image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
2041 {
2042 return ERROR_OK;
2043 }
2044
2045 image_size = 0x0;
2046 retval = ERROR_OK;
2047 for (i = 0; i < image.num_sections; i++)
2048 {
2049 buffer = malloc(image.sections[i].size);
2050 if (buffer == NULL)
2051 {
2052 command_print(cmd_ctx, "error allocating buffer for section (%d bytes)", image.sections[i].size);
2053 break;
2054 }
2055
2056 if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
2057 {
2058 free(buffer);
2059 break;
2060 }
2061
2062 u32 offset=0;
2063 u32 length=buf_cnt;
2064
2065 /* DANGER!!! beware of unsigned comparision here!!! */
2066
2067 if ((image.sections[i].base_address+buf_cnt>=min_address)&&
2068 (image.sections[i].base_address<max_address))
2069 {
2070 if (image.sections[i].base_address<min_address)
2071 {
2072 /* clip addresses below */
2073 offset+=min_address-image.sections[i].base_address;
2074 length-=offset;
2075 }
2076
2077 if (image.sections[i].base_address+buf_cnt>max_address)
2078 {
2079 length-=(image.sections[i].base_address+buf_cnt)-max_address;
2080 }
2081
2082 if ((retval = target_write_buffer(target, image.sections[i].base_address+offset, length, buffer+offset)) != ERROR_OK)
2083 {
2084 free(buffer);
2085 break;
2086 }
2087 image_size += length;
2088 command_print(cmd_ctx, "%u byte written at address 0x%8.8x", length, image.sections[i].base_address+offset);
2089 }
2090
2091 free(buffer);
2092 }
2093
2094 if((retvaltemp = duration_stop_measure(&duration, &duration_text)) != ERROR_OK)
2095 {
2096 image_close(&image);
2097 return retvaltemp;
2098 }
2099
2100 if (retval==ERROR_OK)
2101 {
2102 command_print(cmd_ctx, "downloaded %u byte in %s", image_size, duration_text);
2103 }
2104 free(duration_text);
2105
2106 image_close(&image);
2107
2108 return retval;
2109
2110 }
2111
2112 static int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2113 {
2114 fileio_t fileio;
2115
2116 u32 address;
2117 u32 size;
2118 u8 buffer[560];
2119 int retval=ERROR_OK, retvaltemp;
2120
2121 duration_t duration;
2122 char *duration_text;
2123
2124 target_t *target = get_current_target(cmd_ctx);
2125
2126 if (argc != 3)
2127 {
2128 command_print(cmd_ctx, "usage: dump_image <filename> <address> <size>");
2129 return ERROR_OK;
2130 }
2131
2132 address = strtoul(args[1], NULL, 0);
2133 size = strtoul(args[2], NULL, 0);
2134
2135 if (fileio_open(&fileio, args[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)
2136 {
2137 return ERROR_OK;
2138 }
2139
2140 duration_start_measure(&duration);
2141
2142 while (size > 0)
2143 {
2144 u32 size_written;
2145 u32 this_run_size = (size > 560) ? 560 : size;
2146
2147 retval = target_read_buffer(target, address, this_run_size, buffer);
2148 if (retval != ERROR_OK)
2149 {
2150 break;
2151 }
2152
2153 retval = fileio_write(&fileio, this_run_size, buffer, &size_written);
2154 if (retval != ERROR_OK)
2155 {
2156 break;
2157 }
2158
2159 size -= this_run_size;
2160 address += this_run_size;
2161 }
2162
2163 if((retvaltemp = fileio_close(&fileio)) != ERROR_OK)
2164 return retvaltemp;
2165
2166 if((retvaltemp = duration_stop_measure(&duration, &duration_text)) != ERROR_OK)
2167 return retvaltemp;
2168
2169 if (retval==ERROR_OK)
2170 {
2171 command_print(cmd_ctx, "dumped %lld byte in %s",
2172 fileio.size, duration_text);
2173 free(duration_text);
2174 }
2175
2176 return retval;
2177 }
2178
2179 static int handle_verify_image_command_internal(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, int verify)
2180 {
2181 u8 *buffer;
2182 u32 buf_cnt;
2183 u32 image_size;
2184 int i;
2185 int retval, retvaltemp;
2186 u32 checksum = 0;
2187 u32 mem_checksum = 0;
2188
2189 image_t image;
2190
2191 duration_t duration;
2192 char *duration_text;
2193
2194 target_t *target = get_current_target(cmd_ctx);
2195
2196 if (argc < 1)
2197 {
2198 return ERROR_COMMAND_SYNTAX_ERROR;
2199 }
2200
2201 if (!target)
2202 {
2203 LOG_ERROR("no target selected");
2204 return ERROR_FAIL;
2205 }
2206
2207 duration_start_measure(&duration);
2208
2209 if (argc >= 2)
2210 {
2211 image.base_address_set = 1;
2212 image.base_address = strtoul(args[1], NULL, 0);
2213 }
2214 else
2215 {
2216 image.base_address_set = 0;
2217 image.base_address = 0x0;
2218 }
2219
2220 image.start_address_set = 0;
2221
2222 if ((retval=image_open(&image, args[0], (argc == 3) ? args[2] : NULL)) != ERROR_OK)
2223 {
2224 return retval;
2225 }
2226
2227 image_size = 0x0;
2228 retval=ERROR_OK;
2229 for (i = 0; i < image.num_sections; i++)
2230 {
2231 buffer = malloc(image.sections[i].size);
2232 if (buffer == NULL)
2233 {
2234 command_print(cmd_ctx, "error allocating buffer for section (%d bytes)", image.sections[i].size);
2235 break;
2236 }
2237 if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
2238 {
2239 free(buffer);
2240 break;
2241 }
2242
2243 if (verify)
2244 {
2245 /* calculate checksum of image */
2246 image_calculate_checksum( buffer, buf_cnt, &checksum );
2247
2248 retval = target_checksum_memory(target, image.sections[i].base_address, buf_cnt, &mem_checksum);
2249 if( retval != ERROR_OK )
2250 {
2251 free(buffer);
2252 break;
2253 }
2254
2255 if( checksum != mem_checksum )
2256 {
2257 /* failed crc checksum, fall back to a binary compare */
2258 u8 *data;
2259
2260 command_print(cmd_ctx, "checksum mismatch - attempting binary compare");
2261
2262 data = (u8*)malloc(buf_cnt);
2263
2264 /* Can we use 32bit word accesses? */
2265 int size = 1;
2266 int count = buf_cnt;
2267 if ((count % 4) == 0)
2268 {
2269 size *= 4;
2270 count /= 4;
2271 }
2272 retval = target_read_memory(target, image.sections[i].base_address, size, count, data);
2273 if (retval == ERROR_OK)
2274 {
2275 u32 t;
2276 for (t = 0; t < buf_cnt; t++)
2277 {
2278 if (data[t] != buffer[t])
2279 {
2280 command_print(cmd_ctx, "Verify operation failed address 0x%08x. Was 0x%02x instead of 0x%02x\n", t + image.sections[i].base_address, data[t], buffer[t]);
2281 free(data);
2282 free(buffer);
2283 retval=ERROR_FAIL;
2284 goto done;
2285 }
2286 if ((t%16384)==0)
2287 {
2288 keep_alive();
2289 }
2290 }
2291 }
2292
2293 free(data);
2294 }
2295 } else
2296 {
2297 command_print(cmd_ctx, "address 0x%08x length 0x%08x", image.sections[i].base_address, buf_cnt);
2298 }
2299
2300 free(buffer);
2301 image_size += buf_cnt;
2302 }
2303 done:
2304
2305 if((retvaltemp = duration_stop_measure(&duration, &duration_text)) != ERROR_OK)
2306 {
2307 image_close(&image);
2308 return retvaltemp;
2309 }
2310
2311 if (retval==ERROR_OK)
2312 {
2313 command_print(cmd_ctx, "verified %u bytes in %s", image_size, duration_text);
2314 }
2315 free(duration_text);
2316
2317 image_close(&image);
2318
2319 return retval;
2320 }
2321
2322 static int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2323 {
2324 return handle_verify_image_command_internal(cmd_ctx, cmd, args, argc, 1);
2325 }
2326
2327 static int handle_test_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2328 {
2329 return handle_verify_image_command_internal(cmd_ctx, cmd, args, argc, 0);
2330 }
2331
2332 static int handle_bp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2333 {
2334 int retval;
2335 target_t *target = get_current_target(cmd_ctx);
2336
2337 if (argc == 0)
2338 {
2339 breakpoint_t *breakpoint = target->breakpoints;
2340
2341 while (breakpoint)
2342 {
2343 if (breakpoint->type == BKPT_SOFT)
2344 {
2345 char* buf = buf_to_str(breakpoint->orig_instr, breakpoint->length, 16);
2346 command_print(cmd_ctx, "0x%8.8x, 0x%x, %i, 0x%s", breakpoint->address, breakpoint->length, breakpoint->set, buf);
2347 free(buf);
2348 }
2349 else
2350 {
2351 command_print(cmd_ctx, "0x%8.8x, 0x%x, %i", breakpoint->address, breakpoint->length, breakpoint->set);
2352 }
2353 breakpoint = breakpoint->next;
2354 }
2355 }
2356 else if (argc >= 2)
2357 {
2358 int hw = BKPT_SOFT;
2359 u32 length = 0;
2360
2361 length = strtoul(args[1], NULL, 0);
2362
2363 if (argc >= 3)
2364 if (strcmp(args[2], "hw") == 0)
2365 hw = BKPT_HARD;
2366
2367 if ((retval = breakpoint_add(target, strtoul(args[0], NULL, 0), length, hw)) != ERROR_OK)
2368 {
2369 LOG_ERROR("Failure setting breakpoints");
2370 }
2371 else
2372 {
2373 command_print(cmd_ctx, "breakpoint added at address 0x%8.8lx",
2374 strtoul(args[0], NULL, 0));
2375 }
2376 }
2377 else
2378 {
2379 command_print(cmd_ctx, "usage: bp <address> <length> ['hw']");
2380 }
2381
2382 return ERROR_OK;
2383 }
2384
2385 static int handle_rbp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2386 {
2387 target_t *target = get_current_target(cmd_ctx);
2388
2389 if (argc > 0)
2390 breakpoint_remove(target, strtoul(args[0], NULL, 0));
2391
2392 return ERROR_OK;
2393 }
2394
2395 static int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2396 {
2397 target_t *target = get_current_target(cmd_ctx);
2398 int retval;
2399
2400 if (argc == 0)
2401 {
2402 watchpoint_t *watchpoint = target->watchpoints;
2403
2404 while (watchpoint)
2405 {
2406 command_print(cmd_ctx, "address: 0x%8.8x, len: 0x%8.8x, r/w/a: %i, value: 0x%8.8x, mask: 0x%8.8x", watchpoint->address, watchpoint->length, watchpoint->rw, watchpoint->value, watchpoint->mask);
2407 watchpoint = watchpoint->next;
2408 }
2409 }
2410 else if (argc >= 2)
2411 {
2412 enum watchpoint_rw type = WPT_ACCESS;
2413 u32 data_value = 0x0;
2414 u32 data_mask = 0xffffffff;
2415
2416 if (argc >= 3)
2417 {
2418 switch(args[2][0])
2419 {
2420 case 'r':
2421 type = WPT_READ;
2422 break;
2423 case 'w':
2424 type = WPT_WRITE;
2425 break;
2426 case 'a':
2427 type = WPT_ACCESS;
2428 break;
2429 default:
2430 command_print(cmd_ctx, "usage: wp <address> <length> [r/w/a] [value] [mask]");
2431 return ERROR_OK;
2432 }
2433 }
2434 if (argc >= 4)
2435 {
2436 data_value = strtoul(args[3], NULL, 0);
2437 }
2438 if (argc >= 5)
2439 {
2440 data_mask = strtoul(args[4], NULL, 0);
2441 }
2442
2443 if ((retval = watchpoint_add(target, strtoul(args[0], NULL, 0),
2444 strtoul(args[1], NULL, 0), type, data_value, data_mask)) != ERROR_OK)
2445 {
2446 LOG_ERROR("Failure setting breakpoints");
2447 }
2448 }
2449 else
2450 {
2451 command_print(cmd_ctx, "usage: wp <address> <length> [r/w/a] [value] [mask]");
2452 }
2453
2454 return ERROR_OK;
2455 }
2456
2457 static int handle_rwp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2458 {
2459 target_t *target = get_current_target(cmd_ctx);
2460
2461 if (argc > 0)
2462 watchpoint_remove(target, strtoul(args[0], NULL, 0));
2463
2464 return ERROR_OK;
2465 }
2466
2467 static int handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
2468 {
2469 int retval;
2470 target_t *target = get_current_target(cmd_ctx);
2471 u32 va;
2472 u32 pa;
2473
2474 if (argc != 1)
2475 {
2476 return ERROR_COMMAND_SYNTAX_ERROR;
2477 }
2478 va = strtoul(args[0], NULL, 0);
2479
2480 retval = target->type->virt2phys(target, va, &pa);
2481 if (retval == ERROR_OK)
2482 {
2483 command_print(cmd_ctx, "Physical address 0x%08x", pa);
2484 }
2485 else
2486 {
2487 /* lower levels will have logged a detailed error which is
2488 * forwarded to telnet/GDB session.
2489 */
2490 }
2491 return retval;
2492 }
2493
2494 static void writeData(FILE *f, const void *data, size_t len)
2495 {
2496 size_t written = fwrite(data, len, 1, f);
2497 if (written != len)
2498 LOG_ERROR("failed to write %zu bytes: %s", len, strerror(errno));
2499 }
2500
2501 static void writeLong(FILE *f, int l)
2502 {
2503 int i;
2504 for (i=0; i<4; i++)
2505 {
2506 char c=(l>>(i*8))&0xff;
2507 writeData(f, &c, 1);
2508 }
2509
2510 }
2511
2512 static void writeString(FILE *f, char *s)
2513 {
2514 writeData(f, s, strlen(s));
2515 }
2516
2517 /* Dump a gmon.out histogram file. */
2518 static void writeGmon(u32 *samples, u32 sampleNum, char *filename)
2519 {
2520 u32 i;
2521 FILE *f=fopen(filename, "w");
2522 if (f==NULL)
2523 return;
2524 writeString(f, "gmon");
2525 writeLong(f, 0x00000001); /* Version */
2526 writeLong(f, 0); /* padding */
2527 writeLong(f, 0); /* padding */
2528 writeLong(f, 0); /* padding */
2529
2530 u8 zero = 0; /* GMON_TAG_TIME_HIST */
2531 writeData(f, &zero, 1);
2532
2533 /* figure out bucket size */
2534 u32 min=samples[0];
2535 u32 max=samples[0];
2536 for (i=0; i<sampleNum; i++)
2537 {
2538 if (min>samples[i])
2539 {
2540 min=samples[i];
2541 }
2542 if (max<samples[i])
2543 {
2544 max=samples[i];
2545 }
2546 }
2547
2548 int addressSpace=(max-min+1);
2549
2550 static const u32 maxBuckets = 256 * 1024; /* maximum buckets. */
2551 u32 length = addressSpace;
2552 if (length > maxBuckets)
2553 {
2554 length=maxBuckets;
2555 }
2556 int *buckets=malloc(sizeof(int)*length);
2557 if (buckets==NULL)
2558 {
2559 fclose(f);
2560 return;
2561 }
2562 memset(buckets, 0, sizeof(int)*length);
2563 for (i=0; i<sampleNum;i++)
2564 {
2565 u32 address=samples[i];
2566 long long a=address-min;
2567 long long b=length-1;
2568 long long c=addressSpace-1;
2569 int index=(a*b)/c; /* danger!!!! int32 overflows */
2570 buckets[index]++;
2571 }
2572
2573 /* append binary memory gmon.out &profile_hist_hdr ((char*)&profile_hist_hdr + sizeof(struct gmon_hist_hdr)) */
2574 writeLong(f, min); /* low_pc */
2575 writeLong(f, max); /* high_pc */
2576 writeLong(f, length); /* # of samples */
2577 writeLong(f, 64000000); /* 64MHz */
2578 writeString(f, "seconds");
2579 for (i=0; i<(15-strlen("seconds")); i++)
2580 writeData(f, &zero, 1);
2581 writeString(f, "s");
2582
2583 /*append binary memory gmon.out profile_hist_data (profile_hist_data + profile_hist_hdr.hist_size) */
2584
2585 char *data=malloc(2*length);
2586 if (data!=NULL)
2587 {
2588 for (i=0; i<length;i++)
2589 {
2590 int val;
2591 val=buckets[i];
2592 if (val>65535)
2593 {
2594 val=65535;
2595 }
2596 data[i*2]=val&0xff;
2597 data[i*2+1]=(val>>8)&0xff;
2598 }
2599 free(buckets);
2600 writeData(f, data, length * 2);
2601 free(data);
2602 } else
2603 {
2604 free(buckets);
2605 }
2606
2607 fclose(f);
2608 }
2609
2610 /* profiling samples the CPU PC as quickly as OpenOCD is able, which will be used as a random sampling of PC */
2611 static int handle_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2612 {
2613 target_t *target = get_current_target(cmd_ctx);
2614 struct timeval timeout, now;
2615
2616 gettimeofday(&timeout, NULL);
2617 if (argc!=2)
2618 {
2619 return ERROR_COMMAND_SYNTAX_ERROR;
2620 }
2621 char *end;
2622 timeval_add_time(&timeout, strtoul(args[0], &end, 0), 0);
2623 if (*end)
2624 {
2625 return ERROR_OK;
2626 }
2627
2628 command_print(cmd_ctx, "Starting profiling. Halting and resuming the target as often as we can...");
2629
2630 static const int maxSample=10000;
2631 u32 *samples=malloc(sizeof(u32)*maxSample);
2632 if (samples==NULL)
2633 return ERROR_OK;
2634
2635 int numSamples=0;
2636 int retval=ERROR_OK;
2637 /* hopefully it is safe to cache! We want to stop/restart as quickly as possible. */
2638 reg_t *reg = register_get_by_name(target->reg_cache, "pc", 1);
2639
2640 for (;;)
2641 {
2642 target_poll(target);
2643 if (target->state == TARGET_HALTED)
2644 {
2645 u32 t=*((u32 *)reg->value);
2646 samples[numSamples++]=t;
2647 retval = target_resume(target, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */
2648 target_poll(target);
2649 alive_sleep(10); /* sleep 10ms, i.e. <100 samples/second. */
2650 } else if (target->state == TARGET_RUNNING)
2651 {
2652 /* We want to quickly sample the PC. */
2653 if((retval = target_halt(target)) != ERROR_OK)
2654 {
2655 free(samples);
2656 return retval;
2657 }
2658 } else
2659 {
2660 command_print(cmd_ctx, "Target not halted or running");
2661 retval=ERROR_OK;
2662 break;
2663 }
2664 if (retval!=ERROR_OK)
2665 {
2666 break;
2667 }
2668
2669 gettimeofday(&now, NULL);
2670 if ((numSamples>=maxSample) || ((now.tv_sec >= timeout.tv_sec) && (now.tv_usec >= timeout.tv_usec)))
2671 {
2672 command_print(cmd_ctx, "Profiling completed. %d samples.", numSamples);
2673 if((retval = target_poll(target)) != ERROR_OK)
2674 {
2675 free(samples);
2676 return retval;
2677 }
2678 if (target->state == TARGET_HALTED)
2679 {
2680 target_resume(target, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */
2681 }
2682 if((retval = target_poll(target)) != ERROR_OK)
2683 {
2684 free(samples);
2685 return retval;
2686 }
2687 writeGmon(samples, numSamples, args[1]);
2688 command_print(cmd_ctx, "Wrote %s", args[1]);
2689 break;
2690 }
2691 }
2692 free(samples);
2693
2694 return ERROR_OK;
2695 }
2696
2697 static int new_int_array_element(Jim_Interp * interp, const char *varname, int idx, u32 val)
2698 {
2699 char *namebuf;
2700 Jim_Obj *nameObjPtr, *valObjPtr;
2701 int result;
2702
2703 namebuf = alloc_printf("%s(%d)", varname, idx);
2704 if (!namebuf)
2705 return JIM_ERR;
2706
2707 nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);
2708 valObjPtr = Jim_NewIntObj(interp, val);
2709 if (!nameObjPtr || !valObjPtr)
2710 {
2711 free(namebuf);
2712 return JIM_ERR;
2713 }
2714
2715 Jim_IncrRefCount(nameObjPtr);
2716 Jim_IncrRefCount(valObjPtr);
2717 result = Jim_SetVariable(interp, nameObjPtr, valObjPtr);
2718 Jim_DecrRefCount(interp, nameObjPtr);
2719 Jim_DecrRefCount(interp, valObjPtr);
2720 free(namebuf);
2721 /* printf("%s(%d) <= 0%08x\n", varname, idx, val); */
2722 return result;
2723 }
2724
2725 static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
2726 {
2727 command_context_t *context;
2728 target_t *target;
2729
2730 context = Jim_GetAssocData(interp, "context");
2731 if (context == NULL)
2732 {
2733 LOG_ERROR("mem2array: no command context");
2734 return JIM_ERR;
2735 }
2736 target = get_current_target(context);
2737 if (target == NULL)
2738 {
2739 LOG_ERROR("mem2array: no current target");
2740 return JIM_ERR;
2741 }
2742
2743 return target_mem2array(interp, target, argc-1, argv+1);
2744 }
2745
2746 static int target_mem2array(Jim_Interp *interp, target_t *target, int argc, Jim_Obj *const *argv)
2747 {
2748 long l;
2749 u32 width;
2750 int len;
2751 u32 addr;
2752 u32 count;
2753 u32 v;
2754 const char *varname;
2755 u8 buffer[4096];
2756 int n, e, retval;
2757 u32 i;
2758
2759 /* argv[1] = name of array to receive the data
2760 * argv[2] = desired width
2761 * argv[3] = memory address
2762 * argv[4] = count of times to read
2763 */
2764 if (argc != 4) {
2765 Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");
2766 return JIM_ERR;
2767 }
2768 varname = Jim_GetString(argv[0], &len);
2769 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
2770
2771 e = Jim_GetLong(interp, argv[1], &l);
2772 width = l;
2773 if (e != JIM_OK) {
2774 return e;
2775 }
2776
2777 e = Jim_GetLong(interp, argv[2], &l);
2778 addr = l;
2779 if (e != JIM_OK) {
2780 return e;
2781 }
2782 e = Jim_GetLong(interp, argv[3], &l);
2783 len = l;
2784 if (e != JIM_OK) {
2785 return e;
2786 }
2787 switch (width) {
2788 case 8:
2789 width = 1;
2790 break;
2791 case 16:
2792 width = 2;
2793 break;
2794 case 32:
2795 width = 4;
2796 break;
2797 default:
2798 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2799 Jim_AppendStrings( interp, Jim_GetResult(interp), "Invalid width param, must be 8/16/32", NULL );
2800 return JIM_ERR;
2801 }
2802 if (len == 0) {
2803 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2804 Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: zero width read?", NULL);
2805 return JIM_ERR;
2806 }
2807 if ((addr + (len * width)) < addr) {
2808 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2809 Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: addr + len - wraps to zero?", NULL);
2810 return JIM_ERR;
2811 }
2812 /* absurd transfer size? */
2813 if (len > 65536) {
2814 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2815 Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: absurd > 64K item request", NULL);
2816 return JIM_ERR;
2817 }
2818
2819 if ((width == 1) ||
2820 ((width == 2) && ((addr & 1) == 0)) ||
2821 ((width == 4) && ((addr & 3) == 0))) {
2822 /* all is well */
2823 } else {
2824 char buf[100];
2825 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2826 sprintf(buf, "mem2array address: 0x%08x is not aligned for %d byte reads", addr, width);
2827 Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);
2828 return JIM_ERR;
2829 }
2830
2831 /* Transfer loop */
2832
2833 /* index counter */
2834 n = 0;
2835 /* assume ok */
2836 e = JIM_OK;
2837 while (len) {
2838 /* Slurp... in buffer size chunks */
2839
2840 count = len; /* in objects.. */
2841 if (count > (sizeof(buffer)/width)) {
2842 count = (sizeof(buffer)/width);
2843 }
2844
2845 retval = target_read_memory( target, addr, width, count, buffer );
2846 if (retval != ERROR_OK) {
2847 /* BOO !*/
2848 LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed", addr, width, count);
2849 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2850 Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: cannot read memory", NULL);
2851 e = JIM_ERR;
2852 len = 0;
2853 } else {
2854 v = 0; /* shut up gcc */
2855 for (i = 0 ;i < count ;i++, n++) {
2856 switch (width) {
2857 case 4:
2858 v = target_buffer_get_u32(target, &buffer[i*width]);
2859 break;
2860 case 2:
2861 v = target_buffer_get_u16(target, &buffer[i*width]);
2862 break;
2863 case 1:
2864 v = buffer[i] & 0x0ff;
2865 break;
2866 }
2867 new_int_array_element(interp, varname, n, v);
2868 }
2869 len -= count;
2870 }
2871 }
2872
2873 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2874
2875 return JIM_OK;
2876 }
2877
2878 static int get_int_array_element(Jim_Interp * interp, const char *varname, int idx, u32 *val)
2879 {
2880 char *namebuf;
2881 Jim_Obj *nameObjPtr, *valObjPtr;
2882 int result;
2883 long l;
2884
2885 namebuf = alloc_printf("%s(%d)", varname, idx);
2886 if (!namebuf)
2887 return JIM_ERR;
2888
2889 nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);
2890 if (!nameObjPtr)
2891 {
2892 free(namebuf);
2893 return JIM_ERR;
2894 }
2895
2896 Jim_IncrRefCount(nameObjPtr);
2897 valObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_ERRMSG);
2898 Jim_DecrRefCount(interp, nameObjPtr);
2899 free(namebuf);
2900 if (valObjPtr == NULL)
2901 return JIM_ERR;
2902
2903 result = Jim_GetLong(interp, valObjPtr, &l);
2904 /* printf("%s(%d) => 0%08x\n", varname, idx, val); */
2905 *val = l;
2906 return result;
2907 }
2908
2909 static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
2910 {
2911 command_context_t *context;
2912 target_t *target;
2913
2914 context = Jim_GetAssocData(interp, "context");
2915 if (context == NULL){
2916 LOG_ERROR("array2mem: no command context");
2917 return JIM_ERR;
2918 }
2919 target = get_current_target(context);
2920 if (target == NULL){
2921 LOG_ERROR("array2mem: no current target");
2922 return JIM_ERR;
2923 }
2924
2925 return target_array2mem( interp,target, argc-1, argv+1 );
2926 }
2927
2928 static int target_array2mem(Jim_Interp *interp, target_t *target, int argc, Jim_Obj *const *argv)
2929 {
2930 long l;
2931 u32 width;
2932 int len;
2933 u32 addr;
2934 u32 count;
2935 u32 v;
2936 const char *varname;
2937 u8 buffer[4096];
2938 int n, e, retval;
2939 u32 i;
2940
2941 /* argv[1] = name of array to get the data
2942 * argv[2] = desired width
2943 * argv[3] = memory address
2944 * argv[4] = count to write
2945 */
2946 if (argc != 4) {
2947 Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");
2948 return JIM_ERR;
2949 }
2950 varname = Jim_GetString(argv[0], &len);
2951 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
2952
2953 e = Jim_GetLong(interp, argv[1], &l);
2954 width = l;
2955 if (e != JIM_OK) {
2956 return e;
2957 }
2958
2959 e = Jim_GetLong(interp, argv[2], &l);
2960 addr = l;
2961 if (e != JIM_OK) {
2962 return e;
2963 }
2964 e = Jim_GetLong(interp, argv[3], &l);
2965 len = l;
2966 if (e != JIM_OK) {
2967 return e;
2968 }
2969 switch (width) {
2970 case 8:
2971 width = 1;
2972 break;
2973 case 16:
2974 width = 2;
2975 break;
2976 case 32:
2977 width = 4;
2978 break;
2979 default:
2980 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2981 Jim_AppendStrings( interp, Jim_GetResult(interp), "Invalid width param, must be 8/16/32", NULL );
2982 return JIM_ERR;
2983 }
2984 if (len == 0) {
2985 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2986 Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: zero width read?", NULL);
2987 return JIM_ERR;
2988 }
2989 if ((addr + (len * width)) < addr) {
2990 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2991 Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: addr + len - wraps to zero?", NULL);
2992 return JIM_ERR;
2993 }
2994 /* absurd transfer size? */
2995 if (len > 65536) {
2996 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2997 Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: absurd > 64K item request", NULL);
2998 return JIM_ERR;
2999 }
3000
3001 if ((width == 1) ||
3002 ((width == 2) && ((addr & 1) == 0)) ||
3003 ((width == 4) && ((addr & 3) == 0))) {
3004 /* all is well */
3005 } else {
3006 char buf[100];
3007 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
3008 sprintf(buf, "array2mem address: 0x%08x is not aligned for %d byte reads", addr, width);
3009 Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);
3010 return JIM_ERR;
3011 }
3012
3013 /* Transfer loop */
3014
3015 /* index counter */
3016 n = 0;
3017 /* assume ok */
3018 e = JIM_OK;
3019 while (len) {
3020 /* Slurp... in buffer size chunks */
3021
3022 count = len; /* in objects.. */
3023 if (count > (sizeof(buffer)/width)) {
3024 count = (sizeof(buffer)/width);
3025 }
3026
3027 v = 0; /* shut up gcc */
3028 for (i = 0 ;i < count ;i++, n++) {
3029 get_int_array_element(interp, varname, n, &v);
3030 switch (width) {
3031 case 4:
3032 target_buffer_set_u32(target, &buffer[i*width], v);
3033 break;
3034 case 2:
3035 target_buffer_set_u16(target, &buffer[i*width], v);
3036 break;
3037 case 1:
3038 buffer[i] = v & 0x0ff;
3039 break;
3040 }
3041 }
3042 len -= count;
3043
3044 retval = target_write_memory(target, addr, width, count, buffer);
3045 if (retval != ERROR_OK) {
3046 /* BOO !*/
3047 LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed", addr, width, count);
3048 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
3049 Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: cannot read memory", NULL);
3050 e = JIM_ERR;
3051 len = 0;
3052 }
3053 }
3054
3055 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
3056
3057 return JIM_OK;
3058 }
3059
3060 void target_all_handle_event( enum target_event e )
3061 {
3062 target_t *target;
3063
3064 LOG_DEBUG( "**all*targets: event: %d, %s",
3065 e,
3066 Jim_Nvp_value2name_simple( nvp_target_event, e )->name );
3067
3068 target = all_targets;
3069 while (target){
3070 target_handle_event( target, e );
3071 target = target->next;
3072 }
3073 }
3074
3075 void target_handle_event( target_t *target, enum target_event e )
3076 {
3077 target_event_action_t *teap;
3078 int done;
3079
3080 teap = target->event_action;
3081
3082 done = 0;
3083 while( teap ){
3084 if( teap->event == e ){
3085 done = 1;
3086 LOG_DEBUG( "target: (%d) %s (%s) event: %d (%s) action: %s\n",
3087 target->target_number,
3088 target->cmd_name,
3089 target->type->name,
3090 e,
3091 Jim_Nvp_value2name_simple( nvp_target_event, e )->name,
3092 Jim_GetString( teap->body, NULL ) );
3093 if (Jim_EvalObj( interp, teap->body )!=JIM_OK)
3094 {
3095 Jim_PrintErrorMessage(interp);
3096 }
3097 }
3098 teap = teap->next;
3099 }
3100 if( !done ){
3101 LOG_DEBUG( "event: %d %s - no action",
3102 e,
3103 Jim_Nvp_value2name_simple( nvp_target_event, e )->name );
3104 }
3105 }
3106
3107 enum target_cfg_param {
3108 TCFG_TYPE,
3109 TCFG_EVENT,
3110 TCFG_WORK_AREA_VIRT,
3111 TCFG_WORK_AREA_PHYS,
3112 TCFG_WORK_AREA_SIZE,
3113 TCFG_WORK_AREA_BACKUP,
3114 TCFG_ENDIAN,
3115 TCFG_VARIANT,
3116 TCFG_CHAIN_POSITION,
3117 };
3118
3119 static Jim_Nvp nvp_config_opts[] = {
3120 { .name = "-type", .value = TCFG_TYPE },
3121 { .name = "-event", .value = TCFG_EVENT },
3122 { .name = "-work-area-virt", .value = TCFG_WORK_AREA_VIRT },
3123 { .name = "-work-area-phys", .value = TCFG_WORK_AREA_PHYS },
3124 { .name = "-work-area-size", .value = TCFG_WORK_AREA_SIZE },
3125 { .name = "-work-area-backup", .value = TCFG_WORK_AREA_BACKUP },
3126 { .name = "-endian" , .value = TCFG_ENDIAN },
3127 { .name = "-variant", .value = TCFG_VARIANT },
3128 { .name = "-chain-position", .value = TCFG_CHAIN_POSITION },
3129
3130 { .name = NULL, .value = -1 }
3131 };
3132
3133 static int target_configure( Jim_GetOptInfo *goi, target_t *target )
3134 {
3135 Jim_Nvp *n;
3136 Jim_Obj *o;
3137 jim_wide w;
3138 char *cp;
3139 int e;
3140
3141 /* parse config or cget options ... */
3142 while( goi->argc > 0 ){
3143 Jim_SetEmptyResult( goi->interp );
3144 /* Jim_GetOpt_Debug( goi ); */
3145
3146 if( target->type->target_jim_configure ){
3147 /* target defines a configure function */
3148 /* target gets first dibs on parameters */
3149 e = (*(target->type->target_jim_configure))( target, goi );
3150 if( e == JIM_OK ){
3151 /* more? */
3152 continue;
3153 }
3154 if( e == JIM_ERR ){
3155 /* An error */
3156 return e;
3157 }
3158 /* otherwise we 'continue' below */
3159 }
3160 e = Jim_GetOpt_Nvp( goi, nvp_config_opts, &n );
3161 if( e != JIM_OK ){
3162 Jim_GetOpt_NvpUnknown( goi, nvp_config_opts, 0 );
3163 return e;
3164 }
3165 switch( n->value ){
3166 case TCFG_TYPE:
3167 /* not setable */
3168 if( goi->isconfigure ){
3169 Jim_SetResult_sprintf( goi->interp, "not setable: %s", n->name );
3170 return JIM_ERR;
3171 } else {
3172 no_params:
3173 if( goi->argc != 0 ){
3174 Jim_WrongNumArgs( goi->interp, goi->argc, goi->argv, "NO PARAMS");
3175 return JIM_ERR;
3176 }
3177 }
3178 Jim_SetResultString( goi->interp, target->type->name, -1 );
3179 /* loop for more */
3180 break;
3181 case TCFG_EVENT:
3182 if( goi->argc == 0 ){
3183 Jim_WrongNumArgs( goi->interp, goi->argc, goi->argv, "-event ?event-name? ...");
3184 return JIM_ERR;
3185 }
3186
3187 e = Jim_GetOpt_Nvp( goi, nvp_target_event, &n );
3188 if( e != JIM_OK ){
3189 Jim_GetOpt_NvpUnknown( goi, nvp_target_event, 1 );
3190 return e;
3191 }
3192
3193 if( goi->isconfigure ){
3194 if( goi->argc != 1 ){
3195 Jim_WrongNumArgs( goi->interp, goi->argc, goi->argv, "-event ?event-name? ?EVENT-BODY?");
3196 return JIM_ERR;
3197 }
3198 } else {
3199 if( goi->argc != 0 ){
3200 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name?");
3201 return JIM_ERR;
3202 }
3203 }
3204
3205 {
3206 target_event_action_t *teap;
3207
3208 teap = target->event_action;
3209 /* replace existing? */
3210 while( teap ){
3211 if( teap->event == (enum target_event)n->value ){
3212 break;
3213 }
3214 teap = teap->next;
3215 }
3216
3217 if( goi->isconfigure ){
3218 if( teap == NULL ){
3219 /* create new */
3220 teap = calloc( 1, sizeof(*teap) );
3221 }
3222 teap->event = n->value;
3223 Jim_GetOpt_Obj( goi, &o );
3224 if( teap->body ){
3225 Jim_DecrRefCount( interp, teap->body );
3226 }
3227 teap->body = Jim_DuplicateObj( goi->interp, o );
3228 /*
3229 * FIXME:
3230 * Tcl/TK - "tk events" have a nice feature.
3231 * See the "BIND" command.
3232 * We should support that here.
3233 * You can specify %X and %Y in the event code.
3234 * The idea is: %T - target name.
3235 * The idea is: %N - target number
3236 * The idea is: %E - event name.
3237 */
3238 Jim_IncrRefCount( teap->body );
3239
3240 /* add to head of event list */
3241 teap->next = target->event_action;
3242 target->event_action = teap;
3243 Jim_SetEmptyResult(goi->interp);
3244 } else {
3245 /* get */
3246 if( teap == NULL ){
3247 Jim_SetEmptyResult( goi->interp );
3248 } else {
3249 Jim_SetResult( goi->interp, Jim_DuplicateObj( goi->interp, teap->body ) );
3250 }
3251 }
3252 }
3253 /* loop for more */
3254 break;
3255
3256 case TCFG_WORK_AREA_VIRT:
3257 if( goi->isconfigure ){
3258 target_free_all_working_areas(target);
3259 e = Jim_GetOpt_Wide( goi, &w );
3260 if( e != JIM_OK ){
3261 return e;
3262 }
3263 target->working_area_virt = w;
3264 } else {
3265 if( goi->argc != 0 ){
3266 goto no_params;
3267 }
3268 }
3269 Jim_SetResult( interp, Jim_NewIntObj( goi->interp, target->working_area_virt ) );
3270 /* loop for more */
3271 break;
3272
3273 case TCFG_WORK_AREA_PHYS:
3274 if( goi->isconfigure ){
3275 target_free_all_working_areas(target);
3276 e = Jim_GetOpt_Wide( goi, &w );
3277 if( e != JIM_OK ){
3278 return e;
3279 }
3280 target->working_area_phys = w;
3281 } else {
3282 if( goi->argc != 0 ){
3283 goto no_params;
3284 }
3285 }
3286 Jim_SetResult( interp, Jim_NewIntObj( goi->interp, target->working_area_phys ) );
3287 /* loop for more */
3288 break;
3289
3290 case TCFG_WORK_AREA_SIZE:
3291 if( goi->isconfigure ){
3292 target_free_all_working_areas(target);
3293 e = Jim_GetOpt_Wide( goi, &w );
3294 if( e != JIM_OK ){
3295 return e;
3296 }
3297 target->working_area_size = w;
3298 } else {
3299 if( goi->argc != 0 ){
3300 goto no_params;
3301 }
3302 }
3303 Jim_SetResult( interp, Jim_NewIntObj( goi->interp, target->working_area_size ) );
3304 /* loop for more */
3305 break;
3306
3307 case TCFG_WORK_AREA_BACKUP:
3308 if( goi->isconfigure ){
3309 target_free_all_working_areas(target);
3310 e = Jim_GetOpt_Wide( goi, &w );
3311 if( e != JIM_OK ){
3312 return e;
3313 }
3314 /* make this exactly 1 or 0 */
3315 target->backup_working_area = (!!w);
3316 } else {
3317 if( goi->argc != 0 ){
3318 goto no_params;
3319 }
3320 }
3321 Jim_SetResult( interp, Jim_NewIntObj( goi->interp, target->working_area_size ) );
3322 /* loop for more e*/
3323 break;
3324
3325 case TCFG_ENDIAN:
3326 if( goi->isconfigure ){
3327 e = Jim_GetOpt_Nvp( goi, nvp_target_endian, &n );
3328 if( e != JIM_OK ){
3329 Jim_GetOpt_NvpUnknown( goi, nvp_target_endian, 1 );
3330 return e;
3331 }
3332 target->endianness = n->value;
3333 } else {
3334 if( goi->argc != 0 ){
3335 goto no_params;
3336 }
3337 }
3338 n = Jim_Nvp_value2name_simple( nvp_target_endian, target->endianness );
3339 if( n->name == NULL ){
3340 target->endianness = TARGET_LITTLE_ENDIAN;
3341 n = Jim_Nvp_value2name_simple( nvp_target_endian, target->endianness );
3342 }
3343 Jim_SetResultString( goi->interp, n->name, -1 );
3344 /* loop for more */
3345 break;
3346
3347 case TCFG_VARIANT:
3348 if( goi->isconfigure ){
3349 if( goi->argc < 1 ){
3350 Jim_SetResult_sprintf( goi->interp,
3351 "%s ?STRING?",
3352 n->name );
3353 return JIM_ERR;
3354 }
3355 if( target->variant ){
3356 free((void *)(target->variant));
3357 }
3358 e = Jim_GetOpt_String( goi, &cp, NULL );
3359 target->variant = strdup(cp);
3360 } else {
3361 if( goi->argc != 0 ){
3362 goto no_params;
3363 }
3364 }
3365 Jim_SetResultString( goi->interp, target->variant,-1 );
3366 /* loop for more */
3367 break;
3368 case TCFG_CHAIN_POSITION:
3369 if( goi->isconfigure ){
3370 Jim_Obj *o;
3371 jtag_tap_t *tap;
3372 target_free_all_working_areas(target);
3373 e = Jim_GetOpt_Obj( goi, &o );
3374 if( e != JIM_OK ){
3375 return e;
3376 }
3377 tap = jtag_TapByJimObj( goi->interp, o );
3378 if( tap == NULL ){
3379 return JIM_ERR;
3380 }
3381 /* make this exactly 1 or 0 */
3382 target->tap = tap;
3383 } else {
3384 if( goi->argc != 0 ){
3385 goto no_params;
3386 }
3387 }
3388 Jim_SetResultString( interp, target->tap->dotted_name, -1 );
3389 /* loop for more e*/
3390 break;
3391 }
3392 } /* while( goi->argc ) */
3393
3394
3395 /* done - we return */
3396 return JIM_OK;
3397 }
3398
3399 /** this is the 'tcl' handler for the target specific command */
3400 static int tcl_target_func( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
3401 {
3402 Jim_GetOptInfo goi;
3403 jim_wide a,b,c;
3404 int x,y,z;
3405 u8 target_buf[32];
3406 Jim_Nvp *n;
3407 target_t *target;
3408 struct command_context_s *cmd_ctx;
3409 int e;
3410
3411 enum {
3412 TS_CMD_CONFIGURE,
3413 TS_CMD_CGET,
3414
3415 TS_CMD_MWW, TS_CMD_MWH, TS_CMD_MWB,
3416 TS_CMD_MDW, TS_CMD_MDH, TS_CMD_MDB,
3417 TS_CMD_MRW, TS_CMD_MRH, TS_CMD_MRB,
3418 TS_CMD_MEM2ARRAY, TS_CMD_ARRAY2MEM,
3419 TS_CMD_EXAMINE,
3420 TS_CMD_POLL,
3421 TS_CMD_RESET,
3422 TS_CMD_HALT,
3423 TS_CMD_WAITSTATE,
3424 TS_CMD_EVENTLIST,
3425 TS_CMD_CURSTATE,
3426 TS_CMD_INVOKE_EVENT,
3427 };
3428
3429 static const Jim_Nvp target_options[] = {
3430 { .name = "configure", .value = TS_CMD_CONFIGURE },
3431 { .name = "cget", .value = TS_CMD_CGET },
3432 { .name = "mww", .value = TS_CMD_MWW },
3433 { .name = "mwh", .value = TS_CMD_MWH },
3434 { .name = "mwb", .value = TS_CMD_MWB },
3435 { .name = "mdw", .value = TS_CMD_MDW },
3436 { .name = "mdh", .value = TS_CMD_MDH },
3437 { .name = "mdb", .value = TS_CMD_MDB },
3438 { .name = "mem2array", .value = TS_CMD_MEM2ARRAY },
3439 { .name = "array2mem", .value = TS_CMD_ARRAY2MEM },
3440 { .name = "eventlist", .value = TS_CMD_EVENTLIST },
3441 { .name = "curstate", .value = TS_CMD_CURSTATE },
3442
3443 { .name = "arp_examine", .value = TS_CMD_EXAMINE },
3444 { .name = "arp_poll", .value = TS_CMD_POLL },
3445 { .name = "arp_reset", .value = TS_CMD_RESET },
3446 { .name = "arp_halt", .value = TS_CMD_HALT },
3447 { .name = "arp_waitstate", .value = TS_CMD_WAITSTATE },
3448 { .name = "invoke-event", .value = TS_CMD_INVOKE_EVENT },
3449
3450 { .name = NULL, .value = -1 },
3451 };
3452
3453 /* go past the "command" */
3454 Jim_GetOpt_Setup( &goi, interp, argc-1, argv+1 );
3455
3456 target = Jim_CmdPrivData( goi.interp );
3457 cmd_ctx = Jim_GetAssocData(goi.interp, "context");
3458
3459 /* commands here are in an NVP table */
3460 e = Jim_GetOpt_Nvp( &goi, target_options, &n );
3461 if( e != JIM_OK ){
3462 Jim_GetOpt_NvpUnknown( &goi, target_options, 0 );
3463 return e;
3464 }
3465 /* Assume blank result */
3466 Jim_SetEmptyResult( goi.interp );
3467
3468 switch( n->value ){
3469 case TS_CMD_CONFIGURE:
3470 if( goi.argc < 2 ){
3471 Jim_WrongNumArgs( goi.interp, goi.argc, goi.argv, "missing: -option VALUE ...");
3472 return JIM_ERR;
3473 }
3474 goi.isconfigure = 1;
3475 return target_configure( &goi, target );
3476 case TS_CMD_CGET:
3477 // some things take params
3478 if( goi.argc < 1 ){
3479 Jim_WrongNumArgs( goi.interp, 0, goi.argv, "missing: ?-option?");
3480 return JIM_ERR;
3481 }
3482 goi.isconfigure = 0;
3483 return target_configure( &goi, target );
3484 break;
3485 case TS_CMD_MWW:
3486 case TS_CMD_MWH:
3487 case TS_CMD_MWB:
3488 /* argv[0] = cmd
3489 * argv[1] = address
3490 * argv[2] = data
3491 * argv[3] = optional count.
3492 */
3493
3494 if( (goi.argc == 3) || (goi.argc == 4) ){
3495 /* all is well */
3496 } else {
3497 mwx_error:
3498 Jim_SetResult_sprintf( goi.interp, "expected: %s ADDR DATA [COUNT]", n->name );
3499 return JIM_ERR;
3500 }
3501
3502 e = Jim_GetOpt_Wide( &goi, &a );
3503 if( e != JIM_OK ){
3504 goto mwx_error;
3505 }
3506
3507 e = Jim_GetOpt_Wide( &goi, &b );
3508 if( e != JIM_OK ){
3509 goto mwx_error;
3510 }
3511 if( goi.argc ){
3512 e = Jim_GetOpt_Wide( &goi, &c );
3513 if( e != JIM_OK ){
3514 goto mwx_error;
3515 }
3516 } else {
3517 c = 1;
3518 }
3519
3520 switch( n->value ){
3521 case TS_CMD_MWW:
3522 target_buffer_set_u32( target, target_buf, b );
3523 b = 4;
3524 break;
3525 case TS_CMD_MWH:
3526 target_buffer_set_u16( target, target_buf, b );
3527 b = 2;
3528 break;
3529 case TS_CMD_MWB:
3530 target_buffer_set_u8( target, target_buf, b );
3531 b = 1;
3532 break;
3533 }
3534 for( x = 0 ; x < c ; x++ ){
3535 e = target_write_memory( target, a, b, 1, target_buf );
3536 if( e != ERROR_OK ){
3537 Jim_SetResult_sprintf( interp, "Error writing @ 0x%08x: %d\n", (int)(a), e );
3538 return JIM_ERR;
3539 }
3540 /* b = width */
3541 a = a + b;
3542 }
3543 return JIM_OK;
3544 break;
3545
3546 /* display */
3547 case TS_CMD_MDW:
3548 case TS_CMD_MDH:
3549 case TS_CMD_MDB:
3550 /* argv[0] = command
3551 * argv[1] = address
3552 * argv[2] = optional count
3553 */
3554 if( (goi.argc == 2) || (goi.argc == 3) ){
3555 Jim_SetResult_sprintf( goi.interp, "expected: %s ADDR [COUNT]", n->name );
3556 return JIM_ERR;
3557 }
3558 e = Jim_GetOpt_Wide( &goi, &a );
3559 if( e != JIM_OK ){
3560 return JIM_ERR;
3561 }
3562 if( goi.argc ){
3563 e = Jim_GetOpt_Wide( &goi, &c );
3564 if( e != JIM_OK ){
3565 return JIM_ERR;
3566 }
3567 } else {
3568 c = 1;
3569 }
3570 b = 1; /* shut up gcc */
3571 switch( n->value ){
3572 case TS_CMD_MDW:
3573 b = 4;
3574 break;
3575 case TS_CMD_MDH:
3576 b = 2;
3577 break;
3578 case TS_CMD_MDB:
3579 b = 1;
3580 break;
3581 }
3582
3583 /* convert to "bytes" */
3584 c = c * b;
3585 /* count is now in 'BYTES' */
3586 while( c > 0 ){
3587 y = c;
3588 if( y > 16 ){
3589 y = 16;
3590 }
3591 e = target_read_memory( target, a, b, y / b, target_buf );
3592 if( e != ERROR_OK ){
3593 Jim_SetResult_sprintf( interp, "error reading target @ 0x%08lx", (int)(a) );
3594 return JIM_ERR;
3595 }
3596
3597 Jim_fprintf( interp, interp->cookie_stdout, "0x%08x ", (int)(a) );
3598 switch( b ){
3599 case 4:
3600 for( x = 0 ; (x < 16) && (x < y) ; x += 4 ){
3601 z = target_buffer_get_u32( target, &(target_buf[ x * 4 ]) );
3602 Jim_fprintf( interp, interp->cookie_stdout, "%08x ", (int)(z) );
3603 }
3604 for( ; (x < 16) ; x += 4 ){
3605 Jim_fprintf( interp, interp->cookie_stdout, " " );
3606 }
3607 break;
3608 case 2:
3609 for( x = 0 ; (x < 16) && (x < y) ; x += 2 ){
3610 z = target_buffer_get_u16( target, &(target_buf[ x * 2 ]) );
3611 Jim_fprintf( interp, interp->cookie_stdout, "%04x ", (int)(z) );
3612 }
3613 for( ; (x < 16) ; x += 2 ){
3614 Jim_fprintf( interp, interp->cookie_stdout, " " );
3615 }
3616 break;
3617 case 1:
3618 default:
3619 for( x = 0 ; (x < 16) && (x < y) ; x += 1 ){
3620 z = target_buffer_get_u8( target, &(target_buf[ x * 4 ]) );
3621 Jim_fprintf( interp, interp->cookie_stdout, "%02x ", (int)(z) );
3622 }
3623 for( ; (x < 16) ; x += 1 ){
3624 Jim_fprintf( interp, interp->cookie_stdout, " " );
3625 }
3626 break;
3627 }
3628 /* ascii-ify the bytes */
3629 for( x = 0 ; x < y ; x++ ){
3630 if( (target_buf[x] >= 0x20) &&
3631 (target_buf[x] <= 0x7e) ){
3632 /* good */
3633 } else {
3634 /* smack it */
3635 target_buf[x] = '.';
3636 }
3637 }
3638 /* space pad */
3639 while( x < 16 ){
3640 target_buf[x] = ' ';
3641 x++;
3642 }
3643 /* terminate */
3644 target_buf[16] = 0;
3645 /* print - with a newline */
3646 Jim_fprintf( interp, interp->cookie_stdout, "%s\n", target_buf );
3647 /* NEXT... */
3648 c -= 16;
3649 a += 16;
3650 }
3651 return JIM_OK;
3652 case TS_CMD_MEM2ARRAY:
3653 return target_mem2array( goi.interp, target, goi.argc, goi.argv );
3654 break;
3655 case TS_CMD_ARRAY2MEM:
3656 return target_array2mem( goi.interp, target, goi.argc, goi.argv );
3657 break;
3658 case TS_CMD_EXAMINE:
3659 if( goi.argc ){
3660 Jim_WrongNumArgs( goi.interp, 2, argv, "[no parameters]");
3661 return JIM_ERR;
3662 }
3663 e = target->type->examine( target );
3664 if( e != ERROR_OK ){
3665 Jim_SetResult_sprintf( interp, "examine-fails: %d", e );
3666 return JIM_ERR;
3667 }
3668 return JIM_OK;
3669 case TS_CMD_POLL:
3670 if( goi.argc ){
3671 Jim_WrongNumArgs( goi.interp, 2, argv, "[no parameters]");
3672 return JIM_ERR;
3673 }
3674 if( !(target->type->examined) ){
3675 e = ERROR_TARGET_NOT_EXAMINED;
3676 } else {
3677 e = target->type->poll( target );
3678 }
3679 if( e != ERROR_OK ){
3680 Jim_SetResult_sprintf( interp, "poll-fails: %d", e );
3681 return JIM_ERR;
3682 } else {
3683 return JIM_OK;
3684 }
3685 break;
3686 case TS_CMD_RESET:
3687 if( goi.argc != 2 ){
3688 Jim_WrongNumArgs( interp, 2, argv, "t|f|assert|deassert BOOL");
3689 return JIM_ERR;
3690 }
3691 e = Jim_GetOpt_Nvp( &goi, nvp_assert, &n );
3692 if( e != JIM_OK ){
3693 Jim_GetOpt_NvpUnknown( &goi, nvp_assert, 1 );
3694 return e;
3695 }
3696 /* the halt or not param */
3697 e = Jim_GetOpt_Wide( &goi, &a);
3698 if( e != JIM_OK ){
3699 return e;
3700 }
3701 /* determine if we should halt or not. */
3702 target->reset_halt = !!a;
3703 /* When this happens - all workareas are invalid. */
3704 target_free_all_working_areas_restore(target, 0);
3705
3706 /* do the assert */
3707 if( n->value == NVP_ASSERT ){
3708 target->type->assert_reset( target );
3709 } else {
3710 target->type->deassert_reset( target );
3711 }
3712 return JIM_OK;
3713 case TS_CMD_HALT:
3714 if( goi.argc ){
3715 Jim_WrongNumArgs( goi.interp, 0, argv, "halt [no parameters]");
3716 return JIM_ERR;
3717 }
3718 target->type->halt( target );
3719 return JIM_OK;
3720 case TS_CMD_WAITSTATE:
3721 /* params: <name> statename timeoutmsecs */
3722 if( goi.argc != 2 ){
3723 Jim_SetResult_sprintf( goi.interp, "%s STATENAME TIMEOUTMSECS", n->name );
3724 return JIM_ERR;
3725 }
3726 e = Jim_GetOpt_Nvp( &goi, nvp_target_state, &n );
3727 if( e != JIM_OK ){
3728 Jim_GetOpt_NvpUnknown( &goi, nvp_target_state,1 );
3729 return e;
3730 }
3731 e = Jim_GetOpt_Wide( &goi, &a );
3732 if( e != JIM_OK ){
3733 return e;
3734 }
3735 e = target_wait_state( target, n->value, a );
3736 if( e != ERROR_OK ){
3737 Jim_SetResult_sprintf( goi.interp,
3738 "target: %s wait %s fails (%d) %s",
3739 target->cmd_name,
3740 n->name,
3741 e, target_strerror_safe(e) );
3742 return JIM_ERR;
3743 } else {
3744 return JIM_OK;
3745 }
3746 case TS_CMD_EVENTLIST:
3747 /* List for human, Events defined for this target.
3748 * scripts/programs should use 'name cget -event NAME'
3749 */
3750 {
3751 target_event_action_t *teap;
3752 teap = target->event_action;
3753 command_print( cmd_ctx, "Event actions for target (%d) %s\n",
3754 target->target_number,
3755 target->cmd_name );
3756 command_print( cmd_ctx, "%-25s | Body", "Event");
3757 command_print( cmd_ctx, "------------------------- | ----------------------------------------");
3758 while( teap ){
3759 command_print( cmd_ctx,
3760 "%-25s | %s",
3761 Jim_Nvp_value2name_simple( nvp_target_event, teap->event )->name,
3762 Jim_GetString( teap->body, NULL ) );
3763 teap = teap->next;
3764 }
3765 command_print( cmd_ctx, "***END***");
3766 return JIM_OK;
3767 }
3768 case TS_CMD_CURSTATE:
3769 if( goi.argc != 0 ){
3770 Jim_WrongNumArgs( goi.interp, 0, argv, "[no parameters]");
3771 return JIM_ERR;
3772 }
3773 Jim_SetResultString( goi.interp,
3774 Jim_Nvp_value2name_simple(nvp_target_state,target->state)->name,-1);
3775 return JIM_OK;
3776 case TS_CMD_INVOKE_EVENT:
3777 if( goi.argc != 1 ){
3778 Jim_SetResult_sprintf( goi.interp, "%s ?EVENTNAME?",n->name);
3779 return JIM_ERR;
3780 }
3781 e = Jim_GetOpt_Nvp( &goi, nvp_target_event, &n );
3782 if( e != JIM_OK ){
3783 Jim_GetOpt_NvpUnknown( &goi, nvp_target_event, 1 );
3784 return e;
3785 }
3786 target_handle_event( target, n->value );
3787 return JIM_OK;
3788 }
3789 return JIM_ERR;
3790 }
3791
3792 static int target_create( Jim_GetOptInfo *goi )
3793 {
3794 Jim_Obj *new_cmd;
3795 Jim_Cmd *cmd;
3796 const char *cp;
3797 char *cp2;
3798 int e;
3799 int x;
3800 target_t *target;
3801 struct command_context_s *cmd_ctx;
3802
3803 cmd_ctx = Jim_GetAssocData(goi->interp, "context");
3804 if( goi->argc < 3 ){
3805 Jim_WrongNumArgs( goi->interp, 1, goi->argv, "?name? ?type? ..options...");
3806 return JIM_ERR;
3807 }
3808
3809 /* COMMAND */
3810 Jim_GetOpt_Obj( goi, &new_cmd );
3811 /* does this command exist? */
3812 cmd = Jim_GetCommand( goi->interp, new_cmd, JIM_ERRMSG );
3813 if( cmd ){
3814 cp = Jim_GetString( new_cmd, NULL );
3815 Jim_SetResult_sprintf(goi->interp, "Command/target: %s Exists", cp);
3816 return JIM_ERR;
3817 }
3818
3819 /* TYPE */
3820 e = Jim_GetOpt_String( goi, &cp2, NULL );
3821 cp = cp2;
3822 /* now does target type exist */
3823 for( x = 0 ; target_types[x] ; x++ ){
3824 if( 0 == strcmp( cp, target_types[x]->name ) ){
3825 /* found */
3826 break;
3827 }
3828 }
3829 if( target_types[x] == NULL ){
3830 Jim_SetResult_sprintf( goi->interp, "Unknown target type %s, try one of ", cp );
3831 for( x = 0 ; target_types[x] ; x++ ){
3832 if( target_types[x+1] ){
3833 Jim_AppendStrings( goi->interp,
3834 Jim_GetResult(goi->interp),
3835 target_types[x]->name,
3836 ", ", NULL);
3837 } else {
3838 Jim_AppendStrings( goi->interp,
3839 Jim_GetResult(goi->interp),
3840 " or ",
3841 target_types[x]->name,NULL );
3842 }
3843 }
3844 return JIM_ERR;
3845 }
3846
3847 /* Create it */
3848 target = calloc(1,sizeof(target_t));
3849 /* set target number */
3850 target->target_number = new_target_number();
3851
3852 /* allocate memory for each unique target type */
3853 target->type = (target_type_t*)calloc(1,sizeof(target_type_t));
3854
3855 memcpy( target->type, target_types[x], sizeof(target_type_t));
3856
3857 /* will be set by "-endian" */
3858 target->endianness = TARGET_ENDIAN_UNKNOWN;
3859
3860 target->working_area = 0x0;
3861 target->working_area_size = 0x0;
3862 target->working_areas = NULL;
3863 target->backup_working_area = 0;
3864
3865 target->state = TARGET_UNKNOWN;
3866 target->debug_reason = DBG_REASON_UNDEFINED;
3867 target->reg_cache = NULL;
3868 target->breakpoints = NULL;
3869 target->watchpoints = NULL;
3870 target->next = NULL;
3871 target->arch_info = NULL;
3872
3873 target->display = 1;
3874
3875 /* initialize trace information */
3876 target->trace_info = malloc(sizeof(trace_t));
3877 target->trace_info->num_trace_points = 0;
3878 target->trace_info->trace_points_size = 0;
3879 target->trace_info->trace_points = NULL;
3880 target->trace_info->trace_history_size = 0;
3881 target->trace_info->trace_history = NULL;
3882 target->trace_info->trace_history_pos = 0;
3883 target->trace_info->trace_history_overflowed = 0;
3884
3885 target->dbgmsg = NULL;
3886 target->dbg_msg_enabled = 0;
3887
3888 target->endianness = TARGET_ENDIAN_UNKNOWN;
3889
3890 /* Do the rest as "configure" options */
3891 goi->isconfigure = 1;
3892 e = target_configure( goi, target);
3893
3894 if (target->tap == NULL)
3895 {
3896 Jim_SetResultString( interp, "-chain-position required when creating target", -1);
3897 e=JIM_ERR;
3898 }
3899
3900 if( e != JIM_OK ){
3901 free( target->type );
3902 free( target );
3903 return e;
3904 }
3905
3906 if( target->endianness == TARGET_ENDIAN_UNKNOWN ){
3907 /* default endian to little if not specified */
3908 target->endianness = TARGET_LITTLE_ENDIAN;
3909 }
3910
3911 /* incase variant is not set */
3912 if (!target->variant)
3913 target->variant = strdup("");
3914
3915 /* create the target specific commands */
3916 if( target->type->register_commands ){
3917 (*(target->type->register_commands))( cmd_ctx );
3918 }
3919 if( target->type->target_create ){
3920 (*(target->type->target_create))( target, goi->interp );
3921 }
3922
3923 /* append to end of list */
3924 {
3925 target_t **tpp;
3926 tpp = &(all_targets);
3927 while( *tpp ){
3928 tpp = &( (*tpp)->next );
3929 }
3930 *tpp = target;
3931 }
3932
3933 cp = Jim_GetString( new_cmd, NULL );
3934 target->cmd_name = strdup(cp);
3935
3936 /* now - create the new target name command */
3937 e = Jim_CreateCommand( goi->interp,
3938 /* name */
3939 cp,
3940 tcl_target_func, /* C function */
3941 target, /* private data */
3942 NULL ); /* no del proc */
3943
3944 return e;
3945 }
3946
3947 static int jim_target( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
3948 {
3949 int x,r,e;
3950 jim_wide w;
3951 struct command_context_s *cmd_ctx;
3952 target_t *target;
3953 Jim_GetOptInfo goi;
3954 enum tcmd {
3955 /* TG = target generic */
3956 TG_CMD_CREATE,
3957 TG_CMD_TYPES,
3958 TG_CMD_NAMES,
3959 TG_CMD_CURRENT,
3960 TG_CMD_NUMBER,
3961 TG_CMD_COUNT,
3962 };
3963 const char *target_cmds[] = {
3964 "create", "types", "names", "current", "number",
3965 "count",
3966 NULL /* terminate */
3967 };
3968
3969 LOG_DEBUG("Target command params:");
3970 LOG_DEBUG("%s", Jim_Debug_ArgvString(interp, argc, argv));
3971
3972 cmd_ctx = Jim_GetAssocData( interp, "context" );
3973
3974 Jim_GetOpt_Setup( &goi, interp, argc-1, argv+1 );
3975
3976 if( goi.argc == 0 ){
3977 Jim_WrongNumArgs(interp, 1, argv, "missing: command ...");
3978 return JIM_ERR;
3979 }
3980
3981 /* Jim_GetOpt_Debug( &goi ); */
3982 r = Jim_GetOpt_Enum( &goi, target_cmds, &x );
3983 if( r != JIM_OK ){
3984 return r;
3985 }
3986
3987 switch(x){
3988 default:
3989 Jim_Panic(goi.interp,"Why am I here?");
3990 return JIM_ERR;
3991 case TG_CMD_CURRENT:
3992 if( goi.argc != 0 ){
3993 Jim_WrongNumArgs( goi.interp, 1, goi.argv, "Too many parameters");
3994 return JIM_ERR;
3995 }
3996 Jim_SetResultString( goi.interp, get_current_target( cmd_ctx )->cmd_name, -1 );
3997 return JIM_OK;
3998 case TG_CMD_TYPES:
3999 if( goi.argc != 0 ){
4000 Jim_WrongNumArgs( goi.interp, 1, goi.argv, "Too many parameters" );
4001 return JIM_ERR;
4002 }
4003 Jim_SetResult( goi.interp, Jim_NewListObj( goi.interp, NULL, 0 ) );
4004 for( x = 0 ; target_types[x] ; x++ ){
4005 Jim_ListAppendElement( goi.interp,
4006 Jim_GetResult(goi.interp),
4007 Jim_NewStringObj( goi.interp, target_types[x]->name, -1 ) );
4008 }
4009 return JIM_OK;
4010 case TG_CMD_NAMES:
4011 if( goi.argc != 0 ){
4012 Jim_WrongNumArgs( goi.interp, 1, goi.argv, "Too many parameters" );
4013 return JIM_ERR;
4014 }
4015 Jim_SetResult( goi.interp, Jim_NewListObj( goi.interp, NULL, 0 ) );
4016 target = all_targets;
4017 while( target ){
4018 Jim_ListAppendElement( goi.interp,
4019 Jim_GetResult(goi.interp),
4020 Jim_NewStringObj( goi.interp, target->cmd_name, -1 ) );
4021 target = target->next;
4022 }
4023 return JIM_OK;
4024 case TG_CMD_CREATE:
4025 if( goi.argc < 3 ){
4026 Jim_WrongNumArgs( goi.interp, goi.argc, goi.argv, "?name ... config options ...");
4027 return JIM_ERR;
4028 }
4029 return target_create( &goi );
4030 break;
4031 case TG_CMD_NUMBER:
4032 if( goi.argc != 1 ){
4033 Jim_SetResult_sprintf( goi.interp, "expected: target number ?NUMBER?");
4034 return JIM_ERR;
4035 }
4036 e = Jim_GetOpt_Wide( &goi, &w );
4037 if( e != JIM_OK ){
4038 return JIM_ERR;
4039 }
4040 {
4041 target_t *t;
4042 t = get_target_by_num(w);
4043 if( t == NULL ){
4044 Jim_SetResult_sprintf( goi.interp,"Target: number %d does not exist", (int)(w));
4045 return JIM_ERR;
4046 }
4047 Jim_SetResultString( goi.interp, t->cmd_name, -1 );
4048 return JIM_OK;
4049 }
4050 case TG_CMD_COUNT:
4051 if( goi.argc != 0 ){
4052 Jim_WrongNumArgs( goi.interp, 0, goi.argv, "<no parameters>");
4053 return JIM_ERR;
4054 }
4055 Jim_SetResult( goi.interp,
4056 Jim_NewIntObj( goi.interp, max_target_number()));
4057 return JIM_OK;
4058 }
4059
4060 return JIM_ERR;
4061 }
4062
4063
4064 struct FastLoad
4065 {
4066 u32 address;
4067 u8 *data;
4068 int length;
4069
4070 };
4071
4072 static int fastload_num;
4073 static struct FastLoad *fastload;
4074
4075 static void free_fastload(void)
4076 {
4077 if (fastload!=NULL)
4078 {
4079 int i;
4080 for (i=0; i<fastload_num; i++)
4081 {
4082 if (fastload[i].data)
4083 free(fastload[i].data);
4084 }
4085 free(fastload);
4086 fastload=NULL;
4087 }
4088 }
4089
4090
4091
4092
4093 static int handle_fast_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
4094 {
4095 u8 *buffer;
4096 u32 buf_cnt;
4097 u32 image_size;
4098 u32 min_address=0;
4099 u32 max_address=0xffffffff;
4100 int i;
4101 int retval;
4102
4103 image_t image;
4104
4105 duration_t duration;
4106 char *duration_text;
4107
4108 if ((argc < 1)||(argc > 5))
4109 {
4110 return ERROR_COMMAND_SYNTAX_ERROR;
4111 }
4112
4113 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
4114 if (argc >= 2)
4115 {
4116 image.base_address_set = 1;
4117 image.base_address = strtoul(args[1], NULL, 0);
4118 }
4119 else
4120 {
4121 image.base_address_set = 0;
4122 }
4123
4124
4125 image.start_address_set = 0;
4126
4127 if (argc>=4)
4128 {
4129 min_address=strtoul(args[3], NULL, 0);
4130 }
4131 if (argc>=5)
4132 {
4133 max_address=strtoul(args[4], NULL, 0)+min_address;
4134 }
4135
4136 if (min_address>max_address)
4137 {
4138 return ERROR_COMMAND_SYNTAX_ERROR;
4139 }
4140
4141 duration_start_measure(&duration);
4142
4143 if (image_open(&image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
4144 {
4145 return ERROR_OK;
4146 }
4147
4148 image_size = 0x0;
4149 retval = ERROR_OK;
4150 fastload_num=image.num_sections;
4151 fastload=(struct FastLoad *)malloc(sizeof(struct FastLoad)*image.num_sections);
4152 if (fastload==NULL)
4153 {
4154 image_close(&image);
4155 return ERROR_FAIL;
4156 }
4157 memset(fastload, 0, sizeof(struct FastLoad)*image.num_sections);
4158 for (i = 0; i < image.num_sections; i++)
4159 {
4160 buffer = malloc(image.sections[i].size);
4161 if (buffer == NULL)
4162 {
4163 command_print(cmd_ctx, "error allocating buffer for section (%d bytes)", image.sections[i].size);
4164 break;
4165 }
4166
4167 if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
4168 {
4169 free(buffer);
4170 break;
4171 }
4172
4173 u32 offset=0;
4174 u32 length=buf_cnt;
4175
4176
4177 /* DANGER!!! beware of unsigned comparision here!!! */
4178
4179 if ((image.sections[i].base_address+buf_cnt>=min_address)&&
4180 (image.sections[i].base_address<max_address))
4181 {
4182 if (image.sections[i].base_address<min_address)
4183 {
4184 /* clip addresses below */
4185 offset+=min_address-image.sections[i].base_address;
4186 length-=offset;
4187 }
4188
4189 if (image.sections[i].base_address+buf_cnt>max_address)
4190 {
4191 length-=(image.sections[i].base_address+buf_cnt)-max_address;
4192 }
4193
4194 fastload[i].address=image.sections[i].base_address+offset;
4195 fastload[i].data=malloc(length);
4196 if (fastload[i].data==NULL)
4197 {
4198 free(buffer);
4199 break;
4200 }
4201 memcpy(fastload[i].data, buffer+offset, length);
4202 fastload[i].length=length;
4203
4204 image_size += length;
4205 command_print(cmd_ctx, "%u byte written at address 0x%8.8x", length, image.sections[i].base_address+offset);
4206 }
4207
4208 free(buffer);
4209 }
4210
4211 duration_stop_measure(&duration, &duration_text);
4212 if (retval==ERROR_OK)
4213 {
4214 command_print(cmd_ctx, "Loaded %u bytes in %s", image_size, duration_text);
4215 command_print(cmd_ctx, "NB!!! image has not been loaded to target, issue a subsequent 'fast_load' to do so.");
4216 }
4217 free(duration_text);
4218
4219 image_close(&image);
4220
4221 if (retval!=ERROR_OK)
4222 {
4223 free_fastload();
4224 }
4225
4226 return retval;
4227 }
4228
4229 static int handle_fast_load_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
4230 {
4231 if (argc>0)
4232 return ERROR_COMMAND_SYNTAX_ERROR;
4233 if (fastload==NULL)
4234 {
4235 LOG_ERROR("No image in memory");
4236 return ERROR_FAIL;
4237 }
4238 int i;
4239 int ms=timeval_ms();
4240 int size=0;
4241 int retval=ERROR_OK;
4242 for (i=0; i<fastload_num;i++)
4243 {
4244 target_t *target = get_current_target(cmd_ctx);
4245 command_print(cmd_ctx, "Write to 0x%08x, length 0x%08x", fastload[i].address, fastload[i].length);
4246 if (retval==ERROR_OK)
4247 {
4248 retval = target_write_buffer(target, fastload[i].address, fastload[i].length, fastload[i].data);
4249 }
4250 size+=fastload[i].length;
4251 }
4252 int after=timeval_ms();
4253 command_print(cmd_ctx, "Loaded image %f kBytes/s", (float)(size/1024.0)/((float)(after-ms)/1000.0));
4254 return retval;
4255 }

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)