- added configurable delays after reset lines get deasserted. useful if reset circuit...
[openocd.git] / src / target / arm7_9_common.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 "replacements.h"
25
26 #include "embeddedice.h"
27 #include "target.h"
28 #include "armv4_5.h"
29 #include "arm_jtag.h"
30 #include "jtag.h"
31 #include "log.h"
32 #include "arm7_9_common.h"
33 #include "breakpoints.h"
34
35 #include <stdlib.h>
36 #include <string.h>
37 #include <unistd.h>
38
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <sys/time.h>
42 #include <errno.h>
43
44 int arm7_9_debug_entry(target_t *target);
45 int arm7_9_enable_sw_bkpts(struct target_s *target);
46
47 /* command handler forward declarations */
48 int handle_arm7_9_write_xpsr_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
49 int handle_arm7_9_write_xpsr_im8_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
50 int handle_arm7_9_read_core_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
51 int handle_arm7_9_write_core_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
52 int handle_arm7_9_sw_bkpts_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
53 int handle_arm7_9_force_hw_bkpts_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
54 int handle_arm7_9_dbgrq_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
55 int handle_arm7_9_fast_writes_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
56 int handle_arm7_9_dcc_downloads_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
57
58 int arm7_9_reinit_embeddedice(target_t *target)
59 {
60 armv4_5_common_t *armv4_5 = target->arch_info;
61 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
62
63 breakpoint_t *breakpoint = target->breakpoints;
64
65 arm7_9->wp_available = 2;
66 arm7_9->wp0_used = 0;
67 arm7_9->wp1_used = 0;
68
69 /* mark all hardware breakpoints as unset */
70 while (breakpoint)
71 {
72 if (breakpoint->type == BKPT_HARD)
73 {
74 breakpoint->set = 0;
75 }
76 breakpoint = breakpoint->next;
77 }
78
79 if (arm7_9->sw_bkpts_enabled && arm7_9->sw_bkpts_use_wp)
80 {
81 arm7_9->sw_bkpts_enabled = 0;
82 arm7_9_enable_sw_bkpts(target);
83 }
84
85 arm7_9->reinit_embeddedice = 0;
86
87 return ERROR_OK;
88 }
89
90 int arm7_9_jtag_callback(enum jtag_event event, void *priv)
91 {
92 target_t *target = priv;
93 armv4_5_common_t *armv4_5 = target->arch_info;
94 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
95
96 /* a test-logic reset occured
97 * the EmbeddedICE registers have been reset
98 * hardware breakpoints have been cleared
99 */
100 if (event == JTAG_TRST_ASSERTED)
101 {
102 arm7_9->reinit_embeddedice = 1;
103 }
104
105 return ERROR_OK;
106 }
107
108 int arm7_9_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, arm7_9_common_t **arm7_9_p)
109 {
110 armv4_5_common_t *armv4_5 = target->arch_info;
111 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
112
113 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
114 {
115 return -1;
116 }
117
118 if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
119 {
120 return -1;
121 }
122
123 *armv4_5_p = armv4_5;
124 *arm7_9_p = arm7_9;
125
126 return ERROR_OK;
127 }
128
129 int arm7_9_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
130 {
131 armv4_5_common_t *armv4_5 = target->arch_info;
132 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
133
134 if (target->state != TARGET_HALTED)
135 {
136 WARNING("target not halted");
137 return ERROR_TARGET_NOT_HALTED;
138 }
139
140 if (arm7_9->force_hw_bkpts)
141 breakpoint->type = BKPT_HARD;
142
143 if (breakpoint->set)
144 {
145 WARNING("breakpoint already set");
146 return ERROR_OK;
147 }
148
149 if (breakpoint->type == BKPT_HARD)
150 {
151 /* either an ARM (4 byte) or Thumb (2 byte) breakpoint */
152 u32 mask = (breakpoint->length == 4) ? 0x3u : 0x1u;
153 if (!arm7_9->wp0_used)
154 {
155 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE], breakpoint->address);
156 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], mask);
157 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffffu);
158 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], ~EICE_W_CTRL_nOPC & 0xff);
159 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], EICE_W_CTRL_ENABLE);
160
161 jtag_execute_queue();
162 arm7_9->wp0_used = 1;
163 breakpoint->set = 1;
164 }
165 else if (!arm7_9->wp1_used)
166 {
167 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE], breakpoint->address);
168 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], mask);
169 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK], 0xffffffffu);
170 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK], ~EICE_W_CTRL_nOPC & 0xff);
171 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], EICE_W_CTRL_ENABLE);
172
173 jtag_execute_queue();
174 arm7_9->wp1_used = 1;
175 breakpoint->set = 2;
176 }
177 else
178 {
179 ERROR("BUG: no hardware comparator available");
180 return ERROR_OK;
181 }
182 }
183 else if (breakpoint->type == BKPT_SOFT)
184 {
185 if (breakpoint->length == 4)
186 {
187 target->type->read_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr);
188 target->type->write_memory(target, breakpoint->address, 4, 1, (u8*)(&arm7_9->arm_bkpt));
189 }
190 else
191 {
192 target->type->read_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr);
193 target->type->write_memory(target, breakpoint->address, 2, 1, (u8*)(&arm7_9->thumb_bkpt));
194 }
195 breakpoint->set = 1;
196 }
197
198 return ERROR_OK;
199
200 }
201
202 int arm7_9_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
203 {
204 armv4_5_common_t *armv4_5 = target->arch_info;
205 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
206
207 if (target->state != TARGET_HALTED)
208 {
209 WARNING("target not halted");
210 return ERROR_TARGET_NOT_HALTED;
211 }
212
213 if (!breakpoint->set)
214 {
215 WARNING("breakpoint not set");
216 return ERROR_OK;
217 }
218
219 if (breakpoint->type == BKPT_HARD)
220 {
221 if (breakpoint->set == 1)
222 {
223 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x0);
224 jtag_execute_queue();
225 arm7_9->wp0_used = 0;
226 }
227 else if (breakpoint->set == 2)
228 {
229 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0x0);
230 jtag_execute_queue();
231 arm7_9->wp1_used = 0;
232 }
233 breakpoint->set = 0;
234 }
235 else
236 {
237 if (breakpoint->length == 4)
238 {
239 target->type->write_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr);
240 }
241 else
242 {
243 target->type->write_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr);
244 }
245 breakpoint->set = 0;
246 }
247
248 return ERROR_OK;
249 }
250
251 int arm7_9_add_breakpoint(struct target_s *target, u32 address, u32 length, enum breakpoint_type type)
252 {
253 armv4_5_common_t *armv4_5 = target->arch_info;
254 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
255
256 if (target->state != TARGET_HALTED)
257 {
258 WARNING("target not halted");
259 return ERROR_TARGET_NOT_HALTED;
260 }
261
262 if (arm7_9->force_hw_bkpts)
263 {
264 type = BKPT_HARD;
265 }
266
267 if ((type == BKPT_SOFT) && (arm7_9->sw_bkpts_enabled == 0))
268 {
269 INFO("sw breakpoint requested, but software breakpoints not enabled");
270 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
271 }
272
273 if ((type == BKPT_HARD) && (arm7_9->wp_available < 1))
274 {
275 INFO("no watchpoint unit available for hardware breakpoint");
276 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
277 }
278
279 if (type == BKPT_HARD)
280 arm7_9->wp_available--;
281
282 if ((length != 2) && (length != 4))
283 {
284 INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
285 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
286 }
287
288 return ERROR_OK;
289 }
290
291 int arm7_9_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
292 {
293 armv4_5_common_t *armv4_5 = target->arch_info;
294 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
295
296 if (target->state != TARGET_HALTED)
297 {
298 WARNING("target not halted");
299 return ERROR_TARGET_NOT_HALTED;
300 }
301
302 if (breakpoint->set)
303 {
304 arm7_9_unset_breakpoint(target, breakpoint);
305 }
306
307 if (breakpoint->type == BKPT_HARD)
308 arm7_9->wp_available++;
309
310 return ERROR_OK;
311 }
312
313 int arm7_9_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
314 {
315 armv4_5_common_t *armv4_5 = target->arch_info;
316 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
317 int rw_mask = 1;
318 u32 mask;
319
320 mask = watchpoint->length - 1;
321
322 if (target->state != TARGET_HALTED)
323 {
324 WARNING("target not halted");
325 return ERROR_TARGET_NOT_HALTED;
326 }
327
328 if (watchpoint->rw == WPT_ACCESS)
329 rw_mask = 0;
330 else
331 rw_mask = 1;
332
333 if (!arm7_9->wp0_used)
334 {
335 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE], watchpoint->address);
336 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], mask);
337 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], watchpoint->mask);
338 if( watchpoint->mask != 0xffffffffu )
339 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_VALUE], watchpoint->value);
340 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0xff & ~EICE_W_CTRL_nOPC & ~rw_mask);
341 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], EICE_W_CTRL_ENABLE | EICE_W_CTRL_nOPC | (watchpoint->rw & 1));
342
343 jtag_execute_queue();
344 watchpoint->set = 1;
345 arm7_9->wp0_used = 2;
346 }
347 else if (!arm7_9->wp1_used)
348 {
349 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE], watchpoint->address);
350 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], mask);
351 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK], watchpoint->mask);
352 if( watchpoint->mask != 0xffffffffu )
353 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_VALUE], watchpoint->value);
354 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK], 0xff & ~EICE_W_CTRL_nOPC & ~rw_mask);
355 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], EICE_W_CTRL_ENABLE | EICE_W_CTRL_nOPC | (watchpoint->rw & 1));
356
357 jtag_execute_queue();
358 watchpoint->set = 2;
359 arm7_9->wp1_used = 2;
360 }
361 else
362 {
363 ERROR("BUG: no hardware comparator available");
364 return ERROR_OK;
365 }
366
367 return ERROR_OK;
368 }
369
370 int arm7_9_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
371 {
372 armv4_5_common_t *armv4_5 = target->arch_info;
373 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
374
375 if (target->state != TARGET_HALTED)
376 {
377 WARNING("target not halted");
378 return ERROR_TARGET_NOT_HALTED;
379 }
380
381 if (!watchpoint->set)
382 {
383 WARNING("breakpoint not set");
384 return ERROR_OK;
385 }
386
387 if (watchpoint->set == 1)
388 {
389 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x0);
390 jtag_execute_queue();
391 arm7_9->wp0_used = 0;
392 }
393 else if (watchpoint->set == 2)
394 {
395 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0x0);
396 jtag_execute_queue();
397 arm7_9->wp1_used = 0;
398 }
399 watchpoint->set = 0;
400
401 return ERROR_OK;
402 }
403
404 int arm7_9_add_watchpoint(struct target_s *target, u32 address, u32 length, enum watchpoint_rw rw)
405 {
406 armv4_5_common_t *armv4_5 = target->arch_info;
407 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
408
409 if (target->state != TARGET_HALTED)
410 {
411 WARNING("target not halted");
412 return ERROR_TARGET_NOT_HALTED;
413 }
414
415 if (arm7_9->wp_available < 1)
416 {
417 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
418 }
419
420 if ((length != 1) && (length != 2) && (length != 4))
421 {
422 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
423 }
424
425 arm7_9->wp_available--;
426
427 return ERROR_OK;
428 }
429
430 int arm7_9_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
431 {
432 armv4_5_common_t *armv4_5 = target->arch_info;
433 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
434
435 if (target->state != TARGET_HALTED)
436 {
437 WARNING("target not halted");
438 return ERROR_TARGET_NOT_HALTED;
439 }
440
441 if (watchpoint->set)
442 {
443 arm7_9_unset_watchpoint(target, watchpoint);
444 }
445
446 arm7_9->wp_available++;
447
448 return ERROR_OK;
449 }
450
451 int arm7_9_enable_sw_bkpts(struct target_s *target)
452 {
453 armv4_5_common_t *armv4_5 = target->arch_info;
454 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
455 int retval;
456
457 if (arm7_9->sw_bkpts_enabled)
458 return ERROR_OK;
459
460 if (arm7_9->wp_available < 1)
461 {
462 WARNING("can't enable sw breakpoints with no watchpoint unit available");
463 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
464 }
465 arm7_9->wp_available--;
466
467 if (!arm7_9->wp0_used)
468 {
469 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_VALUE], arm7_9->arm_bkpt);
470 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0x0);
471 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0xffffffffu);
472 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], ~EICE_W_CTRL_nOPC & 0xff);
473 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], EICE_W_CTRL_ENABLE);
474 arm7_9->sw_bkpts_enabled = 1;
475 arm7_9->wp0_used = 3;
476 }
477 else if (!arm7_9->wp1_used)
478 {
479 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_VALUE], arm7_9->arm_bkpt);
480 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK], 0x0);
481 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], 0xffffffffu);
482 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK], ~EICE_W_CTRL_nOPC & 0xff);
483 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], EICE_W_CTRL_ENABLE);
484 arm7_9->sw_bkpts_enabled = 2;
485 arm7_9->wp1_used = 3;
486 }
487 else
488 {
489 ERROR("BUG: both watchpoints used, but wp_available >= 1");
490 exit(-1);
491 }
492
493 if ((retval = jtag_execute_queue()) != ERROR_OK)
494 {
495 ERROR("error writing EmbeddedICE registers to enable sw breakpoints");
496 exit(-1);
497 };
498
499 return ERROR_OK;
500 }
501
502 int arm7_9_disable_sw_bkpts(struct target_s *target)
503 {
504 armv4_5_common_t *armv4_5 = target->arch_info;
505 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
506
507 if (!arm7_9->sw_bkpts_enabled)
508 return ERROR_OK;
509
510 if (arm7_9->sw_bkpts_enabled == 1)
511 {
512 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x0);
513 arm7_9->sw_bkpts_enabled = 0;
514 arm7_9->wp0_used = 0;
515 arm7_9->wp_available++;
516 }
517 else if (arm7_9->sw_bkpts_enabled == 2)
518 {
519 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0x0);
520 arm7_9->sw_bkpts_enabled = 0;
521 arm7_9->wp1_used = 0;
522 arm7_9->wp_available++;
523 }
524
525 return ERROR_OK;
526 }
527
528 int arm7_9_execute_sys_speed(struct target_s *target)
529 {
530 int timeout;
531 int retval;
532
533 armv4_5_common_t *armv4_5 = target->arch_info;
534 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
535 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
536 reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
537
538 /* set RESTART instruction */
539 jtag_add_end_state(TAP_RTI);
540 arm_jtag_set_instr(jtag_info, 0x4);
541
542 for (timeout=0; timeout<50; timeout++)
543 {
544 /* read debug status register */
545 embeddedice_read_reg(dbg_stat);
546 if ((retval = jtag_execute_queue()) != ERROR_OK)
547 return retval;
548 if ((buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1))
549 && (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_SYSCOMP, 1)))
550 break;
551 usleep(100000);
552 }
553 if (timeout == 50)
554 {
555 ERROR("timeout waiting for SYSCOMP & DBGACK, last DBG_STATUS: %x", buf_get_u32(dbg_stat->value, 0, dbg_stat->size));
556 return ERROR_TARGET_TIMEOUT;
557 }
558
559 return ERROR_OK;
560 }
561
562 int arm7_9_execute_fast_sys_speed(struct target_s *target)
563 {
564 u8 check_value[4], check_mask[4];
565
566 armv4_5_common_t *armv4_5 = target->arch_info;
567 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
568 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
569 reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
570
571 /* set RESTART instruction */
572 jtag_add_end_state(TAP_RTI);
573 arm_jtag_set_instr(jtag_info, 0x4);
574
575 /* check for DBGACK and SYSCOMP set (others don't care) */
576 buf_set_u32(check_value, 0, 32, 0x9);
577 buf_set_u32(check_mask, 0, 32, 0x9);
578
579 /* read debug status register */
580 embeddedice_read_reg_w_check(dbg_stat, check_value, check_value);
581
582 return ERROR_OK;
583 }
584
585 enum target_state arm7_9_poll(target_t *target)
586 {
587 int retval;
588 armv4_5_common_t *armv4_5 = target->arch_info;
589 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
590 reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
591 reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
592
593 if (arm7_9->reinit_embeddedice)
594 {
595 arm7_9_reinit_embeddedice(target);
596 }
597
598 /* read debug status register */
599 embeddedice_read_reg(dbg_stat);
600 if ((retval = jtag_execute_queue()) != ERROR_OK)
601 {
602 switch (retval)
603 {
604 case ERROR_JTAG_QUEUE_FAILED:
605 ERROR("JTAG queue failed while reading EmbeddedICE status register");
606 exit(-1);
607 break;
608 default:
609 break;
610 }
611 }
612
613 if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1))
614 {
615 DEBUG("DBGACK set, dbg_state->value: 0x%x", buf_get_u32(dbg_stat->value, 0, 32));
616 if ((target->state == TARGET_UNKNOWN))
617 {
618 WARNING("DBGACK set while target was in unknown state. Reset or initialize target before resuming");
619 target->state = TARGET_RUNNING;
620 }
621 if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET))
622 {
623 target->state = TARGET_HALTED;
624 if ((retval = arm7_9_debug_entry(target)) != ERROR_OK)
625 return retval;
626
627 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
628 }
629 if (target->state == TARGET_DEBUG_RUNNING)
630 {
631 target->state = TARGET_HALTED;
632 if ((retval = arm7_9_debug_entry(target)) != ERROR_OK)
633 return retval;
634
635 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
636 }
637 }
638 else
639 {
640 if (target->state != TARGET_DEBUG_RUNNING)
641 target->state = TARGET_RUNNING;
642 }
643
644 return target->state;
645 }
646
647 int arm7_9_assert_reset(target_t *target)
648 {
649 int retval;
650
651 DEBUG("target->state: %s", target_state_strings[target->state]);
652
653 if (target->state == TARGET_HALTED || target->state == TARGET_UNKNOWN)
654 {
655 /* assert SRST and TRST */
656 /* system would get ouf sync if we didn't reset test-logic, too */
657 if ((retval = jtag_add_reset(1, 1)) != ERROR_OK)
658 {
659 if (retval == ERROR_JTAG_RESET_CANT_SRST)
660 {
661 WARNING("can't assert srst");
662 return retval;
663 }
664 else
665 {
666 ERROR("unknown error");
667 exit(-1);
668 }
669 }
670 jtag_add_sleep(5000);
671 if ((retval = jtag_add_reset(0, 1)) != ERROR_OK)
672 {
673 if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
674 {
675 WARNING("srst resets test logic, too");
676 retval = jtag_add_reset(1, 1);
677 }
678 }
679 }
680 else
681 {
682 if ((retval = jtag_add_reset(0, 1)) != ERROR_OK)
683 {
684 if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
685 {
686 WARNING("srst resets test logic, too");
687 retval = jtag_add_reset(1, 1);
688 }
689
690 if (retval == ERROR_JTAG_RESET_CANT_SRST)
691 {
692 WARNING("can't assert srst");
693 return retval;
694 }
695 else if (retval != ERROR_OK)
696 {
697 ERROR("unknown error");
698 exit(-1);
699 }
700 }
701 }
702
703 target->state = TARGET_RESET;
704 jtag_add_sleep(50000);
705
706 armv4_5_invalidate_core_regs(target);
707
708 return ERROR_OK;
709
710 }
711
712 int arm7_9_deassert_reset(target_t *target)
713 {
714 DEBUG("target->state: %s", target_state_strings[target->state]);
715
716 /* deassert reset lines */
717 jtag_add_reset(0, 0);
718
719 return ERROR_OK;
720
721 }
722
723 int arm7_9_soft_reset_halt(struct target_s *target)
724 {
725 armv4_5_common_t *armv4_5 = target->arch_info;
726 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
727 reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
728 int i;
729
730 if (target->state == TARGET_RUNNING)
731 {
732 target->type->halt(target);
733 }
734
735 while (buf_get_u32(dbg_stat->value, EICE_DBG_CONTROL_DBGACK, 1) == 0)
736 {
737 embeddedice_read_reg(dbg_stat);
738 jtag_execute_queue();
739 }
740 target->state = TARGET_HALTED;
741
742 /* all register content is now invalid */
743 armv4_5_invalidate_core_regs(target);
744
745 /* SVC, ARM state, IRQ and FIQ disabled */
746 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8, 0xd3);
747 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
748 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
749
750 /* start fetching from 0x0 */
751 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
752 armv4_5->core_cache->reg_list[15].dirty = 1;
753 armv4_5->core_cache->reg_list[15].valid = 1;
754
755 armv4_5->core_mode = ARMV4_5_MODE_SVC;
756 armv4_5->core_state = ARMV4_5_STATE_ARM;
757
758 /* reset registers */
759 for (i = 0; i <= 14; i++)
760 {
761 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).value, 0, 32, 0xffffffff);
762 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = 1;
763 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid = 1;
764 }
765
766 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
767
768 return ERROR_OK;
769 }
770
771 int arm7_9_halt(target_t *target)
772 {
773 armv4_5_common_t *armv4_5 = target->arch_info;
774 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
775 reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
776
777 DEBUG("target->state: %s", target_state_strings[target->state]);
778
779 if (target->state == TARGET_HALTED)
780 {
781 WARNING("target was already halted");
782 return ERROR_TARGET_ALREADY_HALTED;
783 }
784
785 if (target->state == TARGET_UNKNOWN)
786 {
787 WARNING("target was in unknown state when halt was requested");
788 }
789
790 if ((target->state == TARGET_RESET) && (jtag_reset_config & RESET_SRST_PULLS_TRST) && (jtag_srst))
791 {
792 ERROR("can't request a halt while in reset if nSRST pulls nTRST");
793 return ERROR_TARGET_FAILURE;
794 }
795
796 if (arm7_9->use_dbgrq)
797 {
798 /* program EmbeddedICE Debug Control Register to assert DBGRQ
799 */
800 buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 1);
801 embeddedice_store_reg(dbg_ctrl);
802 }
803 else
804 {
805 /* program watchpoint unit to match on any address
806 */
807 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0xffffffff);
808 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff);
809 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x100);
810 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0xf7);
811 }
812
813 target->debug_reason = DBG_REASON_DBGRQ;
814
815 return ERROR_OK;
816 }
817
818 int arm7_9_clear_halt(target_t *target)
819 {
820 armv4_5_common_t *armv4_5 = target->arch_info;
821 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
822 reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
823
824 if (arm7_9->use_dbgrq)
825 {
826 /* program EmbeddedICE Debug Control Register to deassert DBGRQ
827 */
828 buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 0);
829 embeddedice_store_reg(dbg_ctrl);
830 }
831 else
832 {
833 /* restore registers if watchpoint unit 0 was in use
834 */
835 if (arm7_9->wp0_used)
836 {
837 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK]);
838 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK]);
839 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK]);
840 }
841 /* control value always has to be restored, as it was either disabled,
842 * or enabled with possibly different bits
843 */
844 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE]);
845 }
846
847 return ERROR_OK;
848 }
849
850 int arm7_9_debug_entry(target_t *target)
851 {
852 int i;
853 u32 context[16];
854 u32* context_p[16];
855 u32 r0_thumb, pc_thumb;
856 u32 cpsr;
857 int retval;
858 /* get pointers to arch-specific information */
859 armv4_5_common_t *armv4_5 = target->arch_info;
860 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
861 reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
862 reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
863
864 #ifdef _DEBUG_ARM7_9_
865 DEBUG("");
866 #endif
867
868 if (arm7_9->pre_debug_entry)
869 arm7_9->pre_debug_entry(target);
870
871 /* program EmbeddedICE Debug Control Register to assert DBGACK and INTDIS
872 * ensure that DBGRQ is cleared
873 */
874 buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 1);
875 buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 0);
876 buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_INTDIS, 1, 1);
877 embeddedice_store_reg(dbg_ctrl);
878
879 arm7_9_clear_halt(target);
880
881 if ((retval = jtag_execute_queue()) != ERROR_OK)
882 {
883 switch (retval)
884 {
885 case ERROR_JTAG_QUEUE_FAILED:
886 ERROR("JTAG queue failed while writing EmbeddedICE control register");
887 exit(-1);
888 break;
889 default:
890 break;
891 }
892 }
893
894 if ((retval = arm7_9->examine_debug_reason(target)) != ERROR_OK)
895 return retval;
896
897
898 if (target->state != TARGET_HALTED)
899 {
900 WARNING("target not halted");
901 return ERROR_TARGET_NOT_HALTED;
902 }
903
904 /* if the target is in Thumb state, change to ARM state */
905 if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_ITBIT, 1))
906 {
907 DEBUG("target entered debug from Thumb state");
908 /* Entered debug from Thumb mode */
909 armv4_5->core_state = ARMV4_5_STATE_THUMB;
910 arm7_9->change_to_arm(target, &r0_thumb, &pc_thumb);
911 DEBUG("r0_thumb: 0x%8.8x, pc_thumb: 0x%8.8x", r0_thumb, pc_thumb);
912 }
913 else
914 {
915 DEBUG("target entered debug from ARM state");
916 /* Entered debug from ARM mode */
917 armv4_5->core_state = ARMV4_5_STATE_ARM;
918 }
919
920 for (i = 0; i < 16; i++)
921 context_p[i] = &context[i];
922 /* save core registers (r0 - r15 of current core mode) */
923 arm7_9->read_core_regs(target, 0xffff, context_p);
924
925 arm7_9->read_xpsr(target, &cpsr, 0);
926
927 if ((retval = jtag_execute_queue()) != ERROR_OK)
928 return retval;
929 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32, cpsr);
930 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 0;
931 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
932
933 armv4_5->core_mode = cpsr & 0x1f;
934 DEBUG("target entered debug state in %s mode", armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)]);
935
936 if (armv4_5_mode_to_number(armv4_5->core_mode) == -1)
937 {
938 target->state = TARGET_UNKNOWN;
939 ERROR("cpsr contains invalid mode value - communication failure");
940 return ERROR_TARGET_FAILURE;
941 }
942
943 if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
944 {
945 DEBUG("thumb state, applying fixups");
946 context[0] = r0_thumb;
947 context[15] = pc_thumb;
948 } else if (armv4_5->core_state == ARMV4_5_STATE_ARM)
949 {
950 /* adjust value stored by STM */
951 context[15] -= 3 * 4;
952 }
953
954 if ((target->debug_reason == DBG_REASON_BREAKPOINT)
955 || (target->debug_reason == DBG_REASON_SINGLESTEP)
956 || (target->debug_reason == DBG_REASON_WATCHPOINT)
957 || (target->debug_reason == DBG_REASON_WPTANDBKPT)
958 || ((target->debug_reason == DBG_REASON_DBGRQ) && (arm7_9->use_dbgrq == 0)))
959 context[15] -= 3 * ((armv4_5->core_state == ARMV4_5_STATE_ARM) ? 4 : 2);
960 else if (target->debug_reason == DBG_REASON_DBGRQ)
961 context[15] -= arm7_9->dbgreq_adjust_pc * ((armv4_5->core_state == ARMV4_5_STATE_ARM) ? 4 : 2);
962 else
963 {
964 ERROR("unknown debug reason: %i", target->debug_reason);
965 }
966
967
968 for (i=0; i<=15; i++)
969 {
970 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).value, 0, 32, context[i]);
971 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = 0;
972 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid = 1;
973 }
974
975 DEBUG("entered debug state at PC 0x%x", context[15]);
976
977 /* exceptions other than USR & SYS have a saved program status register */
978 if ((armv4_5_mode_to_number(armv4_5->core_mode) != ARMV4_5_MODE_USR) && (armv4_5_mode_to_number(armv4_5->core_mode) != ARMV4_5_MODE_SYS))
979 {
980 u32 spsr;
981 arm7_9->read_xpsr(target, &spsr, 1);
982 jtag_execute_queue();
983 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32, spsr);
984 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).dirty = 0;
985 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).valid = 1;
986 }
987
988 /* r0 and r15 (pc) have to be restored later */
989 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = 1;
990 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 15).dirty = 1;
991
992 if ((retval = jtag->execute_queue()) != ERROR_OK)
993 return retval;
994
995 if (arm7_9->post_debug_entry)
996 arm7_9->post_debug_entry(target);
997
998 return ERROR_OK;
999 }
1000
1001 int arm7_9_full_context(target_t *target)
1002 {
1003 int i;
1004 int retval;
1005 armv4_5_common_t *armv4_5 = target->arch_info;
1006 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1007
1008 DEBUG("");
1009
1010 if (target->state != TARGET_HALTED)
1011 {
1012 WARNING("target not halted");
1013 return ERROR_TARGET_NOT_HALTED;
1014 }
1015
1016 /* iterate through processor modes (User, FIQ, IRQ, SVC, ABT, UND)
1017 * SYS shares registers with User, so we don't touch SYS
1018 */
1019 for(i = 0; i < 6; i++)
1020 {
1021 u32 mask = 0;
1022 u32* reg_p[16];
1023 int j;
1024 int valid = 1;
1025
1026 /* check if there are invalid registers in the current mode
1027 */
1028 for (j = 0; j <= 16; j++)
1029 {
1030 if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).valid == 0)
1031 valid = 0;
1032 }
1033
1034 if (!valid)
1035 {
1036 u32 tmp_cpsr;
1037
1038 /* change processor mode */
1039 tmp_cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & 0xE0;
1040 tmp_cpsr |= armv4_5_number_to_mode(i);
1041 arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);
1042
1043 for (j = 0; j < 15; j++)
1044 {
1045 if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).valid == 0)
1046 {
1047 reg_p[j] = (u32*)ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).value;
1048 mask |= 1 << j;
1049 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).valid = 1;
1050 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty = 0;
1051 }
1052 }
1053
1054 /* if only the PSR is invalid, mask is all zeroes */
1055 if (mask)
1056 arm7_9->read_core_regs(target, mask, reg_p);
1057
1058 /* check if the PSR has to be read */
1059 if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).valid == 0)
1060 {
1061 arm7_9->read_xpsr(target, (u32*)ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).value, 1);
1062 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).valid = 1;
1063 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty = 0;
1064 }
1065 }
1066 }
1067
1068 /* restore processor mode */
1069 arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8), 0, 0);
1070
1071 if ((retval = jtag_execute_queue()) != ERROR_OK)
1072 {
1073 ERROR("JTAG failure");
1074 exit(-1);
1075 }
1076 return ERROR_OK;
1077 }
1078
1079 int arm7_9_restore_context(target_t *target)
1080 {
1081 armv4_5_common_t *armv4_5 = target->arch_info;
1082 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1083 reg_t *reg;
1084 armv4_5_core_reg_t *reg_arch_info;
1085 enum armv4_5_mode current_mode = armv4_5->core_mode;
1086 int i, j;
1087 int dirty;
1088 int mode_change;
1089
1090 DEBUG("");
1091
1092 if (target->state != TARGET_HALTED)
1093 {
1094 WARNING("target not halted");
1095 return ERROR_TARGET_NOT_HALTED;
1096 }
1097
1098 if (arm7_9->pre_restore_context)
1099 arm7_9->pre_restore_context(target);
1100
1101 /* iterate through processor modes (User, FIQ, IRQ, SVC, ABT, UND)
1102 * SYS shares registers with User, so we don't touch SYS
1103 */
1104 for (i = 0; i < 6; i++)
1105 {
1106 DEBUG("examining %s mode", armv4_5_mode_strings[i]);
1107 dirty = 0;
1108 mode_change = 0;
1109 /* check if there are dirty registers in the current mode
1110 */
1111 for (j = 0; j <= 16; j++)
1112 {
1113 reg = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j);
1114 reg_arch_info = reg->arch_info;
1115 if (reg->dirty == 1)
1116 {
1117 if (reg->valid == 1)
1118 {
1119 dirty = 1;
1120 DEBUG("examining dirty reg: %s", reg->name);
1121 if ((reg_arch_info->mode != ARMV4_5_MODE_ANY)
1122 && (reg_arch_info->mode != current_mode)
1123 && !((reg_arch_info->mode == ARMV4_5_MODE_USR) && (armv4_5->core_mode == ARMV4_5_MODE_SYS))
1124 && !((reg_arch_info->mode == ARMV4_5_MODE_SYS) && (armv4_5->core_mode == ARMV4_5_MODE_USR)))
1125 {
1126 mode_change = 1;
1127 DEBUG("require mode change");
1128 }
1129 }
1130 else
1131 {
1132 ERROR("BUG: dirty register '%s', but no valid data", reg->name);
1133 exit(-1);
1134 }
1135 }
1136 }
1137
1138 if (dirty)
1139 {
1140 u32 mask = 0x0;
1141 int num_regs = 0;
1142 u32 regs[16];
1143
1144 if (mode_change)
1145 {
1146 u32 tmp_cpsr;
1147
1148 /* change processor mode */
1149 tmp_cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & 0xE0;
1150 tmp_cpsr |= armv4_5_number_to_mode(i);
1151 arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);
1152 current_mode = armv4_5_number_to_mode(i);
1153 }
1154
1155 for (j = 0; j <= 14; j++)
1156 {
1157 reg = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j);
1158 reg_arch_info = reg->arch_info;
1159
1160
1161 if (reg->dirty == 1)
1162 {
1163 regs[j] = buf_get_u32(reg->value, 0, 32);
1164 mask |= 1 << j;
1165 num_regs++;
1166 reg->dirty = 0;
1167 reg->valid = 1;
1168 DEBUG("writing register %i of mode %s with value 0x%8.8x", j, armv4_5_mode_strings[i], regs[j]);
1169 }
1170 }
1171
1172 if (mask)
1173 {
1174 arm7_9->write_core_regs(target, mask, regs);
1175 }
1176
1177 reg = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16);
1178 reg_arch_info = reg->arch_info;
1179 if ((reg->dirty) && (reg_arch_info->mode != ARMV4_5_MODE_ANY))
1180 {
1181 DEBUG("writing SPSR of mode %i with value 0x%8.8x", i, buf_get_u32(reg->value, 0, 32));
1182 arm7_9->write_xpsr(target, buf_get_u32(reg->value, 0, 32), 1);
1183 }
1184 }
1185 }
1186
1187 if ((armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty == 0) && (armv4_5->core_mode != current_mode))
1188 {
1189 /* restore processor mode */
1190 u32 tmp_cpsr;
1191
1192 tmp_cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & 0xE0;
1193 tmp_cpsr |= armv4_5_number_to_mode(i);
1194 DEBUG("writing lower 8 bit of cpsr with value 0x%2.2x", tmp_cpsr);
1195 arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);
1196 }
1197 else if (armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty == 1)
1198 {
1199 /* CPSR has been changed, full restore necessary */
1200 DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1201 arm7_9->write_xpsr(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32), 0);
1202 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 0;
1203 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
1204 }
1205
1206 /* restore PC */
1207 DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1208 arm7_9->write_pc(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1209 armv4_5->core_cache->reg_list[15].dirty = 0;
1210
1211 if (arm7_9->post_restore_context)
1212 arm7_9->post_restore_context(target);
1213
1214 return ERROR_OK;
1215 }
1216
1217 int arm7_9_restart_core(struct target_s *target)
1218 {
1219 armv4_5_common_t *armv4_5 = target->arch_info;
1220 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1221 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
1222
1223 /* set RESTART instruction */
1224 jtag_add_end_state(TAP_RTI);
1225 arm_jtag_set_instr(jtag_info, 0x4);
1226
1227 jtag_add_runtest(1, TAP_RTI);
1228 if ((jtag_execute_queue()) != ERROR_OK)
1229 {
1230 exit(-1);
1231 }
1232
1233 return ERROR_OK;
1234 }
1235
1236 void arm7_9_enable_watchpoints(struct target_s *target)
1237 {
1238 watchpoint_t *watchpoint = target->watchpoints;
1239
1240 while (watchpoint)
1241 {
1242 if (watchpoint->set == 0)
1243 arm7_9_set_watchpoint(target, watchpoint);
1244 watchpoint = watchpoint->next;
1245 }
1246 }
1247
1248 void arm7_9_enable_breakpoints(struct target_s *target)
1249 {
1250 breakpoint_t *breakpoint = target->breakpoints;
1251
1252 /* set any pending breakpoints */
1253 while (breakpoint)
1254 {
1255 if (breakpoint->set == 0)
1256 arm7_9_set_breakpoint(target, breakpoint);
1257 breakpoint = breakpoint->next;
1258 }
1259 }
1260
1261 void arm7_9_disable_bkpts_and_wpts(struct target_s *target)
1262 {
1263 breakpoint_t *breakpoint = target->breakpoints;
1264 watchpoint_t *watchpoint = target->watchpoints;
1265
1266 /* set any pending breakpoints */
1267 while (breakpoint)
1268 {
1269 if (breakpoint->set != 0)
1270 arm7_9_unset_breakpoint(target, breakpoint);
1271 breakpoint = breakpoint->next;
1272 }
1273
1274 while (watchpoint)
1275 {
1276 if (watchpoint->set != 0)
1277 arm7_9_unset_watchpoint(target, watchpoint);
1278 watchpoint = watchpoint->next;
1279 }
1280 }
1281
1282 int arm7_9_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution)
1283 {
1284 armv4_5_common_t *armv4_5 = target->arch_info;
1285 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1286 breakpoint_t *breakpoint = target->breakpoints;
1287 reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
1288
1289 DEBUG("");
1290
1291 if (target->state != TARGET_HALTED)
1292 {
1293 WARNING("target not halted");
1294 return ERROR_TARGET_NOT_HALTED;
1295 }
1296
1297 if (!debug_execution)
1298 {
1299 target_free_all_working_areas(target);
1300 }
1301
1302 /* current = 1: continue on current pc, otherwise continue at <address> */
1303 if (!current)
1304 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address);
1305
1306 /* the front-end may request us not to handle breakpoints */
1307 if (handle_breakpoints)
1308 {
1309 if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))))
1310 {
1311 DEBUG("unset breakpoint at 0x%8.8x", breakpoint->address);
1312 arm7_9_unset_breakpoint(target, breakpoint);
1313
1314 DEBUG("enable single-step");
1315 arm7_9->enable_single_step(target);
1316
1317 target->debug_reason = DBG_REASON_SINGLESTEP;
1318
1319 arm7_9_restore_context(target);
1320
1321 if (armv4_5->core_state == ARMV4_5_STATE_ARM)
1322 arm7_9->branch_resume(target);
1323 else if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
1324 {
1325 arm7_9->branch_resume_thumb(target);
1326 }
1327 else
1328 {
1329 ERROR("unhandled core state");
1330 exit(-1);
1331 }
1332
1333 buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 0);
1334 embeddedice_write_reg(dbg_ctrl, buf_get_u32(dbg_ctrl->value, 0, dbg_ctrl->size));
1335 arm7_9_execute_sys_speed(target);
1336
1337 DEBUG("disable single-step");
1338 arm7_9->disable_single_step(target);
1339
1340 arm7_9_debug_entry(target);
1341 DEBUG("new PC after step: 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1342
1343 DEBUG("set breakpoint at 0x%8.8x", breakpoint->address);
1344 arm7_9_set_breakpoint(target, breakpoint);
1345 }
1346 }
1347
1348 /* enable any pending breakpoints and watchpoints */
1349 arm7_9_enable_breakpoints(target);
1350 arm7_9_enable_watchpoints(target);
1351
1352 arm7_9_restore_context(target);
1353
1354 if (armv4_5->core_state == ARMV4_5_STATE_ARM)
1355 {
1356 arm7_9->branch_resume(target);
1357 }
1358 else if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
1359 {
1360 arm7_9->branch_resume_thumb(target);
1361 }
1362 else
1363 {
1364 ERROR("unhandled core state");
1365 exit(-1);
1366 }
1367
1368 /* deassert DBGACK and INTDIS */
1369 buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 0);
1370 /* INTDIS only when we really resume, not during debug execution */
1371 if (!debug_execution)
1372 buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_INTDIS, 1, 0);
1373 embeddedice_write_reg(dbg_ctrl, buf_get_u32(dbg_ctrl->value, 0, dbg_ctrl->size));
1374
1375 arm7_9_restart_core(target);
1376
1377 target->debug_reason = DBG_REASON_NOTHALTED;
1378
1379 if (!debug_execution)
1380 {
1381 /* registers are now invalid */
1382 armv4_5_invalidate_core_regs(target);
1383 target->state = TARGET_RUNNING;
1384 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1385 }
1386 else
1387 {
1388 target->state = TARGET_DEBUG_RUNNING;
1389 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
1390 }
1391
1392 DEBUG("target resumed");
1393
1394 return ERROR_OK;
1395 }
1396
1397 void arm7_9_enable_eice_step(target_t *target)
1398 {
1399 armv4_5_common_t *armv4_5 = target->arch_info;
1400 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1401
1402 /* setup an inverse breakpoint on the current PC
1403 * - comparator 1 matches the current address
1404 * - rangeout from comparator 1 is connected to comparator 0 rangein
1405 * - comparator 0 matches any address, as long as rangein is low */
1406 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0xffffffff);
1407 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff);
1408 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x100);
1409 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0x77);
1410 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE], buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1411 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], 0);
1412 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK], 0xffffffff);
1413 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0x0);
1414 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK], 0xf7);
1415 }
1416
1417 void arm7_9_disable_eice_step(target_t *target)
1418 {
1419 armv4_5_common_t *armv4_5 = target->arch_info;
1420 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1421
1422 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK]);
1423 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK]);
1424 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE]);
1425 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK]);
1426 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE]);
1427 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK]);
1428 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK]);
1429 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK]);
1430 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE]);
1431 }
1432
1433 int arm7_9_step(struct target_s *target, int current, u32 address, int handle_breakpoints)
1434 {
1435 armv4_5_common_t *armv4_5 = target->arch_info;
1436 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1437 breakpoint_t *breakpoint = target->breakpoints;
1438
1439 if (target->state != TARGET_HALTED)
1440 {
1441 WARNING("target not halted");
1442 return ERROR_TARGET_NOT_HALTED;
1443 }
1444
1445 /* current = 1: continue on current pc, otherwise continue at <address> */
1446 if (!current)
1447 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address);
1448
1449 /* the front-end may request us not to handle breakpoints */
1450 if (handle_breakpoints)
1451 if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))))
1452 arm7_9_unset_breakpoint(target, breakpoint);
1453
1454 target->debug_reason = DBG_REASON_SINGLESTEP;
1455
1456 arm7_9_restore_context(target);
1457
1458 arm7_9->enable_single_step(target);
1459
1460 if (armv4_5->core_state == ARMV4_5_STATE_ARM)
1461 {
1462 arm7_9->branch_resume(target);
1463 }
1464 else if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
1465 {
1466 arm7_9->branch_resume_thumb(target);
1467 }
1468 else
1469 {
1470 ERROR("unhandled core state");
1471 exit(-1);
1472 }
1473
1474 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1475
1476 arm7_9_execute_sys_speed(target);
1477 arm7_9->disable_single_step(target);
1478
1479 /* registers are now invalid */
1480 armv4_5_invalidate_core_regs(target);
1481
1482 arm7_9_debug_entry(target);
1483
1484 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1485
1486 if (breakpoint)
1487 arm7_9_set_breakpoint(target, breakpoint);
1488
1489 DEBUG("target stepped");
1490
1491 return ERROR_OK;
1492
1493 }
1494
1495 int arm7_9_read_core_reg(struct target_s *target, int num, enum armv4_5_mode mode)
1496 {
1497 u32* reg_p[16];
1498 int retval;
1499 armv4_5_common_t *armv4_5 = target->arch_info;
1500 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1501 enum armv4_5_mode reg_mode = ((armv4_5_core_reg_t*)ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).arch_info)->mode;
1502
1503 if ((num < 0) || (num > 16))
1504 return ERROR_INVALID_ARGUMENTS;
1505
1506 if ((mode != ARMV4_5_MODE_ANY)
1507 && (mode != armv4_5->core_mode)
1508 && (reg_mode != ARMV4_5_MODE_ANY))
1509 {
1510 u32 tmp_cpsr;
1511
1512 /* change processor mode */
1513 tmp_cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & 0xE0;
1514 tmp_cpsr |= mode;
1515 arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);
1516 }
1517
1518 if ((num >= 0) && (num <= 15))
1519 {
1520 /* read a normal core register */
1521 reg_p[num] = (u32*)ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).value;
1522
1523 arm7_9->read_core_regs(target, 1 << num, reg_p);
1524 }
1525 else
1526 {
1527 /* read a program status register
1528 * if the register mode is MODE_ANY, we read the cpsr, otherwise a spsr
1529 */
1530 armv4_5_core_reg_t *arch_info = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).arch_info;
1531 int spsr = (arch_info->mode == ARMV4_5_MODE_ANY) ? 0 : 1;
1532
1533 arm7_9->read_xpsr(target, (u32*)ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).value, spsr);
1534 }
1535
1536 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
1537 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).dirty = 0;
1538
1539 if ((mode != ARMV4_5_MODE_ANY)
1540 && (mode != armv4_5->core_mode)
1541 && (reg_mode != ARMV4_5_MODE_ANY)) {
1542 /* restore processor mode */
1543 arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8), 0, 0);
1544 }
1545
1546 if ((retval = jtag_execute_queue()) != ERROR_OK)
1547 {
1548 ERROR("JTAG failure");
1549 exit(-1);
1550 }
1551
1552 return ERROR_OK;
1553
1554 }
1555
1556 int arm7_9_write_core_reg(struct target_s *target, int num, enum armv4_5_mode mode, u32 value)
1557 {
1558 u32 reg[16];
1559 int retval;
1560 armv4_5_common_t *armv4_5 = target->arch_info;
1561 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1562 enum armv4_5_mode reg_mode = ((armv4_5_core_reg_t*)ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).arch_info)->mode;
1563
1564 if ((num < 0) || (num > 16))
1565 return ERROR_INVALID_ARGUMENTS;
1566
1567 if ((mode != ARMV4_5_MODE_ANY)
1568 && (mode != armv4_5->core_mode)
1569 && (reg_mode != ARMV4_5_MODE_ANY)) {
1570 u32 tmp_cpsr;
1571
1572 /* change processor mode */
1573 tmp_cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & 0xE0;
1574 tmp_cpsr |= mode;
1575 arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);
1576 }
1577
1578 if ((num >= 0) && (num <= 15))
1579 {
1580 /* write a normal core register */
1581 reg[num] = value;
1582
1583 arm7_9->write_core_regs(target, 1 << num, reg);
1584 }
1585 else
1586 {
1587 /* write a program status register
1588 * if the register mode is MODE_ANY, we write the cpsr, otherwise a spsr
1589 */
1590 armv4_5_core_reg_t *arch_info = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).arch_info;
1591 int spsr = (arch_info->mode == ARMV4_5_MODE_ANY) ? 0 : 1;
1592
1593 arm7_9->write_xpsr(target, value, spsr);
1594 }
1595
1596 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
1597 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).dirty = 0;
1598
1599 if ((mode != ARMV4_5_MODE_ANY)
1600 && (mode != armv4_5->core_mode)
1601 && (reg_mode != ARMV4_5_MODE_ANY)) {
1602 /* restore processor mode */
1603 arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8), 0, 0);
1604 }
1605
1606 if ((retval = jtag_execute_queue()) != ERROR_OK)
1607 {
1608 ERROR("JTAG failure");
1609 exit(-1);
1610 }
1611
1612 return ERROR_OK;
1613
1614 }
1615
1616 int arm7_9_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1617 {
1618 armv4_5_common_t *armv4_5 = target->arch_info;
1619 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1620
1621 u32 reg[16];
1622 u32 *reg_p[16];
1623 int num_accesses = 0;
1624 int thisrun_accesses;
1625 int i;
1626 u32 cpsr;
1627 int retval;
1628 int last_reg = 0;
1629
1630 DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
1631
1632 if (target->state != TARGET_HALTED)
1633 {
1634 WARNING("target not halted");
1635 return ERROR_TARGET_NOT_HALTED;
1636 }
1637
1638 /* sanitize arguments */
1639 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1640 return ERROR_INVALID_ARGUMENTS;
1641
1642 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
1643 return ERROR_TARGET_UNALIGNED_ACCESS;
1644
1645 for (i = 0; i < 16; i++)
1646 {
1647 reg_p[i] = &reg[i];
1648 }
1649
1650 /* load the base register with the address of the first word */
1651 reg[0] = address;
1652 arm7_9->write_core_regs(target, 0x1, reg);
1653
1654 switch (size)
1655 {
1656 case 4:
1657 while (num_accesses < count)
1658 {
1659 u32 reg_list;
1660 thisrun_accesses = ((count - num_accesses) >= 14) ? 14 : (count - num_accesses);
1661 reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;
1662
1663 arm7_9->load_word_regs(target, reg_list);
1664 arm7_9_execute_sys_speed(target);
1665
1666 arm7_9->read_core_regs(target, reg_list, reg_p);
1667 jtag_execute_queue();
1668
1669 for (i = 1; i <= thisrun_accesses; i++)
1670 {
1671 if (i > last_reg)
1672 last_reg = i;
1673 target_buffer_set_u32(target, buffer, reg[i]);
1674 buffer += 4;
1675 }
1676 num_accesses += thisrun_accesses;
1677 }
1678 break;
1679 case 2:
1680 while (num_accesses < count)
1681 {
1682 u32 reg_list;
1683 thisrun_accesses = ((count - num_accesses) >= 14) ? 14 : (count - num_accesses);
1684 reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;
1685
1686 for (i = 1; i <= thisrun_accesses; i++)
1687 {
1688 if (i > last_reg)
1689 last_reg = i;
1690 arm7_9->load_hword_reg(target, i);
1691 arm7_9_execute_sys_speed(target);
1692 }
1693
1694 arm7_9->read_core_regs(target, reg_list, reg_p);
1695 jtag_execute_queue();
1696
1697 for (i = 1; i <= thisrun_accesses; i++)
1698 {
1699 target_buffer_set_u16(target, buffer, reg[i]);
1700 buffer += 2;
1701 }
1702 num_accesses += thisrun_accesses;
1703 }
1704 break;
1705 case 1:
1706 while (num_accesses < count)
1707 {
1708 u32 reg_list;
1709 thisrun_accesses = ((count - num_accesses) >= 14) ? 14 : (count - num_accesses);
1710 reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;
1711
1712 for (i = 1; i <= thisrun_accesses; i++)
1713 {
1714 if (i > last_reg)
1715 last_reg = i;
1716 arm7_9->load_byte_reg(target, i);
1717 arm7_9_execute_sys_speed(target);
1718 }
1719
1720 arm7_9->read_core_regs(target, reg_list, reg_p);
1721 jtag_execute_queue();
1722
1723 for (i = 1; i <= thisrun_accesses; i++)
1724 {
1725 *(buffer++) = reg[i] & 0xff;
1726 }
1727 num_accesses += thisrun_accesses;
1728 }
1729 break;
1730 default:
1731 ERROR("BUG: we shouldn't get here");
1732 exit(-1);
1733 break;
1734 }
1735
1736 for (i=0; i<=last_reg; i++)
1737 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = 1;
1738
1739 arm7_9->read_xpsr(target, &cpsr, 0);
1740 if ((retval = jtag_execute_queue()) != ERROR_OK)
1741 {
1742 ERROR("JTAG error while reading cpsr");
1743 exit(-1);
1744 }
1745
1746 if (((cpsr & 0x1f) == ARMV4_5_MODE_ABT) && (armv4_5->core_mode != ARMV4_5_MODE_ABT))
1747 {
1748 ERROR("memory read caused data abort");
1749
1750 arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8), 0, 0);
1751
1752 return ERROR_TARGET_DATA_ABORT;
1753 }
1754
1755 return ERROR_OK;
1756 }
1757
1758 int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1759 {
1760 armv4_5_common_t *armv4_5 = target->arch_info;
1761 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1762
1763 u32 reg[16];
1764 int num_accesses = 0;
1765 int thisrun_accesses;
1766 int i;
1767 u32 cpsr;
1768 int retval;
1769 int last_reg = 0;
1770
1771 DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
1772
1773 if (target->state != TARGET_HALTED)
1774 {
1775 WARNING("target not halted");
1776 return ERROR_TARGET_NOT_HALTED;
1777 }
1778
1779 /* sanitize arguments */
1780 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1781 return ERROR_INVALID_ARGUMENTS;
1782
1783 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
1784 return ERROR_TARGET_UNALIGNED_ACCESS;
1785
1786 /* load the base register with the address of the first word */
1787 reg[0] = address;
1788 arm7_9->write_core_regs(target, 0x1, reg);
1789
1790 switch (size)
1791 {
1792 case 4:
1793 while (num_accesses < count)
1794 {
1795 u32 reg_list;
1796 thisrun_accesses = ((count - num_accesses) >= 14) ? 14 : (count - num_accesses);
1797 reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;
1798
1799 for (i = 1; i <= thisrun_accesses; i++)
1800 {
1801 if (i > last_reg)
1802 last_reg = i;
1803 reg[i] = target_buffer_get_u32(target, buffer);
1804 buffer += 4;
1805 }
1806
1807 arm7_9->write_core_regs(target, reg_list, reg);
1808
1809 arm7_9->store_word_regs(target, reg_list);
1810
1811 /* fast memory writes are only safe when the target is running
1812 * from a sufficiently high clock (32 kHz is usually too slow)
1813 */
1814 if (arm7_9->fast_memory_writes)
1815 arm7_9_execute_fast_sys_speed(target);
1816 else
1817 arm7_9_execute_sys_speed(target);
1818
1819 num_accesses += thisrun_accesses;
1820 }
1821 break;
1822 case 2:
1823 while (num_accesses < count)
1824 {
1825 u32 reg_list;
1826 thisrun_accesses = ((count - num_accesses) >= 14) ? 14 : (count - num_accesses);
1827 reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;
1828
1829 for (i = 1; i <= thisrun_accesses; i++)
1830 {
1831 if (i > last_reg)
1832 last_reg = i;
1833 reg[i] = target_buffer_get_u16(target, buffer) & 0xffff;
1834 buffer += 2;
1835 }
1836
1837 arm7_9->write_core_regs(target, reg_list, reg);
1838
1839 for (i = 1; i <= thisrun_accesses; i++)
1840 {
1841 arm7_9->store_hword_reg(target, i);
1842
1843 /* fast memory writes are only safe when the target is running
1844 * from a sufficiently high clock (32 kHz is usually too slow)
1845 */
1846 if (arm7_9->fast_memory_writes)
1847 arm7_9_execute_fast_sys_speed(target);
1848 else
1849 arm7_9_execute_sys_speed(target);
1850 }
1851
1852 num_accesses += thisrun_accesses;
1853 }
1854 break;
1855 case 1:
1856 while (num_accesses < count)
1857 {
1858 u32 reg_list;
1859 thisrun_accesses = ((count - num_accesses) >= 14) ? 14 : (count - num_accesses);
1860 reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;
1861
1862 for (i = 1; i <= thisrun_accesses; i++)
1863 {
1864 if (i > last_reg)
1865 last_reg = i;
1866 reg[i] = *buffer++ & 0xff;
1867 }
1868
1869 arm7_9->write_core_regs(target, reg_list, reg);
1870
1871 for (i = 1; i <= thisrun_accesses; i++)
1872 {
1873 arm7_9->store_byte_reg(target, i);
1874 /* fast memory writes are only safe when the target is running
1875 * from a sufficiently high clock (32 kHz is usually too slow)
1876 */
1877 if (arm7_9->fast_memory_writes)
1878 arm7_9_execute_fast_sys_speed(target);
1879 else
1880 arm7_9_execute_sys_speed(target);
1881 }
1882
1883 num_accesses += thisrun_accesses;
1884 }
1885 break;
1886 default:
1887 ERROR("BUG: we shouldn't get here");
1888 exit(-1);
1889 break;
1890 }
1891
1892 if ((retval = jtag_execute_queue()) != ERROR_OK)
1893 {
1894 ERROR("JTAG error while writing target memory");
1895 exit(-1);
1896 }
1897
1898 for (i=0; i<=last_reg; i++)
1899 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = 1;
1900
1901 arm7_9->read_xpsr(target, &cpsr, 0);
1902 if ((retval = jtag_execute_queue()) != ERROR_OK)
1903 {
1904 ERROR("JTAG error while reading cpsr");
1905 exit(-1);
1906 }
1907
1908 if (((cpsr & 0x1f) == ARMV4_5_MODE_ABT) && (armv4_5->core_mode != ARMV4_5_MODE_ABT))
1909 {
1910 ERROR("memory write caused data abort");
1911
1912 arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8), 0, 0);
1913
1914 return ERROR_TARGET_DATA_ABORT;
1915 }
1916
1917 return ERROR_OK;
1918 }
1919
1920 int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
1921 {
1922 armv4_5_common_t *armv4_5 = target->arch_info;
1923 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
1924 enum armv4_5_state core_state = armv4_5->core_state;
1925 u32 r0 = buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32);
1926 u32 r1 = buf_get_u32(armv4_5->core_cache->reg_list[1].value, 0, 32);
1927 u32 pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
1928 int i;
1929
1930 u32 dcc_code[] =
1931 {
1932 /* MRC TST BNE MRC STR B */
1933 0xee101e10, 0xe3110001, 0x0afffffc, 0xee111e10, 0xe4801004, 0xeafffff9
1934 };
1935
1936 if (!arm7_9->dcc_downloads)
1937 return target->type->write_memory(target, address, 4, count, buffer);
1938
1939 /* regrab previously allocated working_area, or allocate a new one */
1940 if (!arm7_9->dcc_working_area)
1941 {
1942 /* make sure we have a working area */
1943 if (target_alloc_working_area(target, 24, &arm7_9->dcc_working_area) != ERROR_OK)
1944 {
1945 INFO("no working area available, falling back to memory writes");
1946 return target->type->write_memory(target, address, 4, count, buffer);
1947 }
1948
1949 /* write DCC code to working area */
1950 target->type->write_memory(target, arm7_9->dcc_working_area->address, 4, 6, (u8*)dcc_code);
1951 }
1952
1953 buf_set_u32(armv4_5->core_cache->reg_list[0].value, 0, 32, address);
1954 armv4_5->core_cache->reg_list[0].valid = 1;
1955 armv4_5->core_cache->reg_list[0].dirty = 1;
1956 armv4_5->core_state = ARMV4_5_STATE_ARM;
1957
1958 arm7_9_resume(target, 0, arm7_9->dcc_working_area->address, 1, 1);
1959
1960 for (i = 0; i < count; i++)
1961 {
1962 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], target_buffer_get_u32(target, buffer));
1963 buffer += 4;
1964 }
1965
1966 target->type->halt(target);
1967
1968 while (target->state != TARGET_HALTED)
1969 target->type->poll(target);
1970
1971 /* restore target state */
1972 buf_set_u32(armv4_5->core_cache->reg_list[0].value, 0, 32, r0);
1973 armv4_5->core_cache->reg_list[0].valid = 1;
1974 armv4_5->core_cache->reg_list[0].dirty = 1;
1975 buf_set_u32(armv4_5->core_cache->reg_list[1].value, 0, 32, r1);
1976 armv4_5->core_cache->reg_list[1].valid = 1;
1977 armv4_5->core_cache->reg_list[1].dirty = 1;
1978 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, pc);
1979 armv4_5->core_cache->reg_list[15].valid = 1;
1980 armv4_5->core_cache->reg_list[15].dirty = 1;
1981 armv4_5->core_state = core_state;
1982
1983 return ERROR_OK;
1984 }
1985
1986 int arm7_9_register_commands(struct command_context_s *cmd_ctx)
1987 {
1988 command_t *arm7_9_cmd;
1989
1990 arm7_9_cmd = register_command(cmd_ctx, NULL, "arm7_9", NULL, COMMAND_ANY, NULL);
1991
1992 register_command(cmd_ctx, arm7_9_cmd, "write_xpsr", handle_arm7_9_write_xpsr_command, COMMAND_EXEC, "write program status register <value> <not cpsr|spsr>");
1993 register_command(cmd_ctx, arm7_9_cmd, "write_xpsr_im8", handle_arm7_9_write_xpsr_im8_command, COMMAND_EXEC, "write program status register <8bit immediate> <rotate> <not cpsr|spsr>");
1994
1995 register_command(cmd_ctx, arm7_9_cmd, "write_core_reg", handle_arm7_9_write_core_reg_command, COMMAND_EXEC, "write core register <num> <mode> <value>");
1996
1997 register_command(cmd_ctx, arm7_9_cmd, "sw_bkpts", handle_arm7_9_sw_bkpts_command, COMMAND_EXEC, "support for software breakpoints <enable|disable>");
1998 register_command(cmd_ctx, arm7_9_cmd, "force_hw_bkpts", handle_arm7_9_force_hw_bkpts_command, COMMAND_EXEC, "use hardware breakpoints for all breakpoints (disables sw breakpoint support) <enable|disable>");
1999 register_command(cmd_ctx, arm7_9_cmd, "dbgrq", handle_arm7_9_dbgrq_command,
2000 COMMAND_ANY, "use EmbeddedICE dbgrq instead of breakpoint for target halt requests <enable|disable>");
2001 register_command(cmd_ctx, arm7_9_cmd, "fast_writes", handle_arm7_9_fast_writes_command,
2002 COMMAND_ANY, "use fast memory writes instead of slower but potentially unsafe slow writes <enable|disable>");
2003 register_command(cmd_ctx, arm7_9_cmd, "dcc_downloads", handle_arm7_9_dcc_downloads_command,
2004 COMMAND_ANY, "use DCC downloads for larger memory writes <enable|disable>");
2005
2006 armv4_5_register_commands(cmd_ctx);
2007
2008 return ERROR_OK;
2009 }
2010
2011 int handle_arm7_9_write_xpsr_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2012 {
2013 u32 value;
2014 int spsr;
2015 int retval;
2016 target_t *target = get_current_target(cmd_ctx);
2017 armv4_5_common_t *armv4_5;
2018 arm7_9_common_t *arm7_9;
2019
2020 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2021 {
2022 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2023 return ERROR_OK;
2024 }
2025
2026 if (target->state != TARGET_HALTED)
2027 {
2028 command_print(cmd_ctx, "can't write registers while running");
2029 return ERROR_OK;
2030 }
2031
2032 if (argc < 2)
2033 {
2034 command_print(cmd_ctx, "usage: write_xpsr <value> <not cpsr|spsr>");
2035 return ERROR_OK;
2036 }
2037
2038 value = strtoul(args[0], NULL, 0);
2039 spsr = strtol(args[1], NULL, 0);
2040
2041 arm7_9->write_xpsr(target, value, spsr);
2042 if ((retval = jtag_execute_queue()) != ERROR_OK)
2043 {
2044 ERROR("JTAG error while writing to xpsr");
2045 exit(-1);
2046 }
2047
2048 return ERROR_OK;
2049 }
2050
2051 int handle_arm7_9_write_xpsr_im8_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2052 {
2053 u32 value;
2054 int rotate;
2055 int spsr;
2056 int retval;
2057 target_t *target = get_current_target(cmd_ctx);
2058 armv4_5_common_t *armv4_5;
2059 arm7_9_common_t *arm7_9;
2060
2061 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2062 {
2063 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2064 return ERROR_OK;
2065 }
2066
2067 if (target->state != TARGET_HALTED)
2068 {
2069 command_print(cmd_ctx, "can't write registers while running");
2070 return ERROR_OK;
2071 }
2072
2073 if (argc < 3)
2074 {
2075 command_print(cmd_ctx, "usage: write_xpsr_im8 <im8> <rotate> <not cpsr|spsr>");
2076 return ERROR_OK;
2077 }
2078
2079 value = strtoul(args[0], NULL, 0);
2080 rotate = strtol(args[1], NULL, 0);
2081 spsr = strtol(args[2], NULL, 0);
2082
2083 arm7_9->write_xpsr_im8(target, value, rotate, spsr);
2084 if ((retval = jtag_execute_queue()) != ERROR_OK)
2085 {
2086 ERROR("JTAG error while writing 8-bit immediate to xpsr");
2087 exit(-1);
2088 }
2089
2090 return ERROR_OK;
2091 }
2092
2093 int handle_arm7_9_write_core_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2094 {
2095 u32 value;
2096 u32 mode;
2097 int num;
2098 target_t *target = get_current_target(cmd_ctx);
2099 armv4_5_common_t *armv4_5;
2100 arm7_9_common_t *arm7_9;
2101
2102 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2103 {
2104 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2105 return ERROR_OK;
2106 }
2107
2108 if (target->state != TARGET_HALTED)
2109 {
2110 command_print(cmd_ctx, "can't write registers while running");
2111 return ERROR_OK;
2112 }
2113
2114 if (argc < 3)
2115 {
2116 command_print(cmd_ctx, "usage: write_core_reg <num> <mode> <value>");
2117 return ERROR_OK;
2118 }
2119
2120 num = strtol(args[0], NULL, 0);
2121 mode = strtoul(args[1], NULL, 0);
2122 value = strtoul(args[2], NULL, 0);
2123
2124 arm7_9_write_core_reg(target, num, mode, value);
2125
2126 return ERROR_OK;
2127 }
2128
2129 int handle_arm7_9_sw_bkpts_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2130 {
2131 target_t *target = get_current_target(cmd_ctx);
2132 armv4_5_common_t *armv4_5;
2133 arm7_9_common_t *arm7_9;
2134
2135 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2136 {
2137 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2138 return ERROR_OK;
2139 }
2140
2141 if (argc == 0)
2142 {
2143 command_print(cmd_ctx, "software breakpoints %s", (arm7_9->sw_bkpts_enabled) ? "enabled" : "disabled");
2144 return ERROR_OK;
2145 }
2146
2147 if (strcmp("enable", args[0]) == 0)
2148 {
2149 if (arm7_9->sw_bkpts_use_wp)
2150 {
2151 arm7_9_enable_sw_bkpts(target);
2152 }
2153 else
2154 {
2155 arm7_9->sw_bkpts_enabled = 1;
2156 }
2157 }
2158 else if (strcmp("disable", args[0]) == 0)
2159 {
2160 if (arm7_9->sw_bkpts_use_wp)
2161 {
2162 arm7_9_disable_sw_bkpts(target);
2163 }
2164 else
2165 {
2166 arm7_9->sw_bkpts_enabled = 0;
2167 }
2168 }
2169 else
2170 {
2171 command_print(cmd_ctx, "usage: arm7_9 sw_bkpts <enable|disable>");
2172 }
2173
2174 command_print(cmd_ctx, "software breakpoints %s", (arm7_9->sw_bkpts_enabled) ? "enabled" : "disabled");
2175
2176 return ERROR_OK;
2177 }
2178
2179 int handle_arm7_9_force_hw_bkpts_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2180 {
2181 target_t *target = get_current_target(cmd_ctx);
2182 armv4_5_common_t *armv4_5;
2183 arm7_9_common_t *arm7_9;
2184
2185 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2186 {
2187 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2188 return ERROR_OK;
2189 }
2190
2191 if ((argc >= 1) && (strcmp("enable", args[0]) == 0))
2192 {
2193 arm7_9->force_hw_bkpts = 1;
2194 if (arm7_9->sw_bkpts_use_wp)
2195 {
2196 arm7_9_disable_sw_bkpts(target);
2197 }
2198 }
2199 else if ((argc >= 1) && (strcmp("disable", args[0]) == 0))
2200 {
2201 arm7_9->force_hw_bkpts = 0;
2202 }
2203 else
2204 {
2205 command_print(cmd_ctx, "usage: arm7_9 force_hw_bkpts <enable|disable>");
2206 }
2207
2208 command_print(cmd_ctx, "force hardware breakpoints %s", (arm7_9->force_hw_bkpts) ? "enabled" : "disabled");
2209
2210 return ERROR_OK;
2211 }
2212
2213 int handle_arm7_9_dbgrq_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2214 {
2215 target_t *target = get_current_target(cmd_ctx);
2216 armv4_5_common_t *armv4_5;
2217 arm7_9_common_t *arm7_9;
2218
2219 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2220 {
2221 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2222 return ERROR_OK;
2223 }
2224
2225 if (argc > 0)
2226 {
2227 if (strcmp("enable", args[0]) == 0)
2228 {
2229 arm7_9->use_dbgrq = 1;
2230 }
2231 else if (strcmp("disable", args[0]) == 0)
2232 {
2233 arm7_9->use_dbgrq = 0;
2234 }
2235 else
2236 {
2237 command_print(cmd_ctx, "usage: arm7_9 dbgrq <enable|disable>");
2238 }
2239 }
2240
2241 command_print(cmd_ctx, "use of EmbeddedICE dbgrq instead of breakpoint for target halt %s", (arm7_9->use_dbgrq) ? "enabled" : "disabled");
2242
2243 return ERROR_OK;
2244 }
2245
2246 int handle_arm7_9_fast_writes_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2247 {
2248 target_t *target = get_current_target(cmd_ctx);
2249 armv4_5_common_t *armv4_5;
2250 arm7_9_common_t *arm7_9;
2251
2252 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2253 {
2254 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2255 return ERROR_OK;
2256 }
2257
2258 if (argc > 0)
2259 {
2260 if (strcmp("enable", args[0]) == 0)
2261 {
2262 arm7_9->fast_memory_writes = 1;
2263 }
2264 else if (strcmp("disable", args[0]) == 0)
2265 {
2266 arm7_9->fast_memory_writes = 0;
2267 }
2268 else
2269 {
2270 command_print(cmd_ctx, "usage: arm7_9 fast_writes <enable|disable>");
2271 }
2272 }
2273
2274 command_print(cmd_ctx, "fast memory writes are %s", (arm7_9->fast_memory_writes) ? "enabled" : "disabled");
2275
2276 return ERROR_OK;
2277 }
2278
2279 int handle_arm7_9_dcc_downloads_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2280 {
2281 target_t *target = get_current_target(cmd_ctx);
2282 armv4_5_common_t *armv4_5;
2283 arm7_9_common_t *arm7_9;
2284
2285 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
2286 {
2287 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
2288 return ERROR_OK;
2289 }
2290
2291 if (argc > 0)
2292 {
2293 if (strcmp("enable", args[0]) == 0)
2294 {
2295 arm7_9->dcc_downloads = 1;
2296 }
2297 else if (strcmp("disable", args[0]) == 0)
2298 {
2299 arm7_9->dcc_downloads = 0;
2300 }
2301 else
2302 {
2303 command_print(cmd_ctx, "usage: arm7_9 dcc_downloads <enable|disable>");
2304 }
2305 }
2306
2307 command_print(cmd_ctx, "dcc downloads are %s", (arm7_9->dcc_downloads) ? "enabled" : "disabled");
2308
2309 return ERROR_OK;
2310 }
2311
2312 int arm7_9_init_arch_info(target_t *target, arm7_9_common_t *arm7_9)
2313 {
2314 armv4_5_common_t *armv4_5 = &arm7_9->armv4_5_common;
2315
2316 arm7_9->common_magic = ARM7_9_COMMON_MAGIC;
2317
2318 arm_jtag_setup_connection(&arm7_9->jtag_info);
2319 arm7_9->wp_available = 2;
2320 arm7_9->wp0_used = 0;
2321 arm7_9->wp1_used = 0;
2322 arm7_9->force_hw_bkpts = 0;
2323 arm7_9->use_dbgrq = 0;
2324 arm7_9->has_etm = 0;
2325
2326 arm7_9->reinit_embeddedice = 0;
2327
2328 arm7_9->dcc_working_area = NULL;
2329
2330 arm7_9->fast_memory_writes = 0;
2331 arm7_9->dcc_downloads = 0;
2332
2333 jtag_register_event_callback(arm7_9_jtag_callback, target);
2334
2335 armv4_5->arch_info = arm7_9;
2336 armv4_5->read_core_reg = arm7_9_read_core_reg;
2337 armv4_5->write_core_reg = arm7_9_write_core_reg;
2338 armv4_5->full_context = arm7_9_full_context;
2339
2340 armv4_5_init_arch_info(target, armv4_5);
2341
2342 return ERROR_OK;
2343 }

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)