1 /***************************************************************************
2 * Copyright (C) 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2007,2008,2009 by Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
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. *
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. *
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 ***************************************************************************/
27 #include "arm926ejs.h"
28 #include "time_support.h"
29 #include "target_type.h"
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:
37 * 1 ... core debugging
39 * 3 ... external boundary scan (SoC-specific, unused here)
41 * 15 ... coprocessor 15
45 #define _DEBUG_INSTRUCTION_EXECUTION_
48 #define ARM926EJS_CP15_ADDR(opcode_1, opcode_2, CRn, CRm) ((opcode_1 << 11) | (opcode_2 << 8) | (CRn << 4) | (CRm << 0))
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
)
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];
63 buf_set_u32(address_buf
, 0, 14, address
);
65 jtag_set_end_state(TAP_IDLE
);
66 if ((retval
= arm_jtag_scann(jtag_info
, 0xf)) != ERROR_OK
)
70 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
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
;
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
;
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
;
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
;
93 jtag_add_dr_scan(4, fields
, jtag_get_end_state());
95 long long then
= timeval_ms();
99 /* rescan with NOP, to wait for the access to complete */
102 jtag_add_dr_scan(4, fields
, jtag_get_end_state());
104 jtag_add_callback(arm_le_to_h_u32
, (jtag_callback_data_t
)value
);
106 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
111 if (buf_get_u32(&access
, 0, 1) == 1)
117 if ((timeval_ms()-then
)>10)
119 LOG_ERROR("cp15 read operation timed out");
124 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
125 LOG_DEBUG("addr: 0x%x value: %8.8x", address
, *value
);
128 arm_jtag_set_instr(jtag_info
, 0xc, NULL
);
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
)
137 LOG_ERROR("Only cp15 is supported");
140 return arm926ejs_cp15_read(target
, op1
, op2
, CRn
, CRm
, value
);
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
)
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;
157 buf_set_u32(address_buf
, 0, 14, address
);
158 buf_set_u32(value_buf
, 0, 32, value
);
160 jtag_set_end_state(TAP_IDLE
);
161 if ((retval
= arm_jtag_scann(jtag_info
, 0xf)) != ERROR_OK
)
165 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
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
;
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
;
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
;
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
;
187 jtag_add_dr_scan(4, fields
, jtag_get_end_state());
189 long long then
= timeval_ms();
193 /* rescan with NOP, to wait for the access to complete */
196 jtag_add_dr_scan(4, fields
, jtag_get_end_state());
197 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
202 if (buf_get_u32(&access
, 0, 1) == 1)
208 if ((timeval_ms()-then
)>10)
210 LOG_ERROR("cp15 write operation timed out");
215 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
216 LOG_DEBUG("addr: 0x%x value: %8.8x", address
, value
);
219 arm_jtag_set_instr(jtag_info
, 0xf, NULL
);
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
)
228 LOG_ERROR("Only cp15 is supported");
231 return arm926ejs_cp15_write(target
, op1
, op2
, CRn
, CRm
, value
);
234 static int arm926ejs_examine_debug_reason(target_t
*target
)
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
];
242 embeddedice_read_reg(dbg_stat
);
243 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
246 /* Method-Of-Entry (MOE) field */
247 debug_reason
= buf_get_u32(dbg_stat
->value
, 6, 4);
249 switch (debug_reason
)
252 LOG_DEBUG("no *NEW* debug entry (?missed one?)");
253 /* ... since last restart or debug reset ... */
254 target
->debug_reason
= DBG_REASON_DBGRQ
;
257 LOG_DEBUG("breakpoint from EICE unit 0");
258 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
261 LOG_DEBUG("breakpoint from EICE unit 1");
262 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
265 LOG_DEBUG("soft breakpoint (BKPT instruction)");
266 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
269 LOG_DEBUG("vector catch breakpoint");
270 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
273 LOG_DEBUG("external breakpoint");
274 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
277 LOG_DEBUG("watchpoint from EICE unit 0");
278 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
281 LOG_DEBUG("watchpoint from EICE unit 1");
282 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
285 LOG_DEBUG("external watchpoint");
286 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
289 LOG_DEBUG("internal debug request");
290 target
->debug_reason
= DBG_REASON_DBGRQ
;
293 LOG_DEBUG("external debug request");
294 target
->debug_reason
= DBG_REASON_DBGRQ
;
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).
302 switch (target
->debug_reason
) {
303 case DBG_REASON_DBGRQ
:
306 LOG_ERROR("unexpected -- debug re-entry");
308 case DBG_REASON_UNDEFINED
:
309 target
->debug_reason
= DBG_REASON_DBGRQ
;
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....
321 LOG_WARNING("WARNING: mystery debug reason MOE = 0xc. Try issuing a resume + halt.");
322 target
->debug_reason
= DBG_REASON_DBGRQ
;
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?
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 */
338 static uint32_t arm926ejs_get_ttb(target_t
*target
)
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
;
347 if ((retval
= arm926ejs
->read_cp15(target
, 0, 0, 2, 0, &ttb
)) != ERROR_OK
)
353 static void arm926ejs_disable_mmu_caches(target_t
*target
, int mmu
,
354 int d_u_cache
, int i_cache
)
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
;
362 /* read cp15 control register */
363 arm926ejs
->read_cp15(target
, 0, 0, 1, 0, &cp15_control
);
364 jtag_execute_queue();
369 arm926ejs
->write_cp15(target
, 0, 0, 8, 7, 0x0);
371 cp15_control
&= ~0x1U
;
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
);
383 /* clean and invalidate DCache */
384 arm926ejs
->write_cp15(target
, 0, 0, 7, 5, 0x0);
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
);
391 cp15_control
&= ~0x4U
;
396 /* invalidate ICache */
397 arm926ejs
->write_cp15(target
, 0, 0, 7, 5, 0x0);
399 cp15_control
&= ~0x1000U
;
402 arm926ejs
->write_cp15(target
, 0, 0, 1, 0, cp15_control
);
405 static void arm926ejs_enable_mmu_caches(target_t
*target
, int mmu
,
406 int d_u_cache
, int i_cache
)
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
;
414 /* read cp15 control register */
415 arm926ejs
->read_cp15(target
, 0, 0, 1, 0, &cp15_control
);
416 jtag_execute_queue();
419 cp15_control
|= 0x1U
;
422 cp15_control
|= 0x4U
;
425 cp15_control
|= 0x1000U
;
427 arm926ejs
->write_cp15(target
, 0, 0, 1, 0, cp15_control
);
430 static void arm926ejs_post_debug_entry(target_t
*target
)
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
;
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
);
442 if (arm926ejs
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
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
);
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;
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
);
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
);
463 uint32_t cache_dbg_ctrl
;
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
);
472 static void arm926ejs_pre_restore_context(target_t
*target
)
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
;
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
);
484 uint32_t cache_dbg_ctrl
;
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
);
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
)
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
;
504 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
509 arm7_9
= armv4_5
->arch_info
;
510 if (arm7_9
->common_magic
!= ARM7_9_COMMON_MAGIC
)
515 arm9tdmi
= arm7_9
->arch_info
;
516 if (arm9tdmi
->common_magic
!= ARM9TDMI_COMMON_MAGIC
)
521 arm926ejs
= arm9tdmi
->arch_info
;
522 if (arm926ejs
->common_magic
!= ARM926EJS_COMMON_MAGIC
)
527 *armv4_5_p
= armv4_5
;
529 *arm9tdmi_p
= arm9tdmi
;
530 *arm926ejs_p
= arm926ejs
;
535 /** Logs summary of ARM926 state for a halted target. */
536 int arm926ejs_arch_state(struct target_s
*target
)
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
;
545 "disabled", "enabled"
548 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
550 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
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
]);
570 int arm926ejs_soft_reset_halt(struct target_s
*target
)
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
];
579 if ((retval
= target_halt(target
)) != ERROR_OK
)
584 long long then
= timeval_ms();
586 while (!(timeout
= ((timeval_ms()-then
) > 1000)))
588 if (buf_get_u32(dbg_stat
->value
, EICE_DBG_STATUS_DBGACK
, 1) == 0)
590 embeddedice_read_reg(dbg_stat
);
591 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
599 if (debug_level
>= 1)
601 /* do not eat all CPU, time out after 1 se*/
610 LOG_ERROR("Failed to halt CPU after 1 sec");
611 return ERROR_TARGET_TIMEOUT
;
614 target
->state
= TARGET_HALTED
;
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;
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;
626 armv4_5
->core_mode
= ARMV4_5_MODE_SVC
;
627 armv4_5
->core_state
= ARMV4_5_STATE_ARM
;
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;
634 return target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
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
)
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
;
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)))
652 /* special case the handling of single word writes to bypass MMU
653 * to allow implementation of breakpoints in memory marked read only
655 if (arm926ejs
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
657 /* flush and invalidate data cache
659 * MCR p15,0,p,c7,c10,1 - clean cache line using virtual address
662 retval
= arm926ejs
->write_cp15(target
, 0, 1, 7, 10, address
&~0x3);
663 if (retval
!= ERROR_OK
)
668 retval
= target
->type
->virt2phys(target
, address
, &pa
);
669 if (retval
!= ERROR_OK
)
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
)
678 if ((retval
= arm7_9_write_memory(target
, address
, size
, count
, buffer
)) != ERROR_OK
)
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
685 if (arm926ejs
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
689 /* invalidate ICache single entry with MVA */
690 arm926ejs
->write_cp15(target
, 0, 1, 7, 5, address
);
694 /* invalidate ICache */
695 arm926ejs
->write_cp15(target
, 0, 0, 7, 5, address
);
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
)
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
;
711 return armv4_5_mmu_write_physical(target
, &arm926ejs
->armv4_5_mmu
, address
, size
, count
, buffer
);
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
)
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
;
723 return armv4_5_mmu_read_physical(target
, &arm926ejs
->armv4_5_mmu
, address
, size
, count
, buffer
);
726 int arm926ejs_init_arch_info(target_t
*target
, arm926ejs_common_t
*arm926ejs
,
729 arm9tdmi_common_t
*arm9tdmi
= &arm926ejs
->arm9tdmi_common
;
730 arm7_9_common_t
*arm7_9
= &arm9tdmi
->arm7_9_common
;
732 /* initialize arm9tdmi specific info (including arm7_9 and armv4_5)
734 arm9tdmi_init_arch_info(target
, arm9tdmi
, tap
);
736 arm9tdmi
->arch_info
= arm926ejs
;
737 arm926ejs
->common_magic
= ARM926EJS_COMMON_MAGIC
;
739 arm7_9
->post_debug_entry
= arm926ejs_post_debug_entry
;
740 arm7_9
->pre_restore_context
= arm926ejs_pre_restore_context
;
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;
753 arm7_9
->examine_debug_reason
= arm926ejs_examine_debug_reason
;
755 /* The ARM926EJ-S implements the ARMv5TE architecture which
756 * has the BKPT instruction, so we don't have to use a watchpoint comparator
758 arm7_9
->arm_bkpt
= ARMV5_BKPT(0x0);
759 arm7_9
->thumb_bkpt
= ARMV5_T_BKPT(0x0) & 0xffff;
764 static int arm926ejs_target_create(struct target_s
*target
, Jim_Interp
*interp
)
766 arm926ejs_common_t
*arm926ejs
= calloc(1,sizeof(arm926ejs_common_t
));
768 /* ARM9EJ-S core always reports 0x1 in Capture-IR */
769 target
->tap
->ir_capture_mask
= 0x0f;
771 return arm926ejs_init_arch_info(target
, arm926ejs
, target
->tap
);
774 static int arm926ejs_handle_cp15_command(struct command_context_s
*cmd_ctx
,
775 char *cmd
, char **args
, int argc
)
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
;
788 if ((argc
< 4) || (argc
> 5))
790 command_print(cmd_ctx
, "usage: arm926ejs cp15 <opcode_1> <opcode_2> <CRn> <CRm> [value]");
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
);
799 if (arm926ejs_get_arch_pointers(target
, &armv4_5
, &arm7_9
, &arm9tdmi
, &arm926ejs
) != ERROR_OK
)
801 command_print(cmd_ctx
, "current target isn't an ARM926EJ-S target");
805 if (target
->state
!= TARGET_HALTED
)
807 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
814 if ((retval
= arm926ejs
->read_cp15(target
, opcode_1
, opcode_2
, CRn
, CRm
, &value
)) != ERROR_OK
)
816 command_print(cmd_ctx
, "couldn't access register");
819 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
824 command_print(cmd_ctx
, "%i %i %i %i: %8.8" PRIx32
"", opcode_1
, opcode_2
, CRn
, CRm
, 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
)
832 command_print(cmd_ctx
, "couldn't access register");
835 command_print(cmd_ctx
, "%i %i %i %i: %8.8" PRIx32
"", opcode_1
, opcode_2
, CRn
, CRm
, value
);
842 arm926ejs_handle_cache_info_command(struct command_context_s
*cmd_ctx
,
843 char *cmd
, char **args
, int argc
)
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
;
851 if (arm926ejs_get_arch_pointers(target
, &armv4_5
, &arm7_9
, &arm9tdmi
, &arm926ejs
) != ERROR_OK
)
853 command_print(cmd_ctx
, "current target isn't an ARM926EJ-S target");
857 return armv4_5_handle_cache_info_command(cmd_ctx
, &arm926ejs
->armv4_5_mmu
.armv4_5_cache
);
860 static int arm926ejs_virt2phys(struct target_s
*target
, uint32_t virtual, uint32_t *physical
)
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
)
877 uint32_t ret
= armv4_5_mmu_translate_va(target
, &arm926ejs
->armv4_5_mmu
, virtual, &type
, &cb
, &domain
, &ap
);
886 static int arm926ejs_mmu(struct target_s
*target
, int *enabled
)
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
;
893 if (target
->state
!= TARGET_HALTED
)
895 LOG_ERROR("Target not halted");
896 return ERROR_TARGET_INVALID
;
898 *enabled
= arm926ejs
->armv4_5_mmu
.mmu_enabled
;
902 /** Registers commands to access coprocessor, cache, and debug resources. */
903 int arm926ejs_register_commands(struct command_context_s
*cmd_ctx
)
906 command_t
*arm926ejs_cmd
;
908 retval
= arm9tdmi_register_commands(cmd_ctx
);
910 arm926ejs_cmd
= register_command(cmd_ctx
, NULL
, "arm926ejs",
912 "arm926ejs specific commands");
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]");
919 register_command(cmd_ctx
, arm926ejs_cmd
, "cache_info",
920 arm926ejs_handle_cache_info_command
, COMMAND_EXEC
,
921 "display information about target caches");
926 /** Holds methods for ARM926 targets. */
927 target_type_t arm926ejs_target
=
932 .arch_state
= arm926ejs_arch_state
,
934 .target_request_data
= arm7_9_target_request_data
,
937 .resume
= arm7_9_resume
,
940 .assert_reset
= arm7_9_assert_reset
,
941 .deassert_reset
= arm7_9_deassert_reset
,
942 .soft_reset_halt
= arm926ejs_soft_reset_halt
,
944 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
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
,
952 .run_algorithm
= armv4_5_run_algorithm
,
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
,
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
,
966 .read_phys_memory
= arm926ejs_read_phys_memory
,
967 .write_phys_memory
= arm926ejs_write_phys_memory
,
968 .mrc
= arm926ejs_mrc
,
969 .mcr
= arm926ejs_mcr
,
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)