- endianess fixes everywhere but in the flash code. flashing might still be broken...
[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 /* fetch MOV */
351 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_MOV_IM(0, 0x0), NULL, 0);
352
353 /* fetch BX */
354 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_BX(0), NULL, 0);
355 /* NOP fetched, BX in Decode, MOV in Execute */
356 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
357 /* NOP fetched, BX in Execute (1) */
358 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
359
360 jtag_execute_queue();
361
362 /* fix program counter:
363 * MOV r0, r15 was the 4th instruction (+6)
364 * reading PC in Thumb state gives address of instruction + 4
365 */
366 *pc -= 0xa;
367
368 }
369
370 void arm7tdmi_read_core_regs(target_t *target, u32 mask, u32* core_regs[16])
371 {
372 int i;
373 /* get pointers to arch-specific information */
374 armv4_5_common_t *armv4_5 = target->arch_info;
375 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
376 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
377
378 /* STMIA r0-15, [r0] at debug speed
379 * register values will start to appear on 4th DCLK
380 */
381 arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), NULL, 0);
382
383 /* fetch NOP, STM in DECODE stage */
384 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
385 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
386 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
387
388 for (i = 0; i <= 15; i++)
389 {
390 if (mask & (1 << i))
391 /* nothing fetched, STM still in EXECUTE (1+i cycle) */
392 arm7tdmi_clock_data_in(jtag_info, core_regs[i]);
393 }
394
395 }
396
397 void arm7tdmi_read_core_regs_target_buffer(target_t *target, u32 mask, void* buffer, int size)
398 {
399 int i;
400 /* get pointers to arch-specific information */
401 armv4_5_common_t *armv4_5 = target->arch_info;
402 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
403 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
404 int be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0;
405 u32 *buf_u32 = buffer;
406 u16 *buf_u16 = buffer;
407 u8 *buf_u8 = buffer;
408
409 /* STMIA r0-15, [r0] at debug speed
410 * register values will start to appear on 4th DCLK
411 */
412 arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), NULL, 0);
413
414 /* fetch NOP, STM in DECODE stage */
415 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
416 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
417 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
418
419 for (i = 0; i <= 15; i++)
420 {
421 /* nothing fetched, STM still in EXECUTE (1+i cycle), read databus */
422 if (mask & (1 << i))
423 {
424 switch (size)
425 {
426 case 4:
427 arm7tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);
428 break;
429 case 2:
430 arm7tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be);
431 break;
432 case 1:
433 arm7tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be);
434 break;
435 }
436 }
437 }
438
439 }
440
441 void arm7tdmi_read_xpsr(target_t *target, u32 *xpsr, int spsr)
442 {
443 /* get pointers to arch-specific information */
444 armv4_5_common_t *armv4_5 = target->arch_info;
445 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
446 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
447
448 /* MRS r0, cpsr */
449 arm7tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), NULL, 0);
450
451 /* STR r0, [r15] */
452 arm7tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), NULL, 0);
453 /* fetch NOP, STR in DECODE stage */
454 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
455 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
456 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
457 /* nothing fetched, STR still in EXECUTE (2nd cycle) */
458 arm7tdmi_clock_data_in(jtag_info, xpsr);
459
460 }
461
462 void arm7tdmi_write_xpsr(target_t *target, u32 xpsr, int spsr)
463 {
464 /* get pointers to arch-specific information */
465 armv4_5_common_t *armv4_5 = target->arch_info;
466 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
467 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
468
469 DEBUG("xpsr: %8.8x, spsr: %i", xpsr, spsr);
470
471 /* MSR1 fetched */
472 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), NULL, 0);
473 /* MSR2 fetched, MSR1 in DECODE */
474 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), NULL, 0);
475 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
476 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), NULL, 0);
477 /* nothing fetched, MSR1 in EXECUTE (2) */
478 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
479 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
480 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), NULL, 0);
481 /* nothing fetched, MSR2 in EXECUTE (2) */
482 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
483 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
484 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
485 /* nothing fetched, MSR3 in EXECUTE (2) */
486 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
487 /* NOP fetched, MSR4 in EXECUTE (1) */
488 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
489 /* nothing fetched, MSR4 in EXECUTE (2) */
490 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
491 }
492
493 void arm7tdmi_write_xpsr_im8(target_t *target, u8 xpsr_im, int rot, int spsr)
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 DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr);
501
502 /* MSR fetched */
503 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), NULL, 0);
504 /* NOP fetched, MSR in DECODE */
505 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
506 /* NOP fetched, MSR in EXECUTE (1) */
507 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
508 /* nothing fetched, MSR in EXECUTE (2) */
509 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
510
511 }
512
513 void arm7tdmi_write_core_regs(target_t *target, u32 mask, u32 core_regs[16])
514 {
515 int i;
516 /* get pointers to arch-specific information */
517 armv4_5_common_t *armv4_5 = target->arch_info;
518 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
519 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
520
521 /* LDMIA r0-15, [r0] at debug speed
522 * register values will start to appear on 4th DCLK
523 */
524 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), NULL, 0);
525
526 /* fetch NOP, LDM in DECODE stage */
527 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
528 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
529 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
530
531 for (i = 0; i <= 15; i++)
532 {
533 if (mask & (1 << i))
534 /* nothing fetched, LDM still in EXECUTE (1+i cycle) */
535 arm7tdmi_clock_out(jtag_info, core_regs[i], NULL, 0);
536 }
537 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
538
539 }
540
541 void arm7tdmi_load_word_regs(target_t *target, u32 mask)
542 {
543 /* get pointers to arch-specific information */
544 armv4_5_common_t *armv4_5 = target->arch_info;
545 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
546 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
547
548 /* put system-speed load-multiple into the pipeline */
549 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
550 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
551 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 1), NULL, 0);
552
553 }
554
555 void arm7tdmi_load_hword_reg(target_t *target, int num)
556 {
557 /* get pointers to arch-specific information */
558 armv4_5_common_t *armv4_5 = target->arch_info;
559 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
560 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
561
562 /* put system-speed load half-word into the pipeline */
563 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
564 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
565 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDRH_IP(num, 0), NULL, 0);
566
567 }
568
569 void arm7tdmi_load_byte_reg(target_t *target, int num)
570 {
571 /* get pointers to arch-specific information */
572 armv4_5_common_t *armv4_5 = target->arch_info;
573 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
574 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
575
576 /* put system-speed load byte into the pipeline */
577 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
578 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
579 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDRB_IP(num, 0), NULL, 0);
580
581 }
582
583 void arm7tdmi_store_word_regs(target_t *target, u32 mask)
584 {
585 /* get pointers to arch-specific information */
586 armv4_5_common_t *armv4_5 = target->arch_info;
587 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
588 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
589
590 /* put system-speed store-multiple into the pipeline */
591 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
592 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
593 arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask, 0, 1), NULL, 0);
594
595 }
596
597 void arm7tdmi_store_hword_reg(target_t *target, int num)
598 {
599 /* get pointers to arch-specific information */
600 armv4_5_common_t *armv4_5 = target->arch_info;
601 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
602 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
603
604 /* put system-speed store half-word into the pipeline */
605 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
606 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
607 arm7tdmi_clock_out(jtag_info, ARMV4_5_STRH_IP(num, 0), NULL, 0);
608
609 }
610
611 void arm7tdmi_store_byte_reg(target_t *target, int num)
612 {
613 /* get pointers to arch-specific information */
614 armv4_5_common_t *armv4_5 = target->arch_info;
615 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
616 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
617
618 /* put system-speed store byte into the pipeline */
619 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
620 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
621 arm7tdmi_clock_out(jtag_info, ARMV4_5_STRB_IP(num, 0), NULL, 0);
622
623 }
624
625 void arm7tdmi_write_pc(target_t *target, u32 pc)
626 {
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
632 /* LDMIA r0-15, [r0] at debug speed
633 * register values will start to appear on 4th DCLK
634 */
635 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), NULL, 0);
636 /* fetch NOP, LDM in DECODE stage */
637 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
638 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
639 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
640 /* nothing fetched, LDM in EXECUTE stage (1st cycle) load register */
641 arm7tdmi_clock_out(jtag_info, pc, NULL, 0);
642 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) load register */
643 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
644 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) load register */
645 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
646 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
647 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
648 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
649 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
650 }
651
652 void arm7tdmi_branch_resume(target_t *target)
653 {
654 /* get pointers to arch-specific information */
655 armv4_5_common_t *armv4_5 = target->arch_info;
656 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
657 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
658
659 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
660 arm7tdmi_clock_out(jtag_info, ARMV4_5_B(0xfffffa, 0), NULL, 0);
661
662 }
663
664 void arm7tdmi_branch_resume_thumb(target_t *target)
665 {
666 DEBUG("");
667
668 /* get pointers to arch-specific information */
669 armv4_5_common_t *armv4_5 = target->arch_info;
670 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
671 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
672 reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
673
674 /* LDMIA r0, [r0] at debug speed
675 * register values will start to appear on 4th DCLK
676 */
677 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x1, 0, 0), NULL, 0);
678
679 /* fetch NOP, LDM in DECODE stage */
680 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
681 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
682 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
683 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
684 arm7tdmi_clock_out(jtag_info, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) | 1, NULL, 0);
685 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
686 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
687
688 /* Branch and eXchange */
689 arm7tdmi_clock_out(jtag_info, ARMV4_5_BX(0), NULL, 0);
690
691 embeddedice_read_reg(dbg_stat);
692
693 /* fetch NOP, BX in DECODE stage */
694 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
695
696 /* target is now in Thumb state */
697 embeddedice_read_reg(dbg_stat);
698
699 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
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 /* clean r0 bits to avoid alignment problems */
706 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_MOV_IM(0, 0x0), NULL, 0);
707 /* load r0 value, MOV_IM in Decode*/
708 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_LDR(0, 0), NULL, 0);
709 /* fetch NOP, LDR in Decode, MOV_IM in Execute */
710 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
711 /* fetch NOP, LDR in Execute */
712 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
713 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
714 arm7tdmi_clock_out(jtag_info, buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32), NULL, 0);
715 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
716 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
717
718 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
719 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
720
721 embeddedice_read_reg(dbg_stat);
722
723 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 1);
724 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f7), NULL, 0);
725
726 }
727
728 void arm7tdmi_build_reg_cache(target_t *target)
729 {
730 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
731 /* get pointers to arch-specific information */
732 armv4_5_common_t *armv4_5 = target->arch_info;
733 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
734 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
735 arm7tdmi_common_t *arch_info = arm7_9->arch_info;
736
737
738 (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
739 armv4_5->core_cache = (*cache_p);
740
741 (*cache_p)->next = embeddedice_build_reg_cache(target, jtag_info, 0);
742 arm7_9->eice_cache = (*cache_p)->next;
743
744 if (arm7_9->has_etm)
745 {
746 (*cache_p)->next->next = etm_build_reg_cache(target, jtag_info, 0);
747 arm7_9->etm_cache = (*cache_p)->next->next;
748 }
749
750 if (arch_info->has_monitor_mode)
751 (*cache_p)->next->reg_list[EICE_DBG_CTRL].size = 6;
752 else
753 (*cache_p)->next->reg_list[EICE_DBG_CTRL].size = 3;
754
755 (*cache_p)->next->reg_list[EICE_DBG_STAT].size = 5;
756
757 }
758
759 int arm7tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
760 {
761
762 arm7tdmi_build_reg_cache(target);
763
764 return ERROR_OK;
765
766 }
767
768 int arm7tdmi_quit()
769 {
770
771 return ERROR_OK;
772 }
773
774 int arm7tdmi_init_arch_info(target_t *target, arm7tdmi_common_t *arm7tdmi, int chain_pos, char *variant)
775 {
776 armv4_5_common_t *armv4_5;
777 arm7_9_common_t *arm7_9;
778 int has_etm = 0;
779
780 arm7_9 = &arm7tdmi->arm7_9_common;
781 armv4_5 = &arm7_9->armv4_5_common;
782
783 /* prepare JTAG information for the new target */
784 arm7_9->jtag_info.chain_pos = chain_pos;
785 arm7_9->jtag_info.scann_size = 4;
786
787 /* register arch-specific functions */
788 arm7_9->examine_debug_reason = arm7tdmi_examine_debug_reason;
789 arm7_9->change_to_arm = arm7tdmi_change_to_arm;
790 arm7_9->read_core_regs = arm7tdmi_read_core_regs;
791 arm7_9->read_core_regs_target_buffer = arm7tdmi_read_core_regs_target_buffer;
792 arm7_9->read_xpsr = arm7tdmi_read_xpsr;
793
794 arm7_9->write_xpsr = arm7tdmi_write_xpsr;
795 arm7_9->write_xpsr_im8 = arm7tdmi_write_xpsr_im8;
796 arm7_9->write_core_regs = arm7tdmi_write_core_regs;
797
798 arm7_9->load_word_regs = arm7tdmi_load_word_regs;
799 arm7_9->load_hword_reg = arm7tdmi_load_hword_reg;
800 arm7_9->load_byte_reg = arm7tdmi_load_byte_reg;
801
802 arm7_9->store_word_regs = arm7tdmi_store_word_regs;
803 arm7_9->store_hword_reg = arm7tdmi_store_hword_reg;
804 arm7_9->store_byte_reg = arm7tdmi_store_byte_reg;
805
806 arm7_9->write_pc = arm7tdmi_write_pc;
807 arm7_9->branch_resume = arm7tdmi_branch_resume;
808 arm7_9->branch_resume_thumb = arm7tdmi_branch_resume_thumb;
809
810 arm7_9->enable_single_step = arm7_9_enable_eice_step;
811 arm7_9->disable_single_step = arm7_9_disable_eice_step;
812
813 arm7_9->pre_debug_entry = NULL;
814 arm7_9->post_debug_entry = NULL;
815
816 arm7_9->pre_restore_context = NULL;
817 arm7_9->post_restore_context = NULL;
818
819 /* initialize arch-specific breakpoint handling */
820 buf_set_u32((u8*)(&arm7_9->arm_bkpt), 0, 32, 0xdeeedeee);
821 buf_set_u32((u8*)(&arm7_9->thumb_bkpt), 0, 16, 0xdeee);
822
823 arm7_9->sw_bkpts_use_wp = 1;
824 arm7_9->sw_bkpts_enabled = 0;
825 arm7_9->dbgreq_adjust_pc = 2;
826 arm7_9->arch_info = arm7tdmi;
827
828 arm7tdmi->has_monitor_mode = 0;
829 arm7tdmi->arch_info = NULL;
830 arm7tdmi->common_magic = ARM7TDMI_COMMON_MAGIC;
831
832 if (variant)
833 {
834 if (strcmp(variant, "arm7tdmi-s_r4") == 0)
835 arm7tdmi->has_monitor_mode = 1;
836 else if (strcmp(variant, "arm7tdmi_r4") == 0)
837 arm7tdmi->has_monitor_mode = 1;
838 else if (strcmp(variant, "lpc2000") == 0)
839 {
840 arm7tdmi->has_monitor_mode = 1;
841 has_etm = 1;
842 }
843 arm7tdmi->variant = strdup(variant);
844 }
845 else
846 arm7tdmi->variant = strdup("");
847
848 arm7_9_init_arch_info(target, arm7_9);
849
850 arm7_9->has_etm = has_etm;
851
852 return ERROR_OK;
853 }
854
855 /* target arm7tdmi <endianess> <startup_mode> <chain_pos> <variant> */
856 int arm7tdmi_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
857 {
858 int chain_pos;
859 char *variant = NULL;
860 arm7tdmi_common_t *arm7tdmi = malloc(sizeof(arm7tdmi_common_t));
861
862 if (argc < 4)
863 {
864 ERROR("'target arm7tdmi' requires at least one additional argument");
865 exit(-1);
866 }
867
868 chain_pos = strtoul(args[2], NULL, 0);
869
870 if (argc >= 5)
871 variant = args[4];
872
873 arm7tdmi_init_arch_info(target, arm7tdmi, chain_pos, variant);
874
875 return ERROR_OK;
876 }
877
878 int arm7tdmi_register_commands(struct command_context_s *cmd_ctx)
879 {
880 int retval;
881
882 retval = arm7_9_register_commands(cmd_ctx);
883
884 return ERROR_OK;
885
886 }
887

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)