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

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)