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