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

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)