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

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)