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

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)