- added myself to copyright on files i remember adding large contributions for over...
[fw/openocd] / src / target / arm9tdmi.c
1 /***************************************************************************
2  *   Copyright (C) 2005 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   Copyright (C) 2008 by Spencer Oliver                                  *
6  *   spen@spen-soft.co.uk                                                  *
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 "arm9tdmi.h"
28
29 #include "arm7_9_common.h"
30 #include "register.h"
31 #include "target.h"
32 #include "armv4_5.h"
33 #include "embeddedice.h"
34 #include "etm.h"
35 #include "etb.h"
36 #include "log.h"
37 #include "jtag.h"
38 #include "arm_jtag.h"
39
40 #include <stdlib.h>
41 #include <string.h>
42
43 #if 0
44 #define _DEBUG_INSTRUCTION_EXECUTION_
45 #endif
46
47 /* cli handling */
48 int arm9tdmi_register_commands(struct command_context_s *cmd_ctx);
49 int handle_arm9tdmi_catch_vectors_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
50
51 /* forward declarations */
52 int arm9tdmi_target_create( struct target_s *target, Jim_Interp *interp );
53
54 int arm9tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
55 int arm9tdmi_quit(void);
56                 
57 target_type_t arm9tdmi_target =
58 {
59         .name = "arm9tdmi",
60
61         .poll = arm7_9_poll,
62         .arch_state = armv4_5_arch_state,
63
64         .target_request_data = arm7_9_target_request_data,
65
66         .halt = arm7_9_halt,
67         .resume = arm7_9_resume,
68         .step = arm7_9_step,
69
70         .assert_reset = arm7_9_assert_reset,
71         .deassert_reset = arm7_9_deassert_reset,
72         .soft_reset_halt = arm7_9_soft_reset_halt,
73
74         .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
75
76         .read_memory = arm7_9_read_memory,
77         .write_memory = arm7_9_write_memory,
78         .bulk_write_memory = arm7_9_bulk_write_memory,
79         .checksum_memory = arm7_9_checksum_memory,
80         .blank_check_memory = arm7_9_blank_check_memory,
81         
82         .run_algorithm = armv4_5_run_algorithm,
83         
84         .add_breakpoint = arm7_9_add_breakpoint,
85         .remove_breakpoint = arm7_9_remove_breakpoint,
86         .add_watchpoint = arm7_9_add_watchpoint,
87         .remove_watchpoint = arm7_9_remove_watchpoint,
88
89         .register_commands = arm9tdmi_register_commands,
90         .target_create = arm9tdmi_target_create,
91         .init_target = arm9tdmi_init_target,
92         .examine = arm9tdmi_examine,
93         .quit = arm9tdmi_quit
94 };
95
96 arm9tdmi_vector_t arm9tdmi_vectors[] =
97 {
98         {"reset", ARM9TDMI_RESET_VECTOR},
99         {"undef", ARM9TDMI_UNDEF_VECTOR},
100         {"swi", ARM9TDMI_SWI_VECTOR},
101         {"pabt", ARM9TDMI_PABT_VECTOR},
102         {"dabt", ARM9TDMI_DABT_VECTOR},
103         {"reserved", ARM9TDMI_RESERVED_VECTOR},
104         {"irq", ARM9TDMI_IRQ_VECTOR},
105         {"fiq", ARM9TDMI_FIQ_VECTOR},
106         {0, 0},
107 };
108
109 int arm9tdmi_examine_debug_reason(target_t *target)
110 {
111         /* get pointers to arch-specific information */
112         armv4_5_common_t *armv4_5 = target->arch_info;
113         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
114         
115         /* only check the debug reason if we don't know it already */
116         if ((target->debug_reason != DBG_REASON_DBGRQ)
117                         && (target->debug_reason != DBG_REASON_SINGLESTEP))
118         {
119                 scan_field_t fields[3];
120                 u8 databus[4];
121                 u8 instructionbus[4];
122                 u8 debug_reason;
123
124                 jtag_add_end_state(TAP_PD);
125
126                 fields[0].device = arm7_9->jtag_info.chain_pos;
127                 fields[0].num_bits = 32;
128                 fields[0].out_value = NULL;
129                 fields[0].out_mask = NULL;
130                 fields[0].in_value = databus;
131                 fields[0].in_check_value = NULL;
132                 fields[0].in_check_mask = NULL;
133                 fields[0].in_handler = NULL;
134                 fields[0].in_handler_priv = NULL;
135                 
136                 fields[1].device = arm7_9->jtag_info.chain_pos;
137                 fields[1].num_bits = 3;
138                 fields[1].out_value = NULL;
139                 fields[1].out_mask = NULL;
140                 fields[1].in_value = &debug_reason;
141                 fields[1].in_check_value = NULL;
142                 fields[1].in_check_mask = NULL;
143                 fields[1].in_handler = NULL;
144                 fields[1].in_handler_priv = NULL;
145                 
146                 fields[2].device = arm7_9->jtag_info.chain_pos;
147                 fields[2].num_bits = 32;
148                 fields[2].out_value = NULL;
149                 fields[2].out_mask = NULL;
150                 fields[2].in_value = instructionbus;
151                 fields[2].in_check_value = NULL;
152                 fields[2].in_check_mask = NULL;
153                 fields[2].in_handler = NULL;
154                 fields[2].in_handler_priv = NULL;
155                 
156                 arm_jtag_scann(&arm7_9->jtag_info, 0x1);
157                 arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL);
158
159                 jtag_add_dr_scan(3, fields, TAP_PD);
160                 jtag_execute_queue();
161                 
162                 fields[0].in_value = NULL;
163                 fields[0].out_value = databus;
164                 fields[1].in_value = NULL;
165                 fields[1].out_value = &debug_reason;
166                 fields[2].in_value = NULL;
167                 fields[2].out_value = instructionbus;
168                 
169                 jtag_add_dr_scan(3, fields, TAP_PD);
170
171                 if (debug_reason & 0x4)
172                         if (debug_reason & 0x2)
173                                 target->debug_reason = DBG_REASON_WPTANDBKPT;
174                 else
175                         target->debug_reason = DBG_REASON_WATCHPOINT;
176                 else
177                         target->debug_reason = DBG_REASON_BREAKPOINT;
178         }
179
180         return ERROR_OK;
181 }
182
183 /* put an instruction in the ARM9TDMI pipeline or write the data bus, and optionally read data */
184 int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int sysspeed)
185 {
186         scan_field_t fields[3];
187         u8 out_buf[4];
188         u8 instr_buf[4];
189         u8 sysspeed_buf = 0x0;
190         
191         /* prepare buffer */
192         buf_set_u32(out_buf, 0, 32, out);
193         
194         buf_set_u32(instr_buf, 0, 32, flip_u32(instr, 32));
195         
196         if (sysspeed)
197                 buf_set_u32(&sysspeed_buf, 2, 1, 1);
198         
199         jtag_add_end_state(TAP_PD);
200         arm_jtag_scann(jtag_info, 0x1);
201         
202         arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
203                 
204         fields[0].device = jtag_info->chain_pos;
205         fields[0].num_bits = 32;
206         fields[0].out_value = out_buf;
207         fields[0].out_mask = NULL;
208         fields[0].in_value = NULL;
209         if (in)
210         {
211                 fields[0].in_handler = arm_jtag_buf_to_u32;
212                 fields[0].in_handler_priv = in;
213         }
214         else
215         {
216                 fields[0].in_handler = NULL;
217                 fields[0].in_handler_priv = NULL;
218         }
219         fields[0].in_check_value = NULL;
220         fields[0].in_check_mask = NULL;
221         
222         fields[1].device = jtag_info->chain_pos;
223         fields[1].num_bits = 3;
224         fields[1].out_value = &sysspeed_buf;
225         fields[1].out_mask = NULL;
226         fields[1].in_value = NULL;
227         fields[1].in_check_value = NULL;
228         fields[1].in_check_mask = NULL;
229         fields[1].in_handler = NULL;
230         fields[1].in_handler_priv = NULL;
231                 
232         fields[2].device = jtag_info->chain_pos;
233         fields[2].num_bits = 32;
234         fields[2].out_value = instr_buf;
235         fields[2].out_mask = NULL;
236         fields[2].in_value = NULL;
237         fields[2].in_check_value = NULL;
238         fields[2].in_check_mask = NULL;
239         fields[2].in_handler = NULL;
240         fields[2].in_handler_priv = NULL;
241
242         jtag_add_dr_scan(3, fields, -1);
243
244         jtag_add_runtest(0, -1);
245         
246 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
247         {
248                 jtag_execute_queue();
249                 
250                 if (in)
251                 {
252                         LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x, in: 0x%8.8x", instr, out, *in);
253                 }
254                 else
255                         LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x", instr, out);
256         }
257 #endif
258
259         return ERROR_OK;
260 }
261
262 /* just read data (instruction and data-out = don't care) */
263 int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
264 {
265         scan_field_t fields[3];
266
267         jtag_add_end_state(TAP_PD);
268         arm_jtag_scann(jtag_info, 0x1);
269         
270         arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
271                 
272         fields[0].device = jtag_info->chain_pos;
273         fields[0].num_bits = 32;
274         fields[0].out_value = NULL;
275         fields[0].out_mask = NULL;
276         fields[0].in_value = NULL;
277         fields[0].in_handler = arm_jtag_buf_to_u32;
278         fields[0].in_handler_priv = in;
279         fields[0].in_check_value = NULL;
280         fields[0].in_check_mask = NULL;
281         
282         fields[1].device = jtag_info->chain_pos;
283         fields[1].num_bits = 3;
284         fields[1].out_value = NULL;
285         fields[1].out_mask = NULL;
286         fields[1].in_value = NULL;
287         fields[1].in_handler = NULL;
288         fields[1].in_handler_priv = NULL;
289         fields[1].in_check_value = NULL;
290         fields[1].in_check_mask = NULL;
291
292         fields[2].device = jtag_info->chain_pos;
293         fields[2].num_bits = 32;
294         fields[2].out_value = NULL;
295         fields[2].out_mask = NULL;
296         fields[2].in_value = NULL;
297         fields[2].in_check_value = NULL;
298         fields[2].in_check_mask = NULL;
299         fields[2].in_handler = NULL;
300         fields[2].in_handler_priv = NULL;
301         
302         jtag_add_dr_scan(3, fields, -1);
303
304         jtag_add_runtest(0, -1);
305         
306 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
307         {
308                 jtag_execute_queue();
309                         
310                 if (in)
311                 {
312                         LOG_DEBUG("in: 0x%8.8x", *in);
313                 }
314                 else
315                 {
316                         LOG_ERROR("BUG: called with in == NULL");
317                 }
318         }
319 #endif
320
321         return ERROR_OK;
322 }
323
324 /* clock the target, and read the databus
325  * the *in pointer points to a buffer where elements of 'size' bytes
326  * are stored in big (be==1) or little (be==0) endianness
327  */
328 int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, int be)
329 {
330         scan_field_t fields[3];
331         
332         jtag_add_end_state(TAP_PD);
333         arm_jtag_scann(jtag_info, 0x1);
334         
335         arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
336                 
337         fields[0].device = jtag_info->chain_pos;
338         fields[0].num_bits = 32;
339         fields[0].out_value = NULL;
340         fields[0].out_mask = NULL;
341         fields[0].in_value = NULL;
342         switch (size)
343         {
344                 case 4:
345                         fields[0].in_handler = (be) ? arm_jtag_buf_to_be32 : arm_jtag_buf_to_le32;
346                         break;
347                 case 2:
348                         fields[0].in_handler = (be) ? arm_jtag_buf_to_be16 : arm_jtag_buf_to_le16;
349                         break;
350                 case 1:
351                         fields[0].in_handler = arm_jtag_buf_to_8;
352                         break;
353         }
354         fields[0].in_handler_priv = in;
355         fields[0].in_check_value = NULL;
356         fields[0].in_check_mask = NULL;
357         
358         fields[1].device = jtag_info->chain_pos;
359         fields[1].num_bits = 3;
360         fields[1].out_value = NULL;
361         fields[1].out_mask = NULL;
362         fields[1].in_value = NULL;
363         fields[1].in_handler = NULL;
364         fields[1].in_handler_priv = NULL;
365         fields[1].in_check_value = NULL;
366         fields[1].in_check_mask = NULL;
367
368         fields[2].device = jtag_info->chain_pos;
369         fields[2].num_bits = 32;
370         fields[2].out_value = NULL;
371         fields[2].out_mask = NULL;
372         fields[2].in_value = NULL;
373         fields[2].in_check_value = NULL;
374         fields[2].in_check_mask = NULL;
375         fields[2].in_handler = NULL;
376         fields[2].in_handler_priv = NULL;
377         
378         jtag_add_dr_scan(3, fields, -1);
379
380         jtag_add_runtest(0, -1);
381         
382 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
383         {
384                 jtag_execute_queue();
385                         
386                 if (in)
387                 {
388                         LOG_DEBUG("in: 0x%8.8x", *(u32*)in);
389                 }
390                 else
391                 {
392                         LOG_ERROR("BUG: called with in == NULL");
393                 }
394         }
395 #endif
396
397         return ERROR_OK;
398 }
399
400 void arm9tdmi_change_to_arm(target_t *target, u32 *r0, u32 *pc)
401 {
402         /* get pointers to arch-specific information */
403         armv4_5_common_t *armv4_5 = target->arch_info;
404         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
405         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
406         
407         /* save r0 before using it and put system in ARM state 
408          * to allow common handling of ARM and THUMB debugging */
409         
410         /* fetch STR r0, [r0] */
411         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);
412         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
413         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
414         /* STR r0, [r0] in Memory */
415         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, r0, 0);
416
417         /* MOV r0, r15 fetched, STR in Decode */        
418         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), 0, NULL, 0);
419         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
420         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);
421         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
422         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
423         /* nothing fetched, STR r0, [r0] in Memory */
424         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, pc, 0);
425
426         /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
427         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0, NULL, 0);
428         /* LDR in Decode */
429         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
430         /* LDR in Execute */
431         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
432         /* LDR in Memory (to account for interlock) */
433         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
434
435         /* fetch BX */
436         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_BX(0), 0, NULL, 0);
437         /* NOP fetched, BX in Decode, MOV in Execute */
438         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
439         /* NOP fetched, BX in Execute (1) */
440         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
441         
442         jtag_execute_queue();
443         
444         /* fix program counter:
445          * MOV r0, r15 was the 5th instruction (+8)
446          * reading PC in Thumb state gives address of instruction + 4
447          */
448         *pc -= 0xc;
449 }
450
451 void arm9tdmi_read_core_regs(target_t *target, u32 mask, u32* core_regs[16])
452 {
453         int i;
454         /* get pointers to arch-specific information */
455         armv4_5_common_t *armv4_5 = target->arch_info;
456         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
457         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
458                 
459         /* STMIA r0-15, [r0] at debug speed
460          * register values will start to appear on 4th DCLK
461          */
462         arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
463
464         /* fetch NOP, STM in DECODE stage */
465         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
466         /* fetch NOP, STM in EXECUTE stage (1st cycle) */
467         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
468
469         for (i = 0; i <= 15; i++)
470         {
471                 if (mask & (1 << i))
472                         /* nothing fetched, STM in MEMORY (i'th cycle) */
473                         arm9tdmi_clock_data_in(jtag_info, core_regs[i]);
474         }
475
476 }
477
478 void arm9tdmi_read_core_regs_target_buffer(target_t *target, u32 mask, void* buffer, int size)
479 {
480         int i;
481         /* get pointers to arch-specific information */
482         armv4_5_common_t *armv4_5 = target->arch_info;
483         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
484         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
485         int be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0;
486         u32 *buf_u32 = buffer;
487         u16 *buf_u16 = buffer;
488         u8 *buf_u8 = buffer;
489         
490         /* STMIA r0-15, [r0] at debug speed
491          * register values will start to appear on 4th DCLK
492          */
493         arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
494
495         /* fetch NOP, STM in DECODE stage */
496         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
497         /* fetch NOP, STM in EXECUTE stage (1st cycle) */
498         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
499
500         for (i = 0; i <= 15; i++)
501         {
502                 if (mask & (1 << i))
503                         /* nothing fetched, STM in MEMORY (i'th cycle) */
504                         switch (size)
505                         {
506                                 case 4:
507                                         arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);
508                                         break;
509                                 case 2:
510                                         arm9tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be);
511                                         break;
512                                 case 1:
513                                         arm9tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be);
514                                         break;
515                         }
516         }
517
518 }
519
520 void arm9tdmi_read_xpsr(target_t *target, u32 *xpsr, int spsr)
521 {
522         /* get pointers to arch-specific information */
523         armv4_5_common_t *armv4_5 = target->arch_info;
524         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
525         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
526                 
527         /* MRS r0, cpsr */
528         arm9tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), 0, NULL, 0);
529         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
530         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
531         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
532         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
533
534         /* STR r0, [r15] */
535         arm9tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), 0, NULL, 0);
536         /* fetch NOP, STR in DECODE stage */
537         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
538         /* fetch NOP, STR in EXECUTE stage (1st cycle) */
539         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
540         /* nothing fetched, STR in MEMORY */
541         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, xpsr, 0);
542
543 }
544
545 void arm9tdmi_write_xpsr(target_t *target, u32 xpsr, int spsr)
546 {
547         /* get pointers to arch-specific information */
548         armv4_5_common_t *armv4_5 = target->arch_info;
549         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
550         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
551                 
552         LOG_DEBUG("xpsr: %8.8x, spsr: %i", xpsr, spsr);
553
554         /* MSR1 fetched */
555         arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), 0, NULL, 0);
556         /* MSR2 fetched, MSR1 in DECODE */
557         arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), 0, NULL, 0);
558         /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
559         arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), 0, NULL, 0);
560         /* nothing fetched, MSR1 in EXECUTE (2) */
561         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
562         /* nothing fetched, MSR1 in EXECUTE (3) */
563         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
564         /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
565         arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), 0, NULL, 0);
566         /* nothing fetched, MSR2 in EXECUTE (2) */
567         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
568         /* nothing fetched, MSR2 in EXECUTE (3) */
569         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
570         /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
571         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
572         /* nothing fetched, MSR3 in EXECUTE (2) */
573         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
574         /* nothing fetched, MSR3 in EXECUTE (3) */
575         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
576         /* NOP fetched, MSR4 in EXECUTE (1) */
577         /* last MSR writes flags, which takes only one cycle */
578         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
579 }
580
581 void arm9tdmi_write_xpsr_im8(target_t *target, u8 xpsr_im, int rot, int spsr)
582 {
583         /* get pointers to arch-specific information */
584         armv4_5_common_t *armv4_5 = target->arch_info;
585         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
586         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
587                 
588         LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr);
589         
590         /* MSR fetched */
591         arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), 0, NULL, 0);
592         /* NOP fetched, MSR in DECODE */
593         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
594         /* NOP fetched, MSR in EXECUTE (1) */
595         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
596         
597         /* rot == 4 writes flags, which takes only one cycle */
598         if (rot != 4)
599         {
600                 /* nothing fetched, MSR in EXECUTE (2) */
601                 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
602                 /* nothing fetched, MSR in EXECUTE (3) */
603                 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
604         }
605 }
606
607 void arm9tdmi_write_core_regs(target_t *target, u32 mask, u32 core_regs[16])
608 {
609         int i;
610         /* get pointers to arch-specific information */
611         armv4_5_common_t *armv4_5 = target->arch_info;
612         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
613         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
614                 
615         /* LDMIA r0-15, [r0] at debug speed
616         * register values will start to appear on 4th DCLK
617         */
618         arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
619
620         /* fetch NOP, LDM in DECODE stage */
621         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
622         /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
623         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
624
625         for (i = 0; i <= 15; i++)
626         {
627                 if (mask & (1 << i))
628                         /* nothing fetched, LDM still in EXECUTE (1+i cycle) */
629                         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, core_regs[i], NULL, 0);
630         }
631         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
632         
633 }
634
635 void arm9tdmi_load_word_regs(target_t *target, u32 mask)
636 {
637         /* get pointers to arch-specific information */
638         armv4_5_common_t *armv4_5 = target->arch_info;
639         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
640         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
641
642         /* put system-speed load-multiple into the pipeline */
643         arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 1), 0, NULL, 0);
644         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
645
646 }
647
648 void arm9tdmi_load_hword_reg(target_t *target, int num)
649 {
650         /* get pointers to arch-specific information */
651         armv4_5_common_t *armv4_5 = target->arch_info;
652         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
653         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
654         
655         /* put system-speed load half-word into the pipeline */
656         arm9tdmi_clock_out(jtag_info, ARMV4_5_LDRH_IP(num, 0), 0, NULL, 0);
657         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
658 }
659
660 void arm9tdmi_load_byte_reg(target_t *target, int num)
661 {
662         /* get pointers to arch-specific information */
663         armv4_5_common_t *armv4_5 = target->arch_info;
664         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
665         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
666
667         /* put system-speed load byte into the pipeline */
668         arm9tdmi_clock_out(jtag_info, ARMV4_5_LDRB_IP(num, 0), 0, NULL, 0);
669         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
670
671 }
672
673 void arm9tdmi_store_word_regs(target_t *target, u32 mask)
674 {
675         /* get pointers to arch-specific information */
676         armv4_5_common_t *armv4_5 = target->arch_info;
677         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
678         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
679
680         /* put system-speed store-multiple into the pipeline */
681         arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask, 0, 1), 0, NULL, 0);
682         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
683
684 }
685
686 void arm9tdmi_store_hword_reg(target_t *target, int num)
687 {
688         /* get pointers to arch-specific information */
689         armv4_5_common_t *armv4_5 = target->arch_info;
690         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
691         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
692
693         /* put system-speed store half-word into the pipeline */
694         arm9tdmi_clock_out(jtag_info, ARMV4_5_STRH_IP(num, 0), 0, NULL, 0);
695         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
696
697 }
698
699 void arm9tdmi_store_byte_reg(target_t *target, int num)
700 {
701         /* get pointers to arch-specific information */
702         armv4_5_common_t *armv4_5 = target->arch_info;
703         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
704         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
705
706         /* put system-speed store byte into the pipeline */
707         arm9tdmi_clock_out(jtag_info, ARMV4_5_STRB_IP(num, 0), 0, NULL, 0);
708         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
709
710 }
711
712 void arm9tdmi_write_pc(target_t *target, u32 pc)
713 {
714         /* get pointers to arch-specific information */
715         armv4_5_common_t *armv4_5 = target->arch_info;
716         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
717         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
718         
719         /* LDMIA r0-15, [r0] at debug speed
720          * register values will start to appear on 4th DCLK
721          */
722         arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL, 0);
723
724         /* fetch NOP, LDM in DECODE stage */
725         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
726         /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
727         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
728         /* nothing fetched, LDM in EXECUTE stage (2nd cycle) (output data) */
729         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, pc, NULL, 0);
730         /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
731         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
732         /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
733         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
734         /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
735         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
736
737 }
738
739 void arm9tdmi_branch_resume(target_t *target)
740 {
741         /* get pointers to arch-specific information */
742         armv4_5_common_t *armv4_5 = target->arch_info;
743         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
744         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
745         
746         arm9tdmi_clock_out(jtag_info, ARMV4_5_B(0xfffffc, 0), 0, NULL, 0);
747         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
748
749 }
750
751 void arm9tdmi_branch_resume_thumb(target_t *target)
752 {
753         LOG_DEBUG("-");
754         
755         /* get pointers to arch-specific information */
756         armv4_5_common_t *armv4_5 = target->arch_info;
757         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
758         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
759         reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
760
761         /* LDMIA r0-15, [r0] at debug speed
762         * register values will start to appear on 4th DCLK
763         */
764         arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x1, 0, 0), 0, NULL, 0);
765
766         /* fetch NOP, LDM in DECODE stage */
767         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
768         /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
769         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
770         /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
771         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) | 1, NULL, 0);
772         /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
773         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
774
775         /* Branch and eXchange */
776         arm9tdmi_clock_out(jtag_info, ARMV4_5_BX(0), 0, NULL, 0);
777         
778         embeddedice_read_reg(dbg_stat);
779         
780         /* fetch NOP, BX in DECODE stage */
781         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
782         
783         embeddedice_read_reg(dbg_stat);
784         
785         /* fetch NOP, BX in EXECUTE stage (1st cycle) */
786         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
787
788         /* target is now in Thumb state */
789         embeddedice_read_reg(dbg_stat);
790
791         /* load r0 value, MOV_IM in Decode*/
792         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0, NULL, 0);
793         /* fetch NOP, LDR in Decode, MOV_IM in Execute */
794         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
795         /* fetch NOP, LDR in Execute */
796         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
797         /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
798         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32), NULL, 0);
799         /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
800         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
801         
802         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
803         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
804
805         embeddedice_read_reg(dbg_stat);
806         
807         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f7), 0, NULL, 1);
808         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
809
810 }
811
812 void arm9tdmi_enable_single_step(target_t *target)
813 {
814         /* get pointers to arch-specific information */
815         armv4_5_common_t *armv4_5 = target->arch_info;
816         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
817         
818         if (arm7_9->has_single_step)
819         {
820                 buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 1);
821                 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);
822         }
823         else
824         {
825                 arm7_9_enable_eice_step(target);
826         }
827 }
828
829 void arm9tdmi_disable_single_step(target_t *target)
830 {
831         /* get pointers to arch-specific information */
832         armv4_5_common_t *armv4_5 = target->arch_info;
833         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
834         
835         if (arm7_9->has_single_step)
836         {
837                 buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 0);
838                 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);
839         }
840         else
841         {
842                 arm7_9_disable_eice_step(target);
843         }
844 }
845
846 void arm9tdmi_build_reg_cache(target_t *target)
847 {
848         reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
849         /* get pointers to arch-specific information */
850         armv4_5_common_t *armv4_5 = target->arch_info;
851
852         (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
853         armv4_5->core_cache = (*cache_p);
854 }
855
856
857 int arm9tdmi_examine(struct target_s *target)
858 {
859         /* get pointers to arch-specific information */
860         int retval;
861         armv4_5_common_t *armv4_5 = target->arch_info;
862         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
863         if (!target->type->examined)
864         {
865                 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
866                 reg_cache_t *t;
867                 /* one extra register (vector catch) */
868                 t=embeddedice_build_reg_cache(target, arm7_9);
869                 if (t==NULL)
870                         return ERROR_FAIL;
871                 (*cache_p) = t;
872                 arm7_9->eice_cache = (*cache_p);
873         
874                 if (arm7_9->etm_ctx)
875                 {
876                         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
877                         (*cache_p)->next = etm_build_reg_cache(target, jtag_info, arm7_9->etm_ctx);
878                         arm7_9->etm_ctx->reg_cache = (*cache_p)->next;
879                 }
880                 target->type->examined = 1;
881         }
882         if ((retval=embeddedice_setup(target))!=ERROR_OK)
883                 return retval;
884         if ((retval=arm7_9_setup(target))!=ERROR_OK)
885                 return retval;
886         if (arm7_9->etm_ctx)
887         {
888                 if ((retval=etm_setup(target))!=ERROR_OK)
889                         return retval;
890         }
891         return ERROR_OK;
892 }
893
894 int arm9tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
895 {
896         
897         arm9tdmi_build_reg_cache(target);
898         
899         return ERROR_OK;
900         
901 }
902
903 int arm9tdmi_quit(void)
904 {
905         
906         return ERROR_OK;
907 }
908
909 int arm9tdmi_init_arch_info(target_t *target, arm9tdmi_common_t *arm9tdmi, int chain_pos, const char *variant)
910 {
911         armv4_5_common_t *armv4_5;
912         arm7_9_common_t *arm7_9;
913         
914         arm7_9 = &arm9tdmi->arm7_9_common;
915         armv4_5 = &arm7_9->armv4_5_common;
916         
917         /* prepare JTAG information for the new target */
918         arm7_9->jtag_info.chain_pos = chain_pos;
919         arm7_9->jtag_info.scann_size = 5;
920         
921         /* register arch-specific functions */
922         arm7_9->examine_debug_reason = arm9tdmi_examine_debug_reason;
923         arm7_9->change_to_arm = arm9tdmi_change_to_arm;
924         arm7_9->read_core_regs = arm9tdmi_read_core_regs;
925         arm7_9->read_core_regs_target_buffer = arm9tdmi_read_core_regs_target_buffer;
926         arm7_9->read_xpsr = arm9tdmi_read_xpsr;
927         
928         arm7_9->write_xpsr = arm9tdmi_write_xpsr;
929         arm7_9->write_xpsr_im8 = arm9tdmi_write_xpsr_im8;
930         arm7_9->write_core_regs = arm9tdmi_write_core_regs;
931         
932         arm7_9->load_word_regs = arm9tdmi_load_word_regs;
933         arm7_9->load_hword_reg = arm9tdmi_load_hword_reg;
934         arm7_9->load_byte_reg = arm9tdmi_load_byte_reg;
935         
936         arm7_9->store_word_regs = arm9tdmi_store_word_regs;
937         arm7_9->store_hword_reg = arm9tdmi_store_hword_reg;
938         arm7_9->store_byte_reg = arm9tdmi_store_byte_reg;
939         
940         arm7_9->write_pc = arm9tdmi_write_pc;
941         arm7_9->branch_resume = arm9tdmi_branch_resume;
942         arm7_9->branch_resume_thumb = arm9tdmi_branch_resume_thumb;
943
944         arm7_9->enable_single_step = arm9tdmi_enable_single_step;
945         arm7_9->disable_single_step = arm9tdmi_disable_single_step;
946         
947         arm7_9->pre_debug_entry = NULL;
948         arm7_9->post_debug_entry = NULL;
949         
950         arm7_9->pre_restore_context = NULL;
951         arm7_9->post_restore_context = NULL;
952
953         /* initialize arch-specific breakpoint handling */
954         arm7_9->arm_bkpt = 0xdeeedeee;
955         arm7_9->thumb_bkpt = 0xdeee;
956         
957         arm7_9->dbgreq_adjust_pc = 3;
958         arm7_9->arch_info = arm9tdmi;
959         
960         arm9tdmi->common_magic = ARM9TDMI_COMMON_MAGIC;
961         arm9tdmi->arch_info = NULL;
962
963         if (variant)
964         {
965                 arm9tdmi->variant = strdup(variant);
966         }
967         else
968         {
969                 arm9tdmi->variant = strdup("");
970         }
971         
972         arm7_9_init_arch_info(target, arm7_9);
973
974         /* override use of DBGRQ, this is safe on ARM9TDMI */
975         arm7_9->use_dbgrq = 1;
976
977         /* all ARM9s have the vector catch register */
978         arm7_9->has_vector_catch = 1;
979         
980         return ERROR_OK;
981 }
982
983 int arm9tdmi_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, arm7_9_common_t **arm7_9_p, arm9tdmi_common_t **arm9tdmi_p)
984 {
985         armv4_5_common_t *armv4_5 = target->arch_info;
986         arm7_9_common_t *arm7_9;
987         arm9tdmi_common_t *arm9tdmi;
988         
989         if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
990         {
991                 return -1;
992         }
993         
994         arm7_9 = armv4_5->arch_info;
995         if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
996         {
997                 return -1;
998         }
999         
1000         arm9tdmi = arm7_9->arch_info;
1001         if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
1002         {
1003                 return -1;
1004         }
1005         
1006         *armv4_5_p = armv4_5;
1007         *arm7_9_p = arm7_9;
1008         *arm9tdmi_p = arm9tdmi;
1009         
1010         return ERROR_OK;
1011 }
1012
1013
1014
1015 int arm9tdmi_target_create(struct target_s *target, Jim_Interp *interp)
1016 {
1017         arm9tdmi_common_t *arm9tdmi = calloc(1,sizeof(arm9tdmi_common_t));
1018
1019         arm9tdmi_init_arch_info(target, arm9tdmi, target->chain_position, target->variant);
1020         
1021         return ERROR_OK;
1022 }
1023
1024 int arm9tdmi_register_commands(struct command_context_s *cmd_ctx)
1025 {
1026         int retval;
1027         
1028         command_t *arm9tdmi_cmd;
1029         
1030                 
1031         retval = arm7_9_register_commands(cmd_ctx);
1032         
1033         arm9tdmi_cmd = register_command(cmd_ctx, NULL, "arm9tdmi", NULL, COMMAND_ANY, "arm9tdmi specific commands");
1034
1035         register_command(cmd_ctx, arm9tdmi_cmd, "vector_catch", handle_arm9tdmi_catch_vectors_command, COMMAND_EXEC, "catch arm920t vectors ['all'|'none'|'<vec1 vec2 ...>']");
1036         
1037         
1038         return ERROR_OK;
1039
1040 }
1041
1042 int handle_arm9tdmi_catch_vectors_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1043 {
1044         target_t *target = get_current_target(cmd_ctx);
1045         armv4_5_common_t *armv4_5;
1046         arm7_9_common_t *arm7_9;
1047         arm9tdmi_common_t *arm9tdmi;
1048         reg_t *vector_catch;
1049         u32 vector_catch_value;
1050         int i, j;
1051         
1052         if (arm9tdmi_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi) != ERROR_OK)
1053         {
1054                 command_print(cmd_ctx, "current target isn't an ARM9TDMI based target");
1055                 return ERROR_OK;
1056         }
1057         
1058         vector_catch = &arm7_9->eice_cache->reg_list[EICE_VEC_CATCH];
1059         
1060         /* read the vector catch register if necessary */
1061         if (!vector_catch->valid)
1062                 embeddedice_read_reg(vector_catch);
1063         
1064         /* get the current setting */
1065         vector_catch_value = buf_get_u32(vector_catch->value, 0, 32);
1066         
1067         if (argc > 0)
1068         {
1069                 vector_catch_value = 0x0;
1070                 if (strcmp(args[0], "all") == 0)
1071                 {
1072                         vector_catch_value = 0xdf;
1073                 }
1074                 else if (strcmp(args[0], "none") == 0)
1075                 {
1076                         /* do nothing */
1077                 }
1078                 else
1079                 {
1080                         for (i = 0; i < argc; i++)
1081                         {
1082                                 /* go through list of vectors */
1083                                 for(j = 0; arm9tdmi_vectors[j].name; j++)
1084                                 {
1085                                         if (strcmp(args[i], arm9tdmi_vectors[j].name) == 0)
1086                                         {
1087                                                 vector_catch_value |= arm9tdmi_vectors[j].value;
1088                                                 break;
1089                                         }
1090                                 }
1091                                 
1092                                 /* complain if vector wasn't found */
1093                                 if (!arm9tdmi_vectors[j].name)
1094                                 {
1095                                         command_print(cmd_ctx, "vector '%s' not found, leaving current setting unchanged", args[i]);
1096                                         
1097                                         /* reread current setting */
1098                                         vector_catch_value = buf_get_u32(vector_catch->value, 0, 32);
1099                                         
1100                                         break;
1101                                 }
1102                         }
1103                 }
1104                 
1105                 /* store new settings */
1106                 buf_set_u32(vector_catch->value, 0, 32, vector_catch_value);
1107                 embeddedice_store_reg(vector_catch);
1108         }
1109                 
1110         /* output current settings (skip RESERVED vector) */
1111         for (i = 0; i < 8; i++)
1112         {
1113                 if (i != 5)
1114                 {
1115                         command_print(cmd_ctx, "%s: %s", arm9tdmi_vectors[i].name,
1116                                 (vector_catch_value & (1 << i)) ? "catch" : "don't catch");
1117                 }  
1118         }
1119
1120         return ERROR_OK;
1121 }