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

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)