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