48b201a11c28df439e8dd57d0938cb70159b5e38
[openocd.git] / src / target / arm9tdmi.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 #include "config.h"
21
22 #include "arm9tdmi.h"
23
24 #include "arm7_9_common.h"
25 #include "register.h"
26 #include "target.h"
27 #include "armv4_5.h"
28 #include "embeddedice.h"
29 #include "log.h"
30 #include "jtag.h"
31 #include "arm_jtag.h"
32
33 #include <stdlib.h>
34 #include <string.h>
35
36 #if 0
37 #define _DEBUG_INSTRUCTION_EXECUTION_
38 #endif
39
40 /* cli handling */
41 int arm9tdmi_register_commands(struct command_context_s *cmd_ctx);
42
43 /* forward declarations */
44 int arm9tdmi_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
45 int arm9tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
46 int arm9tdmi_quit();
47
48 /* target function declarations */
49 enum target_state arm9tdmi_poll(struct target_s *target);
50 int arm9tdmi_halt(target_t *target);
51 int arm9tdmi_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
52
53 target_type_t arm9tdmi_target =
54 {
55 .name = "arm9tdmi",
56
57 .poll = arm7_9_poll,
58 .arch_state = armv4_5_arch_state,
59
60 .halt = arm7_9_halt,
61 .resume = arm7_9_resume,
62 .step = arm7_9_step,
63
64 .assert_reset = arm7_9_assert_reset,
65 .deassert_reset = arm7_9_deassert_reset,
66 .soft_reset_halt = arm7_9_soft_reset_halt,
67
68 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
69
70 .read_memory = arm7_9_read_memory,
71 .write_memory = arm7_9_write_memory,
72 .bulk_write_memory = arm7_9_bulk_write_memory,
73
74 .add_breakpoint = arm7_9_add_breakpoint,
75 .remove_breakpoint = arm7_9_remove_breakpoint,
76 .add_watchpoint = arm7_9_add_watchpoint,
77 .remove_watchpoint = arm7_9_remove_watchpoint,
78
79 .register_commands = arm9tdmi_register_commands,
80 .target_command = arm9tdmi_target_command,
81 .init_target = arm9tdmi_init_target,
82 .quit = arm9tdmi_quit
83 };
84
85 int arm9tdmi_examine_debug_reason(target_t *target)
86 {
87 /* get pointers to arch-specific information */
88 armv4_5_common_t *armv4_5 = target->arch_info;
89 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
90
91 /* only check the debug reason if we don't know it already */
92 if ((target->debug_reason != DBG_REASON_DBGRQ)
93 && (target->debug_reason != DBG_REASON_SINGLESTEP))
94 {
95 scan_field_t fields[3];
96 u8 databus[4];
97 u8 instructionbus[4];
98 u8 debug_reason;
99
100 jtag_add_end_state(TAP_PD);
101
102 fields[0].device = arm7_9->jtag_info.chain_pos;
103 fields[0].num_bits = 32;
104 fields[0].out_value = NULL;
105 fields[0].out_mask = NULL;
106 fields[0].in_value = databus;
107 fields[0].in_check_value = NULL;
108 fields[0].in_check_mask = NULL;
109 fields[0].in_handler = NULL;
110 fields[0].in_handler_priv = NULL;
111
112 fields[1].device = arm7_9->jtag_info.chain_pos;
113 fields[1].num_bits = 3;
114 fields[1].out_value = NULL;
115 fields[1].out_mask = NULL;
116 fields[1].in_value = &debug_reason;
117 fields[1].in_check_value = NULL;
118 fields[1].in_check_mask = NULL;
119 fields[1].in_handler = NULL;
120 fields[1].in_handler_priv = NULL;
121
122 fields[2].device = arm7_9->jtag_info.chain_pos;
123 fields[2].num_bits = 32;
124 fields[2].out_value = NULL;
125 fields[2].out_mask = NULL;
126 fields[2].in_value = instructionbus;
127 fields[2].in_check_value = NULL;
128 fields[2].in_check_mask = NULL;
129 fields[2].in_handler = NULL;
130 fields[2].in_handler_priv = NULL;
131
132 arm_jtag_scann(&arm7_9->jtag_info, 0x1);
133 arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr);
134
135 jtag_add_dr_scan(3, fields, TAP_PD);
136 jtag_execute_queue();
137
138 fields[0].in_value = NULL;
139 fields[0].out_value = databus;
140 fields[1].in_value = NULL;
141 fields[1].out_value = &debug_reason;
142 fields[2].in_value = NULL;
143 fields[2].out_value = instructionbus;
144
145 jtag_add_dr_scan(3, fields, TAP_PD);
146
147 if (debug_reason & 0x4)
148 if (debug_reason & 0x2)
149 target->debug_reason = DBG_REASON_WPTANDBKPT;
150 else
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 /* put an instruction in the ARM9TDMI pipeline or write the data bus, and optionally read data */
160 int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int sysspeed)
161 {
162 scan_field_t fields[3];
163 u8 out_buf[4];
164 u8 instr_buf[4];
165 u8 sysspeed_buf = 0x0;
166
167 /* prepare buffer */
168 buf_set_u32(out_buf, 0, 32, out);
169
170 instr = flip_u32(instr, 32);
171 buf_set_u32(instr_buf, 0, 32, instr);
172
173 if (sysspeed)
174 buf_set_u32(&sysspeed_buf, 2, 1, 1);
175
176 jtag_add_end_state(TAP_PD);
177 arm_jtag_scann(jtag_info, 0x1);
178 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr);
179
180 fields[0].device = jtag_info->chain_pos;
181 fields[0].num_bits = 32;
182 fields[0].out_value = out_buf;
183 fields[0].out_mask = NULL;
184 if (in)
185 {
186 fields[0].in_value = (u8*)in;
187 } else
188 {
189 fields[0].in_value = NULL;
190 }
191 fields[0].in_check_value = NULL;
192 fields[0].in_check_mask = NULL;
193 fields[0].in_handler = NULL;
194 fields[0].in_handler_priv = NULL;
195
196 fields[1].device = jtag_info->chain_pos;
197 fields[1].num_bits = 3;
198 fields[1].out_value = &sysspeed_buf;
199 fields[1].out_mask = NULL;
200 fields[1].in_value = NULL;
201 fields[1].in_check_value = NULL;
202 fields[1].in_check_mask = NULL;
203 fields[1].in_handler = NULL;
204 fields[1].in_handler_priv = NULL;
205
206 fields[2].device = jtag_info->chain_pos;
207 fields[2].num_bits = 32;
208 fields[2].out_value = instr_buf;
209 fields[2].out_mask = NULL;
210 fields[2].in_value = NULL;
211 fields[2].in_check_value = NULL;
212 fields[2].in_check_mask = NULL;
213 fields[2].in_handler = NULL;
214 fields[2].in_handler_priv = NULL;
215
216 jtag_add_dr_scan(3, fields, -1);
217
218 jtag_add_runtest(0, -1);
219
220 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
221 {
222 char* in_string;
223 jtag_execute_queue();
224
225 if (in)
226 {
227 in_string = buf_to_char((u8*)in, 32);
228 DEBUG("instr: 0x%8.8x, out: 0x%8.8x, in: %s", flip_u32(instr, 32), out, in_string);
229 free(in_string);
230 }
231 else
232 DEBUG("instr: 0x%8.8x, out: 0x%8.8x", flip_u32(instr, 32), out);
233 }
234 #endif
235
236 return ERROR_OK;
237 }
238
239 /* just read data (instruction and data-out = don't care) */
240 int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
241 {
242 scan_field_t fields[3];
243
244 jtag_add_end_state(TAP_PD);
245 arm_jtag_scann(jtag_info, 0x1);
246 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr);
247
248 fields[0].device = jtag_info->chain_pos;
249 fields[0].num_bits = 32;
250 fields[0].out_value = NULL;
251 fields[0].out_mask = NULL;
252 fields[0].in_value = (u8*)in;
253 fields[0].in_handler = NULL;
254 fields[0].in_handler_priv = NULL;
255 fields[0].in_check_value = NULL;
256 fields[0].in_check_mask = NULL;
257
258 fields[1].device = jtag_info->chain_pos;
259 fields[1].num_bits = 3;
260 fields[1].out_value = NULL;
261 fields[1].out_mask = NULL;
262 fields[1].in_value = NULL;
263 fields[1].in_handler = NULL;
264 fields[1].in_handler_priv = NULL;
265 fields[1].in_check_value = NULL;
266 fields[1].in_check_mask = NULL;
267
268 fields[2].device = jtag_info->chain_pos;
269 fields[2].num_bits = 32;
270 fields[2].out_value = NULL;
271 fields[2].out_mask = NULL;
272 fields[2].in_value = NULL;
273 fields[2].in_check_value = NULL;
274 fields[2].in_check_mask = NULL;
275 fields[2].in_handler = NULL;
276 fields[2].in_handler_priv = NULL;
277
278 jtag_add_dr_scan(3, fields, -1);
279
280 jtag_add_runtest(0, -1);
281
282 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
283 {
284 char* in_string;
285 jtag_execute_queue();
286
287 if (in)
288 {
289 in_string = buf_to_char((u8*)in, 32);
290 DEBUG("in: %s", in_string);
291 free(in_string);
292 }
293 }
294 #endif
295
296 return ERROR_OK;
297 }
298
299 void arm9tdmi_change_to_arm(target_t *target, u32 *r0, u32 *pc)
300 {
301 /* get pointers to arch-specific information */
302 armv4_5_common_t *armv4_5 = target->arch_info;
303 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
304 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
305
306 /* save r0 before using it and put system in ARM state
307 * to allow common handling of ARM and THUMB debugging */
308
309 /* fetch STR r0, [r0] */
310 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);
311 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
312 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
313 /* STR r0, [r0] in Memory */
314 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, r0, 0);
315
316 /* MOV r0, r15 fetched, STR in Decode */
317 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), 0, NULL, 0);
318 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
319 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);
320 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
321 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
322 /* nothing fetched, STR r0, [r0] in Memory */
323 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, pc, 0);
324
325 /* fetch MOV */
326 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_MOV_IM(0, 0x0), 0, NULL, 0);
327 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
328 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
329
330 /* fetch BX */
331 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_BX(0), 0, NULL, 0);
332 /* NOP fetched, BX in Decode, MOV in Execute */
333 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
334 /* NOP fetched, BX in Execute (1) */
335 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
336
337 jtag_execute_queue();
338
339 /* fix program counter:
340 * MOV r0, r15 was the 5th instruction (+8)
341 * reading PC in Thumb state gives address of instruction + 4
342 */
343 *pc -= 0xc;
344 }
345
346 void arm9tdmi_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 arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
358
359 /* fetch NOP, STM in DECODE stage */
360 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
361 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
362 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
363
364 for (i = 0; i <= 15; i++)
365 {
366 if (mask & (1 << i))
367 /* nothing fetched, STM in MEMORY (i'th cycle) */
368 arm9tdmi_clock_data_in(jtag_info, core_regs[i]);
369 }
370
371 }
372
373 void arm9tdmi_read_xpsr(target_t *target, u32 *xpsr, int spsr)
374 {
375 /* get pointers to arch-specific information */
376 armv4_5_common_t *armv4_5 = target->arch_info;
377 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
378 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
379
380 /* MRS r0, cpsr */
381 arm9tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), 0, NULL, 0);
382 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
383 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
384 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
385 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
386
387 /* STR r0, [r15] */
388 arm9tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), 0, NULL, 0);
389 /* fetch NOP, STR in DECODE stage */
390 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
391 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
392 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
393 /* nothing fetched, STR in MEMORY */
394 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, xpsr, 0);
395
396 }
397
398 void arm9tdmi_write_xpsr(target_t *target, u32 xpsr, int spsr)
399 {
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
405 DEBUG("xpsr: %8.8x, spsr: %i", xpsr, spsr);
406
407 /* MSR1 fetched */
408 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), 0, NULL, 0);
409 /* MSR2 fetched, MSR1 in DECODE */
410 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), 0, NULL, 0);
411 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
412 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), 0, NULL, 0);
413 /* nothing fetched, MSR1 in EXECUTE (2) */
414 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
415 /* nothing fetched, MSR1 in EXECUTE (3) */
416 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
417 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
418 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), 0, NULL, 0);
419 /* nothing fetched, MSR2 in EXECUTE (2) */
420 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
421 /* nothing fetched, MSR2 in EXECUTE (3) */
422 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
423 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
424 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
425 /* nothing fetched, MSR3 in EXECUTE (2) */
426 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
427 /* nothing fetched, MSR3 in EXECUTE (3) */
428 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
429 /* NOP fetched, MSR4 in EXECUTE (1) */
430 /* last MSR writes flags, which takes only one cycle */
431 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
432 }
433
434 void arm9tdmi_write_xpsr_im8(target_t *target, u8 xpsr_im, int rot, 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 DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr);
442
443 /* MSR fetched */
444 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), 0, NULL, 0);
445 /* NOP fetched, MSR in DECODE */
446 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
447 /* NOP fetched, MSR in EXECUTE (1) */
448 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
449
450 /* rot == 4 writes flags, which takes only one cycle */
451 if (rot != 4)
452 {
453 /* nothing fetched, MSR in EXECUTE (2) */
454 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
455 /* nothing fetched, MSR in EXECUTE (3) */
456 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
457 }
458 }
459
460 void arm9tdmi_write_core_regs(target_t *target, u32 mask, u32 core_regs[16])
461 {
462 int i;
463 /* get pointers to arch-specific information */
464 armv4_5_common_t *armv4_5 = target->arch_info;
465 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
466 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
467
468 /* LDMIA r0-15, [r0] at debug speed
469 * register values will start to appear on 4th DCLK
470 */
471 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
472
473 /* fetch NOP, LDM in DECODE stage */
474 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
475 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
476 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
477
478 for (i = 0; i <= 15; i++)
479 {
480 if (mask & (1 << i))
481 /* nothing fetched, LDM still in EXECUTE (1+i cycle) */
482 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, core_regs[i], NULL, 0);
483 }
484 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
485
486 }
487
488 void arm9tdmi_load_word_regs(target_t *target, u32 mask)
489 {
490 /* get pointers to arch-specific information */
491 armv4_5_common_t *armv4_5 = target->arch_info;
492 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
493 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
494
495 /* put system-speed load-multiple into the pipeline */
496 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 1), 0, NULL, 0);
497 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
498
499 }
500
501 void arm9tdmi_load_hword_reg(target_t *target, int num)
502 {
503 /* get pointers to arch-specific information */
504 armv4_5_common_t *armv4_5 = target->arch_info;
505 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
506 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
507
508 /* put system-speed load half-word into the pipeline */
509 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDRH_IP(num, 0), 0, NULL, 0);
510 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
511 }
512
513 void arm9tdmi_load_byte_reg(target_t *target, int num)
514 {
515 /* get pointers to arch-specific information */
516 armv4_5_common_t *armv4_5 = target->arch_info;
517 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
518 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
519
520 /* put system-speed load byte into the pipeline */
521 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDRB_IP(num, 0), 0, NULL, 0);
522 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
523
524 }
525
526 void arm9tdmi_store_word_regs(target_t *target, u32 mask)
527 {
528 /* get pointers to arch-specific information */
529 armv4_5_common_t *armv4_5 = target->arch_info;
530 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
531 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
532
533 /* put system-speed store-multiple into the pipeline */
534 arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask, 0, 1), 0, NULL, 0);
535 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
536
537 }
538
539 void arm9tdmi_store_hword_reg(target_t *target, int num)
540 {
541 /* get pointers to arch-specific information */
542 armv4_5_common_t *armv4_5 = target->arch_info;
543 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
544 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
545
546 /* put system-speed store half-word into the pipeline */
547 arm9tdmi_clock_out(jtag_info, ARMV4_5_STRH_IP(num, 0), 0, NULL, 0);
548 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
549
550 }
551
552 void arm9tdmi_store_byte_reg(target_t *target, int num)
553 {
554 /* get pointers to arch-specific information */
555 armv4_5_common_t *armv4_5 = target->arch_info;
556 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
557 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
558
559 /* put system-speed store byte into the pipeline */
560 arm9tdmi_clock_out(jtag_info, ARMV4_5_STRB_IP(num, 0), 0, NULL, 0);
561 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
562
563 }
564
565 void arm9tdmi_write_pc(target_t *target, u32 pc)
566 {
567 /* get pointers to arch-specific information */
568 armv4_5_common_t *armv4_5 = target->arch_info;
569 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
570 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
571
572 /* LDMIA r0-15, [r0] at debug speed
573 * register values will start to appear on 4th DCLK
574 */
575 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL, 0);
576
577 /* fetch NOP, LDM in DECODE stage */
578 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
579 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
580 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
581 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) (output data) */
582 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, pc, NULL, 0);
583 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
584 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
585 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
586 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
587 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
588 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
589
590 }
591
592 void arm9tdmi_branch_resume(target_t *target)
593 {
594 /* get pointers to arch-specific information */
595 armv4_5_common_t *armv4_5 = target->arch_info;
596 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
597 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
598
599 arm9tdmi_clock_out(jtag_info, ARMV4_5_B(0xfffffc, 0), 0, NULL, 0);
600 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
601
602 }
603
604 void arm9tdmi_branch_resume_thumb(target_t *target)
605 {
606 DEBUG("");
607
608 /* get pointers to arch-specific information */
609 armv4_5_common_t *armv4_5 = target->arch_info;
610 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
611 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
612 reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
613
614 /* LDMIA r0-15, [r0] at debug speed
615 * register values will start to appear on 4th DCLK
616 */
617 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x1, 0, 0), 0, NULL, 0);
618
619 /* fetch NOP, LDM in DECODE stage */
620 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
621 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
622 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
623 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
624 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) | 1, NULL, 0);
625 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
626 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
627
628 /* Branch and eXchange */
629 arm9tdmi_clock_out(jtag_info, ARMV4_5_BX(0), 0, NULL, 0);
630
631 embeddedice_read_reg(dbg_stat);
632
633 /* fetch NOP, BX in DECODE stage */
634 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
635
636 embeddedice_read_reg(dbg_stat);
637
638 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
639 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
640
641 /* target is now in Thumb state */
642 embeddedice_read_reg(dbg_stat);
643
644 /* clean r0 bits to avoid alignment problems */
645 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_MOV_IM(0, 0x0), 0, NULL, 0);
646 /* load r0 value, MOV_IM in Decode*/
647 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDR(0, 0), 0, NULL, 0);
648 /* fetch NOP, LDR in Decode, MOV_IM in Execute */
649 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
650 /* fetch NOP, LDR in Execute */
651 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
652 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
653 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32), NULL, 0);
654 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
655 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
656
657 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
658 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
659
660 embeddedice_read_reg(dbg_stat);
661
662 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f6), 0, NULL, 1);
663 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
664
665 }
666
667 void arm9tdmi_enable_single_step(target_t *target)
668 {
669 /* get pointers to arch-specific information */
670 armv4_5_common_t *armv4_5 = target->arch_info;
671 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
672 arm9tdmi_common_t *arm9 = arm7_9->arch_info;
673
674 if (arm9->has_single_step)
675 {
676 buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 1);
677 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);
678 }
679 else
680 {
681 arm7_9_enable_eice_step(target);
682 }
683 }
684
685 void arm9tdmi_disable_single_step(target_t *target)
686 {
687 /* get pointers to arch-specific information */
688 armv4_5_common_t *armv4_5 = target->arch_info;
689 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
690 arm9tdmi_common_t *arm9 = arm7_9->arch_info;
691
692 if (arm9->has_single_step)
693 {
694 buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 0);
695 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);
696 }
697 else
698 {
699 arm7_9_disable_eice_step(target);
700 }
701 }
702
703 void arm9tdmi_build_reg_cache(target_t *target)
704 {
705 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
706 /* get pointers to arch-specific information */
707 armv4_5_common_t *armv4_5 = target->arch_info;
708 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
709 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
710 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
711
712
713 (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
714 armv4_5->core_cache = (*cache_p);
715
716 (*cache_p)->next = embeddedice_build_reg_cache(target, jtag_info, 0);
717 arm7_9->eice_cache = (*cache_p)->next;
718
719 if (arm9tdmi->has_monitor_mode)
720 (*cache_p)->next->reg_list[0].size = 6;
721 else
722 (*cache_p)->next->reg_list[0].size = 4;
723
724 (*cache_p)->next->reg_list[1].size = 5;
725
726 }
727
728 int arm9tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
729 {
730
731 arm9tdmi_build_reg_cache(target);
732
733 return ERROR_OK;
734
735 }
736
737 int arm9tdmi_quit()
738 {
739
740 return ERROR_OK;
741 }
742
743 int arm9tdmi_init_arch_info(target_t *target, arm9tdmi_common_t *arm9tdmi, int chain_pos, char *variant)
744 {
745 armv4_5_common_t *armv4_5;
746 arm7_9_common_t *arm7_9;
747
748 arm7_9 = &arm9tdmi->arm7_9_common;
749 armv4_5 = &arm7_9->armv4_5_common;
750
751 /* prepare JTAG information for the new target */
752 arm7_9->jtag_info.chain_pos = chain_pos;
753 arm7_9->jtag_info.scann_size = 5;
754
755 /* register arch-specific functions */
756 arm7_9->examine_debug_reason = arm9tdmi_examine_debug_reason;
757 arm7_9->change_to_arm = arm9tdmi_change_to_arm;
758 arm7_9->read_core_regs = arm9tdmi_read_core_regs;
759 arm7_9->read_xpsr = arm9tdmi_read_xpsr;
760
761 arm7_9->write_xpsr = arm9tdmi_write_xpsr;
762 arm7_9->write_xpsr_im8 = arm9tdmi_write_xpsr_im8;
763 arm7_9->write_core_regs = arm9tdmi_write_core_regs;
764
765 arm7_9->load_word_regs = arm9tdmi_load_word_regs;
766 arm7_9->load_hword_reg = arm9tdmi_load_hword_reg;
767 arm7_9->load_byte_reg = arm9tdmi_load_byte_reg;
768
769 arm7_9->store_word_regs = arm9tdmi_store_word_regs;
770 arm7_9->store_hword_reg = arm9tdmi_store_hword_reg;
771 arm7_9->store_byte_reg = arm9tdmi_store_byte_reg;
772
773 arm7_9->write_pc = arm9tdmi_write_pc;
774 arm7_9->branch_resume = arm9tdmi_branch_resume;
775 arm7_9->branch_resume_thumb = arm9tdmi_branch_resume_thumb;
776
777 arm7_9->enable_single_step = arm9tdmi_enable_single_step;
778 arm7_9->disable_single_step = arm9tdmi_disable_single_step;
779
780 arm7_9->pre_debug_entry = NULL;
781 arm7_9->post_debug_entry = NULL;
782
783 arm7_9->pre_restore_context = NULL;
784 arm7_9->post_restore_context = NULL;
785
786 /* initialize arch-specific breakpoint handling */
787 buf_set_u32((u8*)(&arm7_9->arm_bkpt), 0, 32, 0xdeeedeee);
788 buf_set_u32((u8*)(&arm7_9->thumb_bkpt), 0, 16, 0xdeee);
789
790 arm7_9->sw_bkpts_use_wp = 1;
791 arm7_9->sw_bkpts_enabled = 0;
792 arm7_9->dbgreq_adjust_pc = 3;
793 arm7_9->arch_info = arm9tdmi;
794 arm7_9->use_dbgrq = 1;
795
796 arm9tdmi->common_magic = ARM9TDMI_COMMON_MAGIC;
797 arm9tdmi->has_monitor_mode = 0;
798 arm9tdmi->has_single_step = 0;
799 arm9tdmi->arch_info = NULL;
800
801 if (variant)
802 {
803 if (strcmp(variant, "arm920t") == 0)
804 arm9tdmi->has_single_step = 1;
805 else if (strcmp(variant, "arm922t") == 0)
806 arm9tdmi->has_single_step = 1;
807 else if (strcmp(variant, "arm940t") == 0)
808 arm9tdmi->has_single_step = 1;
809 }
810
811 arm7_9_init_arch_info(target, arm7_9);
812
813 return ERROR_OK;
814 }
815
816 /* target arm9tdmi <endianess> <startup_mode> <chain_pos> <variant>*/
817 int arm9tdmi_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
818 {
819 int chain_pos;
820 char *variant = NULL;
821 arm9tdmi_common_t *arm9tdmi = malloc(sizeof(arm9tdmi_common_t));
822
823 if (argc < 4)
824 {
825 ERROR("'target arm9tdmi' requires at least one additional argument");
826 exit(-1);
827 }
828
829 chain_pos = strtoul(args[3], NULL, 0);
830
831 if (argc >= 5)
832 variant = strdup(args[4]);
833
834 arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant);
835
836 return ERROR_OK;
837 }
838
839 int arm9tdmi_register_commands(struct command_context_s *cmd_ctx)
840 {
841 int retval;
842
843 retval = arm7_9_register_commands(cmd_ctx);
844
845 return ERROR_OK;
846
847 }
848

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)