- str9x flash support (Thanks to Spencer Oliver)
[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 armv4_5_common_t *armv4_5 = target->arch_info;
89 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
90 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
91 arm966e_common_t *arm966e = arm9tdmi->arch_info;
92 reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
93 int retval;
94 int trst_asserted_with_srt = 0;
95
96 arm966e->monitor_mode_set = 1;
97
98 DEBUG("target->state: %s", target_state_strings[target->state]);
99
100 if (target->state == TARGET_HALTED || target->state == TARGET_UNKNOWN)
101 {
102 /* assert SRST and TRST */
103 /* system would get ouf sync if we didn't reset test-logic, too */
104 if ((retval = jtag_add_reset(1, 1)) != ERROR_OK)
105 {
106 if (retval == ERROR_JTAG_RESET_CANT_SRST)
107 {
108 WARNING("can't assert srst");
109 return retval;
110 }
111 else
112 {
113 ERROR("unknown error");
114 exit(-1);
115 }
116 }
117 jtag_add_sleep(5000);
118 if ((retval = jtag_add_reset(0, 1)) != ERROR_OK)
119 {
120 if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
121 {
122 WARNING("srst resets test logic, too");
123 retval = jtag_add_reset(1, 1);
124 trst_asserted_with_srt = 1;
125 }
126 }
127 }
128 else
129 {
130 if ((retval = jtag_add_reset(0, 1)) != ERROR_OK)
131 {
132 if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
133 {
134 WARNING("srst resets test logic, too");
135 retval = jtag_add_reset(1, 1);
136 trst_asserted_with_srt = 1;
137 }
138
139 if (retval == ERROR_JTAG_RESET_CANT_SRST)
140 {
141 WARNING("can't assert srst");
142 return retval;
143 }
144 else if (retval != ERROR_OK)
145 {
146 ERROR("unknown error");
147 exit(-1);
148 }
149 }
150 }
151
152 target->state = TARGET_RESET;
153 jtag_add_sleep(50000);
154
155 armv4_5_invalidate_core_regs(target);
156
157 if( trst_asserted_with_srt == 0 )
158 {
159 DEBUG("monitor mode needs clearing");
160
161 /* arm9e monitor mode enabled at reset */
162 embeddedice_read_reg(dbg_ctrl);
163 jtag_execute_queue();
164
165 if(buf_get_u32(dbg_ctrl->value, EICE_DBG_CONTROL_MONEN, 1))
166 {
167 buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_MONEN, 1, 0);
168 embeddedice_store_reg(dbg_ctrl);
169 DEBUG("monitor mode disabled");
170 }
171 arm966e->monitor_mode_set = 0;
172 }
173
174 return ERROR_OK;
175 }
176
177 int arm966e_deassert_reset(target_t *target)
178 {
179 armv4_5_common_t *armv4_5 = target->arch_info;
180 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
181 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
182 arm966e_common_t *arm966e = arm9tdmi->arch_info;
183 reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
184
185 arm7_9_deassert_reset( target );
186
187 if( arm966e->monitor_mode_set == 1 )
188 {
189 DEBUG("monitor mode needs clearing");
190
191 /* arm9e monitor mode enabled at reset */
192 embeddedice_read_reg(dbg_ctrl);
193 jtag_execute_queue();
194
195 if(buf_get_u32(dbg_ctrl->value, EICE_DBG_CONTROL_MONEN, 1))
196 {
197 buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_MONEN, 1, 0);
198 embeddedice_store_reg(dbg_ctrl);
199 arm966e->monitor_mode_set = 0;
200 DEBUG("monitor mode disabled");
201 }
202 }
203
204 return ERROR_OK;
205 }
206
207 int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
208 {
209 arm9tdmi_init_target(cmd_ctx, target);
210
211 return ERROR_OK;
212 }
213
214 int arm966e_quit(void)
215 {
216
217 return ERROR_OK;
218 }
219
220 int arm966e_init_arch_info(target_t *target, arm966e_common_t *arm966e, int chain_pos, char *variant)
221 {
222 arm9tdmi_common_t *arm9tdmi = &arm966e->arm9tdmi_common;
223
224 arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant);
225
226 arm9tdmi->arch_info = arm966e;
227 arm966e->common_magic = ARM966E_COMMON_MAGIC;
228
229 arm9tdmi->has_single_step = 0;
230 arm9tdmi->has_monitor_mode = 1;
231
232 return ERROR_OK;
233 }
234
235 int arm966e_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
236 {
237 int chain_pos;
238 char *variant = NULL;
239 arm966e_common_t *arm966e = malloc(sizeof(arm966e_common_t));
240
241 if (argc < 4)
242 {
243 ERROR("'target arm966e' requires at least one additional argument");
244 exit(-1);
245 }
246
247 chain_pos = strtoul(args[3], NULL, 0);
248
249 if (argc >= 5)
250 variant = args[4];
251
252 DEBUG("chain_pos: %i, variant: %s", chain_pos, variant);
253
254 arm966e_init_arch_info(target, arm966e, chain_pos, variant);
255
256 return ERROR_OK;
257 }
258
259 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)
260 {
261 armv4_5_common_t *armv4_5 = target->arch_info;
262 arm7_9_common_t *arm7_9;
263 arm9tdmi_common_t *arm9tdmi;
264 arm966e_common_t *arm966e;
265
266 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
267 {
268 return -1;
269 }
270
271 arm7_9 = armv4_5->arch_info;
272 if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
273 {
274 return -1;
275 }
276
277 arm9tdmi = arm7_9->arch_info;
278 if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
279 {
280 return -1;
281 }
282
283 arm966e = arm9tdmi->arch_info;
284 if (arm966e->common_magic != ARM966E_COMMON_MAGIC)
285 {
286 return -1;
287 }
288
289 *armv4_5_p = armv4_5;
290 *arm7_9_p = arm7_9;
291 *arm9tdmi_p = arm9tdmi;
292 *arm966e_p = arm966e;
293
294 return ERROR_OK;
295 }
296
297 int arm966e_read_cp15(target_t *target, int reg_addr, u32 *value)
298 {
299 armv4_5_common_t *armv4_5 = target->arch_info;
300 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
301 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
302 scan_field_t fields[3];
303 u8 reg_addr_buf = reg_addr & 0x3f;
304 u8 nr_w_buf = 0;
305
306 jtag_add_end_state(TAP_RTI);
307 arm_jtag_scann(jtag_info, 0xf);
308 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr);
309
310 fields[0].device = jtag_info->chain_pos;
311 fields[0].num_bits = 32;
312 fields[0].out_value = NULL;
313 fields[0].out_mask = NULL;
314 fields[0].in_value = NULL;
315 fields[0].in_check_value = NULL;
316 fields[0].in_check_mask = NULL;
317 fields[0].in_handler = NULL;
318 fields[0].in_handler_priv = NULL;
319
320 fields[1].device = jtag_info->chain_pos;
321 fields[1].num_bits = 6;
322 fields[1].out_value = &reg_addr_buf;
323 fields[1].out_mask = NULL;
324 fields[1].in_value = NULL;
325 fields[1].in_check_value = NULL;
326 fields[1].in_check_mask = NULL;
327 fields[1].in_handler = NULL;
328 fields[1].in_handler_priv = NULL;
329
330 fields[2].device = jtag_info->chain_pos;
331 fields[2].num_bits = 1;
332 fields[2].out_value = &nr_w_buf;
333 fields[2].out_mask = NULL;
334 fields[2].in_value = NULL;
335 fields[2].in_check_value = NULL;
336 fields[2].in_check_mask = NULL;
337 fields[2].in_handler = NULL;
338 fields[2].in_handler_priv = NULL;
339
340 jtag_add_dr_scan(3, fields, -1);
341
342 fields[0].in_value = (u8*)value;
343
344 jtag_add_dr_scan(3, fields, -1);
345
346 return ERROR_OK;
347 }
348
349 int arm966e_write_cp15(target_t *target, int reg_addr, u32 value)
350 {
351 armv4_5_common_t *armv4_5 = target->arch_info;
352 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
353 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
354 scan_field_t fields[3];
355 u8 reg_addr_buf = reg_addr & 0x3f;
356 u8 nr_w_buf = 1;
357
358 jtag_add_end_state(TAP_RTI);
359 arm_jtag_scann(jtag_info, 0xf);
360 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr);
361
362 fields[0].device = jtag_info->chain_pos;
363 fields[0].num_bits = 32;
364 fields[0].out_value = (u8*)&value;
365 fields[0].out_mask = NULL;
366 fields[0].in_value = NULL;
367 fields[0].in_check_value = NULL;
368 fields[0].in_check_mask = NULL;
369 fields[0].in_handler = NULL;
370 fields[0].in_handler_priv = NULL;
371
372 fields[1].device = jtag_info->chain_pos;
373 fields[1].num_bits = 6;
374 fields[1].out_value = &reg_addr_buf;
375 fields[1].out_mask = NULL;
376 fields[1].in_value = NULL;
377 fields[1].in_check_value = NULL;
378 fields[1].in_check_mask = NULL;
379 fields[1].in_handler = NULL;
380 fields[1].in_handler_priv = NULL;
381
382 fields[2].device = jtag_info->chain_pos;
383 fields[2].num_bits = 1;
384 fields[2].out_value = &nr_w_buf;
385 fields[2].out_mask = NULL;
386 fields[2].in_value = NULL;
387 fields[2].in_check_value = NULL;
388 fields[2].in_check_mask = NULL;
389 fields[2].in_handler = NULL;
390 fields[2].in_handler_priv = NULL;
391
392 jtag_add_dr_scan(3, fields, -1);
393
394 return ERROR_OK;
395 }
396
397 int arm966e_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
398 {
399 int retval;
400 target_t *target = get_current_target(cmd_ctx);
401 armv4_5_common_t *armv4_5;
402 arm7_9_common_t *arm7_9;
403 arm9tdmi_common_t *arm9tdmi;
404 arm966e_common_t *arm966e;
405 arm_jtag_t *jtag_info;
406
407 if (arm966e_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm966e) != ERROR_OK)
408 {
409 command_print(cmd_ctx, "current target isn't an ARM966e target");
410 return ERROR_OK;
411 }
412
413 jtag_info = &arm7_9->jtag_info;
414
415 if (target->state != TARGET_HALTED)
416 {
417 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
418 return ERROR_OK;
419 }
420
421 /* one or more argument, access a single register (write if second argument is given */
422 if (argc >= 1)
423 {
424 int address = strtoul(args[0], NULL, 0);
425
426 if (argc == 1)
427 {
428 u32 value;
429 if ((retval = arm966e_read_cp15(target, address, &value)) != ERROR_OK)
430 {
431 command_print(cmd_ctx, "couldn't access reg %i", address);
432 return ERROR_OK;
433 }
434 jtag_execute_queue();
435
436 command_print(cmd_ctx, "%i: %8.8x", address, value);
437 }
438 else if (argc == 2)
439 {
440 u32 value = strtoul(args[1], NULL, 0);
441 if ((retval = arm966e_write_cp15(target, address, value)) != ERROR_OK)
442 {
443 command_print(cmd_ctx, "couldn't access reg %i", address);
444 return ERROR_OK;
445 }
446 command_print(cmd_ctx, "%i: %8.8x", address, value);
447 }
448 }
449
450 return ERROR_OK;
451 }
452
453 int arm966e_register_commands(struct command_context_s *cmd_ctx)
454 {
455 int retval;
456 command_t *arm966e_cmd;
457
458 retval = arm7_9_register_commands(cmd_ctx);
459 arm966e_cmd = register_command(cmd_ctx, NULL, "arm966e", NULL, COMMAND_ANY, "arm966e specific commands");
460 register_command(cmd_ctx, arm966e_cmd, "cp15", arm966e_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register <num> [value]");
461
462 return ERROR_OK;
463 }

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)