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

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)