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

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)