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

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)