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

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)