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

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)