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

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)