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