4a711439472a2b249de07fa925f004ca6ead799c
[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_WARNING("WARNING: mystery debug reason MOE = 0xc. Try issuing a resume + halt.");
364 target->debug_reason = DBG_REASON_DBGRQ;
365 break;
366 default:
367 LOG_WARNING("WARNING: unknown debug reason: 0x%x", debug_reason);
368 /* Oh agony! should we interpret this as a halt request or
369 * that the target stopped on it's own accord?
370 */
371 target->debug_reason = DBG_REASON_DBGRQ;
372 /* if we fail here, we won't talk to the target and it will
373 * be reported to be in the halted state */
374 break;
375 }
376
377 return ERROR_OK;
378 }
379
380 uint32_t arm926ejs_get_ttb(target_t *target)
381 {
382 armv4_5_common_t *armv4_5 = target->arch_info;
383 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
384 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
385 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
386 int retval;
387 uint32_t ttb = 0x0;
388
389 if ((retval = arm926ejs->read_cp15(target, 0, 0, 2, 0, &ttb)) != ERROR_OK)
390 return retval;
391
392 return ttb;
393 }
394
395 void arm926ejs_disable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
396 {
397 armv4_5_common_t *armv4_5 = target->arch_info;
398 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
399 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
400 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
401 uint32_t cp15_control;
402
403 /* read cp15 control register */
404 arm926ejs->read_cp15(target, 0, 0, 1, 0, &cp15_control);
405 jtag_execute_queue();
406
407 if (mmu)
408 {
409 /* invalidate TLB */
410 arm926ejs->write_cp15(target, 0, 0, 8, 7, 0x0);
411
412 cp15_control &= ~0x1U;
413 }
414
415 if (d_u_cache)
416 {
417 uint32_t debug_override;
418 /* read-modify-write CP15 debug override register
419 * to enable "test and clean all" */
420 arm926ejs->read_cp15(target, 0, 0, 15, 0, &debug_override);
421 debug_override |= 0x80000;
422 arm926ejs->write_cp15(target, 0, 0, 15, 0, debug_override);
423
424 /* clean and invalidate DCache */
425 arm926ejs->write_cp15(target, 0, 0, 7, 5, 0x0);
426
427 /* write CP15 debug override register
428 * to disable "test and clean all" */
429 debug_override &= ~0x80000;
430 arm926ejs->write_cp15(target, 0, 0, 15, 0, debug_override);
431
432 cp15_control &= ~0x4U;
433 }
434
435 if (i_cache)
436 {
437 /* invalidate ICache */
438 arm926ejs->write_cp15(target, 0, 0, 7, 5, 0x0);
439
440 cp15_control &= ~0x1000U;
441 }
442
443 arm926ejs->write_cp15(target, 0, 0, 1, 0, cp15_control);
444 }
445
446 void arm926ejs_enable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
447 {
448 armv4_5_common_t *armv4_5 = target->arch_info;
449 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
450 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
451 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
452 uint32_t cp15_control;
453
454 /* read cp15 control register */
455 arm926ejs->read_cp15(target, 0, 0, 1, 0, &cp15_control);
456 jtag_execute_queue();
457
458 if (mmu)
459 cp15_control |= 0x1U;
460
461 if (d_u_cache)
462 cp15_control |= 0x4U;
463
464 if (i_cache)
465 cp15_control |= 0x1000U;
466
467 arm926ejs->write_cp15(target, 0, 0, 1, 0, cp15_control);
468 }
469
470 void arm926ejs_post_debug_entry(target_t *target)
471 {
472 armv4_5_common_t *armv4_5 = target->arch_info;
473 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
474 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
475 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
476
477 /* examine cp15 control reg */
478 arm926ejs->read_cp15(target, 0, 0, 1, 0, &arm926ejs->cp15_control_reg);
479 jtag_execute_queue();
480 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32 "", arm926ejs->cp15_control_reg);
481
482 if (arm926ejs->armv4_5_mmu.armv4_5_cache.ctype == -1)
483 {
484 uint32_t cache_type_reg;
485 /* identify caches */
486 arm926ejs->read_cp15(target, 0, 1, 0, 0, &cache_type_reg);
487 jtag_execute_queue();
488 armv4_5_identify_cache(cache_type_reg, &arm926ejs->armv4_5_mmu.armv4_5_cache);
489 }
490
491 arm926ejs->armv4_5_mmu.mmu_enabled = (arm926ejs->cp15_control_reg & 0x1U) ? 1 : 0;
492 arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = (arm926ejs->cp15_control_reg & 0x4U) ? 1 : 0;
493 arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled = (arm926ejs->cp15_control_reg & 0x1000U) ? 1 : 0;
494
495 /* save i/d fault status and address register */
496 arm926ejs->read_cp15(target, 0, 0, 5, 0, &arm926ejs->d_fsr);
497 arm926ejs->read_cp15(target, 0, 1, 5, 0, &arm926ejs->i_fsr);
498 arm926ejs->read_cp15(target, 0, 0, 6, 0, &arm926ejs->d_far);
499
500 LOG_DEBUG("D FSR: 0x%8.8" PRIx32 ", D FAR: 0x%8.8" PRIx32 ", I FSR: 0x%8.8" PRIx32 "",
501 arm926ejs->d_fsr, arm926ejs->d_far, arm926ejs->i_fsr);
502
503 uint32_t cache_dbg_ctrl;
504
505 /* read-modify-write CP15 cache debug control register
506 * to disable I/D-cache linefills and force WT */
507 arm926ejs->read_cp15(target, 7, 0, 15, 0, &cache_dbg_ctrl);
508 cache_dbg_ctrl |= 0x7;
509 arm926ejs->write_cp15(target, 7, 0, 15, 0, cache_dbg_ctrl);
510 }
511
512 void arm926ejs_pre_restore_context(target_t *target)
513 {
514 armv4_5_common_t *armv4_5 = target->arch_info;
515 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
516 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
517 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
518
519 /* restore i/d fault status and address register */
520 arm926ejs->write_cp15(target, 0, 0, 5, 0, arm926ejs->d_fsr);
521 arm926ejs->write_cp15(target, 0, 1, 5, 0, arm926ejs->i_fsr);
522 arm926ejs->write_cp15(target, 0, 0, 6, 0, arm926ejs->d_far);
523
524 uint32_t cache_dbg_ctrl;
525
526 /* read-modify-write CP15 cache debug control register
527 * to reenable I/D-cache linefills and disable WT */
528 arm926ejs->read_cp15(target, 7, 0, 15, 0, &cache_dbg_ctrl);
529 cache_dbg_ctrl &= ~0x7;
530 arm926ejs->write_cp15(target, 7, 0, 15, 0, cache_dbg_ctrl);
531 }
532
533 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)
534 {
535 armv4_5_common_t *armv4_5 = target->arch_info;
536 arm7_9_common_t *arm7_9;
537 arm9tdmi_common_t *arm9tdmi;
538 arm926ejs_common_t *arm926ejs;
539
540 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
541 {
542 return -1;
543 }
544
545 arm7_9 = armv4_5->arch_info;
546 if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
547 {
548 return -1;
549 }
550
551 arm9tdmi = arm7_9->arch_info;
552 if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
553 {
554 return -1;
555 }
556
557 arm926ejs = arm9tdmi->arch_info;
558 if (arm926ejs->common_magic != ARM926EJS_COMMON_MAGIC)
559 {
560 return -1;
561 }
562
563 *armv4_5_p = armv4_5;
564 *arm7_9_p = arm7_9;
565 *arm9tdmi_p = arm9tdmi;
566 *arm926ejs_p = arm926ejs;
567
568 return ERROR_OK;
569 }
570
571 int arm926ejs_arch_state(struct target_s *target)
572 {
573 armv4_5_common_t *armv4_5 = target->arch_info;
574 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
575 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
576 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
577
578 char *state[] =
579 {
580 "disabled", "enabled"
581 };
582
583 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
584 {
585 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
586 exit(-1);
587 }
588
589 LOG_USER(
590 "target halted in %s state due to %s, current mode: %s\n"
591 "cpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "\n"
592 "MMU: %s, D-Cache: %s, I-Cache: %s",
593 armv4_5_state_strings[armv4_5->core_state],
594 Jim_Nvp_value2name_simple(nvp_target_debug_reason,target->debug_reason)->name,
595 armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
596 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
597 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
598 state[arm926ejs->armv4_5_mmu.mmu_enabled],
599 state[arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
600 state[arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);
601
602 return ERROR_OK;
603 }
604
605 int arm926ejs_soft_reset_halt(struct target_s *target)
606 {
607 int retval = ERROR_OK;
608 armv4_5_common_t *armv4_5 = target->arch_info;
609 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
610 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
611 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
612 reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
613
614 if ((retval = target_halt(target)) != ERROR_OK)
615 {
616 return retval;
617 }
618
619 long long then = timeval_ms();
620 int timeout;
621 while (!(timeout = ((timeval_ms()-then) > 1000)))
622 {
623 if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0)
624 {
625 embeddedice_read_reg(dbg_stat);
626 if ((retval = jtag_execute_queue()) != ERROR_OK)
627 {
628 return retval;
629 }
630 } else
631 {
632 break;
633 }
634 if (debug_level >= 1)
635 {
636 /* do not eat all CPU, time out after 1 se*/
637 alive_sleep(100);
638 } else
639 {
640 keep_alive();
641 }
642 }
643 if (timeout)
644 {
645 LOG_ERROR("Failed to halt CPU after 1 sec");
646 return ERROR_TARGET_TIMEOUT;
647 }
648
649 target->state = TARGET_HALTED;
650
651 /* SVC, ARM state, IRQ and FIQ disabled */
652 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8, 0xd3);
653 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
654 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
655
656 /* start fetching from 0x0 */
657 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
658 armv4_5->core_cache->reg_list[15].dirty = 1;
659 armv4_5->core_cache->reg_list[15].valid = 1;
660
661 armv4_5->core_mode = ARMV4_5_MODE_SVC;
662 armv4_5->core_state = ARMV4_5_STATE_ARM;
663
664 arm926ejs_disable_mmu_caches(target, 1, 1, 1);
665 arm926ejs->armv4_5_mmu.mmu_enabled = 0;
666 arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
667 arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
668
669 return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
670 }
671
672 int arm926ejs_write_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
673 {
674 int retval;
675 armv4_5_common_t *armv4_5 = target->arch_info;
676 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
677 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
678 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
679
680 if ((retval = arm7_9_write_memory(target, address, size, count, buffer)) != ERROR_OK)
681 return retval;
682
683 /* If ICache is enabled, we have to invalidate affected ICache lines
684 * the DCache is forced to write-through, so we don't have to clean it here
685 */
686 if (arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
687 {
688 if (count <= 1)
689 {
690 /* invalidate ICache single entry with MVA */
691 arm926ejs->write_cp15(target, 0, 1, 7, 5, address);
692 }
693 else
694 {
695 /* invalidate ICache */
696 arm926ejs->write_cp15(target, 0, 0, 7, 5, address);
697 }
698 }
699
700 return retval;
701 }
702
703 int arm926ejs_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
704 {
705 arm9tdmi_init_target(cmd_ctx, target);
706
707 return ERROR_OK;
708 }
709
710 int arm926ejs_quit(void)
711 {
712 return ERROR_OK;
713 }
714
715 int arm926ejs_init_arch_info(target_t *target, arm926ejs_common_t *arm926ejs, jtag_tap_t *tap)
716 {
717 arm9tdmi_common_t *arm9tdmi = &arm926ejs->arm9tdmi_common;
718 arm7_9_common_t *arm7_9 = &arm9tdmi->arm7_9_common;
719
720 /* initialize arm9tdmi specific info (including arm7_9 and armv4_5)
721 */
722 arm9tdmi_init_arch_info(target, arm9tdmi, tap);
723
724 arm9tdmi->arch_info = arm926ejs;
725 arm926ejs->common_magic = ARM926EJS_COMMON_MAGIC;
726
727 arm7_9->post_debug_entry = arm926ejs_post_debug_entry;
728 arm7_9->pre_restore_context = arm926ejs_pre_restore_context;
729
730 arm926ejs->read_cp15 = arm926ejs_cp15_read;
731 arm926ejs->write_cp15 = arm926ejs_cp15_write;
732 arm926ejs->armv4_5_mmu.armv4_5_cache.ctype = -1;
733 arm926ejs->armv4_5_mmu.get_ttb = arm926ejs_get_ttb;
734 arm926ejs->armv4_5_mmu.read_memory = arm7_9_read_memory;
735 arm926ejs->armv4_5_mmu.write_memory = arm7_9_write_memory;
736 arm926ejs->armv4_5_mmu.disable_mmu_caches = arm926ejs_disable_mmu_caches;
737 arm926ejs->armv4_5_mmu.enable_mmu_caches = arm926ejs_enable_mmu_caches;
738 arm926ejs->armv4_5_mmu.has_tiny_pages = 1;
739 arm926ejs->armv4_5_mmu.mmu_enabled = 0;
740
741 arm7_9->examine_debug_reason = arm926ejs_examine_debug_reason;
742
743 /* The ARM926EJ-S implements the ARMv5TE architecture which
744 * has the BKPT instruction, so we don't have to use a watchpoint comparator
745 */
746 arm7_9->arm_bkpt = ARMV5_BKPT(0x0);
747 arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
748
749 return ERROR_OK;
750 }
751
752 int arm926ejs_target_create(struct target_s *target, Jim_Interp *interp)
753 {
754 arm926ejs_common_t *arm926ejs = calloc(1,sizeof(arm926ejs_common_t));
755
756 arm926ejs_init_arch_info(target, arm926ejs, target->tap);
757
758 return ERROR_OK;
759 }
760
761 int arm926ejs_register_commands(struct command_context_s *cmd_ctx)
762 {
763 int retval;
764 command_t *arm926ejs_cmd;
765
766
767 retval = arm9tdmi_register_commands(cmd_ctx);
768
769 arm926ejs_cmd = register_command(cmd_ctx, NULL, "arm926ejs", NULL, COMMAND_ANY, "arm926ejs specific commands");
770
771 register_command(cmd_ctx, arm926ejs_cmd, "cp15", arm926ejs_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register <opcode_1> <opcode_2> <CRn> <CRm> [value]");
772
773 register_command(cmd_ctx, arm926ejs_cmd, "cache_info", arm926ejs_handle_cache_info_command, COMMAND_EXEC, "display information about target caches");
774 register_command(cmd_ctx, arm926ejs_cmd, "virt2phys", arm926ejs_handle_virt2phys_command, COMMAND_EXEC, "translate va to pa <va>");
775
776 register_command(cmd_ctx, arm926ejs_cmd, "mdw_phys", arm926ejs_handle_md_phys_command, COMMAND_EXEC, "display memory words <physical addr> [count]");
777 register_command(cmd_ctx, arm926ejs_cmd, "mdh_phys", arm926ejs_handle_md_phys_command, COMMAND_EXEC, "display memory half-words <physical addr> [count]");
778 register_command(cmd_ctx, arm926ejs_cmd, "mdb_phys", arm926ejs_handle_md_phys_command, COMMAND_EXEC, "display memory bytes <physical addr> [count]");
779
780 register_command(cmd_ctx, arm926ejs_cmd, "mww_phys", arm926ejs_handle_mw_phys_command, COMMAND_EXEC, "write memory word <physical addr> <value>");
781 register_command(cmd_ctx, arm926ejs_cmd, "mwh_phys", arm926ejs_handle_mw_phys_command, COMMAND_EXEC, "write memory half-word <physical addr> <value>");
782 register_command(cmd_ctx, arm926ejs_cmd, "mwb_phys", arm926ejs_handle_mw_phys_command, COMMAND_EXEC, "write memory byte <physical addr> <value>");
783
784 return retval;
785 }
786
787 int arm926ejs_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
788 {
789 int retval;
790 target_t *target = get_current_target(cmd_ctx);
791 armv4_5_common_t *armv4_5;
792 arm7_9_common_t *arm7_9;
793 arm9tdmi_common_t *arm9tdmi;
794 arm926ejs_common_t *arm926ejs;
795 int opcode_1;
796 int opcode_2;
797 int CRn;
798 int CRm;
799
800 if ((argc < 4) || (argc > 5))
801 {
802 command_print(cmd_ctx, "usage: arm926ejs cp15 <opcode_1> <opcode_2> <CRn> <CRm> [value]");
803 return ERROR_OK;
804 }
805
806 opcode_1 = strtoul(args[0], NULL, 0);
807 opcode_2 = strtoul(args[1], NULL, 0);
808 CRn = strtoul(args[2], NULL, 0);
809 CRm = strtoul(args[3], NULL, 0);
810
811 if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
812 {
813 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
814 return ERROR_OK;
815 }
816
817 if (target->state != TARGET_HALTED)
818 {
819 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
820 return ERROR_OK;
821 }
822
823 if (argc == 4)
824 {
825 uint32_t value;
826 if ((retval = arm926ejs->read_cp15(target, opcode_1, opcode_2, CRn, CRm, &value)) != ERROR_OK)
827 {
828 command_print(cmd_ctx, "couldn't access register");
829 return ERROR_OK;
830 }
831 if ((retval = jtag_execute_queue()) != ERROR_OK)
832 {
833 return retval;
834 }
835
836 command_print(cmd_ctx, "%i %i %i %i: %8.8" PRIx32 "", opcode_1, opcode_2, CRn, CRm, value);
837 }
838 else
839 {
840 uint32_t value = strtoul(args[4], NULL, 0);
841 if ((retval = arm926ejs->write_cp15(target, opcode_1, opcode_2, CRn, CRm, value)) != ERROR_OK)
842 {
843 command_print(cmd_ctx, "couldn't access register");
844 return ERROR_OK;
845 }
846 command_print(cmd_ctx, "%i %i %i %i: %8.8" PRIx32 "", opcode_1, opcode_2, CRn, CRm, value);
847 }
848
849 return ERROR_OK;
850 }
851
852 int arm926ejs_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
853 {
854 target_t *target = get_current_target(cmd_ctx);
855 armv4_5_common_t *armv4_5;
856 arm7_9_common_t *arm7_9;
857 arm9tdmi_common_t *arm9tdmi;
858 arm926ejs_common_t *arm926ejs;
859
860 if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
861 {
862 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
863 return ERROR_OK;
864 }
865
866 return armv4_5_handle_cache_info_command(cmd_ctx, &arm926ejs->armv4_5_mmu.armv4_5_cache);
867 }
868
869 int arm926ejs_handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
870 {
871 target_t *target = get_current_target(cmd_ctx);
872 armv4_5_common_t *armv4_5;
873 arm7_9_common_t *arm7_9;
874 arm9tdmi_common_t *arm9tdmi;
875 arm926ejs_common_t *arm926ejs;
876 arm_jtag_t *jtag_info;
877
878 if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
879 {
880 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
881 return ERROR_OK;
882 }
883
884 jtag_info = &arm7_9->jtag_info;
885
886 if (target->state != TARGET_HALTED)
887 {
888 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
889 return ERROR_OK;
890 }
891
892 return armv4_5_mmu_handle_virt2phys_command(cmd_ctx, cmd, args, argc, target, &arm926ejs->armv4_5_mmu);
893 }
894
895 int arm926ejs_handle_md_phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
896 {
897 target_t *target = get_current_target(cmd_ctx);
898 armv4_5_common_t *armv4_5;
899 arm7_9_common_t *arm7_9;
900 arm9tdmi_common_t *arm9tdmi;
901 arm926ejs_common_t *arm926ejs;
902 arm_jtag_t *jtag_info;
903
904 if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
905 {
906 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
907 return ERROR_OK;
908 }
909
910 jtag_info = &arm7_9->jtag_info;
911
912 if (target->state != TARGET_HALTED)
913 {
914 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
915 return ERROR_OK;
916 }
917
918 return armv4_5_mmu_handle_md_phys_command(cmd_ctx, cmd, args, argc, target, &arm926ejs->armv4_5_mmu);
919 }
920
921 int arm926ejs_handle_mw_phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
922 {
923 target_t *target = get_current_target(cmd_ctx);
924 armv4_5_common_t *armv4_5;
925 arm7_9_common_t *arm7_9;
926 arm9tdmi_common_t *arm9tdmi;
927 arm926ejs_common_t *arm926ejs;
928 arm_jtag_t *jtag_info;
929
930 if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
931 {
932 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
933 return ERROR_OK;
934 }
935
936 jtag_info = &arm7_9->jtag_info;
937
938 if (target->state != TARGET_HALTED)
939 {
940 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
941 return ERROR_OK;
942 }
943
944 return armv4_5_mmu_handle_mw_phys_command(cmd_ctx, cmd, args, argc, target, &arm926ejs->armv4_5_mmu);
945 }
946
947 static int arm926ejs_virt2phys(struct target_s *target, uint32_t virtual, uint32_t *physical)
948 {
949 int retval;
950 int type;
951 uint32_t cb;
952 int domain;
953 uint32_t ap;
954
955 armv4_5_common_t *armv4_5;
956 arm7_9_common_t *arm7_9;
957 arm9tdmi_common_t *arm9tdmi;
958 arm926ejs_common_t *arm926ejs;
959 retval= arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs);
960 if (retval != ERROR_OK)
961 {
962 return retval;
963 }
964 uint32_t ret = armv4_5_mmu_translate_va(target, &arm926ejs->armv4_5_mmu, virtual, &type, &cb, &domain, &ap);
965 if (type == -1)
966 {
967 return ret;
968 }
969 *physical = ret;
970 return ERROR_OK;
971 }
972
973 static int arm926ejs_mmu(struct target_s *target, int *enabled)
974 {
975 armv4_5_common_t *armv4_5 = target->arch_info;
976 arm926ejs_common_t *arm926ejs = armv4_5->arch_info;
977
978 if (target->state != TARGET_HALTED)
979 {
980 LOG_ERROR("Target not halted");
981 return ERROR_TARGET_INVALID;
982 }
983 *enabled = arm926ejs->armv4_5_mmu.mmu_enabled;
984 return ERROR_OK;
985 }

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)