f6f0cef71cdb135b32eb71270919f0b3ba5a20f7
[fw/openocd] / src / target / arm7tdmi.c
1 /***************************************************************************
2  *   Copyright (C) 2005 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "arm7tdmi.h"
25
26 #include "arm7_9_common.h"
27 #include "register.h"
28 #include "target.h"
29 #include "armv4_5.h"
30 #include "embeddedice.h"
31 #include "etm.h"
32 #include "log.h"
33 #include "jtag.h"
34 #include "arm_jtag.h"
35
36 #include <stdlib.h>
37 #include <string.h>
38
39 #if 0
40 #define _DEBUG_INSTRUCTION_EXECUTION_
41 #endif
42
43 /* cli handling */
44 int arm7tdmi_register_commands(struct command_context_s *cmd_ctx);
45
46 /* forward declarations */
47 int arm7tdmi_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
48 int arm7tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
49 int arm7tdmi_quit();
50
51 /* target function declarations */
52 enum target_state arm7tdmi_poll(struct target_s *target);
53 int arm7tdmi_halt(target_t *target);
54 int arm7tdmi_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
55                 
56 target_type_t arm7tdmi_target =
57 {
58         .name = "arm7tdmi",
59
60         .poll = arm7_9_poll,
61         .arch_state = armv4_5_arch_state,
62
63         .halt = arm7_9_halt,
64         .resume = arm7_9_resume,
65         .step = arm7_9_step,
66
67         .assert_reset = arm7_9_assert_reset,
68         .deassert_reset = arm7_9_deassert_reset,
69         .soft_reset_halt = arm7_9_soft_reset_halt,
70
71         .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
72         
73         .read_memory = arm7_9_read_memory,
74         .write_memory = arm7_9_write_memory,
75         .bulk_write_memory = arm7_9_bulk_write_memory,
76
77         .run_algorithm = armv4_5_run_algorithm,
78         
79         .add_breakpoint = arm7_9_add_breakpoint,
80         .remove_breakpoint = arm7_9_remove_breakpoint,
81         .add_watchpoint = arm7_9_add_watchpoint,
82         .remove_watchpoint = arm7_9_remove_watchpoint,
83
84         .register_commands = arm7tdmi_register_commands,
85         .target_command = arm7tdmi_target_command,
86         .init_target = arm7tdmi_init_target,
87         .quit = arm7tdmi_quit
88 };
89
90 int arm7tdmi_examine_debug_reason(target_t *target)
91 {
92         /* get pointers to arch-specific information */
93         armv4_5_common_t *armv4_5 = target->arch_info;
94         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
95         
96         /* only check the debug reason if we don't know it already */
97         if ((target->debug_reason != DBG_REASON_DBGRQ)
98                         && (target->debug_reason != DBG_REASON_SINGLESTEP))
99         {
100                 scan_field_t fields[2];
101                 u8 databus[4];
102                 u8 breakpoint;
103                 
104                 jtag_add_end_state(TAP_PD);
105
106                 fields[0].device = arm7_9->jtag_info.chain_pos;
107                 fields[0].num_bits = 1;
108                 fields[0].out_value = NULL;
109                 fields[0].out_mask = NULL;
110                 fields[0].in_value = &breakpoint;
111                 fields[0].in_check_value = NULL;
112                 fields[0].in_check_mask = NULL;
113                 fields[0].in_handler = NULL;
114                 fields[0].in_handler_priv = NULL;
115                 
116                 fields[1].device = arm7_9->jtag_info.chain_pos;
117                 fields[1].num_bits = 32;
118                 fields[1].out_value = NULL;
119                 fields[1].out_mask = NULL;
120                 fields[1].in_value = databus;
121                 fields[1].in_check_value = NULL;
122                 fields[1].in_check_mask = NULL;
123                 fields[1].in_handler = NULL;
124                 fields[1].in_handler_priv = NULL;
125                 
126                 arm_jtag_scann(&arm7_9->jtag_info, 0x1);
127                 arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr);
128
129                 jtag_add_dr_scan(2, fields, TAP_PD);
130                 jtag_execute_queue();
131                 
132                 fields[0].in_value = NULL;
133                 fields[0].out_value = &breakpoint;
134                 fields[1].in_value = NULL;
135                 fields[1].out_value = databus;
136                 
137                 jtag_add_dr_scan(2, fields, TAP_PD);
138
139                 if (breakpoint & 1)
140                         target->debug_reason = DBG_REASON_WATCHPOINT; 
141                 else
142                         target->debug_reason = DBG_REASON_BREAKPOINT; 
143         }
144
145         return ERROR_OK;
146 }
147
148 /* put an instruction in the ARM7TDMI pipeline or write the data bus, and optionally read data */
149 int arm7tdmi_clock_out(arm_jtag_t *jtag_info, u32 out, u32 *in, int breakpoint)
150 {
151         scan_field_t fields[2];
152         u8 out_buf[4];
153         u8 breakpoint_buf;
154         
155         out = flip_u32(out, 32);
156         buf_set_u32(out_buf, 0, 32, out);
157         buf_set_u32(&breakpoint_buf, 0, 1, breakpoint);
158
159         jtag_add_end_state(TAP_PD);
160         arm_jtag_scann(jtag_info, 0x1);
161         arm_jtag_set_instr(jtag_info, jtag_info->intest_instr);
162         
163         fields[0].device = jtag_info->chain_pos;
164         fields[0].num_bits = 1;
165         fields[0].out_value = &breakpoint_buf;
166         fields[0].out_mask = NULL;
167         fields[0].in_value = NULL;
168         fields[0].in_check_value = NULL;
169         fields[0].in_check_mask = NULL;
170         fields[0].in_handler = NULL;
171         fields[0].in_handler_priv = NULL;
172                 
173         fields[1].device = jtag_info->chain_pos;
174         fields[1].num_bits = 32;
175         fields[1].out_value = out_buf;
176         fields[1].out_mask = NULL;
177         if (in)
178         {
179                 fields[1].in_value = (u8*)in;
180                 fields[1].in_handler = arm_jtag_buf_to_u32_flip;
181                 fields[1].in_handler_priv = in;
182         } else
183         {
184                 fields[1].in_value = NULL;
185                 fields[1].in_handler = NULL;
186                 fields[1].in_handler_priv = NULL;
187         }
188
189         fields[1].in_check_value = NULL;
190         fields[1].in_check_mask = NULL;
191
192         jtag_add_dr_scan(2, fields, -1);
193
194         jtag_add_runtest(0, -1);
195         
196 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
197 {
198                 char* in_string;
199                 jtag_execute_queue();
200                 
201                 if (in)
202                 {
203                         in_string = buf_to_char((u8*)in, 32);
204                         DEBUG("out: 0x%8.8x, in: %s", flip_u32(out, 32), in_string);
205                         free(in_string);
206                 }
207                 else
208                         DEBUG("out: 0x%8.8x", flip_u32(out, 32));
209 }
210 #endif
211
212         return ERROR_OK;
213 }
214
215 /* put an instruction in the ARM7TDMI pipeline, and optionally read data */
216 int arm7tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
217 {
218         scan_field_t fields[2];
219
220         jtag_add_end_state(TAP_PD);
221         arm_jtag_scann(jtag_info, 0x1);
222         arm_jtag_set_instr(jtag_info, jtag_info->intest_instr);
223         
224         fields[0].device = jtag_info->chain_pos;
225         fields[0].num_bits = 1;
226         fields[0].out_value = NULL;
227         fields[0].out_mask = NULL;
228         fields[0].in_value = NULL;
229         fields[0].in_check_value = NULL;
230         fields[0].in_check_mask = NULL;
231         fields[0].in_handler = NULL;
232         fields[0].in_handler_priv = NULL;
233                 
234         fields[1].device = jtag_info->chain_pos;
235         fields[1].num_bits = 32;
236         fields[1].out_value = NULL;
237         fields[1].out_mask = NULL;
238         fields[1].in_value = (u8*)in;
239         fields[1].in_handler = arm_jtag_buf_to_u32_flip;
240         fields[1].in_handler_priv = in;
241         fields[1].in_check_value = NULL;
242         fields[1].in_check_mask = NULL;
243
244         jtag_add_dr_scan(2, fields, -1);
245
246         jtag_add_runtest(0, -1);
247         
248 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
249 {
250                 char* in_string;
251                 jtag_execute_queue();
252                         
253                 if (in)
254                 {
255                         in_string = buf_to_char((u8*)in, 32);
256                         DEBUG("in: %s", in_string);
257                         free(in_string);
258                 }
259 }
260 #endif
261
262         return ERROR_OK;
263 }
264
265 void arm7tdmi_change_to_arm(target_t *target, u32 *r0, u32 *pc)
266 {
267         /* get pointers to arch-specific information */
268         armv4_5_common_t *armv4_5 = target->arch_info;
269         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
270         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
271         
272         /* save r0 before using it and put system in ARM state 
273          * to allow common handling of ARM and THUMB debugging */
274         
275         /* fetch STR r0, [r0] */
276         arm7tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), NULL, 0);
277         arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
278         arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
279         /* nothing fetched, STR r0, [r0] in Execute (2) */
280         arm7tdmi_clock_data_in(jtag_info, r0);
281
282         /* MOV r0, r15 fetched, STR in Decode */        
283         arm7tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), NULL, 0);
284         arm7tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), NULL, 0);
285         arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
286         arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
287         /* nothing fetched, STR r0, [r0] in Execute (2) */
288         arm7tdmi_clock_data_in(jtag_info, pc);
289
290         /* fetch MOV */
291         arm7tdmi_clock_out(jtag_info, ARMV4_5_T_MOV_IM(0, 0x0), NULL, 0);
292         
293         /* fetch BX */
294         arm7tdmi_clock_out(jtag_info, ARMV4_5_T_BX(0), NULL, 0);
295         /* NOP fetched, BX in Decode, MOV in Execute */
296         arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
297         /* NOP fetched, BX in Execute (1) */
298         arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
299         
300         jtag_execute_queue();
301         
302         /* fix program counter:
303          * MOV r0, r15 was the 4th instruction (+6)
304          * reading PC in Thumb state gives address of instruction + 4
305          */
306         *pc -= 0xa;
307         
308 }
309
310 void arm7tdmi_read_core_regs(target_t *target, u32 mask, u32* core_regs[16])
311 {
312         int i;
313         /* get pointers to arch-specific information */
314         armv4_5_common_t *armv4_5 = target->arch_info;
315         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
316         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
317                 
318         /* STMIA r0-15, [r0] at debug speed
319          * register values will start to appear on 4th DCLK
320          */
321         arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), NULL, 0);
322
323         /* fetch NOP, STM in DECODE stage */
324         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
325         /* fetch NOP, STM in EXECUTE stage (1st cycle) */
326         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
327
328         for (i = 0; i <= 15; i++)
329         {
330                 if (mask & (1 << i))
331                         /* nothing fetched, STM still in EXECUTE (1+i cycle) */
332                         arm7tdmi_clock_data_in(jtag_info, core_regs[i]);
333         }
334
335 }
336
337 void arm7tdmi_read_xpsr(target_t *target, u32 *xpsr, int spsr)
338 {
339         /* get pointers to arch-specific information */
340         armv4_5_common_t *armv4_5 = target->arch_info;
341         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
342         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
343                 
344         /* MRS r0, cpsr */
345         arm7tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), NULL, 0);
346         
347         /* STR r0, [r15] */
348         arm7tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), NULL, 0);
349         /* fetch NOP, STR in DECODE stage */
350         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
351         /* fetch NOP, STR in EXECUTE stage (1st cycle) */
352         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
353         /* nothing fetched, STR still in EXECUTE (2nd cycle) */
354         arm7tdmi_clock_data_in(jtag_info, xpsr);
355
356 }
357
358 void arm7tdmi_write_xpsr(target_t *target, u32 xpsr, int spsr)
359 {
360         /* get pointers to arch-specific information */
361         armv4_5_common_t *armv4_5 = target->arch_info;
362         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
363         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
364                 
365         DEBUG("xpsr: %8.8x, spsr: %i", xpsr, spsr);
366
367         /* MSR1 fetched */
368         arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), NULL, 0);
369         /* MSR2 fetched, MSR1 in DECODE */
370         arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), NULL, 0);
371         /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
372         arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), NULL, 0);
373         /* nothing fetched, MSR1 in EXECUTE (2) */
374         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
375         /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
376         arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), NULL, 0);
377         /* nothing fetched, MSR2 in EXECUTE (2) */
378         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
379         /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
380         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
381         /* nothing fetched, MSR3 in EXECUTE (2) */
382         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
383         /* NOP fetched, MSR4 in EXECUTE (1) */
384         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
385         /* nothing fetched, MSR4 in EXECUTE (2) */
386         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
387 }
388
389 void arm7tdmi_write_xpsr_im8(target_t *target, u8 xpsr_im, int rot, int spsr)
390 {
391         /* get pointers to arch-specific information */
392         armv4_5_common_t *armv4_5 = target->arch_info;
393         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
394         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
395                 
396         DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr);
397         
398         /* MSR fetched */
399         arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), NULL, 0);
400         /* NOP fetched, MSR in DECODE */
401         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
402         /* NOP fetched, MSR in EXECUTE (1) */
403         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
404         /* nothing fetched, MSR in EXECUTE (2) */
405         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
406         
407 }
408
409 void arm7tdmi_write_core_regs(target_t *target, u32 mask, u32 core_regs[16])
410 {
411         int i;
412         /* get pointers to arch-specific information */
413         armv4_5_common_t *armv4_5 = target->arch_info;
414         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
415         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
416                 
417         /* LDMIA r0-15, [r0] at debug speed
418         * register values will start to appear on 4th DCLK
419         */
420         arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), NULL, 0);
421
422         /* fetch NOP, LDM in DECODE stage */
423         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
424         /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
425         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
426
427         for (i = 0; i <= 15; i++)
428         {
429                 if (mask & (1 << i))
430                         /* nothing fetched, LDM still in EXECUTE (1+i cycle) */
431                         arm7tdmi_clock_out(jtag_info, core_regs[i], NULL, 0);
432         }
433         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
434         
435 }
436
437 void arm7tdmi_load_word_regs(target_t *target, u32 mask)
438 {
439         /* get pointers to arch-specific information */
440         armv4_5_common_t *armv4_5 = target->arch_info;
441         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
442         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
443
444         /* put system-speed load-multiple into the pipeline */
445         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
446         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
447         arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 1), NULL, 0);
448
449 }
450
451 void arm7tdmi_load_hword_reg(target_t *target, int num)
452 {
453         /* get pointers to arch-specific information */
454         armv4_5_common_t *armv4_5 = target->arch_info;
455         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
456         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
457         
458         /* put system-speed load half-word into the pipeline */
459         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
460         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
461         arm7tdmi_clock_out(jtag_info, ARMV4_5_LDRH_IP(num, 0), NULL, 0);
462
463 }
464
465 void arm7tdmi_load_byte_reg(target_t *target, int num)
466 {
467         /* get pointers to arch-specific information */
468         armv4_5_common_t *armv4_5 = target->arch_info;
469         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
470         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
471
472         /* put system-speed load byte into the pipeline */
473         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
474         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
475         arm7tdmi_clock_out(jtag_info, ARMV4_5_LDRB_IP(num, 0), NULL, 0);
476
477 }
478
479 void arm7tdmi_store_word_regs(target_t *target, u32 mask)
480 {
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
486         /* put system-speed store-multiple into the pipeline */
487         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
488         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
489         arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask, 0, 1), NULL, 0);
490         
491 }
492
493 void arm7tdmi_store_hword_reg(target_t *target, int num)
494 {
495         /* get pointers to arch-specific information */
496         armv4_5_common_t *armv4_5 = target->arch_info;
497         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
498         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
499
500         /* put system-speed store half-word into the pipeline */
501         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
502         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
503         arm7tdmi_clock_out(jtag_info, ARMV4_5_STRH_IP(num, 0), NULL, 0);
504
505 }
506
507 void arm7tdmi_store_byte_reg(target_t *target, int num)
508 {
509         /* get pointers to arch-specific information */
510         armv4_5_common_t *armv4_5 = target->arch_info;
511         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
512         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
513
514         /* put system-speed store byte into the pipeline */
515         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
516         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
517         arm7tdmi_clock_out(jtag_info, ARMV4_5_STRB_IP(num, 0), NULL, 0);
518
519 }
520
521 void arm7tdmi_write_pc(target_t *target, u32 pc)
522 {
523         /* get pointers to arch-specific information */
524         armv4_5_common_t *armv4_5 = target->arch_info;
525         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
526         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
527         
528         /* LDMIA r0-15, [r0] at debug speed
529          * register values will start to appear on 4th DCLK
530          */
531         arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), NULL, 0);
532         /* fetch NOP, LDM in DECODE stage */
533         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
534         /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
535         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
536         /* nothing fetched, LDM in EXECUTE stage (1st cycle) load register */
537         arm7tdmi_clock_out(jtag_info, pc, NULL, 0);
538         /* nothing fetched, LDM in EXECUTE stage (2nd cycle) load register */
539         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
540         /* nothing fetched, LDM in EXECUTE stage (3rd cycle) load register */
541         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
542         /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
543         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
544         /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
545         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
546 }
547
548 void arm7tdmi_branch_resume(target_t *target)
549 {
550         /* get pointers to arch-specific information */
551         armv4_5_common_t *armv4_5 = target->arch_info;
552         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
553         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
554         
555         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
556         arm7tdmi_clock_out(jtag_info, ARMV4_5_B(0xfffffa, 0), NULL, 0);
557
558 }
559
560 void arm7tdmi_branch_resume_thumb(target_t *target)
561 {
562         DEBUG("");
563         
564         /* get pointers to arch-specific information */
565         armv4_5_common_t *armv4_5 = target->arch_info;
566         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
567         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
568         reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
569
570         /* LDMIA r0, [r0] at debug speed
571          * register values will start to appear on 4th DCLK
572          */
573         arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x1, 0, 0), NULL, 0);
574
575         /* fetch NOP, LDM in DECODE stage */
576         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
577         /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
578         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
579         /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
580         arm7tdmi_clock_out(jtag_info, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) | 1, NULL, 0);
581         /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
582         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
583
584         /* Branch and eXchange */
585         arm7tdmi_clock_out(jtag_info, ARMV4_5_BX(0), NULL, 0);
586         
587         embeddedice_read_reg(dbg_stat);
588         
589         /* fetch NOP, BX in DECODE stage */
590         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
591         
592         /* target is now in Thumb state */
593         embeddedice_read_reg(dbg_stat);
594         
595         /* fetch NOP, BX in EXECUTE stage (1st cycle) */
596         arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
597
598         /* target is now in Thumb state */
599         embeddedice_read_reg(dbg_stat);
600
601         /* clean r0 bits to avoid alignment problems */
602         arm7tdmi_clock_out(jtag_info, ARMV4_5_T_MOV_IM(0, 0x0), NULL, 0);
603         /* load r0 value, MOV_IM in Decode*/
604         arm7tdmi_clock_out(jtag_info, ARMV4_5_T_LDR(0, 0), NULL, 0);
605         /* fetch NOP, LDR in Decode, MOV_IM in Execute */
606         arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
607         /* fetch NOP, LDR in Execute */
608         arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
609         /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
610         arm7tdmi_clock_out(jtag_info, buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32), NULL, 0);
611         /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
612         arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
613         
614         arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
615         arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
616
617         embeddedice_read_reg(dbg_stat);
618         
619         arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 1);
620         arm7tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f7), NULL, 0);
621
622 }
623                 
624 void arm7tdmi_build_reg_cache(target_t *target)
625 {
626         reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
627         /* get pointers to arch-specific information */
628         armv4_5_common_t *armv4_5 = target->arch_info;
629         arm7_9_common_t *arm7_9 = armv4_5->arch_info;
630         arm_jtag_t *jtag_info = &arm7_9->jtag_info;
631         arm7tdmi_common_t *arch_info = arm7_9->arch_info;
632
633
634         (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
635         armv4_5->core_cache = (*cache_p);
636         
637         (*cache_p)->next = embeddedice_build_reg_cache(target, jtag_info, 0);
638         arm7_9->eice_cache = (*cache_p)->next;
639         
640         if (arm7_9->has_etm)
641         {
642                 (*cache_p)->next->next = etm_build_reg_cache(target, jtag_info, 0);
643                 arm7_9->etm_cache = (*cache_p)->next->next;
644         }
645                 
646         if (arch_info->has_monitor_mode)
647                 (*cache_p)->next->reg_list[0].size = 6;
648         else
649                 (*cache_p)->next->reg_list[0].size = 3;
650         
651         (*cache_p)->next->reg_list[1].size = 5;
652
653 }
654
655 int arm7tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
656 {
657         
658         arm7tdmi_build_reg_cache(target);
659         
660         return ERROR_OK;
661         
662 }
663
664 int arm7tdmi_quit()
665 {
666         
667         return ERROR_OK;
668 }
669
670 int arm7tdmi_init_arch_info(target_t *target, arm7tdmi_common_t *arm7tdmi, int chain_pos, char *variant)
671 {
672         armv4_5_common_t *armv4_5;
673         arm7_9_common_t *arm7_9;
674         int has_etm = 0;
675         
676         arm7_9 = &arm7tdmi->arm7_9_common;
677         armv4_5 = &arm7_9->armv4_5_common;
678         
679         /* prepare JTAG information for the new target */
680         arm7_9->jtag_info.chain_pos = chain_pos;
681         arm7_9->jtag_info.scann_size = 4;
682         
683         /* register arch-specific functions */
684         arm7_9->examine_debug_reason = arm7tdmi_examine_debug_reason;
685         arm7_9->change_to_arm = arm7tdmi_change_to_arm;
686         arm7_9->read_core_regs = arm7tdmi_read_core_regs;
687         arm7_9->read_xpsr = arm7tdmi_read_xpsr;
688         
689         arm7_9->write_xpsr = arm7tdmi_write_xpsr;
690         arm7_9->write_xpsr_im8 = arm7tdmi_write_xpsr_im8;
691         arm7_9->write_core_regs = arm7tdmi_write_core_regs;
692         
693         arm7_9->load_word_regs = arm7tdmi_load_word_regs;
694         arm7_9->load_hword_reg = arm7tdmi_load_hword_reg;
695         arm7_9->load_byte_reg = arm7tdmi_load_byte_reg;
696         
697         arm7_9->store_word_regs = arm7tdmi_store_word_regs;
698         arm7_9->store_hword_reg = arm7tdmi_store_hword_reg;
699         arm7_9->store_byte_reg = arm7tdmi_store_byte_reg;
700         
701         arm7_9->write_pc = arm7tdmi_write_pc;
702         arm7_9->branch_resume = arm7tdmi_branch_resume;
703         arm7_9->branch_resume_thumb = arm7tdmi_branch_resume_thumb;
704         
705         arm7_9->enable_single_step = arm7_9_enable_eice_step;
706         arm7_9->disable_single_step = arm7_9_disable_eice_step;
707                 
708         arm7_9->pre_debug_entry = NULL;
709         arm7_9->post_debug_entry = NULL;
710         
711         arm7_9->pre_restore_context = NULL;
712         arm7_9->post_restore_context = NULL;
713         
714         /* initialize arch-specific breakpoint handling */
715         buf_set_u32((u8*)(&arm7_9->arm_bkpt), 0, 32, 0xdeeedeee);
716         buf_set_u32((u8*)(&arm7_9->thumb_bkpt), 0, 16, 0xdeee);
717         
718         arm7_9->sw_bkpts_use_wp = 1;
719         arm7_9->sw_bkpts_enabled = 0;
720         arm7_9->dbgreq_adjust_pc = 2;
721         arm7_9->arch_info = arm7tdmi;
722         
723         arm7tdmi->has_monitor_mode = 0;
724         arm7tdmi->arch_info = NULL;
725         arm7tdmi->common_magic = ARM7TDMI_COMMON_MAGIC;
726         
727         if (variant)
728         {
729                 if (strcmp(variant, "arm7tdmi-s_r4") == 0)
730                         arm7tdmi->has_monitor_mode = 1;
731                 else if (strcmp(variant, "arm7tdmi_r4") == 0)
732                         arm7tdmi->has_monitor_mode = 1;
733                 else if (strcmp(variant, "lpc2000") == 0)
734                 {
735                         arm7tdmi->has_monitor_mode = 1;
736                         has_etm = 1;
737                 }
738                 arm7tdmi->variant = strdup(variant);
739         }
740         else
741                 arm7tdmi->variant = strdup("");
742         
743         arm7_9_init_arch_info(target, arm7_9);
744         
745         arm7_9->has_etm = has_etm;
746
747         return ERROR_OK;
748 }
749
750 /* target arm7tdmi <endianess> <startup_mode> <chain_pos> <variant> */
751 int arm7tdmi_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
752 {
753         int chain_pos;
754         char *variant = NULL;
755         arm7tdmi_common_t *arm7tdmi = malloc(sizeof(arm7tdmi_common_t));
756
757         if (argc < 4)
758         {
759                 ERROR("'target arm7tdmi' requires at least one additional argument");
760                 exit(-1);
761         }
762         
763         chain_pos = strtoul(args[2], NULL, 0);
764         
765         if (argc >= 5)
766                 variant = args[4];
767         
768         arm7tdmi_init_arch_info(target, arm7tdmi, chain_pos, variant);
769         
770         return ERROR_OK;
771 }
772
773 int arm7tdmi_register_commands(struct command_context_s *cmd_ctx)
774 {
775         int retval;
776         
777         retval = arm7_9_register_commands(cmd_ctx);
778         
779         return ERROR_OK;
780
781 }
782