1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
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 "target_type.h"
29 #include "arm_opcodes.h"
33 #define _DEBUG_INSTRUCTION_EXECUTION_
36 int arm966e_init_arch_info(struct target
*target
, struct arm966e_common
*arm966e
, struct jtag_tap
*tap
)
38 struct arm7_9_common
*arm7_9
= &arm966e
->arm7_9_common
;
40 /* initialize arm7/arm9 specific info (including armv4_5) */
41 arm9tdmi_init_arch_info(target
, arm7_9
, tap
);
43 arm966e
->common_magic
= ARM966E_COMMON_MAGIC
;
45 /* The ARM966E-S implements the ARMv5TE architecture which
46 * has the BKPT instruction, so we don't have to use a watchpoint comparator
48 arm7_9
->arm_bkpt
= ARMV5_BKPT(0x0);
49 arm7_9
->thumb_bkpt
= ARMV5_T_BKPT(0x0) & 0xffff;
54 static int arm966e_target_create(struct target
*target
, Jim_Interp
*interp
)
56 struct arm966e_common
*arm966e
= calloc(1,sizeof(struct arm966e_common
));
58 return arm966e_init_arch_info(target
, arm966e
, target
->tap
);
61 static int arm966e_verify_pointer(struct command_context
*cmd_ctx
,
62 struct arm966e_common
*arm966e
)
64 if (arm966e
->common_magic
!= ARM966E_COMMON_MAGIC
) {
65 command_print(cmd_ctx
, "target is not an ARM966");
66 return ERROR_TARGET_INVALID
;
72 * REVISIT: The "read_cp15" and "write_cp15" commands could hook up
73 * to eventual mrc() and mcr() routines ... the reg_addr values being
74 * constructed (for CP15 only) from Opcode_1, Opcode_2, and CRn values.
75 * See section 7.3 of the ARM966E-S TRM.
78 static int arm966e_read_cp15(struct target
*target
, int reg_addr
, uint32_t *value
)
80 int retval
= ERROR_OK
;
81 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
82 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
83 struct scan_field fields
[3];
84 uint8_t reg_addr_buf
= reg_addr
& 0x3f;
87 jtag_set_end_state(TAP_IDLE
);
88 if ((retval
= arm_jtag_scann(jtag_info
, 0xf)) != ERROR_OK
)
92 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
94 fields
[0].tap
= jtag_info
->tap
;
95 fields
[0].num_bits
= 32;
96 /* REVISIT: table 7-2 shows that bits 31-31 need to be
97 * specified for accessing BIST registers ...
99 fields
[0].out_value
= NULL
;
100 fields
[0].in_value
= NULL
;
102 fields
[1].tap
= jtag_info
->tap
;
103 fields
[1].num_bits
= 6;
104 fields
[1].out_value
= ®_addr_buf
;
105 fields
[1].in_value
= NULL
;
107 fields
[2].tap
= jtag_info
->tap
;
108 fields
[2].num_bits
= 1;
109 fields
[2].out_value
= &nr_w_buf
;
110 fields
[2].in_value
= NULL
;
112 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
114 fields
[1].in_value
= (uint8_t *)value
;
116 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
118 jtag_add_callback(arm_le_to_h_u32
, (jtag_callback_data_t
)value
);
121 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
122 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
126 LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr
, *value
);
132 // EXPORTED to str9x (flash)
133 int arm966e_write_cp15(struct target
*target
, int reg_addr
, uint32_t value
)
135 int retval
= ERROR_OK
;
136 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
137 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
138 struct scan_field fields
[3];
139 uint8_t reg_addr_buf
= reg_addr
& 0x3f;
140 uint8_t nr_w_buf
= 1;
141 uint8_t value_buf
[4];
143 buf_set_u32(value_buf
, 0, 32, value
);
145 jtag_set_end_state(TAP_IDLE
);
146 if ((retval
= arm_jtag_scann(jtag_info
, 0xf)) != ERROR_OK
)
150 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
152 fields
[0].tap
= jtag_info
->tap
;
153 fields
[0].num_bits
= 32;
154 fields
[0].out_value
= value_buf
;
155 fields
[0].in_value
= NULL
;
157 fields
[1].tap
= jtag_info
->tap
;
158 fields
[1].num_bits
= 6;
159 fields
[1].out_value
= ®_addr_buf
;
160 fields
[1].in_value
= NULL
;
162 fields
[2].tap
= jtag_info
->tap
;
163 fields
[2].num_bits
= 1;
164 fields
[2].out_value
= &nr_w_buf
;
165 fields
[2].in_value
= NULL
;
167 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
169 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
170 LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr
, value
);
176 COMMAND_HANDLER(arm966e_handle_cp15_command
)
179 struct target
*target
= get_current_target(CMD_CTX
);
180 struct arm966e_common
*arm966e
= target_to_arm966(target
);
182 retval
= arm966e_verify_pointer(CMD_CTX
, arm966e
);
183 if (retval
!= ERROR_OK
)
186 if (target
->state
!= TARGET_HALTED
)
188 command_print(CMD_CTX
, "target must be stopped for \"%s\" command", CMD_NAME
);
192 /* one or more argument, access a single register (write if second argument is given */
196 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
201 if ((retval
= arm966e_read_cp15(target
, address
, &value
)) != ERROR_OK
)
203 command_print(CMD_CTX
,
204 "couldn't access reg %" PRIi32
,
208 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
213 command_print(CMD_CTX
, "%" PRIi32
": %8.8" PRIx32
,
216 else if (CMD_ARGC
== 2)
219 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], value
);
220 if ((retval
= arm966e_write_cp15(target
, address
, value
)) != ERROR_OK
)
222 command_print(CMD_CTX
,
223 "couldn't access reg %" PRIi32
,
227 command_print(CMD_CTX
, "%" PRIi32
": %8.8" PRIx32
,
235 static const struct command_registration arm966e_exec_command_handlers
[] = {
238 .handler
= arm966e_handle_cp15_command
,
239 .mode
= COMMAND_EXEC
,
240 .usage
= "regnum [value]",
241 .help
= "display/modify cp15 register",
243 COMMAND_REGISTRATION_DONE
246 const struct command_registration arm966e_command_handlers
[] = {
248 .chain
= arm9tdmi_command_handlers
,
253 .help
= "arm966e command group",
254 .chain
= arm966e_exec_command_handlers
,
256 COMMAND_REGISTRATION_DONE
259 /** Holds methods for ARM966 targets. */
260 struct target_type arm966e_target
=
265 .arch_state
= arm_arch_state
,
267 .target_request_data
= arm7_9_target_request_data
,
270 .resume
= arm7_9_resume
,
273 .assert_reset
= arm7_9_assert_reset
,
274 .deassert_reset
= arm7_9_deassert_reset
,
275 .soft_reset_halt
= arm7_9_soft_reset_halt
,
277 .get_gdb_reg_list
= arm_get_gdb_reg_list
,
279 .read_memory
= arm7_9_read_memory
,
280 .write_memory
= arm7_9_write_memory
,
281 .bulk_write_memory
= arm7_9_bulk_write_memory
,
283 .checksum_memory
= arm_checksum_memory
,
284 .blank_check_memory
= arm_blank_check_memory
,
286 .run_algorithm
= armv4_5_run_algorithm
,
288 .add_breakpoint
= arm7_9_add_breakpoint
,
289 .remove_breakpoint
= arm7_9_remove_breakpoint
,
290 .add_watchpoint
= arm7_9_add_watchpoint
,
291 .remove_watchpoint
= arm7_9_remove_watchpoint
,
293 .commands
= arm966e_command_handlers
,
294 .target_create
= arm966e_target_create
,
295 .init_target
= arm9tdmi_init_target
,
296 .examine
= arm7_9_examine
,