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

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)