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

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)