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

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)