- Added support for native MinGW builds (thanks to Spencer Oliver and Michael Fischer...
[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 #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

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)