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) 2008 by Spencer Oliver *
8 * spen@spen-soft.co.uk *
9 ***************************************************************************/
16 #include "target_type.h"
17 #include "arm_opcodes.h"
20 #define _DEBUG_INSTRUCTION_EXECUTION_
23 int arm966e_init_arch_info(struct target
*target
, struct arm966e_common
*arm966e
, struct jtag_tap
*tap
)
25 struct arm7_9_common
*arm7_9
= &arm966e
->arm7_9_common
;
27 /* initialize arm7/arm9 specific info (including armv4_5) */
28 arm9tdmi_init_arch_info(target
, arm7_9
, tap
);
30 arm966e
->common_magic
= ARM966E_COMMON_MAGIC
;
32 /* The ARM966E-S implements the ARMv5TE architecture which
33 * has the BKPT instruction, so we don't have to use a watchpoint comparator
35 arm7_9
->arm_bkpt
= ARMV5_BKPT(0x0);
36 arm7_9
->thumb_bkpt
= ARMV5_T_BKPT(0x0) & 0xffff;
41 static int arm966e_target_create(struct target
*target
, Jim_Interp
*interp
)
43 struct arm966e_common
*arm966e
= calloc(1, sizeof(struct arm966e_common
));
45 return arm966e_init_arch_info(target
, arm966e
, target
->tap
);
48 static void arm966e_deinit_target(struct target
*target
)
50 struct arm
*arm
= target_to_arm(target
);
51 struct arm966e_common
*arm966e
= target_to_arm966(target
);
53 arm7_9_deinit(target
);
54 arm_free_reg_cache(arm
);
58 static int arm966e_verify_pointer(struct command_invocation
*cmd
,
59 struct arm966e_common
*arm966e
)
61 if (arm966e
->common_magic
!= ARM966E_COMMON_MAGIC
) {
62 command_print(cmd
, "target is not an ARM966");
63 return ERROR_TARGET_INVALID
;
69 * REVISIT: The "read_cp15" and "write_cp15" commands could hook up
70 * to eventual mrc() and mcr() routines ... the reg_addr values being
71 * constructed (for CP15 only) from Opcode_1, Opcode_2, and CRn values.
72 * See section 7.3 of the ARM966E-S TRM.
75 static int arm966e_read_cp15(struct target
*target
, int reg_addr
, uint32_t *value
)
77 int retval
= ERROR_OK
;
78 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
79 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
80 struct scan_field fields
[3];
81 uint8_t reg_addr_buf
= reg_addr
& 0x3f;
84 retval
= arm_jtag_scann(jtag_info
, 0xf, TAP_IDLE
);
85 if (retval
!= ERROR_OK
)
87 retval
= arm_jtag_set_instr(jtag_info
->tap
, jtag_info
->intest_instr
, NULL
, TAP_IDLE
);
88 if (retval
!= ERROR_OK
)
91 fields
[0].num_bits
= 32;
92 /* REVISIT: table 7-2 shows that bits 31-31 need to be
93 * specified for accessing BIST registers ...
95 fields
[0].out_value
= NULL
;
96 fields
[0].in_value
= NULL
;
98 fields
[1].num_bits
= 6;
99 fields
[1].out_value
= ®_addr_buf
;
100 fields
[1].in_value
= NULL
;
102 fields
[2].num_bits
= 1;
103 fields
[2].out_value
= &nr_w_buf
;
104 fields
[2].in_value
= NULL
;
106 jtag_add_dr_scan(jtag_info
->tap
, 3, fields
, TAP_IDLE
);
108 fields
[1].in_value
= (uint8_t *)value
;
110 jtag_add_dr_scan(jtag_info
->tap
, 3, fields
, TAP_IDLE
);
112 jtag_add_callback(arm_le_to_h_u32
, (jtag_callback_data_t
)value
);
115 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
116 retval
= jtag_execute_queue();
117 if (retval
!= ERROR_OK
)
119 LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr
, *value
);
125 /* EXPORTED to str9x (flash) */
126 int arm966e_write_cp15(struct target
*target
, int reg_addr
, uint32_t value
)
128 int retval
= ERROR_OK
;
129 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
130 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
131 struct scan_field fields
[3];
132 uint8_t reg_addr_buf
= reg_addr
& 0x3f;
133 uint8_t nr_w_buf
= 1;
134 uint8_t value_buf
[4];
136 buf_set_u32(value_buf
, 0, 32, value
);
138 retval
= arm_jtag_scann(jtag_info
, 0xf, TAP_IDLE
);
139 if (retval
!= ERROR_OK
)
141 retval
= arm_jtag_set_instr(jtag_info
->tap
, jtag_info
->intest_instr
, NULL
, TAP_IDLE
);
142 if (retval
!= ERROR_OK
)
145 fields
[0].num_bits
= 32;
146 fields
[0].out_value
= value_buf
;
147 fields
[0].in_value
= NULL
;
149 fields
[1].num_bits
= 6;
150 fields
[1].out_value
= ®_addr_buf
;
151 fields
[1].in_value
= NULL
;
153 fields
[2].num_bits
= 1;
154 fields
[2].out_value
= &nr_w_buf
;
155 fields
[2].in_value
= NULL
;
157 jtag_add_dr_scan(jtag_info
->tap
, 3, fields
, TAP_IDLE
);
159 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
160 LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr
, value
);
166 COMMAND_HANDLER(arm966e_handle_cp15_command
)
169 struct target
*target
= get_current_target(CMD_CTX
);
170 struct arm966e_common
*arm966e
= target_to_arm966(target
);
172 retval
= arm966e_verify_pointer(CMD
, arm966e
);
173 if (retval
!= ERROR_OK
)
176 if (target
->state
!= TARGET_HALTED
) {
177 command_print(CMD
, "target must be stopped for \"%s\" command", CMD_NAME
);
181 /* one or more argument, access a single register (write if second argument is given */
184 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
188 retval
= arm966e_read_cp15(target
, address
, &value
);
189 if (retval
!= ERROR_OK
) {
191 "couldn't access reg %" PRIu32
,
195 retval
= jtag_execute_queue();
196 if (retval
!= ERROR_OK
)
199 command_print(CMD
, "%" PRIu32
": %8.8" PRIx32
,
201 } else if (CMD_ARGC
== 2) {
203 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], value
);
204 retval
= arm966e_write_cp15(target
, address
, value
);
205 if (retval
!= ERROR_OK
) {
207 "couldn't access reg %" PRIu32
,
211 command_print(CMD
, "%" PRIu32
": %8.8" PRIx32
,
219 static const struct command_registration arm966e_exec_command_handlers
[] = {
222 .handler
= arm966e_handle_cp15_command
,
223 .mode
= COMMAND_EXEC
,
224 .usage
= "regnum [value]",
225 .help
= "display/modify cp15 register",
227 COMMAND_REGISTRATION_DONE
230 const struct command_registration arm966e_command_handlers
[] = {
232 .chain
= arm9tdmi_command_handlers
,
237 .help
= "arm966e command group",
239 .chain
= arm966e_exec_command_handlers
,
241 COMMAND_REGISTRATION_DONE
244 /** Holds methods for ARM966 targets. */
245 struct target_type arm966e_target
= {
249 .arch_state
= arm_arch_state
,
251 .target_request_data
= arm7_9_target_request_data
,
254 .resume
= arm7_9_resume
,
257 .assert_reset
= arm7_9_assert_reset
,
258 .deassert_reset
= arm7_9_deassert_reset
,
259 .soft_reset_halt
= arm7_9_soft_reset_halt
,
261 .get_gdb_arch
= arm_get_gdb_arch
,
262 .get_gdb_reg_list
= arm_get_gdb_reg_list
,
264 .read_memory
= arm7_9_read_memory
,
265 .write_memory
= arm7_9_write_memory_opt
,
267 .checksum_memory
= arm_checksum_memory
,
268 .blank_check_memory
= arm_blank_check_memory
,
270 .run_algorithm
= armv4_5_run_algorithm
,
272 .add_breakpoint
= arm7_9_add_breakpoint
,
273 .remove_breakpoint
= arm7_9_remove_breakpoint
,
274 .add_watchpoint
= arm7_9_add_watchpoint
,
275 .remove_watchpoint
= arm7_9_remove_watchpoint
,
277 .commands
= arm966e_command_handlers
,
278 .target_create
= arm966e_target_create
,
279 .init_target
= arm9tdmi_init_target
,
280 .deinit_target
= arm966e_deinit_target
,
281 .examine
= arm7_9_examine
,
282 .check_reset
= arm7_9_check_reset
,