1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 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 ***************************************************************************/
28 #include <helper/time_support.h>
29 #include "target_type.h"
31 #include "arm_opcodes.h"
35 * ARM720 is an ARM7TDMI-S with MMU and ETM7. For information, see
36 * ARM DDI 0229C especially Chapter 9 about debug support.
40 #define _DEBUG_INSTRUCTION_EXECUTION_
43 static int arm720t_scan_cp15(struct target
*target
,
44 uint32_t out
, uint32_t *in
, int instruction
, int clock_arg
)
47 struct arm720t_common
*arm720t
= target_to_arm720(target
);
48 struct arm_jtag
*jtag_info
;
49 struct scan_field fields
[2];
51 uint8_t instruction_buf
= instruction
;
53 jtag_info
= &arm720t
->arm7_9_common
.jtag_info
;
55 buf_set_u32(out_buf
, 0, 32, flip_u32(out
, 32));
57 if ((retval
= arm_jtag_scann(jtag_info
, 0xf, TAP_DRPAUSE
)) != ERROR_OK
)
61 if ((retval
= arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
, TAP_DRPAUSE
)) != ERROR_OK
)
66 fields
[0].num_bits
= 1;
67 fields
[0].out_value
= &instruction_buf
;
68 fields
[0].in_value
= NULL
;
70 fields
[1].num_bits
= 32;
71 fields
[1].out_value
= out_buf
;
72 fields
[1].in_value
= NULL
;
76 fields
[1].in_value
= (uint8_t *)in
;
77 jtag_add_dr_scan(jtag_info
->tap
, 2, fields
, TAP_DRPAUSE
);
78 jtag_add_callback(arm7flip32
, (jtag_callback_data_t
)in
);
81 jtag_add_dr_scan(jtag_info
->tap
, 2, fields
, TAP_DRPAUSE
);
85 jtag_add_runtest(0, TAP_DRPAUSE
);
87 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
88 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
94 LOG_DEBUG("out: %8.8x, in: %8.8x, instruction: %i, clock: %i", out
, *in
, instruction
, clock
);
96 LOG_DEBUG("out: %8.8x, instruction: %i, clock: %i", out
, instruction
, clock_arg
);
98 LOG_DEBUG("out: %8.8" PRIx32
", instruction: %i, clock: %i", out
, instruction
, clock_arg
);
104 static int arm720t_read_cp15(struct target
*target
, uint32_t opcode
, uint32_t *value
)
106 /* fetch CP15 opcode */
107 arm720t_scan_cp15(target
, opcode
, NULL
, 1, 1);
109 arm720t_scan_cp15(target
, ARMV4_5_NOP
, NULL
, 1, 1);
110 /* "EXECUTE" stage (1) */
111 arm720t_scan_cp15(target
, ARMV4_5_NOP
, NULL
, 1, 0);
112 arm720t_scan_cp15(target
, 0x0, NULL
, 0, 1);
113 /* "EXECUTE" stage (2) */
114 arm720t_scan_cp15(target
, 0x0, NULL
, 0, 1);
115 /* "EXECUTE" stage (3), CDATA is read */
116 arm720t_scan_cp15(target
, ARMV4_5_NOP
, value
, 1, 1);
121 static int arm720t_write_cp15(struct target
*target
, uint32_t opcode
, uint32_t value
)
123 /* fetch CP15 opcode */
124 arm720t_scan_cp15(target
, opcode
, NULL
, 1, 1);
126 arm720t_scan_cp15(target
, ARMV4_5_NOP
, NULL
, 1, 1);
127 /* "EXECUTE" stage (1) */
128 arm720t_scan_cp15(target
, ARMV4_5_NOP
, NULL
, 1, 0);
129 arm720t_scan_cp15(target
, 0x0, NULL
, 0, 1);
130 /* "EXECUTE" stage (2) */
131 arm720t_scan_cp15(target
, value
, NULL
, 0, 1);
132 arm720t_scan_cp15(target
, ARMV4_5_NOP
, NULL
, 1, 1);
137 static int arm720t_get_ttb(struct target
*target
, uint32_t *result
)
143 retval
= arm720t_read_cp15(target
, 0xee120f10, &ttb
);
144 if (retval
!= ERROR_OK
)
146 retval
= jtag_execute_queue();
147 if (retval
!= ERROR_OK
)
157 static void arm720t_disable_mmu_caches(struct target
*target
,
158 int mmu
, int d_u_cache
, int i_cache
)
160 uint32_t cp15_control
;
162 /* read cp15 control register */
163 arm720t_read_cp15(target
, 0xee110f10, &cp15_control
);
164 jtag_execute_queue();
167 cp15_control
&= ~0x1U
;
169 if (d_u_cache
|| i_cache
)
170 cp15_control
&= ~0x4U
;
172 arm720t_write_cp15(target
, 0xee010f10, cp15_control
);
175 static void arm720t_enable_mmu_caches(struct target
*target
,
176 int mmu
, int d_u_cache
, int i_cache
)
178 uint32_t cp15_control
;
180 /* read cp15 control register */
181 arm720t_read_cp15(target
, 0xee110f10, &cp15_control
);
182 jtag_execute_queue();
185 cp15_control
|= 0x1U
;
187 if (d_u_cache
|| i_cache
)
188 cp15_control
|= 0x4U
;
190 arm720t_write_cp15(target
, 0xee010f10, cp15_control
);
193 static void arm720t_post_debug_entry(struct target
*target
)
195 struct arm720t_common
*arm720t
= target_to_arm720(target
);
197 /* examine cp15 control reg */
198 arm720t_read_cp15(target
, 0xee110f10, &arm720t
->cp15_control_reg
);
199 jtag_execute_queue();
200 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
"", arm720t
->cp15_control_reg
);
202 arm720t
->armv4_5_mmu
.mmu_enabled
= (arm720t
->cp15_control_reg
& 0x1U
) ? 1 : 0;
203 arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= (arm720t
->cp15_control_reg
& 0x4U
) ? 1 : 0;
204 arm720t
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
206 /* save i/d fault status and address register */
207 arm720t_read_cp15(target
, 0xee150f10, &arm720t
->fsr_reg
);
208 arm720t_read_cp15(target
, 0xee160f10, &arm720t
->far_reg
);
209 jtag_execute_queue();
212 static void arm720t_pre_restore_context(struct target
*target
)
214 struct arm720t_common
*arm720t
= target_to_arm720(target
);
216 /* restore i/d fault status and address register */
217 arm720t_write_cp15(target
, 0xee050f10, arm720t
->fsr_reg
);
218 arm720t_write_cp15(target
, 0xee060f10, arm720t
->far_reg
);
221 static int arm720t_verify_pointer(struct command_context
*cmd_ctx
,
222 struct arm720t_common
*arm720t
)
224 if (arm720t
->common_magic
!= ARM720T_COMMON_MAGIC
) {
225 command_print(cmd_ctx
, "target is not an ARM720");
226 return ERROR_TARGET_INVALID
;
231 static int arm720t_arch_state(struct target
*target
)
233 struct arm720t_common
*arm720t
= target_to_arm720(target
);
236 static const char *state
[] =
238 "disabled", "enabled"
241 armv4_5
= &arm720t
->arm7_9_common
.armv4_5_common
;
243 arm_arch_state(target
);
244 LOG_USER("MMU: %s, Cache: %s",
245 state
[arm720t
->armv4_5_mmu
.mmu_enabled
],
246 state
[arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
]);
251 static int arm720_mmu(struct target
*target
, int *enabled
)
253 if (target
->state
!= TARGET_HALTED
) {
254 LOG_ERROR("%s: target not halted", __func__
);
255 return ERROR_TARGET_INVALID
;
258 *enabled
= target_to_arm720(target
)->armv4_5_mmu
.mmu_enabled
;
262 static int arm720_virt2phys(struct target
*target
,
263 uint32_t virtual, uint32_t *physical
)
266 struct arm720t_common
*arm720t
= target_to_arm720(target
);
269 int retval
= armv4_5_mmu_translate_va(target
,
270 &arm720t
->armv4_5_mmu
, virtual, &cb
, &ret
);
271 if (retval
!= ERROR_OK
)
277 static int arm720t_read_memory(struct target
*target
,
278 uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
)
281 struct arm720t_common
*arm720t
= target_to_arm720(target
);
283 /* disable cache, but leave MMU enabled */
284 if (arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
285 arm720t_disable_mmu_caches(target
, 0, 1, 0);
287 retval
= arm7_9_read_memory(target
, address
, size
, count
, buffer
);
289 if (arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
290 arm720t_enable_mmu_caches(target
, 0, 1, 0);
295 static int arm720t_read_phys_memory(struct target
*target
,
296 uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
)
298 struct arm720t_common
*arm720t
= target_to_arm720(target
);
300 return armv4_5_mmu_read_physical(target
, &arm720t
->armv4_5_mmu
, address
, size
, count
, buffer
);
303 static int arm720t_write_phys_memory(struct target
*target
,
304 uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
)
306 struct arm720t_common
*arm720t
= target_to_arm720(target
);
308 return armv4_5_mmu_write_physical(target
, &arm720t
->armv4_5_mmu
, address
, size
, count
, buffer
);
311 static int arm720t_soft_reset_halt(struct target
*target
)
313 int retval
= ERROR_OK
;
314 struct arm720t_common
*arm720t
= target_to_arm720(target
);
315 struct reg
*dbg_stat
= &arm720t
->arm7_9_common
316 .eice_cache
->reg_list
[EICE_DBG_STAT
];
317 struct arm
*armv4_5
= &arm720t
->arm7_9_common
320 if ((retval
= target_halt(target
)) != ERROR_OK
)
325 long long then
= timeval_ms();
327 while (!(timeout
= ((timeval_ms()-then
) > 1000)))
329 if (buf_get_u32(dbg_stat
->value
, EICE_DBG_STATUS_DBGACK
, 1) == 0)
331 embeddedice_read_reg(dbg_stat
);
332 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
340 if (debug_level
>= 3)
350 LOG_ERROR("Failed to halt CPU after 1 sec");
351 return ERROR_TARGET_TIMEOUT
;
354 target
->state
= TARGET_HALTED
;
356 /* SVC, ARM state, IRQ and FIQ disabled */
359 cpsr
= buf_get_u32(armv4_5
->cpsr
->value
, 0, 32);
362 arm_set_cpsr(armv4_5
, cpsr
);
363 armv4_5
->cpsr
->dirty
= 1;
365 /* start fetching from 0x0 */
366 buf_set_u32(armv4_5
->pc
->value
, 0, 32, 0x0);
367 armv4_5
->pc
->dirty
= 1;
368 armv4_5
->pc
->valid
= 1;
370 arm720t_disable_mmu_caches(target
, 1, 1, 1);
371 arm720t
->armv4_5_mmu
.mmu_enabled
= 0;
372 arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 0;
373 arm720t
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
375 if ((retval
= target_call_event_callbacks(target
, TARGET_EVENT_HALTED
)) != ERROR_OK
)
383 static int arm720t_init_target(struct command_context
*cmd_ctx
, struct target
*target
)
385 return arm7tdmi_init_target(cmd_ctx
, target
);
388 /* FIXME remove forward decls */
389 static int arm720t_mrc(struct target
*target
, int cpnum
,
390 uint32_t op1
, uint32_t op2
,
391 uint32_t CRn
, uint32_t CRm
,
393 static int arm720t_mcr(struct target
*target
, int cpnum
,
394 uint32_t op1
, uint32_t op2
,
395 uint32_t CRn
, uint32_t CRm
,
398 static int arm720t_init_arch_info(struct target
*target
,
399 struct arm720t_common
*arm720t
, struct jtag_tap
*tap
)
401 struct arm7_9_common
*arm7_9
= &arm720t
->arm7_9_common
;
403 arm7_9
->armv4_5_common
.mrc
= arm720t_mrc
;
404 arm7_9
->armv4_5_common
.mcr
= arm720t_mcr
;
406 arm7tdmi_init_arch_info(target
, arm7_9
, tap
);
408 arm720t
->common_magic
= ARM720T_COMMON_MAGIC
;
410 arm7_9
->post_debug_entry
= arm720t_post_debug_entry
;
411 arm7_9
->pre_restore_context
= arm720t_pre_restore_context
;
413 arm720t
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
414 arm720t
->armv4_5_mmu
.get_ttb
= arm720t_get_ttb
;
415 arm720t
->armv4_5_mmu
.read_memory
= arm7_9_read_memory
;
416 arm720t
->armv4_5_mmu
.write_memory
= arm7_9_write_memory
;
417 arm720t
->armv4_5_mmu
.disable_mmu_caches
= arm720t_disable_mmu_caches
;
418 arm720t
->armv4_5_mmu
.enable_mmu_caches
= arm720t_enable_mmu_caches
;
419 arm720t
->armv4_5_mmu
.has_tiny_pages
= 0;
420 arm720t
->armv4_5_mmu
.mmu_enabled
= 0;
425 static int arm720t_target_create(struct target
*target
, Jim_Interp
*interp
)
427 struct arm720t_common
*arm720t
= calloc(1, sizeof(*arm720t
));
429 arm720t
->arm7_9_common
.armv4_5_common
.is_armv4
= true;
430 return arm720t_init_arch_info(target
, arm720t
, target
->tap
);
433 COMMAND_HANDLER(arm720t_handle_cp15_command
)
436 struct target
*target
= get_current_target(CMD_CTX
);
437 struct arm720t_common
*arm720t
= target_to_arm720(target
);
438 struct arm_jtag
*jtag_info
;
440 retval
= arm720t_verify_pointer(CMD_CTX
, arm720t
);
441 if (retval
!= ERROR_OK
)
444 jtag_info
= &arm720t
->arm7_9_common
.jtag_info
;
446 if (target
->state
!= TARGET_HALTED
)
448 command_print(CMD_CTX
, "target must be stopped for \"%s\" command", CMD_NAME
);
452 /* one or more argument, access a single register (write if second argument is given */
456 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], opcode
);
461 if ((retval
= arm720t_read_cp15(target
, opcode
, &value
)) != ERROR_OK
)
463 command_print(CMD_CTX
, "couldn't access cp15 with opcode 0x%8.8" PRIx32
"", opcode
);
467 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
472 command_print(CMD_CTX
, "0x%8.8" PRIx32
": 0x%8.8" PRIx32
"", opcode
, value
);
474 else if (CMD_ARGC
== 2)
477 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], value
);
479 if ((retval
= arm720t_write_cp15(target
, opcode
, value
)) != ERROR_OK
)
481 command_print(CMD_CTX
, "couldn't access cp15 with opcode 0x%8.8" PRIx32
"", opcode
);
484 command_print(CMD_CTX
, "0x%8.8" PRIx32
": 0x%8.8" PRIx32
"", opcode
, value
);
491 static int arm720t_mrc(struct target
*target
, int cpnum
,
492 uint32_t op1
, uint32_t op2
,
493 uint32_t CRn
, uint32_t CRm
,
498 LOG_ERROR("Only cp15 is supported");
503 return arm720t_read_cp15(target
,
504 ARMV4_5_MRC(cpnum
, op1
, 0, CRn
, CRm
, op2
),
509 static int arm720t_mcr(struct target
*target
, int cpnum
,
510 uint32_t op1
, uint32_t op2
,
511 uint32_t CRn
, uint32_t CRm
,
516 LOG_ERROR("Only cp15 is supported");
520 /* write "from" r0 */
521 return arm720t_write_cp15(target
,
522 ARMV4_5_MCR(cpnum
, op1
, 0, CRn
, CRm
, op2
),
526 static const struct command_registration arm720t_exec_command_handlers
[] = {
529 .handler
= arm720t_handle_cp15_command
,
530 .mode
= COMMAND_EXEC
,
531 /* prefer using less error-prone "arm mcr" or "arm mrc" */
532 .help
= "display/modify cp15 register using ARM opcode"
534 .usage
= "instruction [value]",
536 COMMAND_REGISTRATION_DONE
539 static const struct command_registration arm720t_command_handlers
[] = {
541 .chain
= arm7_9_command_handlers
,
546 .help
= "arm720t command group",
547 .chain
= arm720t_exec_command_handlers
,
549 COMMAND_REGISTRATION_DONE
552 /** Holds methods for ARM720 targets. */
553 struct target_type arm720t_target
=
558 .arch_state
= arm720t_arch_state
,
561 .resume
= arm7_9_resume
,
564 .assert_reset
= arm7_9_assert_reset
,
565 .deassert_reset
= arm7_9_deassert_reset
,
566 .soft_reset_halt
= arm720t_soft_reset_halt
,
568 .get_gdb_reg_list
= arm_get_gdb_reg_list
,
570 .read_memory
= arm720t_read_memory
,
571 .write_memory
= arm7_9_write_memory
,
572 .read_phys_memory
= arm720t_read_phys_memory
,
573 .write_phys_memory
= arm720t_write_phys_memory
,
575 .virt2phys
= arm720_virt2phys
,
577 .bulk_write_memory
= arm7_9_bulk_write_memory
,
579 .checksum_memory
= arm_checksum_memory
,
580 .blank_check_memory
= arm_blank_check_memory
,
582 .run_algorithm
= armv4_5_run_algorithm
,
584 .add_breakpoint
= arm7_9_add_breakpoint
,
585 .remove_breakpoint
= arm7_9_remove_breakpoint
,
586 .add_watchpoint
= arm7_9_add_watchpoint
,
587 .remove_watchpoint
= arm7_9_remove_watchpoint
,
589 .commands
= arm720t_command_handlers
,
590 .target_create
= arm720t_target_create
,
591 .init_target
= arm720t_init_target
,
592 .examine
= arm7_9_examine
,
593 .check_reset
= arm7_9_check_reset
,
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)