Improve arm966e command argument parsing.
[openocd.git] / src / target / arm966e.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
7 * *
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. *
12 * *
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. *
17 * *
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 ***************************************************************************/
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "arm966e.h"
28 #include "target_type.h"
29
30
31 #if 0
32 #define _DEBUG_INSTRUCTION_EXECUTION_
33 #endif
34
35 /* forward declarations */
36 int arm966e_target_create(struct target_s *target, Jim_Interp *interp);
37 int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
38
39 target_type_t arm966e_target =
40 {
41 .name = "arm966e",
42
43 .poll = arm7_9_poll,
44 .arch_state = armv4_5_arch_state,
45
46 .target_request_data = arm7_9_target_request_data,
47
48 .halt = arm7_9_halt,
49 .resume = arm7_9_resume,
50 .step = arm7_9_step,
51
52 .assert_reset = arm7_9_assert_reset,
53 .deassert_reset = arm7_9_deassert_reset,
54 .soft_reset_halt = arm7_9_soft_reset_halt,
55
56 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
57
58 .read_memory = arm7_9_read_memory,
59 .write_memory = arm7_9_write_memory,
60 .bulk_write_memory = arm7_9_bulk_write_memory,
61 .checksum_memory = arm7_9_checksum_memory,
62 .blank_check_memory = arm7_9_blank_check_memory,
63
64 .run_algorithm = armv4_5_run_algorithm,
65
66 .add_breakpoint = arm7_9_add_breakpoint,
67 .remove_breakpoint = arm7_9_remove_breakpoint,
68 .add_watchpoint = arm7_9_add_watchpoint,
69 .remove_watchpoint = arm7_9_remove_watchpoint,
70
71 .register_commands = arm966e_register_commands,
72 .target_create = arm966e_target_create,
73 .init_target = arm966e_init_target,
74 .examine = arm9tdmi_examine,
75 };
76
77 int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
78 {
79 arm9tdmi_init_target(cmd_ctx, target);
80
81 return ERROR_OK;
82 }
83
84 int arm966e_init_arch_info(target_t *target, arm966e_common_t *arm966e, jtag_tap_t *tap)
85 {
86 arm9tdmi_common_t *arm9tdmi = &arm966e->arm9tdmi_common;
87 arm7_9_common_t *arm7_9 = &arm9tdmi->arm7_9_common;
88
89 arm9tdmi_init_arch_info(target, arm9tdmi, tap);
90
91 arm9tdmi->arch_info = arm966e;
92 arm966e->common_magic = ARM966E_COMMON_MAGIC;
93
94 /* The ARM966E-S implements the ARMv5TE architecture which
95 * has the BKPT instruction, so we don't have to use a watchpoint comparator
96 */
97 arm7_9->arm_bkpt = ARMV5_BKPT(0x0);
98 arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
99
100 return ERROR_OK;
101 }
102
103 int arm966e_target_create(struct target_s *target, Jim_Interp *interp)
104 {
105 arm966e_common_t *arm966e = calloc(1,sizeof(arm966e_common_t));
106
107 arm966e_init_arch_info(target, arm966e, target->tap);
108
109 return ERROR_OK;
110 }
111
112 int arm966e_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, arm7_9_common_t **arm7_9_p, arm9tdmi_common_t **arm9tdmi_p, arm966e_common_t **arm966e_p)
113 {
114 armv4_5_common_t *armv4_5 = target->arch_info;
115 arm7_9_common_t *arm7_9;
116 arm9tdmi_common_t *arm9tdmi;
117 arm966e_common_t *arm966e;
118
119 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
120 {
121 return -1;
122 }
123
124 arm7_9 = armv4_5->arch_info;
125 if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
126 {
127 return -1;
128 }
129
130 arm9tdmi = arm7_9->arch_info;
131 if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
132 {
133 return -1;
134 }
135
136 arm966e = arm9tdmi->arch_info;
137 if (arm966e->common_magic != ARM966E_COMMON_MAGIC)
138 {
139 return -1;
140 }
141
142 *armv4_5_p = armv4_5;
143 *arm7_9_p = arm7_9;
144 *arm9tdmi_p = arm9tdmi;
145 *arm966e_p = arm966e;
146
147 return ERROR_OK;
148 }
149
150 int arm966e_read_cp15(target_t *target, int reg_addr, uint32_t *value)
151 {
152 int retval = ERROR_OK;
153 armv4_5_common_t *armv4_5 = target->arch_info;
154 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
155 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
156 scan_field_t fields[3];
157 uint8_t reg_addr_buf = reg_addr & 0x3f;
158 uint8_t nr_w_buf = 0;
159
160 jtag_set_end_state(TAP_IDLE);
161 if ((retval = arm_jtag_scann(jtag_info, 0xf)) != ERROR_OK)
162 {
163 return retval;
164 }
165 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
166
167 fields[0].tap = jtag_info->tap;
168 fields[0].num_bits = 32;
169 fields[0].out_value = NULL;
170 fields[0].in_value = NULL;
171
172 fields[1].tap = jtag_info->tap;
173 fields[1].num_bits = 6;
174 fields[1].out_value = &reg_addr_buf;
175 fields[1].in_value = NULL;
176
177 fields[2].tap = jtag_info->tap;
178 fields[2].num_bits = 1;
179 fields[2].out_value = &nr_w_buf;
180 fields[2].in_value = NULL;
181
182 jtag_add_dr_scan(3, fields, jtag_get_end_state());
183
184 fields[1].in_value = (uint8_t *)value;
185
186 jtag_add_dr_scan(3, fields, jtag_get_end_state());
187
188 jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value);
189
190
191 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
192 if ((retval = jtag_execute_queue()) != ERROR_OK)
193 {
194 return retval;
195 }
196 LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value);
197 #endif
198
199 return ERROR_OK;
200 }
201
202 int arm966e_write_cp15(target_t *target, int reg_addr, uint32_t value)
203 {
204 int retval = ERROR_OK;
205 armv4_5_common_t *armv4_5 = target->arch_info;
206 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
207 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
208 scan_field_t fields[3];
209 uint8_t reg_addr_buf = reg_addr & 0x3f;
210 uint8_t nr_w_buf = 1;
211 uint8_t value_buf[4];
212
213 buf_set_u32(value_buf, 0, 32, value);
214
215 jtag_set_end_state(TAP_IDLE);
216 if ((retval = arm_jtag_scann(jtag_info, 0xf)) != ERROR_OK)
217 {
218 return retval;
219 }
220 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
221
222 fields[0].tap = jtag_info->tap;
223 fields[0].num_bits = 32;
224 fields[0].out_value = value_buf;
225 fields[0].in_value = NULL;
226
227 fields[1].tap = jtag_info->tap;
228 fields[1].num_bits = 6;
229 fields[1].out_value = &reg_addr_buf;
230 fields[1].in_value = NULL;
231
232 fields[2].tap = jtag_info->tap;
233 fields[2].num_bits = 1;
234 fields[2].out_value = &nr_w_buf;
235 fields[2].in_value = NULL;
236
237 jtag_add_dr_scan(3, fields, jtag_get_end_state());
238
239 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
240 LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
241 #endif
242
243 return ERROR_OK;
244 }
245
246 int arm966e_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
247 {
248 int retval;
249 target_t *target = get_current_target(cmd_ctx);
250 armv4_5_common_t *armv4_5;
251 arm7_9_common_t *arm7_9;
252 arm9tdmi_common_t *arm9tdmi;
253 arm966e_common_t *arm966e;
254 arm_jtag_t *jtag_info;
255
256 if (arm966e_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm966e) != ERROR_OK)
257 {
258 command_print(cmd_ctx, "current target isn't an ARM966e target");
259 return ERROR_OK;
260 }
261
262 jtag_info = &arm7_9->jtag_info;
263
264 if (target->state != TARGET_HALTED)
265 {
266 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
267 return ERROR_OK;
268 }
269
270 /* one or more argument, access a single register (write if second argument is given */
271 if (argc >= 1)
272 {
273 uint32_t address;
274 COMMAND_PARSE_NUMBER(u32, args[0], address);
275
276 if (argc == 1)
277 {
278 uint32_t value;
279 if ((retval = arm966e_read_cp15(target, address, &value)) != ERROR_OK)
280 {
281 command_print(cmd_ctx, "couldn't access reg %i", address);
282 return ERROR_OK;
283 }
284 if ((retval = jtag_execute_queue()) != ERROR_OK)
285 {
286 return retval;
287 }
288
289 command_print(cmd_ctx, "%i: %8.8" PRIx32 "", address, value);
290 }
291 else if (argc == 2)
292 {
293 uint32_t value;
294 COMMAND_PARSE_NUMBER(u32, args[1], value);
295 if ((retval = arm966e_write_cp15(target, address, value)) != ERROR_OK)
296 {
297 command_print(cmd_ctx, "couldn't access reg %i", address);
298 return ERROR_OK;
299 }
300 command_print(cmd_ctx, "%i: %8.8" PRIx32 "", address, value);
301 }
302 }
303
304 return ERROR_OK;
305 }
306
307 int arm966e_register_commands(struct command_context_s *cmd_ctx)
308 {
309 int retval;
310 command_t *arm966e_cmd;
311
312 retval = arm9tdmi_register_commands(cmd_ctx);
313 arm966e_cmd = register_command(cmd_ctx, NULL, "arm966e", NULL, COMMAND_ANY, "arm966e specific commands");
314 register_command(cmd_ctx, arm966e_cmd, "cp15", arm966e_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register <num> [value]");
315
316 return retval;
317 }

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)