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

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)