debug: debug entry error propagation
[openocd.git] / src / target / arm926ejs.c
1 /***************************************************************************
2 * Copyright (C) 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2007,2008,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 <helper/time_support.h>
29 #include "target_type.h"
30 #include "register.h"
31 #include "arm_opcodes.h"
32
33
34 /*
35 * The ARM926 is built around the ARM9EJ-S core, and most JTAG docs
36 * are in the ARM9EJ-S Technical Reference Manual (ARM DDI 0222B) not
37 * the ARM926 manual (ARM DDI 0198E). The scan chains are:
38 *
39 * 1 ... core debugging
40 * 2 ... EmbeddedICE
41 * 3 ... external boundary scan (SoC-specific, unused here)
42 * 6 ... ETM
43 * 15 ... coprocessor 15
44 */
45
46 #if 0
47 #define _DEBUG_INSTRUCTION_EXECUTION_
48 #endif
49
50 #define ARM926EJS_CP15_ADDR(opcode_1, opcode_2, CRn, CRm) ((opcode_1 << 11) | (opcode_2 << 8) | (CRn << 4) | (CRm << 0))
51
52 static int arm926ejs_cp15_read(struct target *target, uint32_t op1, uint32_t op2,
53 uint32_t CRn, uint32_t CRm, uint32_t *value)
54 {
55 int retval = ERROR_OK;
56 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
57 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
58 uint32_t address = ARM926EJS_CP15_ADDR(op1, op2, CRn, CRm);
59 struct scan_field fields[4];
60 uint8_t address_buf[2] = {0, 0};
61 uint8_t nr_w_buf = 0;
62 uint8_t access_t = 1;
63
64 buf_set_u32(address_buf, 0, 14, address);
65
66 if ((retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE)) != ERROR_OK)
67 {
68 return retval;
69 }
70 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE);
71
72 fields[0].num_bits = 32;
73 fields[0].out_value = NULL;
74 fields[0].in_value = (uint8_t *)value;
75
76 fields[1].num_bits = 1;
77 fields[1].out_value = &access_t;
78 fields[1].in_value = &access_t;
79
80 fields[2].num_bits = 14;
81 fields[2].out_value = address_buf;
82 fields[2].in_value = NULL;
83
84 fields[3].num_bits = 1;
85 fields[3].out_value = &nr_w_buf;
86 fields[3].in_value = NULL;
87
88 jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
89
90 long long then = timeval_ms();
91
92 for (;;)
93 {
94 /* rescan with NOP, to wait for the access to complete */
95 access_t = 0;
96 nr_w_buf = 0;
97 jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
98
99 jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value);
100
101 if ((retval = jtag_execute_queue()) != ERROR_OK)
102 {
103 return retval;
104 }
105
106 if (buf_get_u32(&access_t, 0, 1) == 1)
107 {
108 break;
109 }
110
111 /* 10ms timeout */
112 if ((timeval_ms()-then)>10)
113 {
114 LOG_ERROR("cp15 read operation timed out");
115 return ERROR_FAIL;
116 }
117 }
118
119 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
120 LOG_DEBUG("addr: 0x%x value: %8.8x", address, *value);
121 #endif
122
123 arm_jtag_set_instr(jtag_info, 0xc, NULL, TAP_IDLE);
124
125 return ERROR_OK;
126 }
127
128 static int arm926ejs_mrc(struct target *target, int cpnum, uint32_t op1,
129 uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value)
130 {
131 if (cpnum != 15) {
132 LOG_ERROR("Only cp15 is supported");
133 return ERROR_FAIL;
134 }
135 return arm926ejs_cp15_read(target, op1, op2, CRn, CRm, value);
136 }
137
138 static int arm926ejs_cp15_write(struct target *target, uint32_t op1, uint32_t op2,
139 uint32_t CRn, uint32_t CRm, uint32_t value)
140 {
141 int retval = ERROR_OK;
142 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
143 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
144 uint32_t address = ARM926EJS_CP15_ADDR(op1, op2, CRn, CRm);
145 struct scan_field fields[4];
146 uint8_t value_buf[4];
147 uint8_t address_buf[2] = {0, 0};
148 uint8_t nr_w_buf = 1;
149 uint8_t access_t = 1;
150
151 buf_set_u32(address_buf, 0, 14, address);
152 buf_set_u32(value_buf, 0, 32, value);
153
154 if ((retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE)) != ERROR_OK)
155 {
156 return retval;
157 }
158 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE);
159
160 fields[0].num_bits = 32;
161 fields[0].out_value = value_buf;
162 fields[0].in_value = NULL;
163
164 fields[1].num_bits = 1;
165 fields[1].out_value = &access_t;
166 fields[1].in_value = &access_t;
167
168 fields[2].num_bits = 14;
169 fields[2].out_value = address_buf;
170 fields[2].in_value = NULL;
171
172 fields[3].num_bits = 1;
173 fields[3].out_value = &nr_w_buf;
174 fields[3].in_value = NULL;
175
176 jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
177
178 long long then = timeval_ms();
179
180 for (;;)
181 {
182 /* rescan with NOP, to wait for the access to complete */
183 access_t = 0;
184 nr_w_buf = 0;
185 jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
186 if ((retval = jtag_execute_queue()) != ERROR_OK)
187 {
188 return retval;
189 }
190
191 if (buf_get_u32(&access_t, 0, 1) == 1)
192 {
193 break;
194 }
195
196 /* 10ms timeout */
197 if ((timeval_ms()-then)>10)
198 {
199 LOG_ERROR("cp15 write operation timed out");
200 return ERROR_FAIL;
201 }
202 }
203
204 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
205 LOG_DEBUG("addr: 0x%x value: %8.8x", address, value);
206 #endif
207
208 arm_jtag_set_instr(jtag_info, 0xf, NULL, TAP_IDLE);
209
210 return ERROR_OK;
211 }
212
213 static int arm926ejs_mcr(struct target *target, int cpnum, uint32_t op1,
214 uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value)
215 {
216 if (cpnum != 15) {
217 LOG_ERROR("Only cp15 is supported");
218 return ERROR_FAIL;
219 }
220 return arm926ejs_cp15_write(target, op1, op2, CRn, CRm, value);
221 }
222
223 static int arm926ejs_examine_debug_reason(struct target *target)
224 {
225 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
226 struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
227 int debug_reason;
228 int retval;
229
230 embeddedice_read_reg(dbg_stat);
231 if ((retval = jtag_execute_queue()) != ERROR_OK)
232 return retval;
233
234 /* Method-Of-Entry (MOE) field */
235 debug_reason = buf_get_u32(dbg_stat->value, 6, 4);
236
237 switch (debug_reason)
238 {
239 case 0:
240 LOG_DEBUG("no *NEW* debug entry (?missed one?)");
241 /* ... since last restart or debug reset ... */
242 target->debug_reason = DBG_REASON_DBGRQ;
243 break;
244 case 1:
245 LOG_DEBUG("breakpoint from EICE unit 0");
246 target->debug_reason = DBG_REASON_BREAKPOINT;
247 break;
248 case 2:
249 LOG_DEBUG("breakpoint from EICE unit 1");
250 target->debug_reason = DBG_REASON_BREAKPOINT;
251 break;
252 case 3:
253 LOG_DEBUG("soft breakpoint (BKPT instruction)");
254 target->debug_reason = DBG_REASON_BREAKPOINT;
255 break;
256 case 4:
257 LOG_DEBUG("vector catch breakpoint");
258 target->debug_reason = DBG_REASON_BREAKPOINT;
259 break;
260 case 5:
261 LOG_DEBUG("external breakpoint");
262 target->debug_reason = DBG_REASON_BREAKPOINT;
263 break;
264 case 6:
265 LOG_DEBUG("watchpoint from EICE unit 0");
266 target->debug_reason = DBG_REASON_WATCHPOINT;
267 break;
268 case 7:
269 LOG_DEBUG("watchpoint from EICE unit 1");
270 target->debug_reason = DBG_REASON_WATCHPOINT;
271 break;
272 case 8:
273 LOG_DEBUG("external watchpoint");
274 target->debug_reason = DBG_REASON_WATCHPOINT;
275 break;
276 case 9:
277 LOG_DEBUG("internal debug request");
278 target->debug_reason = DBG_REASON_DBGRQ;
279 break;
280 case 10:
281 LOG_DEBUG("external debug request");
282 target->debug_reason = DBG_REASON_DBGRQ;
283 break;
284 case 11:
285 LOG_DEBUG("debug re-entry from system speed access");
286 /* This is normal when connecting to something that's
287 * already halted, or in some related code paths, but
288 * otherwise is surprising (and presumably wrong).
289 */
290 switch (target->debug_reason) {
291 case DBG_REASON_DBGRQ:
292 break;
293 default:
294 LOG_ERROR("unexpected -- debug re-entry");
295 /* FALLTHROUGH */
296 case DBG_REASON_UNDEFINED:
297 target->debug_reason = DBG_REASON_DBGRQ;
298 break;
299 }
300 break;
301 case 12:
302 /* FIX!!!! here be dragons!!! We need to fail here so
303 * the target will interpreted as halted but we won't
304 * try to talk to it right now... a resume + halt seems
305 * to sync things up again. Please send an email to
306 * openocd development mailing list if you have hardware
307 * to donate to look into this problem....
308 */
309 LOG_WARNING("WARNING: mystery debug reason MOE = 0xc. Try issuing a resume + halt.");
310 target->debug_reason = DBG_REASON_DBGRQ;
311 break;
312 default:
313 LOG_WARNING("WARNING: unknown debug reason: 0x%x", debug_reason);
314 /* Oh agony! should we interpret this as a halt request or
315 * that the target stopped on it's own accord?
316 */
317 target->debug_reason = DBG_REASON_DBGRQ;
318 /* if we fail here, we won't talk to the target and it will
319 * be reported to be in the halted state */
320 break;
321 }
322
323 return ERROR_OK;
324 }
325
326 static int arm926ejs_get_ttb(struct target *target, uint32_t *result)
327 {
328 struct arm926ejs_common *arm926ejs = target_to_arm926(target);
329 int retval;
330 uint32_t ttb = 0x0;
331
332 if ((retval = arm926ejs->read_cp15(target, 0, 0, 2, 0, &ttb)) != ERROR_OK)
333 return retval;
334
335 *result = ttb;
336
337 return ERROR_OK;
338 }
339
340 static int arm926ejs_disable_mmu_caches(struct target *target, int mmu,
341 int d_u_cache, int i_cache)
342 {
343 struct arm926ejs_common *arm926ejs = target_to_arm926(target);
344 uint32_t cp15_control;
345 int retval;
346
347 /* read cp15 control register */
348 retval = arm926ejs->read_cp15(target, 0, 0, 1, 0, &cp15_control);
349 if (retval != ERROR_OK)
350 return retval;
351 retval = jtag_execute_queue();
352 if (retval != ERROR_OK)
353 return retval;
354
355 if (mmu)
356 {
357 /* invalidate TLB */
358 retval = arm926ejs->write_cp15(target, 0, 0, 8, 7, 0x0);
359 if (retval != ERROR_OK)
360 return retval;
361
362 cp15_control &= ~0x1U;
363 }
364
365 if (d_u_cache)
366 {
367 uint32_t debug_override;
368 /* read-modify-write CP15 debug override register
369 * to enable "test and clean all" */
370 retval = arm926ejs->read_cp15(target, 0, 0, 15, 0, &debug_override);
371 if (retval != ERROR_OK)
372 return retval;
373 debug_override |= 0x80000;
374 retval = arm926ejs->write_cp15(target, 0, 0, 15, 0, debug_override);
375 if (retval != ERROR_OK)
376 return retval;
377
378 /* clean and invalidate DCache */
379 retval = arm926ejs->write_cp15(target, 0, 0, 7, 5, 0x0);
380 if (retval != ERROR_OK)
381 return retval;
382
383 /* write CP15 debug override register
384 * to disable "test and clean all" */
385 debug_override &= ~0x80000;
386 retval = arm926ejs->write_cp15(target, 0, 0, 15, 0, debug_override);
387 if (retval != ERROR_OK)
388 return retval;
389
390 cp15_control &= ~0x4U;
391 }
392
393 if (i_cache)
394 {
395 /* invalidate ICache */
396 retval = arm926ejs->write_cp15(target, 0, 0, 7, 5, 0x0);
397 if (retval != ERROR_OK)
398 return retval;
399
400 cp15_control &= ~0x1000U;
401 }
402
403 retval = arm926ejs->write_cp15(target, 0, 0, 1, 0, cp15_control);
404 return retval;
405 }
406
407 static int arm926ejs_enable_mmu_caches(struct target *target, int mmu,
408 int d_u_cache, int i_cache)
409 {
410 struct arm926ejs_common *arm926ejs = target_to_arm926(target);
411 uint32_t cp15_control;
412 int retval;
413
414 /* read cp15 control register */
415 retval = arm926ejs->read_cp15(target, 0, 0, 1, 0, &cp15_control);
416 if (retval != ERROR_OK)
417 return retval;
418 retval = jtag_execute_queue();
419 if (retval != ERROR_OK)
420 return retval;
421
422 if (mmu)
423 cp15_control |= 0x1U;
424
425 if (d_u_cache)
426 cp15_control |= 0x4U;
427
428 if (i_cache)
429 cp15_control |= 0x1000U;
430
431 retval = arm926ejs->write_cp15(target, 0, 0, 1, 0, cp15_control);
432 return retval;
433 }
434
435 static int arm926ejs_post_debug_entry(struct target *target)
436 {
437 struct arm926ejs_common *arm926ejs = target_to_arm926(target);
438 int retval;
439
440 /* examine cp15 control reg */
441 retval = arm926ejs->read_cp15(target, 0, 0, 1, 0, &arm926ejs->cp15_control_reg);
442 if (retval != ERROR_OK)
443 return retval;
444 retval = jtag_execute_queue();
445 if (retval != ERROR_OK)
446 return retval;
447 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32 "", arm926ejs->cp15_control_reg);
448
449 if (arm926ejs->armv4_5_mmu.armv4_5_cache.ctype == -1)
450 {
451 uint32_t cache_type_reg;
452 /* identify caches */
453 retval = arm926ejs->read_cp15(target, 0, 1, 0, 0, &cache_type_reg);
454 if (retval != ERROR_OK)
455 return retval;
456 retval = jtag_execute_queue();
457 if (retval != ERROR_OK)
458 return retval;
459 armv4_5_identify_cache(cache_type_reg, &arm926ejs->armv4_5_mmu.armv4_5_cache);
460 }
461
462 arm926ejs->armv4_5_mmu.mmu_enabled = (arm926ejs->cp15_control_reg & 0x1U) ? 1 : 0;
463 arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = (arm926ejs->cp15_control_reg & 0x4U) ? 1 : 0;
464 arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled = (arm926ejs->cp15_control_reg & 0x1000U) ? 1 : 0;
465
466 /* save i/d fault status and address register */
467 retval = arm926ejs->read_cp15(target, 0, 0, 5, 0, &arm926ejs->d_fsr);
468 if (retval != ERROR_OK)
469 return retval;
470 retval = arm926ejs->read_cp15(target, 0, 1, 5, 0, &arm926ejs->i_fsr);
471 if (retval != ERROR_OK)
472 return retval;
473 retval = arm926ejs->read_cp15(target, 0, 0, 6, 0, &arm926ejs->d_far);
474 if (retval != ERROR_OK)
475 return retval;
476
477 LOG_DEBUG("D FSR: 0x%8.8" PRIx32 ", D FAR: 0x%8.8" PRIx32 ", I FSR: 0x%8.8" PRIx32 "",
478 arm926ejs->d_fsr, arm926ejs->d_far, arm926ejs->i_fsr);
479
480 uint32_t cache_dbg_ctrl;
481
482 /* read-modify-write CP15 cache debug control register
483 * to disable I/D-cache linefills and force WT */
484 retval = arm926ejs->read_cp15(target, 7, 0, 15, 0, &cache_dbg_ctrl);
485 if (retval != ERROR_OK)
486 return retval;
487 cache_dbg_ctrl |= 0x7;
488 retval = arm926ejs->write_cp15(target, 7, 0, 15, 0, cache_dbg_ctrl);
489 return retval;
490 }
491
492 static void arm926ejs_pre_restore_context(struct target *target)
493 {
494 struct arm926ejs_common *arm926ejs = target_to_arm926(target);
495
496 /* restore i/d fault status and address register */
497 arm926ejs->write_cp15(target, 0, 0, 5, 0, arm926ejs->d_fsr);
498 arm926ejs->write_cp15(target, 0, 1, 5, 0, arm926ejs->i_fsr);
499 arm926ejs->write_cp15(target, 0, 0, 6, 0, arm926ejs->d_far);
500
501 uint32_t cache_dbg_ctrl;
502
503 /* read-modify-write CP15 cache debug control register
504 * to reenable I/D-cache linefills and disable WT */
505 arm926ejs->read_cp15(target, 7, 0, 15, 0, &cache_dbg_ctrl);
506 cache_dbg_ctrl &= ~0x7;
507 arm926ejs->write_cp15(target, 7, 0, 15, 0, cache_dbg_ctrl);
508 }
509
510 static const char arm926_not[] = "target is not an ARM926";
511
512 static int arm926ejs_verify_pointer(struct command_context *cmd_ctx,
513 struct arm926ejs_common *arm926)
514 {
515 if (arm926->common_magic != ARM926EJS_COMMON_MAGIC) {
516 command_print(cmd_ctx, arm926_not);
517 return ERROR_TARGET_INVALID;
518 }
519 return ERROR_OK;
520 }
521
522 /** Logs summary of ARM926 state for a halted target. */
523 int arm926ejs_arch_state(struct target *target)
524 {
525 static const char *state[] =
526 {
527 "disabled", "enabled"
528 };
529
530 struct arm926ejs_common *arm926ejs = target_to_arm926(target);
531 struct arm *armv4_5;
532
533 if (arm926ejs->common_magic != ARM926EJS_COMMON_MAGIC)
534 {
535 LOG_ERROR("BUG: %s", arm926_not);
536 return ERROR_TARGET_INVALID;
537 }
538
539 armv4_5 = &arm926ejs->arm7_9_common.armv4_5_common;
540
541 arm_arch_state(target);
542 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
543 state[arm926ejs->armv4_5_mmu.mmu_enabled],
544 state[arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
545 state[arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);
546
547 return ERROR_OK;
548 }
549
550 int arm926ejs_soft_reset_halt(struct target *target)
551 {
552 int retval = ERROR_OK;
553 struct arm926ejs_common *arm926ejs = target_to_arm926(target);
554 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
555 struct arm *armv4_5 = &arm7_9->armv4_5_common;
556 struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
557
558 if ((retval = target_halt(target)) != ERROR_OK)
559 {
560 return retval;
561 }
562
563 long long then = timeval_ms();
564 int timeout;
565 while (!(timeout = ((timeval_ms()-then) > 1000)))
566 {
567 if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0)
568 {
569 embeddedice_read_reg(dbg_stat);
570 if ((retval = jtag_execute_queue()) != ERROR_OK)
571 {
572 return retval;
573 }
574 } else
575 {
576 break;
577 }
578 if (debug_level >= 1)
579 {
580 /* do not eat all CPU, time out after 1 se*/
581 alive_sleep(100);
582 } else
583 {
584 keep_alive();
585 }
586 }
587 if (timeout)
588 {
589 LOG_ERROR("Failed to halt CPU after 1 sec");
590 return ERROR_TARGET_TIMEOUT;
591 }
592
593 target->state = TARGET_HALTED;
594
595 /* SVC, ARM state, IRQ and FIQ disabled */
596 uint32_t cpsr;
597
598 cpsr = buf_get_u32(armv4_5->cpsr->value, 0, 32);
599 cpsr &= ~0xff;
600 cpsr |= 0xd3;
601 arm_set_cpsr(armv4_5, cpsr);
602 armv4_5->cpsr->dirty = 1;
603
604 /* start fetching from 0x0 */
605 buf_set_u32(armv4_5->pc->value, 0, 32, 0x0);
606 armv4_5->pc->dirty = 1;
607 armv4_5->pc->valid = 1;
608
609 retval = arm926ejs_disable_mmu_caches(target, 1, 1, 1);
610 if (retval != ERROR_OK)
611 return retval;
612 arm926ejs->armv4_5_mmu.mmu_enabled = 0;
613 arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
614 arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
615
616 return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
617 }
618
619 /** Writes a buffer, in the specified word size, with current MMU settings. */
620 int arm926ejs_write_memory(struct target *target, uint32_t address,
621 uint32_t size, uint32_t count, uint8_t *buffer)
622 {
623 int retval;
624 struct arm926ejs_common *arm926ejs = target_to_arm926(target);
625
626 /* FIX!!!! this should be cleaned up and made much more general. The
627 * plan is to write up and test on arm926ejs specifically and
628 * then generalize and clean up afterwards.
629 *
630 *
631 * Also it should be moved to the callbacks that handle breakpoints
632 * specifically and not the generic memory write fn's. See XScale code.
633 **/
634 if (arm926ejs->armv4_5_mmu.mmu_enabled && (count == 1) && ((size==2) || (size==4)))
635 {
636 /* special case the handling of single word writes to bypass MMU
637 * to allow implementation of breakpoints in memory marked read only
638 * by MMU */
639 if (arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled)
640 {
641 /* flush and invalidate data cache
642 *
643 * MCR p15,0,p,c7,c10,1 - clean cache line using virtual address
644 *
645 */
646 retval = arm926ejs->write_cp15(target, 0, 1, 7, 10, address&~0x3);
647 if (retval != ERROR_OK)
648 return retval;
649 }
650
651 uint32_t pa;
652 retval = target->type->virt2phys(target, address, &pa);
653 if (retval != ERROR_OK)
654 return retval;
655
656 /* write directly to physical memory bypassing any read only MMU bits, etc. */
657 retval = armv4_5_mmu_write_physical(target, &arm926ejs->armv4_5_mmu, pa, size, count, buffer);
658 if (retval != ERROR_OK)
659 return retval;
660 } else
661 {
662 if ((retval = arm7_9_write_memory(target, address, size, count, buffer)) != ERROR_OK)
663 return retval;
664 }
665
666 /* If ICache is enabled, we have to invalidate affected ICache lines
667 * the DCache is forced to write-through, so we don't have to clean it here
668 */
669 if (arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
670 {
671 if (count <= 1)
672 {
673 /* invalidate ICache single entry with MVA */
674 arm926ejs->write_cp15(target, 0, 1, 7, 5, address);
675 }
676 else
677 {
678 /* invalidate ICache */
679 arm926ejs->write_cp15(target, 0, 0, 7, 5, address);
680 }
681 }
682
683 return retval;
684 }
685
686 static int arm926ejs_write_phys_memory(struct target *target,
687 uint32_t address, uint32_t size,
688 uint32_t count, uint8_t *buffer)
689 {
690 struct arm926ejs_common *arm926ejs = target_to_arm926(target);
691
692 return armv4_5_mmu_write_physical(target, &arm926ejs->armv4_5_mmu,
693 address, size, count, buffer);
694 }
695
696 static int arm926ejs_read_phys_memory(struct target *target,
697 uint32_t address, uint32_t size,
698 uint32_t count, uint8_t *buffer)
699 {
700 struct arm926ejs_common *arm926ejs = target_to_arm926(target);
701
702 return armv4_5_mmu_read_physical(target, &arm926ejs->armv4_5_mmu,
703 address, size, count, buffer);
704 }
705
706 int arm926ejs_init_arch_info(struct target *target, struct arm926ejs_common *arm926ejs,
707 struct jtag_tap *tap)
708 {
709 struct arm7_9_common *arm7_9 = &arm926ejs->arm7_9_common;
710
711 arm7_9->armv4_5_common.mrc = arm926ejs_mrc;
712 arm7_9->armv4_5_common.mcr = arm926ejs_mcr;
713
714 /* initialize arm7/arm9 specific info (including armv4_5) */
715 arm9tdmi_init_arch_info(target, arm7_9, tap);
716
717 arm926ejs->common_magic = ARM926EJS_COMMON_MAGIC;
718
719 arm7_9->post_debug_entry = arm926ejs_post_debug_entry;
720 arm7_9->pre_restore_context = arm926ejs_pre_restore_context;
721
722 arm926ejs->read_cp15 = arm926ejs_cp15_read;
723 arm926ejs->write_cp15 = arm926ejs_cp15_write;
724 arm926ejs->armv4_5_mmu.armv4_5_cache.ctype = -1;
725 arm926ejs->armv4_5_mmu.get_ttb = arm926ejs_get_ttb;
726 arm926ejs->armv4_5_mmu.read_memory = arm7_9_read_memory;
727 arm926ejs->armv4_5_mmu.write_memory = arm7_9_write_memory;
728 arm926ejs->armv4_5_mmu.disable_mmu_caches = arm926ejs_disable_mmu_caches;
729 arm926ejs->armv4_5_mmu.enable_mmu_caches = arm926ejs_enable_mmu_caches;
730 arm926ejs->armv4_5_mmu.has_tiny_pages = 1;
731 arm926ejs->armv4_5_mmu.mmu_enabled = 0;
732
733 arm7_9->examine_debug_reason = arm926ejs_examine_debug_reason;
734
735 /* The ARM926EJ-S implements the ARMv5TE architecture which
736 * has the BKPT instruction, so we don't have to use a watchpoint comparator
737 */
738 arm7_9->arm_bkpt = ARMV5_BKPT(0x0);
739 arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
740
741 return ERROR_OK;
742 }
743
744 static int arm926ejs_target_create(struct target *target, Jim_Interp *interp)
745 {
746 struct arm926ejs_common *arm926ejs = calloc(1,sizeof(struct arm926ejs_common));
747
748 /* ARM9EJ-S core always reports 0x1 in Capture-IR */
749 target->tap->ir_capture_mask = 0x0f;
750
751 return arm926ejs_init_arch_info(target, arm926ejs, target->tap);
752 }
753
754 COMMAND_HANDLER(arm926ejs_handle_cache_info_command)
755 {
756 int retval;
757 struct target *target = get_current_target(CMD_CTX);
758 struct arm926ejs_common *arm926ejs = target_to_arm926(target);
759
760 retval = arm926ejs_verify_pointer(CMD_CTX, arm926ejs);
761 if (retval != ERROR_OK)
762 return retval;
763
764 return armv4_5_handle_cache_info_command(CMD_CTX, &arm926ejs->armv4_5_mmu.armv4_5_cache);
765 }
766
767 static int arm926ejs_virt2phys(struct target *target, uint32_t virtual, uint32_t *physical)
768 {
769 uint32_t cb;
770 struct arm926ejs_common *arm926ejs = target_to_arm926(target);
771
772 uint32_t ret;
773 int retval = armv4_5_mmu_translate_va(target, &arm926ejs->armv4_5_mmu,
774 virtual, &cb, &ret);
775 if (retval != ERROR_OK)
776 return retval;
777 *physical = ret;
778 return ERROR_OK;
779 }
780
781 static int arm926ejs_mmu(struct target *target, int *enabled)
782 {
783 struct arm926ejs_common *arm926ejs = target_to_arm926(target);
784
785 if (target->state != TARGET_HALTED)
786 {
787 LOG_ERROR("Target not halted");
788 return ERROR_TARGET_INVALID;
789 }
790 *enabled = arm926ejs->armv4_5_mmu.mmu_enabled;
791 return ERROR_OK;
792 }
793
794 static const struct command_registration arm926ejs_exec_command_handlers[] = {
795 {
796 .name = "cache_info",
797 .handler = arm926ejs_handle_cache_info_command,
798 .mode = COMMAND_EXEC,
799 .help = "display information about target caches",
800
801 },
802 COMMAND_REGISTRATION_DONE
803 };
804 const struct command_registration arm926ejs_command_handlers[] = {
805 {
806 .chain = arm9tdmi_command_handlers,
807 },
808 {
809 .name = "arm926ejs",
810 .mode = COMMAND_ANY,
811 .help = "arm926ejs command group",
812 .chain = arm926ejs_exec_command_handlers,
813 },
814 COMMAND_REGISTRATION_DONE
815 };
816
817 /** Holds methods for ARM926 targets. */
818 struct target_type arm926ejs_target =
819 {
820 .name = "arm926ejs",
821
822 .poll = arm7_9_poll,
823 .arch_state = arm926ejs_arch_state,
824
825 .target_request_data = arm7_9_target_request_data,
826
827 .halt = arm7_9_halt,
828 .resume = arm7_9_resume,
829 .step = arm7_9_step,
830
831 .assert_reset = arm7_9_assert_reset,
832 .deassert_reset = arm7_9_deassert_reset,
833 .soft_reset_halt = arm926ejs_soft_reset_halt,
834
835 .get_gdb_reg_list = arm_get_gdb_reg_list,
836
837 .read_memory = arm7_9_read_memory,
838 .write_memory = arm926ejs_write_memory,
839 .bulk_write_memory = arm7_9_bulk_write_memory,
840
841 .checksum_memory = arm_checksum_memory,
842 .blank_check_memory = arm_blank_check_memory,
843
844 .run_algorithm = armv4_5_run_algorithm,
845
846 .add_breakpoint = arm7_9_add_breakpoint,
847 .remove_breakpoint = arm7_9_remove_breakpoint,
848 .add_watchpoint = arm7_9_add_watchpoint,
849 .remove_watchpoint = arm7_9_remove_watchpoint,
850
851 .commands = arm926ejs_command_handlers,
852 .target_create = arm926ejs_target_create,
853 .init_target = arm9tdmi_init_target,
854 .examine = arm7_9_examine,
855 .check_reset = arm7_9_check_reset,
856 .virt2phys = arm926ejs_virt2phys,
857 .mmu = arm926ejs_mmu,
858
859 .read_phys_memory = arm926ejs_read_phys_memory,
860 .write_phys_memory = arm926ejs_write_phys_memory,
861 };

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)