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

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)