switch to jtag_add_callback() - USB performance fix
[openocd.git] / src / target / arm926ejs.c
1 /***************************************************************************
2 * Copyright (C) 2007 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 "arm926ejs.h"
25 #include "time_support.h"
26
27
28 #if 0
29 #define _DEBUG_INSTRUCTION_EXECUTION_
30 #endif
31
32 /* cli handling */
33 int arm926ejs_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
34 int arm926ejs_handle_cp15i_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
35 int arm926ejs_handle_virt2phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
36 int arm926ejs_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
37 int arm926ejs_handle_md_phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
38 int arm926ejs_handle_mw_phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
39
40 int arm926ejs_handle_read_cache_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
41 int arm926ejs_handle_read_mmu_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
42
43 /* forward declarations */
44 int arm926ejs_target_create(struct target_s *target, Jim_Interp *interp);
45 int arm926ejs_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
46 int arm926ejs_quit(void);
47 int arm926ejs_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
48
49 static int arm926ejs_virt2phys(struct target_s *target, u32 virtual, u32 *physical);
50 static int arm926ejs_mmu(struct target_s *target, int *enabled);
51
52 target_type_t arm926ejs_target =
53 {
54 .name = "arm926ejs",
55
56 .poll = arm7_9_poll,
57 .arch_state = arm926ejs_arch_state,
58
59 .target_request_data = arm7_9_target_request_data,
60
61 .halt = arm7_9_halt,
62 .resume = arm7_9_resume,
63 .step = arm7_9_step,
64
65 .assert_reset = arm7_9_assert_reset,
66 .deassert_reset = arm7_9_deassert_reset,
67 .soft_reset_halt = arm926ejs_soft_reset_halt,
68
69 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
70
71 .read_memory = arm7_9_read_memory,
72 .write_memory = arm926ejs_write_memory,
73 .bulk_write_memory = arm7_9_bulk_write_memory,
74 .checksum_memory = arm7_9_checksum_memory,
75 .blank_check_memory = arm7_9_blank_check_memory,
76
77 .run_algorithm = armv4_5_run_algorithm,
78
79 .add_breakpoint = arm7_9_add_breakpoint,
80 .remove_breakpoint = arm7_9_remove_breakpoint,
81 .add_watchpoint = arm7_9_add_watchpoint,
82 .remove_watchpoint = arm7_9_remove_watchpoint,
83
84 .register_commands = arm926ejs_register_commands,
85 .target_create = arm926ejs_target_create,
86 .init_target = arm926ejs_init_target,
87 .examine = arm9tdmi_examine,
88 .quit = arm926ejs_quit,
89 .virt2phys = arm926ejs_virt2phys,
90 .mmu = arm926ejs_mmu
91 };
92
93 int arm926ejs_catch_broken_irscan(u8 *captured, void *priv, scan_field_t *field)
94 {
95 /* FIX!!!! this code should be reenabled. For now it does not check
96 * the queue...*/
97 return 0;
98 #if 0
99 /* The ARM926EJ-S' instruction register is 4 bits wide */
100 u8 t = *captured & 0xf;
101 u8 t2 = *field->in_check_value & 0xf;
102 if (t == t2)
103 {
104 return ERROR_OK;
105 }
106 else if ((t == 0x0f) || (t == 0x00))
107 {
108 LOG_DEBUG("caught ARM926EJ-S invalid Capture-IR result after CP15 access");
109 return ERROR_OK;
110 }
111 return ERROR_JTAG_QUEUE_FAILED;;
112 #endif
113 }
114
115 #define ARM926EJS_CP15_ADDR(opcode_1, opcode_2, CRn, CRm) ((opcode_1 << 11) | (opcode_2 << 8) | (CRn << 4) | (CRm << 0))
116
117 int arm926ejs_cp15_read(target_t *target, u32 op1, u32 op2, u32 CRn, u32 CRm, u32 *value)
118 {
119 int retval = ERROR_OK;
120 armv4_5_common_t *armv4_5 = target->arch_info;
121 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
122 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
123 u32 address = ARM926EJS_CP15_ADDR(op1, op2, CRn, CRm);
124 scan_field_t fields[4];
125 u8 address_buf[2];
126 u8 nr_w_buf = 0;
127 u8 access = 1;
128
129 buf_set_u32(address_buf, 0, 14, address);
130
131 jtag_add_end_state(TAP_IDLE);
132 if ((retval = arm_jtag_scann(jtag_info, 0xf)) != ERROR_OK)
133 {
134 return retval;
135 }
136 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
137
138 fields[0].tap = jtag_info->tap;
139 fields[0].num_bits = 32;
140 fields[0].out_value = NULL;
141 fields[0].in_value = (u8 *)value;
142
143
144 fields[1].tap = jtag_info->tap;
145 fields[1].num_bits = 1;
146 fields[1].out_value = &access;
147 fields[1].in_value = &access;
148
149 fields[2].tap = jtag_info->tap;
150 fields[2].num_bits = 14;
151 fields[2].out_value = address_buf;
152 fields[2].in_value = NULL;
153
154 fields[3].tap = jtag_info->tap;
155 fields[3].num_bits = 1;
156 fields[3].out_value = &nr_w_buf;
157 fields[3].in_value = NULL;
158
159 jtag_add_dr_scan(4, fields, TAP_INVALID);
160
161 /*TODO: add timeout*/
162 do
163 {
164 /* rescan with NOP, to wait for the access to complete */
165 access = 0;
166 nr_w_buf = 0;
167 jtag_add_dr_scan(4, fields, TAP_INVALID);
168
169 jtag_add_callback(arm_le_to_h_u32, (u8 *)value);
170
171 if ((retval = jtag_execute_queue()) != ERROR_OK)
172 {
173 return retval;
174 }
175 } while (buf_get_u32(&access, 0, 1) != 1);
176
177 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
178 LOG_DEBUG("addr: 0x%x value: %8.8x", address, *value);
179 #endif
180
181 arm_jtag_set_instr(jtag_info, 0xc, &arm926ejs_catch_broken_irscan);
182
183 return ERROR_OK;
184 }
185
186 int arm926ejs_cp15_write(target_t *target, u32 op1, u32 op2, u32 CRn, u32 CRm, u32 value)
187 {
188 int retval = ERROR_OK;
189 armv4_5_common_t *armv4_5 = target->arch_info;
190 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
191 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
192 u32 address = ARM926EJS_CP15_ADDR(op1, op2, CRn, CRm);
193 scan_field_t fields[4];
194 u8 value_buf[4];
195 u8 address_buf[2];
196 u8 nr_w_buf = 1;
197 u8 access = 1;
198
199 buf_set_u32(address_buf, 0, 14, address);
200 buf_set_u32(value_buf, 0, 32, value);
201
202 jtag_add_end_state(TAP_IDLE);
203 if ((retval = arm_jtag_scann(jtag_info, 0xf)) != ERROR_OK)
204 {
205 return retval;
206 }
207 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
208
209 fields[0].tap = jtag_info->tap;
210 fields[0].num_bits = 32;
211 fields[0].out_value = value_buf;
212 fields[0].in_value = NULL;
213
214 fields[1].tap = jtag_info->tap;
215 fields[1].num_bits = 1;
216 fields[1].out_value = &access;
217 fields[1].in_value = &access;
218
219 fields[2].tap = jtag_info->tap;
220 fields[2].num_bits = 14;
221 fields[2].out_value = address_buf;
222 fields[2].in_value = NULL;
223
224 fields[3].tap = jtag_info->tap;
225 fields[3].num_bits = 1;
226 fields[3].out_value = &nr_w_buf;
227 fields[3].in_value = NULL;
228
229 jtag_add_dr_scan(4, fields, TAP_INVALID);
230 /*TODO: add timeout*/
231 do
232 {
233 /* rescan with NOP, to wait for the access to complete */
234 access = 0;
235 nr_w_buf = 0;
236 jtag_add_dr_scan(4, fields, TAP_INVALID);
237 if ((retval = jtag_execute_queue()) != ERROR_OK)
238 {
239 return retval;
240 }
241 } while (buf_get_u32(&access, 0, 1) != 1);
242
243 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
244 LOG_DEBUG("addr: 0x%x value: %8.8x", address, value);
245 #endif
246
247 arm_jtag_set_instr(jtag_info, 0xf, &arm926ejs_catch_broken_irscan);
248
249 return ERROR_OK;
250 }
251
252 int arm926ejs_examine_debug_reason(target_t *target)
253 {
254 armv4_5_common_t *armv4_5 = target->arch_info;
255 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
256 reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
257 int debug_reason;
258 int retval;
259
260 embeddedice_read_reg(dbg_stat);
261 if ((retval = jtag_execute_queue()) != ERROR_OK)
262 return retval;
263
264 debug_reason = buf_get_u32(dbg_stat->value, 6, 4);
265
266 switch (debug_reason)
267 {
268 case 1:
269 LOG_DEBUG("breakpoint from EICE unit 0");
270 target->debug_reason = DBG_REASON_BREAKPOINT;
271 break;
272 case 2:
273 LOG_DEBUG("breakpoint from EICE unit 1");
274 target->debug_reason = DBG_REASON_BREAKPOINT;
275 break;
276 case 3:
277 LOG_DEBUG("soft breakpoint (BKPT instruction)");
278 target->debug_reason = DBG_REASON_BREAKPOINT;
279 break;
280 case 4:
281 LOG_DEBUG("vector catch breakpoint");
282 target->debug_reason = DBG_REASON_BREAKPOINT;
283 break;
284 case 5:
285 LOG_DEBUG("external breakpoint");
286 target->debug_reason = DBG_REASON_BREAKPOINT;
287 break;
288 case 6:
289 LOG_DEBUG("watchpoint from EICE unit 0");
290 target->debug_reason = DBG_REASON_WATCHPOINT;
291 break;
292 case 7:
293 LOG_DEBUG("watchpoint from EICE unit 1");
294 target->debug_reason = DBG_REASON_WATCHPOINT;
295 break;
296 case 8:
297 LOG_DEBUG("external watchpoint");
298 target->debug_reason = DBG_REASON_WATCHPOINT;
299 break;
300 case 9:
301 LOG_DEBUG("internal debug request");
302 target->debug_reason = DBG_REASON_DBGRQ;
303 break;
304 case 10:
305 LOG_DEBUG("external debug request");
306 target->debug_reason = DBG_REASON_DBGRQ;
307 break;
308 case 11:
309 LOG_ERROR("BUG: debug re-entry from system speed access shouldn't be handled here");
310 break;
311 case 12:
312 /* FIX!!!! here be dragons!!! We need to fail here so
313 * the target will interpreted as halted but we won't
314 * try to talk to it right now... a resume + halt seems
315 * to sync things up again. Please send an email to
316 * openocd development mailing list if you have hardware
317 * to donate to look into this problem....
318 */
319 LOG_ERROR("mystery debug reason MOE=0xc. Try issuing a resume + halt.");
320 target->debug_reason = DBG_REASON_DBGRQ;
321 retval = ERROR_TARGET_FAILURE;
322 break;
323 default:
324 LOG_ERROR("BUG: unknown debug reason: 0x%x", debug_reason);
325 target->debug_reason = DBG_REASON_DBGRQ;
326 /* if we fail here, we won't talk to the target and it will
327 * be reported to be in the halted state */
328 retval = ERROR_TARGET_FAILURE;
329 break;
330 }
331
332 return retval;
333 }
334
335 u32 arm926ejs_get_ttb(target_t *target)
336 {
337 armv4_5_common_t *armv4_5 = target->arch_info;
338 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
339 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
340 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
341 int retval;
342 u32 ttb = 0x0;
343
344 if ((retval = arm926ejs->read_cp15(target, 0, 0, 2, 0, &ttb)) != ERROR_OK)
345 return retval;
346
347 return ttb;
348 }
349
350 void arm926ejs_disable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
351 {
352 armv4_5_common_t *armv4_5 = target->arch_info;
353 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
354 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
355 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
356 u32 cp15_control;
357
358 /* read cp15 control register */
359 arm926ejs->read_cp15(target, 0, 0, 1, 0, &cp15_control);
360 jtag_execute_queue();
361
362 if (mmu)
363 {
364 /* invalidate TLB */
365 arm926ejs->write_cp15(target, 0, 0, 8, 7, 0x0);
366
367 cp15_control &= ~0x1U;
368 }
369
370 if (d_u_cache)
371 {
372 u32 debug_override;
373 /* read-modify-write CP15 debug override register
374 * to enable "test and clean all" */
375 arm926ejs->read_cp15(target, 0, 0, 15, 0, &debug_override);
376 debug_override |= 0x80000;
377 arm926ejs->write_cp15(target, 0, 0, 15, 0, debug_override);
378
379 /* clean and invalidate DCache */
380 arm926ejs->write_cp15(target, 0, 0, 7, 5, 0x0);
381
382 /* write CP15 debug override register
383 * to disable "test and clean all" */
384 debug_override &= ~0x80000;
385 arm926ejs->write_cp15(target, 0, 0, 15, 0, debug_override);
386
387 cp15_control &= ~0x4U;
388 }
389
390 if (i_cache)
391 {
392 /* invalidate ICache */
393 arm926ejs->write_cp15(target, 0, 0, 7, 5, 0x0);
394
395 cp15_control &= ~0x1000U;
396 }
397
398 arm926ejs->write_cp15(target, 0, 0, 1, 0, cp15_control);
399 }
400
401 void arm926ejs_enable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
402 {
403 armv4_5_common_t *armv4_5 = target->arch_info;
404 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
405 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
406 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
407 u32 cp15_control;
408
409 /* read cp15 control register */
410 arm926ejs->read_cp15(target, 0, 0, 1, 0, &cp15_control);
411 jtag_execute_queue();
412
413 if (mmu)
414 cp15_control |= 0x1U;
415
416 if (d_u_cache)
417 cp15_control |= 0x4U;
418
419 if (i_cache)
420 cp15_control |= 0x1000U;
421
422 arm926ejs->write_cp15(target, 0, 0, 1, 0, cp15_control);
423 }
424
425 void arm926ejs_post_debug_entry(target_t *target)
426 {
427 armv4_5_common_t *armv4_5 = target->arch_info;
428 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
429 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
430 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
431
432 /* examine cp15 control reg */
433 arm926ejs->read_cp15(target, 0, 0, 1, 0, &arm926ejs->cp15_control_reg);
434 jtag_execute_queue();
435 LOG_DEBUG("cp15_control_reg: %8.8x", arm926ejs->cp15_control_reg);
436
437 if (arm926ejs->armv4_5_mmu.armv4_5_cache.ctype == -1)
438 {
439 u32 cache_type_reg;
440 /* identify caches */
441 arm926ejs->read_cp15(target, 0, 1, 0, 0, &cache_type_reg);
442 jtag_execute_queue();
443 armv4_5_identify_cache(cache_type_reg, &arm926ejs->armv4_5_mmu.armv4_5_cache);
444 }
445
446 arm926ejs->armv4_5_mmu.mmu_enabled = (arm926ejs->cp15_control_reg & 0x1U) ? 1 : 0;
447 arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = (arm926ejs->cp15_control_reg & 0x4U) ? 1 : 0;
448 arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled = (arm926ejs->cp15_control_reg & 0x1000U) ? 1 : 0;
449
450 /* save i/d fault status and address register */
451 arm926ejs->read_cp15(target, 0, 0, 5, 0, &arm926ejs->d_fsr);
452 arm926ejs->read_cp15(target, 0, 1, 5, 0, &arm926ejs->i_fsr);
453 arm926ejs->read_cp15(target, 0, 0, 6, 0, &arm926ejs->d_far);
454
455 LOG_DEBUG("D FSR: 0x%8.8x, D FAR: 0x%8.8x, I FSR: 0x%8.8x",
456 arm926ejs->d_fsr, arm926ejs->d_far, arm926ejs->i_fsr);
457
458 u32 cache_dbg_ctrl;
459
460 /* read-modify-write CP15 cache debug control register
461 * to disable I/D-cache linefills and force WT */
462 arm926ejs->read_cp15(target, 7, 0, 15, 0, &cache_dbg_ctrl);
463 cache_dbg_ctrl |= 0x7;
464 arm926ejs->write_cp15(target, 7, 0, 15, 0, cache_dbg_ctrl);
465 }
466
467 void arm926ejs_pre_restore_context(target_t *target)
468 {
469 armv4_5_common_t *armv4_5 = target->arch_info;
470 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
471 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
472 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
473
474 /* restore i/d fault status and address register */
475 arm926ejs->write_cp15(target, 0, 0, 5, 0, arm926ejs->d_fsr);
476 arm926ejs->write_cp15(target, 0, 1, 5, 0, arm926ejs->i_fsr);
477 arm926ejs->write_cp15(target, 0, 0, 6, 0, arm926ejs->d_far);
478
479 u32 cache_dbg_ctrl;
480
481 /* read-modify-write CP15 cache debug control register
482 * to reenable I/D-cache linefills and disable WT */
483 arm926ejs->read_cp15(target, 7, 0, 15, 0, &cache_dbg_ctrl);
484 cache_dbg_ctrl &= ~0x7;
485 arm926ejs->write_cp15(target, 7, 0, 15, 0, cache_dbg_ctrl);
486 }
487
488 int arm926ejs_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, arm7_9_common_t **arm7_9_p, arm9tdmi_common_t **arm9tdmi_p, arm926ejs_common_t **arm926ejs_p)
489 {
490 armv4_5_common_t *armv4_5 = target->arch_info;
491 arm7_9_common_t *arm7_9;
492 arm9tdmi_common_t *arm9tdmi;
493 arm926ejs_common_t *arm926ejs;
494
495 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
496 {
497 return -1;
498 }
499
500 arm7_9 = armv4_5->arch_info;
501 if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
502 {
503 return -1;
504 }
505
506 arm9tdmi = arm7_9->arch_info;
507 if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
508 {
509 return -1;
510 }
511
512 arm926ejs = arm9tdmi->arch_info;
513 if (arm926ejs->common_magic != ARM926EJS_COMMON_MAGIC)
514 {
515 return -1;
516 }
517
518 *armv4_5_p = armv4_5;
519 *arm7_9_p = arm7_9;
520 *arm9tdmi_p = arm9tdmi;
521 *arm926ejs_p = arm926ejs;
522
523 return ERROR_OK;
524 }
525
526 int arm926ejs_arch_state(struct target_s *target)
527 {
528 armv4_5_common_t *armv4_5 = target->arch_info;
529 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
530 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
531 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
532
533 char *state[] =
534 {
535 "disabled", "enabled"
536 };
537
538 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
539 {
540 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
541 exit(-1);
542 }
543
544 LOG_USER(
545 "target halted in %s state due to %s, current mode: %s\n"
546 "cpsr: 0x%8.8x pc: 0x%8.8x\n"
547 "MMU: %s, D-Cache: %s, I-Cache: %s",
548 armv4_5_state_strings[armv4_5->core_state],
549 Jim_Nvp_value2name_simple( nvp_target_debug_reason,target->debug_reason)->name,
550 armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
551 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
552 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
553 state[arm926ejs->armv4_5_mmu.mmu_enabled],
554 state[arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
555 state[arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);
556
557 return ERROR_OK;
558 }
559
560 int arm926ejs_soft_reset_halt(struct target_s *target)
561 {
562 int retval = ERROR_OK;
563 armv4_5_common_t *armv4_5 = target->arch_info;
564 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
565 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
566 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
567 reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
568
569 if ((retval = target_halt(target)) != ERROR_OK)
570 {
571 return retval;
572 }
573
574 long long then=timeval_ms();
575 int timeout;
576 while (!(timeout=((timeval_ms()-then)>1000)))
577 {
578 if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0)
579 {
580 embeddedice_read_reg(dbg_stat);
581 if ((retval = jtag_execute_queue()) != ERROR_OK)
582 {
583 return retval;
584 }
585 } else
586 {
587 break;
588 }
589 if (debug_level>=1)
590 {
591 /* do not eat all CPU, time out after 1 se*/
592 alive_sleep(100);
593 } else
594 {
595 keep_alive();
596 }
597 }
598 if (timeout)
599 {
600 LOG_ERROR("Failed to halt CPU after 1 sec");
601 return ERROR_TARGET_TIMEOUT;
602 }
603
604 target->state = TARGET_HALTED;
605
606 /* SVC, ARM state, IRQ and FIQ disabled */
607 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8, 0xd3);
608 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
609 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
610
611 /* start fetching from 0x0 */
612 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
613 armv4_5->core_cache->reg_list[15].dirty = 1;
614 armv4_5->core_cache->reg_list[15].valid = 1;
615
616 armv4_5->core_mode = ARMV4_5_MODE_SVC;
617 armv4_5->core_state = ARMV4_5_STATE_ARM;
618
619 arm926ejs_disable_mmu_caches(target, 1, 1, 1);
620 arm926ejs->armv4_5_mmu.mmu_enabled = 0;
621 arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
622 arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
623
624 return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
625 }
626
627 int arm926ejs_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
628 {
629 int retval;
630 armv4_5_common_t *armv4_5 = target->arch_info;
631 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
632 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
633 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
634
635 if ((retval = arm7_9_write_memory(target, address, size, count, buffer)) != ERROR_OK)
636 return retval;
637
638 /* If ICache is enabled, we have to invalidate affected ICache lines
639 * the DCache is forced to write-through, so we don't have to clean it here
640 */
641 if (arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
642 {
643 if (count <= 1)
644 {
645 /* invalidate ICache single entry with MVA */
646 arm926ejs->write_cp15(target, 0, 1, 7, 5, address);
647 }
648 else
649 {
650 /* invalidate ICache */
651 arm926ejs->write_cp15(target, 0, 0, 7, 5, address);
652 }
653 }
654
655 return retval;
656 }
657
658 int arm926ejs_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
659 {
660 arm9tdmi_init_target(cmd_ctx, target);
661
662 return ERROR_OK;
663 }
664
665 int arm926ejs_quit(void)
666 {
667 return ERROR_OK;
668 }
669
670 int arm926ejs_init_arch_info(target_t *target, arm926ejs_common_t *arm926ejs, jtag_tap_t *tap)
671 {
672 arm9tdmi_common_t *arm9tdmi = &arm926ejs->arm9tdmi_common;
673 arm7_9_common_t *arm7_9 = &arm9tdmi->arm7_9_common;
674
675 /* initialize arm9tdmi specific info (including arm7_9 and armv4_5)
676 */
677 arm9tdmi_init_arch_info(target, arm9tdmi, tap);
678
679 arm9tdmi->arch_info = arm926ejs;
680 arm926ejs->common_magic = ARM926EJS_COMMON_MAGIC;
681
682 arm7_9->post_debug_entry = arm926ejs_post_debug_entry;
683 arm7_9->pre_restore_context = arm926ejs_pre_restore_context;
684
685 arm926ejs->read_cp15 = arm926ejs_cp15_read;
686 arm926ejs->write_cp15 = arm926ejs_cp15_write;
687 arm926ejs->armv4_5_mmu.armv4_5_cache.ctype = -1;
688 arm926ejs->armv4_5_mmu.get_ttb = arm926ejs_get_ttb;
689 arm926ejs->armv4_5_mmu.read_memory = arm7_9_read_memory;
690 arm926ejs->armv4_5_mmu.write_memory = arm7_9_write_memory;
691 arm926ejs->armv4_5_mmu.disable_mmu_caches = arm926ejs_disable_mmu_caches;
692 arm926ejs->armv4_5_mmu.enable_mmu_caches = arm926ejs_enable_mmu_caches;
693 arm926ejs->armv4_5_mmu.has_tiny_pages = 1;
694 arm926ejs->armv4_5_mmu.mmu_enabled = 0;
695
696 arm7_9->examine_debug_reason = arm926ejs_examine_debug_reason;
697
698 /* The ARM926EJ-S implements the ARMv5TE architecture which
699 * has the BKPT instruction, so we don't have to use a watchpoint comparator
700 */
701 arm7_9->arm_bkpt = ARMV5_BKPT(0x0);
702 arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
703
704 return ERROR_OK;
705 }
706
707 int arm926ejs_target_create(struct target_s *target, Jim_Interp *interp)
708 {
709 arm926ejs_common_t *arm926ejs = calloc(1,sizeof(arm926ejs_common_t));
710
711 arm926ejs_init_arch_info(target, arm926ejs, target->tap);
712
713 return ERROR_OK;
714 }
715
716 int arm926ejs_register_commands(struct command_context_s *cmd_ctx)
717 {
718 int retval;
719 command_t *arm926ejs_cmd;
720
721
722 retval = arm9tdmi_register_commands(cmd_ctx);
723
724 arm926ejs_cmd = register_command(cmd_ctx, NULL, "arm926ejs", NULL, COMMAND_ANY, "arm926ejs specific commands");
725
726 register_command(cmd_ctx, arm926ejs_cmd, "cp15", arm926ejs_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register <opcode_1> <opcode_2> <CRn> <CRm> [value]");
727
728 register_command(cmd_ctx, arm926ejs_cmd, "cache_info", arm926ejs_handle_cache_info_command, COMMAND_EXEC, "display information about target caches");
729 register_command(cmd_ctx, arm926ejs_cmd, "virt2phys", arm926ejs_handle_virt2phys_command, COMMAND_EXEC, "translate va to pa <va>");
730
731 register_command(cmd_ctx, arm926ejs_cmd, "mdw_phys", arm926ejs_handle_md_phys_command, COMMAND_EXEC, "display memory words <physical addr> [count]");
732 register_command(cmd_ctx, arm926ejs_cmd, "mdh_phys", arm926ejs_handle_md_phys_command, COMMAND_EXEC, "display memory half-words <physical addr> [count]");
733 register_command(cmd_ctx, arm926ejs_cmd, "mdb_phys", arm926ejs_handle_md_phys_command, COMMAND_EXEC, "display memory bytes <physical addr> [count]");
734
735 register_command(cmd_ctx, arm926ejs_cmd, "mww_phys", arm926ejs_handle_mw_phys_command, COMMAND_EXEC, "write memory word <physical addr> <value>");
736 register_command(cmd_ctx, arm926ejs_cmd, "mwh_phys", arm926ejs_handle_mw_phys_command, COMMAND_EXEC, "write memory half-word <physical addr> <value>");
737 register_command(cmd_ctx, arm926ejs_cmd, "mwb_phys", arm926ejs_handle_mw_phys_command, COMMAND_EXEC, "write memory byte <physical addr> <value>");
738
739 return retval;
740 }
741
742 int arm926ejs_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
743 {
744 int retval;
745 target_t *target = get_current_target(cmd_ctx);
746 armv4_5_common_t *armv4_5;
747 arm7_9_common_t *arm7_9;
748 arm9tdmi_common_t *arm9tdmi;
749 arm926ejs_common_t *arm926ejs;
750 int opcode_1;
751 int opcode_2;
752 int CRn;
753 int CRm;
754
755 if ((argc < 4) || (argc > 5))
756 {
757 command_print(cmd_ctx, "usage: arm926ejs cp15 <opcode_1> <opcode_2> <CRn> <CRm> [value]");
758 return ERROR_OK;
759 }
760
761 opcode_1 = strtoul(args[0], NULL, 0);
762 opcode_2 = strtoul(args[1], NULL, 0);
763 CRn = strtoul(args[2], NULL, 0);
764 CRm = strtoul(args[3], NULL, 0);
765
766 if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
767 {
768 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
769 return ERROR_OK;
770 }
771
772 if (target->state != TARGET_HALTED)
773 {
774 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
775 return ERROR_OK;
776 }
777
778 if (argc == 4)
779 {
780 u32 value;
781 if ((retval = arm926ejs->read_cp15(target, opcode_1, opcode_2, CRn, CRm, &value)) != ERROR_OK)
782 {
783 command_print(cmd_ctx, "couldn't access register");
784 return ERROR_OK;
785 }
786 if ((retval = jtag_execute_queue()) != ERROR_OK)
787 {
788 return retval;
789 }
790
791 command_print(cmd_ctx, "%i %i %i %i: %8.8x", opcode_1, opcode_2, CRn, CRm, value);
792 }
793 else
794 {
795 u32 value = strtoul(args[4], NULL, 0);
796 if ((retval = arm926ejs->write_cp15(target, opcode_1, opcode_2, CRn, CRm, value)) != ERROR_OK)
797 {
798 command_print(cmd_ctx, "couldn't access register");
799 return ERROR_OK;
800 }
801 command_print(cmd_ctx, "%i %i %i %i: %8.8x", opcode_1, opcode_2, CRn, CRm, value);
802 }
803
804 return ERROR_OK;
805 }
806
807 int arm926ejs_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
808 {
809 target_t *target = get_current_target(cmd_ctx);
810 armv4_5_common_t *armv4_5;
811 arm7_9_common_t *arm7_9;
812 arm9tdmi_common_t *arm9tdmi;
813 arm926ejs_common_t *arm926ejs;
814
815 if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
816 {
817 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
818 return ERROR_OK;
819 }
820
821 return armv4_5_handle_cache_info_command(cmd_ctx, &arm926ejs->armv4_5_mmu.armv4_5_cache);
822 }
823
824 int arm926ejs_handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
825 {
826 target_t *target = get_current_target(cmd_ctx);
827 armv4_5_common_t *armv4_5;
828 arm7_9_common_t *arm7_9;
829 arm9tdmi_common_t *arm9tdmi;
830 arm926ejs_common_t *arm926ejs;
831 arm_jtag_t *jtag_info;
832
833 if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
834 {
835 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
836 return ERROR_OK;
837 }
838
839 jtag_info = &arm7_9->jtag_info;
840
841 if (target->state != TARGET_HALTED)
842 {
843 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
844 return ERROR_OK;
845 }
846
847 return armv4_5_mmu_handle_virt2phys_command(cmd_ctx, cmd, args, argc, target, &arm926ejs->armv4_5_mmu);
848 }
849
850 int arm926ejs_handle_md_phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
851 {
852 target_t *target = get_current_target(cmd_ctx);
853 armv4_5_common_t *armv4_5;
854 arm7_9_common_t *arm7_9;
855 arm9tdmi_common_t *arm9tdmi;
856 arm926ejs_common_t *arm926ejs;
857 arm_jtag_t *jtag_info;
858
859 if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
860 {
861 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
862 return ERROR_OK;
863 }
864
865 jtag_info = &arm7_9->jtag_info;
866
867 if (target->state != TARGET_HALTED)
868 {
869 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
870 return ERROR_OK;
871 }
872
873 return armv4_5_mmu_handle_md_phys_command(cmd_ctx, cmd, args, argc, target, &arm926ejs->armv4_5_mmu);
874 }
875
876 int arm926ejs_handle_mw_phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
877 {
878 target_t *target = get_current_target(cmd_ctx);
879 armv4_5_common_t *armv4_5;
880 arm7_9_common_t *arm7_9;
881 arm9tdmi_common_t *arm9tdmi;
882 arm926ejs_common_t *arm926ejs;
883 arm_jtag_t *jtag_info;
884
885 if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
886 {
887 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
888 return ERROR_OK;
889 }
890
891 jtag_info = &arm7_9->jtag_info;
892
893 if (target->state != TARGET_HALTED)
894 {
895 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
896 return ERROR_OK;
897 }
898
899 return armv4_5_mmu_handle_mw_phys_command(cmd_ctx, cmd, args, argc, target, &arm926ejs->armv4_5_mmu);
900 }
901
902 static int arm926ejs_virt2phys(struct target_s *target, u32 virtual, u32 *physical)
903 {
904 int retval;
905 int type;
906 u32 cb;
907 int domain;
908 u32 ap;
909
910 armv4_5_common_t *armv4_5;
911 arm7_9_common_t *arm7_9;
912 arm9tdmi_common_t *arm9tdmi;
913 arm926ejs_common_t *arm926ejs;
914 retval= arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs);
915 if (retval != ERROR_OK)
916 {
917 return retval;
918 }
919 u32 ret = armv4_5_mmu_translate_va(target, &arm926ejs->armv4_5_mmu, virtual, &type, &cb, &domain, &ap);
920 if (type == -1)
921 {
922 return ret;
923 }
924 *physical = ret;
925 return ERROR_OK;
926 }
927
928 static int arm926ejs_mmu(struct target_s *target, int *enabled)
929 {
930 armv4_5_common_t *armv4_5 = target->arch_info;
931 arm926ejs_common_t *arm926ejs = armv4_5->arch_info;
932
933 if (target->state != TARGET_HALTED)
934 {
935 LOG_ERROR("Target not halted");
936 return ERROR_TARGET_INVALID;
937 }
938 *enabled = arm926ejs->armv4_5_mmu.mmu_enabled;
939 return ERROR_OK;
940 }

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)