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

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)