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

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)