- fixed arm926 cp15 command bug (thanks to Vincent Palatin for this patch)
[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_deassert_reset(target_t *target);
47 int arm966e_assert_reset(target_t *target);
48 int arm966e_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
49 int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
50 int arm966e_quit(void);
51
52 target_type_t arm966e_target =
53 {
54 .name = "arm966e",
55
56 .poll = arm7_9_poll,
57 .arch_state = armv4_5_arch_state,
58
59 .halt = arm7_9_halt,
60 .resume = arm7_9_resume,
61 .step = arm7_9_step,
62
63 .assert_reset = arm966e_assert_reset,
64 .deassert_reset = arm966e_deassert_reset,
65 .soft_reset_halt = arm7_9_soft_reset_halt,
66
67 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
68
69 .read_memory = arm7_9_read_memory,
70 .write_memory = arm7_9_write_memory,
71 .bulk_write_memory = arm7_9_bulk_write_memory,
72
73 .run_algorithm = armv4_5_run_algorithm,
74
75 .add_breakpoint = arm7_9_add_breakpoint,
76 .remove_breakpoint = arm7_9_remove_breakpoint,
77 .add_watchpoint = arm7_9_add_watchpoint,
78 .remove_watchpoint = arm7_9_remove_watchpoint,
79
80 .register_commands = arm966e_register_commands,
81 .target_command = arm966e_target_command,
82 .init_target = arm966e_init_target,
83 .quit = arm966e_quit,
84 };
85
86 int arm966e_assert_reset(target_t *target)
87 {
88 int retval;
89
90 DEBUG("target->state: %s", target_state_strings[target->state]);
91
92 if (target->state == TARGET_HALTED || target->state == TARGET_UNKNOWN)
93 {
94 /* assert SRST and TRST */
95 /* system would get ouf sync if we didn't reset test-logic, too */
96 if ((retval = jtag_add_reset(1, 1)) != ERROR_OK)
97 {
98 if (retval == ERROR_JTAG_RESET_CANT_SRST)
99 {
100 WARNING("can't assert srst");
101 return retval;
102 }
103 else
104 {
105 ERROR("unknown error");
106 exit(-1);
107 }
108 }
109 jtag_add_sleep(5000);
110 if ((retval = jtag_add_reset(0, 1)) != ERROR_OK)
111 {
112 if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
113 {
114 WARNING("srst resets test logic, too");
115 retval = jtag_add_reset(1, 1);
116 }
117 }
118 }
119 else
120 {
121 if ((retval = jtag_add_reset(0, 1)) != ERROR_OK)
122 {
123 if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
124 {
125 WARNING("srst resets test logic, too");
126 retval = jtag_add_reset(1, 1);
127 }
128
129 if (retval == ERROR_JTAG_RESET_CANT_SRST)
130 {
131 WARNING("can't assert srst");
132 return retval;
133 }
134 else if (retval != ERROR_OK)
135 {
136 ERROR("unknown error");
137 exit(-1);
138 }
139 }
140 }
141
142 target->state = TARGET_RESET;
143 jtag_add_sleep(50000);
144
145 armv4_5_invalidate_core_regs(target);
146
147 return ERROR_OK;
148 }
149
150 int arm966e_deassert_reset(target_t *target)
151 {
152 arm7_9_deassert_reset( target );
153
154 return ERROR_OK;
155 }
156
157 int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
158 {
159 arm9tdmi_init_target(cmd_ctx, target);
160
161 return ERROR_OK;
162 }
163
164 int arm966e_quit(void)
165 {
166
167 return ERROR_OK;
168 }
169
170 int arm966e_init_arch_info(target_t *target, arm966e_common_t *arm966e, int chain_pos, char *variant)
171 {
172 arm9tdmi_common_t *arm9tdmi = &arm966e->arm9tdmi_common;
173
174 arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant);
175
176 arm9tdmi->arch_info = arm966e;
177 arm966e->common_magic = ARM966E_COMMON_MAGIC;
178
179 return ERROR_OK;
180 }
181
182 int arm966e_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
183 {
184 int chain_pos;
185 char *variant = NULL;
186 arm966e_common_t *arm966e = malloc(sizeof(arm966e_common_t));
187
188 if (argc < 4)
189 {
190 ERROR("'target arm966e' requires at least one additional argument");
191 exit(-1);
192 }
193
194 chain_pos = strtoul(args[3], NULL, 0);
195
196 if (argc >= 5)
197 variant = args[4];
198
199 DEBUG("chain_pos: %i, variant: %s", chain_pos, variant);
200
201 arm966e_init_arch_info(target, arm966e, chain_pos, variant);
202
203 return ERROR_OK;
204 }
205
206 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)
207 {
208 armv4_5_common_t *armv4_5 = target->arch_info;
209 arm7_9_common_t *arm7_9;
210 arm9tdmi_common_t *arm9tdmi;
211 arm966e_common_t *arm966e;
212
213 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
214 {
215 return -1;
216 }
217
218 arm7_9 = armv4_5->arch_info;
219 if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
220 {
221 return -1;
222 }
223
224 arm9tdmi = arm7_9->arch_info;
225 if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
226 {
227 return -1;
228 }
229
230 arm966e = arm9tdmi->arch_info;
231 if (arm966e->common_magic != ARM966E_COMMON_MAGIC)
232 {
233 return -1;
234 }
235
236 *armv4_5_p = armv4_5;
237 *arm7_9_p = arm7_9;
238 *arm9tdmi_p = arm9tdmi;
239 *arm966e_p = arm966e;
240
241 return ERROR_OK;
242 }
243
244 int arm966e_read_cp15(target_t *target, int reg_addr, u32 *value)
245 {
246 armv4_5_common_t *armv4_5 = target->arch_info;
247 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
248 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
249 scan_field_t fields[3];
250 u8 reg_addr_buf = reg_addr & 0x3f;
251 u8 nr_w_buf = 0;
252
253 jtag_add_end_state(TAP_RTI);
254 arm_jtag_scann(jtag_info, 0xf);
255 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr);
256
257 fields[0].device = jtag_info->chain_pos;
258 fields[0].num_bits = 32;
259 fields[0].out_value = NULL;
260 fields[0].out_mask = NULL;
261 fields[0].in_value = NULL;
262 fields[0].in_check_value = NULL;
263 fields[0].in_check_mask = NULL;
264 fields[0].in_handler = NULL;
265 fields[0].in_handler_priv = NULL;
266
267 fields[1].device = jtag_info->chain_pos;
268 fields[1].num_bits = 6;
269 fields[1].out_value = &reg_addr_buf;
270 fields[1].out_mask = NULL;
271 fields[1].in_value = NULL;
272 fields[1].in_check_value = NULL;
273 fields[1].in_check_mask = NULL;
274 fields[1].in_handler = NULL;
275 fields[1].in_handler_priv = NULL;
276
277 fields[2].device = jtag_info->chain_pos;
278 fields[2].num_bits = 1;
279 fields[2].out_value = &nr_w_buf;
280 fields[2].out_mask = NULL;
281 fields[2].in_value = NULL;
282 fields[2].in_check_value = NULL;
283 fields[2].in_check_mask = NULL;
284 fields[2].in_handler = NULL;
285 fields[2].in_handler_priv = NULL;
286
287 jtag_add_dr_scan(3, fields, -1);
288
289 fields[0].in_value = (u8*)value;
290
291 jtag_add_dr_scan(3, fields, -1);
292
293 return ERROR_OK;
294 }
295
296 int arm966e_write_cp15(target_t *target, int reg_addr, u32 value)
297 {
298 armv4_5_common_t *armv4_5 = target->arch_info;
299 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
300 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
301 scan_field_t fields[3];
302 u8 reg_addr_buf = reg_addr & 0x3f;
303 u8 nr_w_buf = 1;
304
305 jtag_add_end_state(TAP_RTI);
306 arm_jtag_scann(jtag_info, 0xf);
307 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr);
308
309 fields[0].device = jtag_info->chain_pos;
310 fields[0].num_bits = 32;
311 fields[0].out_value = (u8*)&value;
312 fields[0].out_mask = NULL;
313 fields[0].in_value = NULL;
314 fields[0].in_check_value = NULL;
315 fields[0].in_check_mask = NULL;
316 fields[0].in_handler = NULL;
317 fields[0].in_handler_priv = NULL;
318
319 fields[1].device = jtag_info->chain_pos;
320 fields[1].num_bits = 6;
321 fields[1].out_value = &reg_addr_buf;
322 fields[1].out_mask = NULL;
323 fields[1].in_value = NULL;
324 fields[1].in_check_value = NULL;
325 fields[1].in_check_mask = NULL;
326 fields[1].in_handler = NULL;
327 fields[1].in_handler_priv = NULL;
328
329 fields[2].device = jtag_info->chain_pos;
330 fields[2].num_bits = 1;
331 fields[2].out_value = &nr_w_buf;
332 fields[2].out_mask = NULL;
333 fields[2].in_value = NULL;
334 fields[2].in_check_value = NULL;
335 fields[2].in_check_mask = NULL;
336 fields[2].in_handler = NULL;
337 fields[2].in_handler_priv = NULL;
338
339 jtag_add_dr_scan(3, fields, -1);
340
341 return ERROR_OK;
342 }
343
344 int arm966e_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
345 {
346 int retval;
347 target_t *target = get_current_target(cmd_ctx);
348 armv4_5_common_t *armv4_5;
349 arm7_9_common_t *arm7_9;
350 arm9tdmi_common_t *arm9tdmi;
351 arm966e_common_t *arm966e;
352 arm_jtag_t *jtag_info;
353
354 if (arm966e_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm966e) != ERROR_OK)
355 {
356 command_print(cmd_ctx, "current target isn't an ARM966e target");
357 return ERROR_OK;
358 }
359
360 jtag_info = &arm7_9->jtag_info;
361
362 if (target->state != TARGET_HALTED)
363 {
364 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
365 return ERROR_OK;
366 }
367
368 /* one or more argument, access a single register (write if second argument is given */
369 if (argc >= 1)
370 {
371 int address = strtoul(args[0], NULL, 0);
372
373 if (argc == 1)
374 {
375 u32 value;
376 if ((retval = arm966e_read_cp15(target, address, &value)) != ERROR_OK)
377 {
378 command_print(cmd_ctx, "couldn't access reg %i", address);
379 return ERROR_OK;
380 }
381 jtag_execute_queue();
382
383 command_print(cmd_ctx, "%i: %8.8x", address, value);
384 }
385 else if (argc == 2)
386 {
387 u32 value = strtoul(args[1], NULL, 0);
388 if ((retval = arm966e_write_cp15(target, address, value)) != ERROR_OK)
389 {
390 command_print(cmd_ctx, "couldn't access reg %i", address);
391 return ERROR_OK;
392 }
393 command_print(cmd_ctx, "%i: %8.8x", address, value);
394 }
395 }
396
397 return ERROR_OK;
398 }
399
400 int arm966e_register_commands(struct command_context_s *cmd_ctx)
401 {
402 int retval;
403 command_t *arm966e_cmd;
404
405 retval = arm7_9_register_commands(cmd_ctx);
406 arm966e_cmd = register_command(cmd_ctx, NULL, "arm966e", NULL, COMMAND_ANY, "arm966e specific commands");
407 register_command(cmd_ctx, arm966e_cmd, "cp15", arm966e_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register <num> [value]");
408
409 return ERROR_OK;
410 }

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)