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