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 "time_support.h"
29 #include "target_type.h"
33 * ARM720 is an ARM7TDMI-S with MMU and ETM7. For information, see
34 * ARM DDI 0229C especially Chapter 9 about debug support.
38 #define _DEBUG_INSTRUCTION_EXECUTION_
41 static int arm720t_scan_cp15(target_t
*target
,
42 uint32_t out
, uint32_t *in
, int instruction
, int clock
)
44 int retval
= ERROR_OK
;
45 armv4_5_common_t
*armv4_5
= target
->arch_info
;
46 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
47 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
48 scan_field_t fields
[2];
50 uint8_t instruction_buf
= instruction
;
52 buf_set_u32(out_buf
, 0, 32, flip_u32(out
, 32));
54 jtag_set_end_state(TAP_DRPAUSE
);
55 if ((retval
= arm_jtag_scann(jtag_info
, 0xf)) != ERROR_OK
)
59 if ((retval
= arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
)) != ERROR_OK
)
64 fields
[0].tap
= jtag_info
->tap
;
65 fields
[0].num_bits
= 1;
66 fields
[0].out_value
= &instruction_buf
;
67 fields
[0].in_value
= NULL
;
69 fields
[1].tap
= jtag_info
->tap
;
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(2, fields
, jtag_get_end_state());
78 jtag_add_callback(arm7flip32
, (jtag_callback_data_t
)in
);
81 jtag_add_dr_scan(2, fields
, jtag_get_end_state());
85 jtag_add_runtest(0, jtag_get_end_state());
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
);
98 LOG_DEBUG("out: %8.8" PRIx32
", instruction: %i, clock: %i", out
, instruction
, clock
);
104 static int arm720t_read_cp15(target_t
*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(target_t
*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 uint32_t arm720t_get_ttb(target_t
*target
)
141 arm720t_read_cp15(target
, 0xee120f10, &ttb
);
142 jtag_execute_queue();
149 static void arm720t_disable_mmu_caches(target_t
*target
,
150 int mmu
, int d_u_cache
, int i_cache
)
152 uint32_t cp15_control
;
154 /* read cp15 control register */
155 arm720t_read_cp15(target
, 0xee110f10, &cp15_control
);
156 jtag_execute_queue();
159 cp15_control
&= ~0x1U
;
161 if (d_u_cache
|| i_cache
)
162 cp15_control
&= ~0x4U
;
164 arm720t_write_cp15(target
, 0xee010f10, cp15_control
);
167 static void arm720t_enable_mmu_caches(target_t
*target
,
168 int mmu
, int d_u_cache
, int i_cache
)
170 uint32_t cp15_control
;
172 /* read cp15 control register */
173 arm720t_read_cp15(target
, 0xee110f10, &cp15_control
);
174 jtag_execute_queue();
177 cp15_control
|= 0x1U
;
179 if (d_u_cache
|| i_cache
)
180 cp15_control
|= 0x4U
;
182 arm720t_write_cp15(target
, 0xee010f10, cp15_control
);
185 static void arm720t_post_debug_entry(target_t
*target
)
187 armv4_5_common_t
*armv4_5
= target
->arch_info
;
188 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
189 arm7tdmi_common_t
*arm7tdmi
= arm7_9
->arch_info
;
190 arm720t_common_t
*arm720t
= arm7tdmi
->arch_info
;
192 /* examine cp15 control reg */
193 arm720t_read_cp15(target
, 0xee110f10, &arm720t
->cp15_control_reg
);
194 jtag_execute_queue();
195 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
"", arm720t
->cp15_control_reg
);
197 arm720t
->armv4_5_mmu
.mmu_enabled
= (arm720t
->cp15_control_reg
& 0x1U
) ? 1 : 0;
198 arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= (arm720t
->cp15_control_reg
& 0x4U
) ? 1 : 0;
199 arm720t
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
201 /* save i/d fault status and address register */
202 arm720t_read_cp15(target
, 0xee150f10, &arm720t
->fsr_reg
);
203 arm720t_read_cp15(target
, 0xee160f10, &arm720t
->far_reg
);
204 jtag_execute_queue();
207 static void arm720t_pre_restore_context(target_t
*target
)
209 armv4_5_common_t
*armv4_5
= target
->arch_info
;
210 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
211 arm7tdmi_common_t
*arm7tdmi
= arm7_9
->arch_info
;
212 arm720t_common_t
*arm720t
= arm7tdmi
->arch_info
;
214 /* restore i/d fault status and address register */
215 arm720t_write_cp15(target
, 0xee050f10, arm720t
->fsr_reg
);
216 arm720t_write_cp15(target
, 0xee060f10, arm720t
->far_reg
);
219 static int arm720t_get_arch_pointers(target_t
*target
,
220 armv4_5_common_t
**armv4_5_p
, arm7_9_common_t
**arm7_9_p
,
221 arm7tdmi_common_t
**arm7tdmi_p
, arm720t_common_t
**arm720t_p
)
223 armv4_5_common_t
*armv4_5
= target
->arch_info
;
224 arm7_9_common_t
*arm7_9
;
225 arm7tdmi_common_t
*arm7tdmi
;
226 arm720t_common_t
*arm720t
;
228 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
233 arm7_9
= armv4_5
->arch_info
;
234 if (arm7_9
->common_magic
!= ARM7_9_COMMON_MAGIC
)
239 arm7tdmi
= arm7_9
->arch_info
;
240 if (arm7tdmi
->common_magic
!= ARM7TDMI_COMMON_MAGIC
)
245 arm720t
= arm7tdmi
->arch_info
;
246 if (arm720t
->common_magic
!= ARM720T_COMMON_MAGIC
)
251 *armv4_5_p
= armv4_5
;
253 *arm7tdmi_p
= arm7tdmi
;
254 *arm720t_p
= arm720t
;
259 static int arm720t_arch_state(struct target_s
*target
)
261 armv4_5_common_t
*armv4_5
= target
->arch_info
;
262 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
263 arm7tdmi_common_t
*arm7tdmi
= arm7_9
->arch_info
;
264 arm720t_common_t
*arm720t
= arm7tdmi
->arch_info
;
266 static const char *state
[] =
268 "disabled", "enabled"
271 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
272 "cpsr: 0x%8.8" PRIx32
" pc: 0x%8.8" PRIx32
"\n"
273 "MMU: %s, Cache: %s",
274 armv4_5_state_strings
[armv4_5
->core_state
],
275 Jim_Nvp_value2name_simple(nvp_target_debug_reason
, target
->debug_reason
)->name
,
276 armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)],
277 buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32),
278 buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32),
279 state
[arm720t
->armv4_5_mmu
.mmu_enabled
],
280 state
[arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
]);
285 static int arm720t_read_memory(struct target_s
*target
,
286 uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
)
289 armv4_5_common_t
*armv4_5
= target
->arch_info
;
290 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
291 arm7tdmi_common_t
*arm7tdmi
= arm7_9
->arch_info
;
292 arm720t_common_t
*arm720t
= arm7tdmi
->arch_info
;
294 /* disable cache, but leave MMU enabled */
295 if (arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
296 arm720t_disable_mmu_caches(target
, 0, 1, 0);
298 retval
= arm7_9_read_memory(target
, address
, size
, count
, buffer
);
300 if (arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
301 arm720t_enable_mmu_caches(target
, 0, 1, 0);
306 static int arm720t_read_phys_memory(struct target_s
*target
,
307 uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
)
309 armv4_5_common_t
*armv4_5
= target
->arch_info
;
310 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
311 arm7tdmi_common_t
*arm7tdmi
= arm7_9
->arch_info
;
312 arm720t_common_t
*arm720t
= arm7tdmi
->arch_info
;
314 return armv4_5_mmu_read_physical(target
, &arm720t
->armv4_5_mmu
, address
, size
, count
, buffer
);
317 static int arm720t_write_phys_memory(struct target_s
*target
,
318 uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
)
320 armv4_5_common_t
*armv4_5
= target
->arch_info
;
321 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
322 arm7tdmi_common_t
*arm7tdmi
= arm7_9
->arch_info
;
323 arm720t_common_t
*arm720t
= arm7tdmi
->arch_info
;
325 return armv4_5_mmu_write_physical(target
, &arm720t
->armv4_5_mmu
, address
, size
, count
, buffer
);
328 static int arm720t_soft_reset_halt(struct target_s
*target
)
330 int retval
= ERROR_OK
;
331 armv4_5_common_t
*armv4_5
= target
->arch_info
;
332 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
333 arm7tdmi_common_t
*arm7tdmi
= arm7_9
->arch_info
;
334 arm720t_common_t
*arm720t
= arm7tdmi
->arch_info
;
335 reg_t
*dbg_stat
= &arm7_9
->eice_cache
->reg_list
[EICE_DBG_STAT
];
337 if ((retval
= target_halt(target
)) != ERROR_OK
)
342 long long then
= timeval_ms();
344 while (!(timeout
= ((timeval_ms()-then
) > 1000)))
346 if (buf_get_u32(dbg_stat
->value
, EICE_DBG_STATUS_DBGACK
, 1) == 0)
348 embeddedice_read_reg(dbg_stat
);
349 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
357 if (debug_level
>= 3)
367 LOG_ERROR("Failed to halt CPU after 1 sec");
368 return ERROR_TARGET_TIMEOUT
;
371 target
->state
= TARGET_HALTED
;
373 /* SVC, ARM state, IRQ and FIQ disabled */
374 buf_set_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 8, 0xd3);
375 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].dirty
= 1;
376 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].valid
= 1;
378 /* start fetching from 0x0 */
379 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, 0x0);
380 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
381 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
383 armv4_5
->core_mode
= ARMV4_5_MODE_SVC
;
384 armv4_5
->core_state
= ARMV4_5_STATE_ARM
;
386 arm720t_disable_mmu_caches(target
, 1, 1, 1);
387 arm720t
->armv4_5_mmu
.mmu_enabled
= 0;
388 arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 0;
389 arm720t
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
391 if ((retval
= target_call_event_callbacks(target
, TARGET_EVENT_HALTED
)) != ERROR_OK
)
399 static int arm720t_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
401 return arm7tdmi_init_target(cmd_ctx
, target
);
404 static int arm720t_init_arch_info(target_t
*target
,
405 arm720t_common_t
*arm720t
, jtag_tap_t
*tap
)
407 arm7tdmi_common_t
*arm7tdmi
= &arm720t
->arm7tdmi_common
;
408 arm7_9_common_t
*arm7_9
= &arm7tdmi
->arm7_9_common
;
410 arm7tdmi_init_arch_info(target
, arm7tdmi
, tap
);
412 arm7tdmi
->arch_info
= arm720t
;
413 arm720t
->common_magic
= ARM720T_COMMON_MAGIC
;
415 arm7_9
->post_debug_entry
= arm720t_post_debug_entry
;
416 arm7_9
->pre_restore_context
= arm720t_pre_restore_context
;
418 arm720t
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
419 arm720t
->armv4_5_mmu
.get_ttb
= arm720t_get_ttb
;
420 arm720t
->armv4_5_mmu
.read_memory
= arm7_9_read_memory
;
421 arm720t
->armv4_5_mmu
.write_memory
= arm7_9_write_memory
;
422 arm720t
->armv4_5_mmu
.disable_mmu_caches
= arm720t_disable_mmu_caches
;
423 arm720t
->armv4_5_mmu
.enable_mmu_caches
= arm720t_enable_mmu_caches
;
424 arm720t
->armv4_5_mmu
.has_tiny_pages
= 0;
425 arm720t
->armv4_5_mmu
.mmu_enabled
= 0;
430 static int arm720t_target_create(struct target_s
*target
, Jim_Interp
*interp
)
432 arm720t_common_t
*arm720t
= calloc(1,sizeof(arm720t_common_t
));
434 return arm720t_init_arch_info(target
, arm720t
, target
->tap
);
437 static int arm720t_handle_cp15_command(struct command_context_s
*cmd_ctx
,
438 char *cmd
, char **args
, int argc
)
441 target_t
*target
= get_current_target(cmd_ctx
);
442 armv4_5_common_t
*armv4_5
;
443 arm7_9_common_t
*arm7_9
;
444 arm7tdmi_common_t
*arm7tdmi
;
445 arm720t_common_t
*arm720t
;
446 arm_jtag_t
*jtag_info
;
448 if (arm720t_get_arch_pointers(target
, &armv4_5
, &arm7_9
, &arm7tdmi
, &arm720t
) != ERROR_OK
)
450 command_print(cmd_ctx
, "current target isn't an ARM720t target");
454 jtag_info
= &arm7_9
->jtag_info
;
456 if (target
->state
!= TARGET_HALTED
)
458 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
462 /* one or more argument, access a single register (write if second argument is given */
466 COMMAND_PARSE_NUMBER(u32
, args
[0], opcode
);
471 if ((retval
= arm720t_read_cp15(target
, opcode
, &value
)) != ERROR_OK
)
473 command_print(cmd_ctx
, "couldn't access cp15 with opcode 0x%8.8" PRIx32
"", opcode
);
477 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
482 command_print(cmd_ctx
, "0x%8.8" PRIx32
": 0x%8.8" PRIx32
"", opcode
, value
);
487 COMMAND_PARSE_NUMBER(u32
, args
[1], value
);
489 if ((retval
= arm720t_write_cp15(target
, opcode
, value
)) != ERROR_OK
)
491 command_print(cmd_ctx
, "couldn't access cp15 with opcode 0x%8.8" PRIx32
"", opcode
);
494 command_print(cmd_ctx
, "0x%8.8" PRIx32
": 0x%8.8" PRIx32
"", opcode
, value
);
501 static int arm720t_mrc(target_t
*target
, int cpnum
, uint32_t op1
, uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
505 LOG_ERROR("Only cp15 is supported");
509 return arm720t_read_cp15(target
, mrc_opcode(cpnum
, op1
, op2
, CRn
, CRm
), value
);
513 static int arm720t_mcr(target_t
*target
, int cpnum
, uint32_t op1
, uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t value
)
517 LOG_ERROR("Only cp15 is supported");
521 return arm720t_write_cp15(target
, mrc_opcode(cpnum
, op1
, op2
, CRn
, CRm
), value
);
524 static int arm720t_register_commands(struct command_context_s
*cmd_ctx
)
527 command_t
*arm720t_cmd
;
530 retval
= arm7_9_register_commands(cmd_ctx
);
532 arm720t_cmd
= register_command(cmd_ctx
, NULL
, "arm720t",
534 "arm720t specific commands");
536 register_command(cmd_ctx
, arm720t_cmd
, "cp15",
537 arm720t_handle_cp15_command
, COMMAND_EXEC
,
538 "display/modify cp15 register <opcode> [value]");
543 /** Holds methods for ARM720 targets. */
544 target_type_t arm720t_target
=
549 .arch_state
= arm720t_arch_state
,
552 .resume
= arm7_9_resume
,
555 .assert_reset
= arm7_9_assert_reset
,
556 .deassert_reset
= arm7_9_deassert_reset
,
557 .soft_reset_halt
= arm720t_soft_reset_halt
,
559 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
561 .read_memory
= arm720t_read_memory
,
562 .write_memory
= arm7_9_write_memory
,
563 .read_phys_memory
= arm720t_read_phys_memory
,
564 .write_phys_memory
= arm720t_write_phys_memory
,
565 .bulk_write_memory
= arm7_9_bulk_write_memory
,
566 .checksum_memory
= arm7_9_checksum_memory
,
567 .blank_check_memory
= arm7_9_blank_check_memory
,
569 .run_algorithm
= armv4_5_run_algorithm
,
571 .add_breakpoint
= arm7_9_add_breakpoint
,
572 .remove_breakpoint
= arm7_9_remove_breakpoint
,
573 .add_watchpoint
= arm7_9_add_watchpoint
,
574 .remove_watchpoint
= arm7_9_remove_watchpoint
,
576 .register_commands
= arm720t_register_commands
,
577 .target_create
= arm720t_target_create
,
578 .init_target
= arm720t_init_target
,
579 .examine
= arm7tdmi_examine
,
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)