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

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)