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

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)