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

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)