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

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)