- added myself to copyright on files i remember adding large contributions for over...
[openocd.git] / src / target / arm7tdmi.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "arm7tdmi.h"
28
29 #include "arm7_9_common.h"
30 #include "register.h"
31 #include "target.h"
32 #include "armv4_5.h"
33 #include "embeddedice.h"
34 #include "etm.h"
35 #include "log.h"
36 #include "jtag.h"
37 #include "arm_jtag.h"
38
39 #include <stdlib.h>
40 #include <string.h>
41
42 #if 0
43 #define _DEBUG_INSTRUCTION_EXECUTION_
44 #endif
45
46 /* cli handling */
47 int arm7tdmi_register_commands(struct command_context_s *cmd_ctx);
48
49 /* forward declarations */
50
51 int arm7tdmi_target_create(struct target_s *target,Jim_Interp *interp);
52 int arm7tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
53 int arm7tdmi_quit(void);
54
55 /* target function declarations */
56 int arm7tdmi_poll(struct target_s *target);
57 int arm7tdmi_halt(target_t *target);
58
59 target_type_t arm7tdmi_target =
60 {
61 .name = "arm7tdmi",
62
63 .poll = arm7_9_poll,
64 .arch_state = armv4_5_arch_state,
65
66 .target_request_data = arm7_9_target_request_data,
67
68 .halt = arm7_9_halt,
69 .resume = arm7_9_resume,
70 .step = arm7_9_step,
71
72 .assert_reset = arm7_9_assert_reset,
73 .deassert_reset = arm7_9_deassert_reset,
74 .soft_reset_halt = arm7_9_soft_reset_halt,
75
76 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
77
78 .read_memory = arm7_9_read_memory,
79 .write_memory = arm7_9_write_memory,
80 .bulk_write_memory = arm7_9_bulk_write_memory,
81 .checksum_memory = arm7_9_checksum_memory,
82 .blank_check_memory = arm7_9_blank_check_memory,
83
84 .run_algorithm = armv4_5_run_algorithm,
85
86 .add_breakpoint = arm7_9_add_breakpoint,
87 .remove_breakpoint = arm7_9_remove_breakpoint,
88 .add_watchpoint = arm7_9_add_watchpoint,
89 .remove_watchpoint = arm7_9_remove_watchpoint,
90
91 .register_commands = arm7tdmi_register_commands,
92 .target_create = arm7tdmi_target_create,
93 .init_target = arm7tdmi_init_target,
94 .examine = arm7tdmi_examine,
95 .quit = arm7tdmi_quit
96 };
97
98 int arm7tdmi_examine_debug_reason(target_t *target)
99 {
100 /* get pointers to arch-specific information */
101 armv4_5_common_t *armv4_5 = target->arch_info;
102 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
103
104 /* only check the debug reason if we don't know it already */
105 if ((target->debug_reason != DBG_REASON_DBGRQ)
106 && (target->debug_reason != DBG_REASON_SINGLESTEP))
107 {
108 scan_field_t fields[2];
109 u8 databus[4];
110 u8 breakpoint;
111
112 jtag_add_end_state(TAP_PD);
113
114 fields[0].device = arm7_9->jtag_info.chain_pos;
115 fields[0].num_bits = 1;
116 fields[0].out_value = NULL;
117 fields[0].out_mask = NULL;
118 fields[0].in_value = &breakpoint;
119 fields[0].in_check_value = NULL;
120 fields[0].in_check_mask = NULL;
121 fields[0].in_handler = NULL;
122 fields[0].in_handler_priv = NULL;
123
124 fields[1].device = arm7_9->jtag_info.chain_pos;
125 fields[1].num_bits = 32;
126 fields[1].out_value = NULL;
127 fields[1].out_mask = NULL;
128 fields[1].in_value = databus;
129 fields[1].in_check_value = NULL;
130 fields[1].in_check_mask = NULL;
131 fields[1].in_handler = NULL;
132 fields[1].in_handler_priv = NULL;
133
134 arm_jtag_scann(&arm7_9->jtag_info, 0x1);
135 arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL);
136
137 jtag_add_dr_scan(2, fields, TAP_PD);
138 jtag_execute_queue();
139
140 fields[0].in_value = NULL;
141 fields[0].out_value = &breakpoint;
142 fields[1].in_value = NULL;
143 fields[1].out_value = databus;
144
145 jtag_add_dr_scan(2, fields, TAP_PD);
146
147 if (breakpoint & 1)
148 target->debug_reason = DBG_REASON_WATCHPOINT;
149 else
150 target->debug_reason = DBG_REASON_BREAKPOINT;
151 }
152
153 return ERROR_OK;
154 }
155
156 static int arm7tdmi_num_bits[]={1, 32};
157 static __inline int arm7tdmi_clock_out_inner(arm_jtag_t *jtag_info, u32 out, int breakpoint)
158 {
159 u32 values[2]={breakpoint, flip_u32(out, 32)};
160
161 jtag_add_dr_out(jtag_info->chain_pos,
162 2,
163 arm7tdmi_num_bits,
164 values,
165 -1);
166
167 jtag_add_runtest(0, -1);
168
169 return ERROR_OK;
170 }
171
172 /* put an instruction in the ARM7TDMI pipeline or write the data bus, and optionally read data */
173 static __inline int arm7tdmi_clock_out(arm_jtag_t *jtag_info, u32 out, u32 *deprecated, int breakpoint)
174 {
175 jtag_add_end_state(TAP_PD);
176 arm_jtag_scann(jtag_info, 0x1);
177 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
178
179 return arm7tdmi_clock_out_inner(jtag_info, out, breakpoint);
180 }
181
182 /* clock the target, reading the databus */
183 int arm7tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
184 {
185 scan_field_t fields[2];
186
187 jtag_add_end_state(TAP_PD);
188 arm_jtag_scann(jtag_info, 0x1);
189 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
190
191 fields[0].device = jtag_info->chain_pos;
192 fields[0].num_bits = 1;
193 fields[0].out_value = NULL;
194 fields[0].out_mask = NULL;
195 fields[0].in_value = NULL;
196 fields[0].in_check_value = NULL;
197 fields[0].in_check_mask = NULL;
198 fields[0].in_handler = NULL;
199 fields[0].in_handler_priv = NULL;
200
201 fields[1].device = jtag_info->chain_pos;
202 fields[1].num_bits = 32;
203 fields[1].out_value = NULL;
204 fields[1].out_mask = NULL;
205 fields[1].in_value = NULL;
206 fields[1].in_handler = arm_jtag_buf_to_u32_flip;
207 fields[1].in_handler_priv = in;
208 fields[1].in_check_value = NULL;
209 fields[1].in_check_mask = NULL;
210
211 jtag_add_dr_scan(2, fields, -1);
212
213 jtag_add_runtest(0, -1);
214
215 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
216 {
217 jtag_execute_queue();
218
219 if (in)
220 {
221 LOG_DEBUG("in: 0x%8.8x", *in);
222 }
223 else
224 {
225 LOG_ERROR("BUG: called with in == NULL");
226 }
227 }
228 #endif
229
230 return ERROR_OK;
231 }
232
233 /* clock the target, and read the databus
234 * the *in pointer points to a buffer where elements of 'size' bytes
235 * are stored in big (be==1) or little (be==0) endianness
236 */
237 int arm7tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, int be)
238 {
239 scan_field_t fields[2];
240
241 jtag_add_end_state(TAP_PD);
242 arm_jtag_scann(jtag_info, 0x1);
243 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
244
245 fields[0].device = jtag_info->chain_pos;
246 fields[0].num_bits = 1;
247 fields[0].out_value = NULL;
248 fields[0].out_mask = NULL;
249 fields[0].in_value = NULL;
250 fields[0].in_check_value = NULL;
251 fields[0].in_check_mask = NULL;
252 fields[0].in_handler = NULL;
253 fields[0].in_handler_priv = NULL;
254
255 fields[1].device = jtag_info->chain_pos;
256 fields[1].num_bits = 32;
257 fields[1].out_value = NULL;
258 fields[1].out_mask = NULL;
259 fields[1].in_value = NULL;
260 switch (size)
261 {
262 case 4:
263 fields[1].in_handler = (be) ? arm_jtag_buf_to_be32_flip : arm_jtag_buf_to_le32_flip;
264 break;
265 case 2:
266 fields[1].in_handler = (be) ? arm_jtag_buf_to_be16_flip : arm_jtag_buf_to_le16_flip;
267 break;
268 case 1:
269 fields[1].in_handler = arm_jtag_buf_to_8_flip;
270 break;
271 }
272 fields[1].in_handler_priv = in;
273 fields[1].in_check_value = NULL;
274 fields[1].in_check_mask = NULL;
275
276 jtag_add_dr_scan(2, fields, -1);
277
278 jtag_add_runtest(0, -1);
279
280 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
281 {
282 jtag_execute_queue();
283
284 if (in)
285 {
286 LOG_DEBUG("in: 0x%8.8x", *(u32*)in);
287 }
288 else
289 {
290 LOG_ERROR("BUG: called with in == NULL");
291 }
292 }
293 #endif
294
295 return ERROR_OK;
296 }
297
298 void arm7tdmi_change_to_arm(target_t *target, u32 *r0, u32 *pc)
299 {
300 /* get pointers to arch-specific information */
301 armv4_5_common_t *armv4_5 = target->arch_info;
302 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
303 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
304
305 /* save r0 before using it and put system in ARM state
306 * to allow common handling of ARM and THUMB debugging */
307
308 /* fetch STR r0, [r0] */
309 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), NULL, 0);
310 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
311 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
312 /* nothing fetched, STR r0, [r0] in Execute (2) */
313 arm7tdmi_clock_data_in(jtag_info, r0);
314
315 /* MOV r0, r15 fetched, STR in Decode */
316 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), NULL, 0);
317 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), NULL, 0);
318 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
319 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
320 /* nothing fetched, STR r0, [r0] in Execute (2) */
321 arm7tdmi_clock_data_in(jtag_info, pc);
322
323 /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
324 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), NULL, 0);
325 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
326 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
327 /* nothing fetched, data for LDR r0, [PC, #0] */
328 arm7tdmi_clock_out(jtag_info, 0x0, NULL, 0);
329 /* nothing fetched, data from previous cycle is written to register */
330 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
331
332 /* fetch BX */
333 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_BX(0), NULL, 0);
334 /* NOP fetched, BX in Decode, MOV in Execute */
335 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
336 /* NOP fetched, BX in Execute (1) */
337 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
338
339 jtag_execute_queue();
340
341 /* fix program counter:
342 * MOV r0, r15 was the 4th instruction (+6)
343 * reading PC in Thumb state gives address of instruction + 4
344 */
345 *pc -= 0xa;
346
347 }
348
349 void arm7tdmi_read_core_regs(target_t *target, u32 mask, u32* core_regs[16])
350 {
351 int i;
352 /* get pointers to arch-specific information */
353 armv4_5_common_t *armv4_5 = target->arch_info;
354 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
355 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
356
357 /* STMIA r0-15, [r0] at debug speed
358 * register values will start to appear on 4th DCLK
359 */
360 arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), NULL, 0);
361
362 /* fetch NOP, STM in DECODE stage */
363 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
364 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
365 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
366
367 for (i = 0; i <= 15; i++)
368 {
369 if (mask & (1 << i))
370 /* nothing fetched, STM still in EXECUTE (1+i cycle) */
371 arm7tdmi_clock_data_in(jtag_info, core_regs[i]);
372 }
373
374 }
375
376 void arm7tdmi_read_core_regs_target_buffer(target_t *target, u32 mask, void* buffer, int size)
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 int be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0;
384 u32 *buf_u32 = buffer;
385 u16 *buf_u16 = buffer;
386 u8 *buf_u8 = buffer;
387
388 /* STMIA r0-15, [r0] at debug speed
389 * register values will start to appear on 4th DCLK
390 */
391 arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), NULL, 0);
392
393 /* fetch NOP, STM in DECODE stage */
394 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
395 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
396 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
397
398 for (i = 0; i <= 15; i++)
399 {
400 /* nothing fetched, STM still in EXECUTE (1+i cycle), read databus */
401 if (mask & (1 << i))
402 {
403 switch (size)
404 {
405 case 4:
406 arm7tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);
407 break;
408 case 2:
409 arm7tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be);
410 break;
411 case 1:
412 arm7tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be);
413 break;
414 }
415 }
416 }
417
418 }
419
420 void arm7tdmi_read_xpsr(target_t *target, u32 *xpsr, int spsr)
421 {
422 /* get pointers to arch-specific information */
423 armv4_5_common_t *armv4_5 = target->arch_info;
424 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
425 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
426
427 /* MRS r0, cpsr */
428 arm7tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), NULL, 0);
429
430 /* STR r0, [r15] */
431 arm7tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), NULL, 0);
432 /* fetch NOP, STR in DECODE stage */
433 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
434 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
435 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
436 /* nothing fetched, STR still in EXECUTE (2nd cycle) */
437 arm7tdmi_clock_data_in(jtag_info, xpsr);
438
439 }
440
441 void arm7tdmi_write_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 LOG_DEBUG("xpsr: %8.8x, spsr: %i", xpsr, spsr);
449
450 /* MSR1 fetched */
451 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), NULL, 0);
452 /* MSR2 fetched, MSR1 in DECODE */
453 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), NULL, 0);
454 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
455 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), NULL, 0);
456 /* nothing fetched, MSR1 in EXECUTE (2) */
457 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
458 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
459 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), NULL, 0);
460 /* nothing fetched, MSR2 in EXECUTE (2) */
461 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
462 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
463 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
464 /* nothing fetched, MSR3 in EXECUTE (2) */
465 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
466 /* NOP fetched, MSR4 in EXECUTE (1) */
467 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
468 /* nothing fetched, MSR4 in EXECUTE (2) */
469 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
470 }
471
472 void arm7tdmi_write_xpsr_im8(target_t *target, u8 xpsr_im, int rot, int spsr)
473 {
474 /* get pointers to arch-specific information */
475 armv4_5_common_t *armv4_5 = target->arch_info;
476 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
477 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
478
479 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr);
480
481 /* MSR fetched */
482 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), NULL, 0);
483 /* NOP fetched, MSR in DECODE */
484 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
485 /* NOP fetched, MSR in EXECUTE (1) */
486 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
487 /* nothing fetched, MSR in EXECUTE (2) */
488 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
489
490 }
491
492 void arm7tdmi_write_core_regs(target_t *target, u32 mask, u32 core_regs[16])
493 {
494 int i;
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 /* LDMIA r0-15, [r0] at debug speed
501 * register values will start to appear on 4th DCLK
502 */
503 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), NULL, 0);
504
505 /* fetch NOP, LDM in DECODE stage */
506 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
507 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
508 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
509
510 for (i = 0; i <= 15; i++)
511 {
512 if (mask & (1 << i))
513 /* nothing fetched, LDM still in EXECUTE (1+i cycle) */
514 arm7tdmi_clock_out_inner(jtag_info, core_regs[i], 0);
515 }
516 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
517
518 }
519
520 void arm7tdmi_load_word_regs(target_t *target, u32 mask)
521 {
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 /* put system-speed load-multiple into the pipeline */
528 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
529 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
530 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 1), NULL, 0);
531
532 }
533
534 void arm7tdmi_load_hword_reg(target_t *target, int num)
535 {
536 /* get pointers to arch-specific information */
537 armv4_5_common_t *armv4_5 = target->arch_info;
538 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
539 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
540
541 /* put system-speed load half-word into the pipeline */
542 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
543 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
544 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDRH_IP(num, 0), NULL, 0);
545
546 }
547
548 void arm7tdmi_load_byte_reg(target_t *target, int num)
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 byte 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_LDRB_IP(num, 0), NULL, 0);
559
560 }
561
562 void arm7tdmi_store_word_regs(target_t *target, u32 mask)
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 store-multiple 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_STMIA(0, mask, 0, 1), NULL, 0);
573
574 }
575
576 void arm7tdmi_store_hword_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 store half-word 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_STRH_IP(num, 0), NULL, 0);
587
588 }
589
590 void arm7tdmi_store_byte_reg(target_t *target, int num)
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 byte 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_STRB_IP(num, 0), NULL, 0);
601
602 }
603
604 void arm7tdmi_write_pc(target_t *target, u32 pc)
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 /* LDMIA r0-15, [r0] at debug speed
612 * register values will start to appear on 4th DCLK
613 */
614 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), NULL, 0);
615 /* fetch NOP, LDM in DECODE stage */
616 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
617 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
618 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
619 /* nothing fetched, LDM in EXECUTE stage (1st cycle) load register */
620 arm7tdmi_clock_out_inner(jtag_info, pc, 0);
621 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) load register */
622 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
623 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) load register */
624 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
625 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
626 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
627 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
628 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
629 }
630
631 void arm7tdmi_branch_resume(target_t *target)
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 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
639 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_B(0xfffffa, 0), 0);
640
641 }
642
643 void arm7tdmi_branch_resume_thumb(target_t *target)
644 {
645 LOG_DEBUG("-");
646
647 /* get pointers to arch-specific information */
648 armv4_5_common_t *armv4_5 = target->arch_info;
649 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
650 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
651 reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
652
653 /* LDMIA r0, [r0] at debug speed
654 * register values will start to appear on 4th DCLK
655 */
656 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x1, 0, 0), NULL, 0);
657
658 /* fetch NOP, LDM in DECODE stage */
659 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
660 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
661 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
662 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
663 arm7tdmi_clock_out(jtag_info, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) | 1, NULL, 0);
664 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
665 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
666
667 /* Branch and eXchange */
668 arm7tdmi_clock_out(jtag_info, ARMV4_5_BX(0), NULL, 0);
669
670 embeddedice_read_reg(dbg_stat);
671
672 /* fetch NOP, BX in DECODE stage */
673 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
674
675 /* target is now in Thumb state */
676 embeddedice_read_reg(dbg_stat);
677
678 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
679 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
680
681 /* target is now in Thumb state */
682 embeddedice_read_reg(dbg_stat);
683
684 /* load r0 value */
685 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), NULL, 0);
686 /* fetch NOP, LDR in Decode */
687 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
688 /* fetch NOP, LDR in Execute */
689 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
690 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
691 arm7tdmi_clock_out(jtag_info, buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32), NULL, 0);
692 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
693 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
694
695 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
696 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
697
698 embeddedice_read_reg(dbg_stat);
699
700 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 1);
701 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f8), NULL, 0);
702
703 }
704
705 void arm7tdmi_build_reg_cache(target_t *target)
706 {
707 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
708 /* get pointers to arch-specific information */
709 armv4_5_common_t *armv4_5 = target->arch_info;
710
711 (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
712 armv4_5->core_cache = (*cache_p);
713 }
714
715 int arm7tdmi_examine(struct target_s *target)
716 {
717 int retval;
718 armv4_5_common_t *armv4_5 = target->arch_info;
719 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
720 if (!target->type->examined)
721 {
722 /* get pointers to arch-specific information */
723 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
724 reg_cache_t *t=embeddedice_build_reg_cache(target, arm7_9);
725 if (t==NULL)
726 return ERROR_FAIL;
727
728 (*cache_p) = t;
729 arm7_9->eice_cache = (*cache_p);
730
731 if (arm7_9->etm_ctx)
732 {
733 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
734 (*cache_p)->next = etm_build_reg_cache(target, jtag_info, arm7_9->etm_ctx);
735 arm7_9->etm_ctx->reg_cache = (*cache_p)->next;
736 }
737 target->type->examined = 1;
738 }
739 if ((retval=embeddedice_setup(target))!=ERROR_OK)
740 return retval;
741 if ((retval=arm7_9_setup(target))!=ERROR_OK)
742 return retval;
743 if (arm7_9->etm_ctx)
744 {
745 if ((retval=etm_setup(target))!=ERROR_OK)
746 return retval;
747 }
748 return ERROR_OK;
749 }
750
751 int arm7tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
752 {
753
754 arm7tdmi_build_reg_cache(target);
755
756 return ERROR_OK;
757
758 }
759
760 int arm7tdmi_quit(void)
761 {
762
763 return ERROR_OK;
764 }
765
766 int arm7tdmi_init_arch_info(target_t *target, arm7tdmi_common_t *arm7tdmi, int chain_pos, const char *variant)
767 {
768 armv4_5_common_t *armv4_5;
769 arm7_9_common_t *arm7_9;
770
771 arm7_9 = &arm7tdmi->arm7_9_common;
772 armv4_5 = &arm7_9->armv4_5_common;
773
774 /* prepare JTAG information for the new target */
775 arm7_9->jtag_info.chain_pos = chain_pos;
776 arm7_9->jtag_info.scann_size = 4;
777
778 /* register arch-specific functions */
779 arm7_9->examine_debug_reason = arm7tdmi_examine_debug_reason;
780 arm7_9->change_to_arm = arm7tdmi_change_to_arm;
781 arm7_9->read_core_regs = arm7tdmi_read_core_regs;
782 arm7_9->read_core_regs_target_buffer = arm7tdmi_read_core_regs_target_buffer;
783 arm7_9->read_xpsr = arm7tdmi_read_xpsr;
784
785 arm7_9->write_xpsr = arm7tdmi_write_xpsr;
786 arm7_9->write_xpsr_im8 = arm7tdmi_write_xpsr_im8;
787 arm7_9->write_core_regs = arm7tdmi_write_core_regs;
788
789 arm7_9->load_word_regs = arm7tdmi_load_word_regs;
790 arm7_9->load_hword_reg = arm7tdmi_load_hword_reg;
791 arm7_9->load_byte_reg = arm7tdmi_load_byte_reg;
792
793 arm7_9->store_word_regs = arm7tdmi_store_word_regs;
794 arm7_9->store_hword_reg = arm7tdmi_store_hword_reg;
795 arm7_9->store_byte_reg = arm7tdmi_store_byte_reg;
796
797 arm7_9->write_pc = arm7tdmi_write_pc;
798 arm7_9->branch_resume = arm7tdmi_branch_resume;
799 arm7_9->branch_resume_thumb = arm7tdmi_branch_resume_thumb;
800
801 arm7_9->enable_single_step = arm7_9_enable_eice_step;
802 arm7_9->disable_single_step = arm7_9_disable_eice_step;
803
804 arm7_9->pre_debug_entry = NULL;
805 arm7_9->post_debug_entry = NULL;
806
807 arm7_9->pre_restore_context = NULL;
808 arm7_9->post_restore_context = NULL;
809
810 /* initialize arch-specific breakpoint handling */
811 arm7_9->arm_bkpt = 0xdeeedeee;
812 arm7_9->thumb_bkpt = 0xdeee;
813
814 arm7_9->dbgreq_adjust_pc = 2;
815 arm7_9->arch_info = arm7tdmi;
816
817 arm7tdmi->arch_info = NULL;
818 arm7tdmi->common_magic = ARM7TDMI_COMMON_MAGIC;
819
820 if (variant)
821 {
822 arm7tdmi->variant = strdup(variant);
823 }
824 else
825 {
826 arm7tdmi->variant = strdup("");
827 }
828
829 arm7_9_init_arch_info(target, arm7_9);
830
831 return ERROR_OK;
832 }
833
834
835
836 int arm7tdmi_target_create( struct target_s *target, Jim_Interp *interp )
837 {
838 arm7tdmi_common_t *arm7tdmi;
839
840 arm7tdmi = calloc(1,sizeof(arm7tdmi_common_t));
841
842 arm7tdmi_init_arch_info(target, arm7tdmi, target->chain_position, target->variant);
843
844 return ERROR_OK;
845 }
846
847
848 int arm7tdmi_register_commands(struct command_context_s *cmd_ctx)
849 {
850 int retval;
851
852 retval = arm7_9_register_commands(cmd_ctx);
853
854 return ERROR_OK;
855
856 }

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)