616fb9463aa65a62d1b522f2050052d4b2b08264
[openocd.git] / src / target / arm966e.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "arm966e.h"
25
26 #include "arm7_9_common.h"
27 #include "register.h"
28 #include "target.h"
29 #include "armv4_5.h"
30 #include "embeddedice.h"
31 #include "log.h"
32 #include "jtag.h"
33 #include "arm_jtag.h"
34
35 #include <stdlib.h>
36 #include <string.h>
37
38 #if 0
39 #define _DEBUG_INSTRUCTION_EXECUTION_
40 #endif
41
42 /* cli handling */
43 int arm966e_register_commands(struct command_context_s *cmd_ctx);
44
45 /* forward declarations */
46 int arm966e_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
47 int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
48 int arm966e_quit(void);
49
50 target_type_t arm966e_target =
51 {
52 .name = "arm966e",
53
54 .poll = arm7_9_poll,
55 .arch_state = armv4_5_arch_state,
56
57 .halt = arm7_9_halt,
58 .resume = arm7_9_resume,
59 .step = arm7_9_step,
60
61 .assert_reset = arm7_9_assert_reset,
62 .deassert_reset = arm7_9_deassert_reset,
63 .soft_reset_halt = arm7_9_soft_reset_halt,
64 .prepare_reset_halt = arm7_9_prepare_reset_halt,
65
66 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
67
68 .read_memory = arm7_9_read_memory,
69 .write_memory = arm7_9_write_memory,
70 .bulk_write_memory = arm7_9_bulk_write_memory,
71
72 .run_algorithm = armv4_5_run_algorithm,
73
74 .add_breakpoint = arm7_9_add_breakpoint,
75 .remove_breakpoint = arm7_9_remove_breakpoint,
76 .add_watchpoint = arm7_9_add_watchpoint,
77 .remove_watchpoint = arm7_9_remove_watchpoint,
78
79 .register_commands = arm966e_register_commands,
80 .target_command = arm966e_target_command,
81 .init_target = arm966e_init_target,
82 .quit = arm966e_quit,
83 };
84
85 int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
86 {
87 arm9tdmi_init_target(cmd_ctx, target);
88
89 return ERROR_OK;
90 }
91
92 int arm966e_quit(void)
93 {
94
95 return ERROR_OK;
96 }
97
98 int arm966e_init_arch_info(target_t *target, arm966e_common_t *arm966e, int chain_pos, char *variant)
99 {
100 arm9tdmi_common_t *arm9tdmi = &arm966e->arm9tdmi_common;
101 arm7_9_common_t *arm7_9 = &arm9tdmi->arm7_9_common;
102
103 arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant);
104
105 arm9tdmi->arch_info = arm966e;
106 arm966e->common_magic = ARM966E_COMMON_MAGIC;
107
108 /* The ARM966E-S implements the ARMv5TE architecture which
109 * has the BKPT instruction, so we don't have to use a watchpoint comparator
110 */
111 arm7_9->arm_bkpt = ARMV5_BKPT(0x0);
112 arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
113
114 arm7_9->sw_bkpts_use_wp = 0;
115 arm7_9->sw_bkpts_enabled = 1;
116
117 return ERROR_OK;
118 }
119
120 int arm966e_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
121 {
122 int chain_pos;
123 char *variant = NULL;
124 arm966e_common_t *arm966e = malloc(sizeof(arm966e_common_t));
125
126 if (argc < 4)
127 {
128 ERROR("'target arm966e' requires at least one additional argument");
129 exit(-1);
130 }
131
132 chain_pos = strtoul(args[3], NULL, 0);
133
134 if (argc >= 5)
135 variant = args[4];
136
137 DEBUG("chain_pos: %i, variant: %s", chain_pos, variant);
138
139 arm966e_init_arch_info(target, arm966e, chain_pos, variant);
140
141 return ERROR_OK;
142 }
143
144 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)
145 {
146 armv4_5_common_t *armv4_5 = target->arch_info;
147 arm7_9_common_t *arm7_9;
148 arm9tdmi_common_t *arm9tdmi;
149 arm966e_common_t *arm966e;
150
151 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
152 {
153 return -1;
154 }
155
156 arm7_9 = armv4_5->arch_info;
157 if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
158 {
159 return -1;
160 }
161
162 arm9tdmi = arm7_9->arch_info;
163 if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
164 {
165 return -1;
166 }
167
168 arm966e = arm9tdmi->arch_info;
169 if (arm966e->common_magic != ARM966E_COMMON_MAGIC)
170 {
171 return -1;
172 }
173
174 *armv4_5_p = armv4_5;
175 *arm7_9_p = arm7_9;
176 *arm9tdmi_p = arm9tdmi;
177 *arm966e_p = arm966e;
178
179 return ERROR_OK;
180 }
181
182 int arm966e_read_cp15(target_t *target, int reg_addr, u32 *value)
183 {
184 armv4_5_common_t *armv4_5 = target->arch_info;
185 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
186 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
187 scan_field_t fields[3];
188 u8 reg_addr_buf = reg_addr & 0x3f;
189 u8 nr_w_buf = 0;
190
191 jtag_add_end_state(TAP_RTI);
192 arm_jtag_scann(jtag_info, 0xf);
193 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
194
195 fields[0].device = jtag_info->chain_pos;
196 fields[0].num_bits = 32;
197 fields[0].out_value = NULL;
198 fields[0].out_mask = NULL;
199 fields[0].in_value = NULL;
200 fields[0].in_check_value = NULL;
201 fields[0].in_check_mask = NULL;
202 fields[0].in_handler = NULL;
203 fields[0].in_handler_priv = NULL;
204
205 fields[1].device = jtag_info->chain_pos;
206 fields[1].num_bits = 6;
207 fields[1].out_value = &reg_addr_buf;
208 fields[1].out_mask = NULL;
209 fields[1].in_value = NULL;
210 fields[1].in_check_value = NULL;
211 fields[1].in_check_mask = NULL;
212 fields[1].in_handler = NULL;
213 fields[1].in_handler_priv = NULL;
214
215 fields[2].device = jtag_info->chain_pos;
216 fields[2].num_bits = 1;
217 fields[2].out_value = &nr_w_buf;
218 fields[2].out_mask = NULL;
219 fields[2].in_value = NULL;
220 fields[2].in_check_value = NULL;
221 fields[2].in_check_mask = NULL;
222 fields[2].in_handler = NULL;
223 fields[2].in_handler_priv = NULL;
224
225 jtag_add_dr_scan(3, fields, -1, NULL);
226
227 fields[0].in_value = (u8*)value;
228
229 jtag_add_dr_scan(3, fields, -1, NULL);
230
231 return ERROR_OK;
232 }
233
234 int arm966e_write_cp15(target_t *target, int reg_addr, u32 value)
235 {
236 armv4_5_common_t *armv4_5 = target->arch_info;
237 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
238 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
239 scan_field_t fields[3];
240 u8 reg_addr_buf = reg_addr & 0x3f;
241 u8 nr_w_buf = 1;
242
243 jtag_add_end_state(TAP_RTI);
244 arm_jtag_scann(jtag_info, 0xf);
245 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
246
247 fields[0].device = jtag_info->chain_pos;
248 fields[0].num_bits = 32;
249 fields[0].out_value = (u8*)&value;
250 fields[0].out_mask = NULL;
251 fields[0].in_value = NULL;
252 fields[0].in_check_value = NULL;
253 fields[0].in_check_mask = NULL;
254 fields[0].in_handler = NULL;
255 fields[0].in_handler_priv = NULL;
256
257 fields[1].device = jtag_info->chain_pos;
258 fields[1].num_bits = 6;
259 fields[1].out_value = &reg_addr_buf;
260 fields[1].out_mask = NULL;
261 fields[1].in_value = NULL;
262 fields[1].in_check_value = NULL;
263 fields[1].in_check_mask = NULL;
264 fields[1].in_handler = NULL;
265 fields[1].in_handler_priv = NULL;
266
267 fields[2].device = jtag_info->chain_pos;
268 fields[2].num_bits = 1;
269 fields[2].out_value = &nr_w_buf;
270 fields[2].out_mask = NULL;
271 fields[2].in_value = NULL;
272 fields[2].in_check_value = NULL;
273 fields[2].in_check_mask = NULL;
274 fields[2].in_handler = NULL;
275 fields[2].in_handler_priv = NULL;
276
277 jtag_add_dr_scan(3, fields, -1, NULL);
278
279 return ERROR_OK;
280 }
281
282 int arm966e_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
283 {
284 int retval;
285 target_t *target = get_current_target(cmd_ctx);
286 armv4_5_common_t *armv4_5;
287 arm7_9_common_t *arm7_9;
288 arm9tdmi_common_t *arm9tdmi;
289 arm966e_common_t *arm966e;
290 arm_jtag_t *jtag_info;
291
292 if (arm966e_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm966e) != ERROR_OK)
293 {
294 command_print(cmd_ctx, "current target isn't an ARM966e target");
295 return ERROR_OK;
296 }
297
298 jtag_info = &arm7_9->jtag_info;
299
300 if (target->state != TARGET_HALTED)
301 {
302 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
303 return ERROR_OK;
304 }
305
306 /* one or more argument, access a single register (write if second argument is given */
307 if (argc >= 1)
308 {
309 int address = strtoul(args[0], NULL, 0);
310
311 if (argc == 1)
312 {
313 u32 value;
314 if ((retval = arm966e_read_cp15(target, address, &value)) != ERROR_OK)
315 {
316 command_print(cmd_ctx, "couldn't access reg %i", address);
317 return ERROR_OK;
318 }
319 jtag_execute_queue();
320
321 command_print(cmd_ctx, "%i: %8.8x", address, value);
322 }
323 else if (argc == 2)
324 {
325 u32 value = strtoul(args[1], NULL, 0);
326 if ((retval = arm966e_write_cp15(target, address, value)) != ERROR_OK)
327 {
328 command_print(cmd_ctx, "couldn't access reg %i", address);
329 return ERROR_OK;
330 }
331 command_print(cmd_ctx, "%i: %8.8x", address, value);
332 }
333 }
334
335 return ERROR_OK;
336 }
337
338 int arm966e_register_commands(struct command_context_s *cmd_ctx)
339 {
340 int retval;
341 command_t *arm966e_cmd;
342
343 retval = arm9tdmi_register_commands(cmd_ctx);
344 arm966e_cmd = register_command(cmd_ctx, NULL, "arm966e", NULL, COMMAND_ANY, "arm966e specific commands");
345 register_command(cmd_ctx, arm966e_cmd, "cp15", arm966e_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register <num> [value]");
346
347 return ERROR_OK;
348 }

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)