1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2005 by Dominic Rath *
5 * Dominic.Rath@gmx.de *
7 * Copyright (C) 2009 by Øyvind Harboe *
8 * oyvind.harboe@zylin.com *
9 ***************************************************************************/
16 #include <helper/time_support.h>
17 #include "target_type.h"
19 #include "arm_opcodes.h"
23 * ARM720 is an ARM7TDMI-S with MMU and ETM7. For information, see
24 * ARM DDI 0229C especially Chapter 9 about debug support.
28 #define _DEBUG_INSTRUCTION_EXECUTION_
31 static int arm720t_scan_cp15(struct target
*target
,
32 uint32_t out
, uint32_t *in
, int instruction
, int clock_arg
)
35 struct arm720t_common
*arm720t
= target_to_arm720(target
);
36 struct arm_jtag
*jtag_info
;
37 struct scan_field fields
[2];
39 uint8_t instruction_buf
= instruction
;
41 jtag_info
= &arm720t
->arm7_9_common
.jtag_info
;
43 buf_set_u32(out_buf
, 0, 32, flip_u32(out
, 32));
45 retval
= arm_jtag_scann(jtag_info
, 0xf, TAP_DRPAUSE
);
46 if (retval
!= ERROR_OK
)
48 retval
= arm_jtag_set_instr(jtag_info
->tap
, jtag_info
->intest_instr
, NULL
, TAP_DRPAUSE
);
49 if (retval
!= ERROR_OK
)
52 fields
[0].num_bits
= 1;
53 fields
[0].out_value
= &instruction_buf
;
54 fields
[0].in_value
= NULL
;
56 fields
[1].num_bits
= 32;
57 fields
[1].out_value
= out_buf
;
58 fields
[1].in_value
= NULL
;
61 fields
[1].in_value
= (uint8_t *)in
;
62 jtag_add_dr_scan(jtag_info
->tap
, 2, fields
, TAP_DRPAUSE
);
63 jtag_add_callback(arm7flip32
, (jtag_callback_data_t
)in
);
65 jtag_add_dr_scan(jtag_info
->tap
, 2, fields
, TAP_DRPAUSE
);
68 jtag_add_runtest(0, TAP_DRPAUSE
);
70 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
71 retval
= jtag_execute_queue();
72 if (retval
!= ERROR_OK
)
76 LOG_DEBUG("out: %8.8x, in: %8.8x, instruction: %i, clock: %i", out
, *in
, instruction
, clock
);
78 LOG_DEBUG("out: %8.8x, instruction: %i, clock: %i", out
, instruction
, clock_arg
);
80 LOG_DEBUG("out: %8.8" PRIx32
", instruction: %i, clock: %i", out
, instruction
, clock_arg
);
86 static int arm720t_read_cp15(struct target
*target
, uint32_t opcode
, uint32_t *value
)
88 /* fetch CP15 opcode */
89 arm720t_scan_cp15(target
, opcode
, NULL
, 1, 1);
91 arm720t_scan_cp15(target
, ARMV4_5_NOP
, NULL
, 1, 1);
92 /* "EXECUTE" stage (1) */
93 arm720t_scan_cp15(target
, ARMV4_5_NOP
, NULL
, 1, 0);
94 arm720t_scan_cp15(target
, 0x0, NULL
, 0, 1);
95 /* "EXECUTE" stage (2) */
96 arm720t_scan_cp15(target
, 0x0, NULL
, 0, 1);
97 /* "EXECUTE" stage (3), CDATA is read */
98 arm720t_scan_cp15(target
, ARMV4_5_NOP
, value
, 1, 1);
103 static int arm720t_write_cp15(struct target
*target
, uint32_t opcode
, uint32_t value
)
105 /* fetch CP15 opcode */
106 arm720t_scan_cp15(target
, opcode
, NULL
, 1, 1);
108 arm720t_scan_cp15(target
, ARMV4_5_NOP
, NULL
, 1, 1);
109 /* "EXECUTE" stage (1) */
110 arm720t_scan_cp15(target
, ARMV4_5_NOP
, NULL
, 1, 0);
111 arm720t_scan_cp15(target
, 0x0, NULL
, 0, 1);
112 /* "EXECUTE" stage (2) */
113 arm720t_scan_cp15(target
, value
, NULL
, 0, 1);
114 arm720t_scan_cp15(target
, ARMV4_5_NOP
, NULL
, 1, 1);
119 static int arm720t_get_ttb(struct target
*target
, uint32_t *result
)
125 retval
= arm720t_read_cp15(target
, 0xee120f10, &ttb
);
126 if (retval
!= ERROR_OK
)
128 retval
= jtag_execute_queue();
129 if (retval
!= ERROR_OK
)
139 static int arm720t_disable_mmu_caches(struct target
*target
,
140 int mmu
, int d_u_cache
, int i_cache
)
142 uint32_t cp15_control
;
145 /* read cp15 control register */
146 retval
= arm720t_read_cp15(target
, 0xee110f10, &cp15_control
);
147 if (retval
!= ERROR_OK
)
149 retval
= jtag_execute_queue();
150 if (retval
!= ERROR_OK
)
154 cp15_control
&= ~0x1U
;
156 if (d_u_cache
|| i_cache
)
157 cp15_control
&= ~0x4U
;
159 retval
= arm720t_write_cp15(target
, 0xee010f10, cp15_control
);
163 static int arm720t_enable_mmu_caches(struct target
*target
,
164 int mmu
, int d_u_cache
, int i_cache
)
166 uint32_t cp15_control
;
169 /* read cp15 control register */
170 retval
= arm720t_read_cp15(target
, 0xee110f10, &cp15_control
);
171 if (retval
!= ERROR_OK
)
173 retval
= jtag_execute_queue();
174 if (retval
!= ERROR_OK
)
178 cp15_control
|= 0x1U
;
180 if (d_u_cache
|| i_cache
)
181 cp15_control
|= 0x4U
;
183 retval
= arm720t_write_cp15(target
, 0xee010f10, cp15_control
);
187 static int arm720t_post_debug_entry(struct target
*target
)
189 struct arm720t_common
*arm720t
= target_to_arm720(target
);
192 /* examine cp15 control reg */
193 retval
= arm720t_read_cp15(target
, 0xee110f10, &arm720t
->cp15_control_reg
);
194 if (retval
!= ERROR_OK
)
196 retval
= jtag_execute_queue();
197 if (retval
!= ERROR_OK
)
199 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
"", arm720t
->cp15_control_reg
);
201 arm720t
->armv4_5_mmu
.mmu_enabled
= (arm720t
->cp15_control_reg
& 0x1U
) ? 1 : 0;
202 arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= (arm720t
->cp15_control_reg
& 0x4U
) ? 1 : 0;
203 arm720t
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
205 /* save i/d fault status and address register */
206 retval
= arm720t_read_cp15(target
, 0xee150f10, &arm720t
->fsr_reg
);
207 if (retval
!= ERROR_OK
)
209 retval
= arm720t_read_cp15(target
, 0xee160f10, &arm720t
->far_reg
);
210 if (retval
!= ERROR_OK
)
212 retval
= jtag_execute_queue();
216 static void arm720t_pre_restore_context(struct target
*target
)
218 struct arm720t_common
*arm720t
= target_to_arm720(target
);
220 /* restore i/d fault status and address register */
221 arm720t_write_cp15(target
, 0xee050f10, arm720t
->fsr_reg
);
222 arm720t_write_cp15(target
, 0xee060f10, arm720t
->far_reg
);
225 static int arm720t_arch_state(struct target
*target
)
227 struct arm720t_common
*arm720t
= target_to_arm720(target
);
229 static const char *state
[] = {
230 "disabled", "enabled"
233 arm_arch_state(target
);
234 LOG_USER("MMU: %s, Cache: %s",
235 state
[arm720t
->armv4_5_mmu
.mmu_enabled
],
236 state
[arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
]);
241 static int arm720_mmu(struct target
*target
, int *enabled
)
243 if (target
->state
!= TARGET_HALTED
) {
244 LOG_ERROR("%s: target not halted", __func__
);
245 return ERROR_TARGET_INVALID
;
248 *enabled
= target_to_arm720(target
)->armv4_5_mmu
.mmu_enabled
;
252 static int arm720_virt2phys(struct target
*target
,
253 target_addr_t
virtual, target_addr_t
*physical
)
256 struct arm720t_common
*arm720t
= target_to_arm720(target
);
259 int retval
= armv4_5_mmu_translate_va(target
,
260 &arm720t
->armv4_5_mmu
, virtual, &cb
, &ret
);
261 if (retval
!= ERROR_OK
)
267 static int arm720t_read_memory(struct target
*target
,
268 target_addr_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
)
271 struct arm720t_common
*arm720t
= target_to_arm720(target
);
273 /* disable cache, but leave MMU enabled */
274 if (arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
) {
275 retval
= arm720t_disable_mmu_caches(target
, 0, 1, 0);
276 if (retval
!= ERROR_OK
)
279 retval
= arm7_9_read_memory(target
, address
, size
, count
, buffer
);
281 if (arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
) {
282 retval
= arm720t_enable_mmu_caches(target
, 0, 1, 0);
283 if (retval
!= ERROR_OK
)
290 static int arm720t_read_phys_memory(struct target
*target
,
291 target_addr_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
)
293 struct arm720t_common
*arm720t
= target_to_arm720(target
);
295 return armv4_5_mmu_read_physical(target
, &arm720t
->armv4_5_mmu
, address
, size
, count
, buffer
);
298 static int arm720t_write_phys_memory(struct target
*target
,
299 target_addr_t address
, uint32_t size
, uint32_t count
, const uint8_t *buffer
)
301 struct arm720t_common
*arm720t
= target_to_arm720(target
);
303 return armv4_5_mmu_write_physical(target
, &arm720t
->armv4_5_mmu
, address
, size
, count
, buffer
);
306 static int arm720t_soft_reset_halt(struct target
*target
)
308 int retval
= ERROR_OK
;
309 struct arm720t_common
*arm720t
= target_to_arm720(target
);
310 struct reg
*dbg_stat
= &arm720t
->arm7_9_common
311 .eice_cache
->reg_list
[EICE_DBG_STAT
];
312 struct arm
*arm
= &arm720t
->arm7_9_common
.arm
;
314 retval
= target_halt(target
);
315 if (retval
!= ERROR_OK
)
318 int64_t then
= timeval_ms();
320 while (!(timeout
= ((timeval_ms()-then
) > 1000))) {
321 if (buf_get_u32(dbg_stat
->value
, EICE_DBG_STATUS_DBGACK
, 1) == 0) {
322 embeddedice_read_reg(dbg_stat
);
323 retval
= jtag_execute_queue();
324 if (retval
!= ERROR_OK
)
328 if (debug_level
>= 3)
334 LOG_ERROR("Failed to halt CPU after 1 sec");
335 return ERROR_TARGET_TIMEOUT
;
338 target
->state
= TARGET_HALTED
;
340 /* SVC, ARM state, IRQ and FIQ disabled */
343 cpsr
= buf_get_u32(arm
->cpsr
->value
, 0, 32);
346 arm_set_cpsr(arm
, cpsr
);
347 arm
->cpsr
->dirty
= true;
349 /* start fetching from 0x0 */
350 buf_set_u32(arm
->pc
->value
, 0, 32, 0x0);
351 arm
->pc
->dirty
= true;
352 arm
->pc
->valid
= true;
354 retval
= arm720t_disable_mmu_caches(target
, 1, 1, 1);
355 if (retval
!= ERROR_OK
)
357 arm720t
->armv4_5_mmu
.mmu_enabled
= 0;
358 arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 0;
359 arm720t
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
361 retval
= target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
362 if (retval
!= ERROR_OK
)
368 static int arm720t_init_target(struct command_context
*cmd_ctx
, struct target
*target
)
370 return arm7tdmi_init_target(cmd_ctx
, target
);
373 static void arm720t_deinit_target(struct target
*target
)
375 arm7tdmi_deinit_target(target
);
378 /* FIXME remove forward decls */
379 static int arm720t_mrc(struct target
*target
, int cpnum
,
380 uint32_t op1
, uint32_t op2
,
381 uint32_t crn
, uint32_t crm
,
383 static int arm720t_mcr(struct target
*target
, int cpnum
,
384 uint32_t op1
, uint32_t op2
,
385 uint32_t crn
, uint32_t crm
,
388 static int arm720t_init_arch_info(struct target
*target
,
389 struct arm720t_common
*arm720t
, struct jtag_tap
*tap
)
391 struct arm7_9_common
*arm7_9
= &arm720t
->arm7_9_common
;
393 arm7_9
->arm
.mrc
= arm720t_mrc
;
394 arm7_9
->arm
.mcr
= arm720t_mcr
;
396 arm7tdmi_init_arch_info(target
, arm7_9
, tap
);
398 arm720t
->common_magic
= ARM720T_COMMON_MAGIC
;
400 arm7_9
->post_debug_entry
= arm720t_post_debug_entry
;
401 arm7_9
->pre_restore_context
= arm720t_pre_restore_context
;
403 arm720t
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
404 arm720t
->armv4_5_mmu
.get_ttb
= arm720t_get_ttb
;
405 arm720t
->armv4_5_mmu
.read_memory
= arm7_9_read_memory
;
406 arm720t
->armv4_5_mmu
.write_memory
= arm7_9_write_memory
;
407 arm720t
->armv4_5_mmu
.disable_mmu_caches
= arm720t_disable_mmu_caches
;
408 arm720t
->armv4_5_mmu
.enable_mmu_caches
= arm720t_enable_mmu_caches
;
409 arm720t
->armv4_5_mmu
.has_tiny_pages
= 0;
410 arm720t
->armv4_5_mmu
.mmu_enabled
= 0;
415 static int arm720t_target_create(struct target
*target
, Jim_Interp
*interp
)
417 struct arm720t_common
*arm720t
= calloc(1, sizeof(*arm720t
));
419 arm720t
->arm7_9_common
.arm
.arch
= ARM_ARCH_V4
;
420 return arm720t_init_arch_info(target
, arm720t
, target
->tap
);
423 static int arm720t_mrc(struct target
*target
, int cpnum
,
424 uint32_t op1
, uint32_t op2
,
425 uint32_t crn
, uint32_t crm
,
429 LOG_ERROR("Only cp15 is supported");
434 return arm720t_read_cp15(target
,
435 ARMV4_5_MRC(cpnum
, op1
, 0, crn
, crm
, op2
),
440 static int arm720t_mcr(struct target
*target
, int cpnum
,
441 uint32_t op1
, uint32_t op2
,
442 uint32_t crn
, uint32_t crm
,
446 LOG_ERROR("Only cp15 is supported");
450 /* write "from" r0 */
451 return arm720t_write_cp15(target
,
452 ARMV4_5_MCR(cpnum
, op1
, 0, crn
, crm
, op2
),
456 static const struct command_registration arm720t_command_handlers
[] = {
458 .chain
= arm7_9_command_handlers
,
460 COMMAND_REGISTRATION_DONE
463 /** Holds methods for ARM720 targets. */
464 struct target_type arm720t_target
= {
468 .arch_state
= arm720t_arch_state
,
471 .resume
= arm7_9_resume
,
474 .assert_reset
= arm7_9_assert_reset
,
475 .deassert_reset
= arm7_9_deassert_reset
,
476 .soft_reset_halt
= arm720t_soft_reset_halt
,
478 .get_gdb_arch
= arm_get_gdb_arch
,
479 .get_gdb_reg_list
= arm_get_gdb_reg_list
,
481 .read_memory
= arm720t_read_memory
,
482 .write_memory
= arm7_9_write_memory_opt
,
483 .read_phys_memory
= arm720t_read_phys_memory
,
484 .write_phys_memory
= arm720t_write_phys_memory
,
486 .virt2phys
= arm720_virt2phys
,
488 .checksum_memory
= arm_checksum_memory
,
489 .blank_check_memory
= arm_blank_check_memory
,
491 .run_algorithm
= armv4_5_run_algorithm
,
493 .add_breakpoint
= arm7_9_add_breakpoint
,
494 .remove_breakpoint
= arm7_9_remove_breakpoint
,
495 .add_watchpoint
= arm7_9_add_watchpoint
,
496 .remove_watchpoint
= arm7_9_remove_watchpoint
,
498 .commands
= arm720t_command_handlers
,
499 .target_create
= arm720t_target_create
,
500 .init_target
= arm720t_init_target
,
501 .deinit_target
= arm720t_deinit_target
,
502 .examine
= arm7_9_examine
,
503 .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)