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

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)