jtag-api: get rid of unecessary buf_set_u23() that make code obtuse.
[openocd.git] / src / target / embeddedice.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2007,2008,2009 √ėyvind Harboe *
6 * oyvind.harboe@zylin.com *
7 * *
8 * Copyright (C) 2008 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
20 * *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 ***************************************************************************/
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "embeddedice.h"
31 #include "register.h"
32
33 /**
34 * @file
35 *
36 * This provides lowlevel glue to the EmbeddedICE (or EmbeddedICE-RT)
37 * module found on scan chain 2 in ARM7, ARM9, and some other families
38 * of ARM cores.
39 *
40 * EmbeddedICE provides basic watchpoint/breakpoint hardware and a Debug
41 * Communications Channel (DCC) used to read or write 32-bit words to
42 * OpenOCD-aware code running on the target CPU.
43 * Newer modules also include vector catch hardware. Some versions
44 * support hardware single-stepping, "monitor mode" debug (which is not
45 * currently supported by OpenOCD), or extended reporting on why the
46 * core entered debug mode.
47 */
48
49 /*
50 * From: ARM9E-S TRM, DDI 0165, table C-4 (and similar, for other cores)
51 */
52 static const struct {
53 char *name;
54 unsigned short addr;
55 unsigned short width;
56 } eice_regs[] = {
57 [EICE_DBG_CTRL] = {
58 .name = "debug_ctrl",
59 .addr = 0,
60 /* width is assigned based on EICE version */
61 },
62 [EICE_DBG_STAT] = {
63 .name = "debug_status",
64 .addr = 1,
65 /* width is assigned based on EICE version */
66 },
67 [EICE_COMMS_CTRL] = {
68 .name = "comms_ctrl",
69 .addr = 4,
70 .width = 6,
71 },
72 [EICE_COMMS_DATA] = {
73 .name = "comms_data",
74 .addr = 5,
75 .width = 32,
76 },
77 [EICE_W0_ADDR_VALUE] = {
78 .name = "watch_0_addr_value",
79 .addr = 8,
80 .width = 32,
81 },
82 [EICE_W0_ADDR_MASK] = {
83 .name = "watch_0_addr_mask",
84 .addr = 9,
85 .width = 32,
86 },
87 [EICE_W0_DATA_VALUE ] = {
88 .name = "watch_0_data_value",
89 .addr = 10,
90 .width = 32,
91 },
92 [EICE_W0_DATA_MASK] = {
93 .name = "watch_0_data_mask",
94 .addr = 11,
95 .width = 32,
96 },
97 [EICE_W0_CONTROL_VALUE] = {
98 .name = "watch_0_control_value",
99 .addr = 12,
100 .width = 9,
101 },
102 [EICE_W0_CONTROL_MASK] = {
103 .name = "watch_0_control_mask",
104 .addr = 13,
105 .width = 8,
106 },
107 [EICE_W1_ADDR_VALUE] = {
108 .name = "watch_1_addr_value",
109 .addr = 16,
110 .width = 32,
111 },
112 [EICE_W1_ADDR_MASK] = {
113 .name = "watch_1_addr_mask",
114 .addr = 17,
115 .width = 32,
116 },
117 [EICE_W1_DATA_VALUE] = {
118 .name = "watch_1_data_value",
119 .addr = 18,
120 .width = 32,
121 },
122 [EICE_W1_DATA_MASK] = {
123 .name = "watch_1_data_mask",
124 .addr = 19,
125 .width = 32,
126 },
127 [EICE_W1_CONTROL_VALUE] = {
128 .name = "watch_1_control_value",
129 .addr = 20,
130 .width = 9,
131 },
132 [EICE_W1_CONTROL_MASK] = {
133 .name = "watch_1_control_mask",
134 .addr = 21,
135 .width = 8,
136 },
137 /* vector_catch isn't always present */
138 [EICE_VEC_CATCH] = {
139 .name = "vector_catch",
140 .addr = 2,
141 .width = 8,
142 },
143 };
144
145
146 static int embeddedice_get_reg(struct reg *reg)
147 {
148 int retval;
149
150 if ((retval = embeddedice_read_reg(reg)) != ERROR_OK)
151 LOG_ERROR("error queueing EmbeddedICE register read");
152 else if ((retval = jtag_execute_queue()) != ERROR_OK)
153 LOG_ERROR("EmbeddedICE register read failed");
154
155 return retval;
156 }
157
158 static const struct reg_arch_type eice_reg_type = {
159 .get = embeddedice_get_reg,
160 .set = embeddedice_set_reg_w_exec,
161 };
162
163 /**
164 * Probe EmbeddedICE module and set up local records of its registers.
165 * Different versions of the modules have different capabilities, such as
166 * hardware support for vector_catch, single stepping, and monitor mode.
167 */
168 struct reg_cache *
169 embeddedice_build_reg_cache(struct target *target, struct arm7_9_common *arm7_9)
170 {
171 int retval;
172 struct reg_cache *reg_cache = malloc(sizeof(struct reg_cache));
173 struct reg *reg_list = NULL;
174 struct embeddedice_reg *arch_info = NULL;
175 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
176 int num_regs = ARRAY_SIZE(eice_regs);
177 int i;
178 int eice_version = 0;
179
180 /* vector_catch isn't always present */
181 if (!arm7_9->has_vector_catch)
182 num_regs--;
183
184 /* the actual registers are kept in two arrays */
185 reg_list = calloc(num_regs, sizeof(struct reg));
186 arch_info = calloc(num_regs, sizeof(struct embeddedice_reg));
187
188 /* fill in values for the reg cache */
189 reg_cache->name = "EmbeddedICE registers";
190 reg_cache->next = NULL;
191 reg_cache->reg_list = reg_list;
192 reg_cache->num_regs = num_regs;
193
194 /* set up registers */
195 for (i = 0; i < num_regs; i++)
196 {
197 reg_list[i].name = eice_regs[i].name;
198 reg_list[i].size = eice_regs[i].width;
199 reg_list[i].dirty = 0;
200 reg_list[i].valid = 0;
201 reg_list[i].value = calloc(1, 4);
202 reg_list[i].arch_info = &arch_info[i];
203 reg_list[i].type = &eice_reg_type;
204 arch_info[i].addr = eice_regs[i].addr;
205 arch_info[i].jtag_info = jtag_info;
206 }
207
208 /* identify EmbeddedICE version by reading DCC control register */
209 embeddedice_read_reg(&reg_list[EICE_COMMS_CTRL]);
210 if ((retval = jtag_execute_queue()) != ERROR_OK)
211 {
212 for (i = 0; i < num_regs; i++)
213 {
214 free(reg_list[i].value);
215 }
216 free(reg_list);
217 free(reg_cache);
218 free(arch_info);
219 return NULL;
220 }
221
222 eice_version = buf_get_u32(reg_list[EICE_COMMS_CTRL].value, 28, 4);
223 LOG_INFO("Embedded ICE version %d", eice_version);
224
225 switch (eice_version)
226 {
227 case 1:
228 /* ARM7TDMI r3, ARM7TDMI-S r3
229 *
230 * REVISIT docs say ARM7TDMI-S r4 uses version 1 but
231 * that it has 6-bit CTRL and 5-bit STAT... doc bug?
232 * ARM7TDMI r4 docs say EICE v4.
233 */
234 reg_list[EICE_DBG_CTRL].size = 3;
235 reg_list[EICE_DBG_STAT].size = 5;
236 break;
237 case 2:
238 /* ARM9TDMI */
239 reg_list[EICE_DBG_CTRL].size = 4;
240 reg_list[EICE_DBG_STAT].size = 5;
241 arm7_9->has_single_step = 1;
242 break;
243 case 3:
244 LOG_ERROR("EmbeddedICE v%d handling might be broken",
245 eice_version);
246 reg_list[EICE_DBG_CTRL].size = 6;
247 reg_list[EICE_DBG_STAT].size = 5;
248 arm7_9->has_single_step = 1;
249 arm7_9->has_monitor_mode = 1;
250 break;
251 case 4:
252 /* ARM7TDMI r4 */
253 reg_list[EICE_DBG_CTRL].size = 6;
254 reg_list[EICE_DBG_STAT].size = 5;
255 arm7_9->has_monitor_mode = 1;
256 break;
257 case 5:
258 /* ARM9E-S rev 1 */
259 reg_list[EICE_DBG_CTRL].size = 6;
260 reg_list[EICE_DBG_STAT].size = 5;
261 arm7_9->has_single_step = 1;
262 arm7_9->has_monitor_mode = 1;
263 break;
264 case 6:
265 /* ARM7EJ-S, ARM9E-S rev 2, ARM9EJ-S */
266 reg_list[EICE_DBG_CTRL].size = 6;
267 reg_list[EICE_DBG_STAT].size = 10;
268 /* DBG_STAT has MOE bits */
269 arm7_9->has_monitor_mode = 1;
270 break;
271 case 7:
272 LOG_ERROR("EmbeddedICE v%d handling might be broken",
273 eice_version);
274 reg_list[EICE_DBG_CTRL].size = 6;
275 reg_list[EICE_DBG_STAT].size = 5;
276 arm7_9->has_monitor_mode = 1;
277 break;
278 default:
279 /*
280 * The Feroceon implementation has the version number
281 * in some unusual bits. Let feroceon.c validate it
282 * and do the appropriate setup itself.
283 */
284 if (strcmp(target_get_name(target), "feroceon") == 0 ||
285 strcmp(target_get_name(target), "dragonite") == 0)
286 break;
287 LOG_ERROR("unknown EmbeddedICE version "
288 "(comms ctrl: 0x%8.8" PRIx32 ")",
289 buf_get_u32(reg_list[EICE_COMMS_CTRL].value, 0, 32));
290 }
291
292 return reg_cache;
293 }
294
295 /**
296 * Initialize EmbeddedICE module, if needed.
297 */
298 int embeddedice_setup(struct target *target)
299 {
300 int retval;
301 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
302
303 /* Explicitly disable monitor mode. For now we only support halting
304 * debug ... we don't know how to talk with a resident debug monitor
305 * that manages break requests. ARM's "Angel Debug Monitor" is one
306 * common example of such code.
307 */
308 if (arm7_9->has_monitor_mode)
309 {
310 struct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
311
312 embeddedice_read_reg(dbg_ctrl);
313 if ((retval = jtag_execute_queue()) != ERROR_OK)
314 return retval;
315 buf_set_u32(dbg_ctrl->value, 4, 1, 0);
316 embeddedice_set_reg_w_exec(dbg_ctrl, dbg_ctrl->value);
317 }
318 return jtag_execute_queue();
319 }
320
321 /**
322 * Queue a read for an EmbeddedICE register into the register cache,
323 * optionally checking the value read.
324 * Note that at this level, all registers are 32 bits wide.
325 */
326 int embeddedice_read_reg_w_check(struct reg *reg,
327 uint8_t *check_value, uint8_t *check_mask)
328 {
329 struct embeddedice_reg *ice_reg = reg->arch_info;
330 uint8_t reg_addr = ice_reg->addr & 0x1f;
331 struct scan_field fields[3];
332 uint8_t field1_out[1];
333 uint8_t field2_out[1];
334
335 jtag_set_end_state(TAP_IDLE);
336 arm_jtag_scann(ice_reg->jtag_info, 0x2);
337
338 arm_jtag_set_instr(ice_reg->jtag_info, ice_reg->jtag_info->intest_instr, NULL);
339
340 /* bits 31:0 -- data (ignored here) */
341 fields[0].tap = ice_reg->jtag_info->tap;
342 fields[0].num_bits = 32;
343 fields[0].out_value = reg->value;
344 fields[0].in_value = NULL;
345 fields[0].check_value = NULL;
346 fields[0].check_mask = NULL;
347
348 /* bits 36:32 -- register */
349 fields[1].tap = ice_reg->jtag_info->tap;
350 fields[1].num_bits = 5;
351 fields[1].out_value = field1_out;
352 fields[1].out_value[0] = reg_addr;
353 fields[1].in_value = NULL;
354 fields[1].check_value = NULL;
355 fields[1].check_mask = NULL;
356
357 /* bit 37 -- 0/read */
358 fields[2].tap = ice_reg->jtag_info->tap;
359 fields[2].num_bits = 1;
360 fields[2].out_value = field2_out;
361 fields[2].out_value[0] = 0;
362 fields[2].in_value = NULL;
363 fields[2].check_value = NULL;
364 fields[2].check_mask = NULL;
365
366 /* traverse Update-DR, setting address for the next read */
367 jtag_add_dr_scan(3, fields, jtag_get_end_state());
368
369 /* bits 31:0 -- the data we're reading (and maybe checking) */
370 fields[0].in_value = reg->value;
371 fields[0].check_value = check_value;
372 fields[0].check_mask = check_mask;
373
374 /* when reading the DCC data register, leaving the address field set to
375 * EICE_COMMS_DATA would read the register twice
376 * reading the control register is safe
377 */
378 fields[1].out_value[0] = eice_regs[EICE_COMMS_CTRL].addr;
379
380 /* traverse Update-DR, reading but with no other side effects */
381 jtag_add_dr_scan_check(3, fields, jtag_get_end_state());
382
383 return ERROR_OK;
384 }
385
386 /**
387 * Receive a block of size 32-bit words from the DCC.
388 * We assume the target is always going to be fast enough (relative to
389 * the JTAG clock) that the debugger won't need to poll the handshake
390 * bit. The JTAG clock is usually at least six times slower than the
391 * functional clock, so the 50+ JTAG clocks needed to receive the word
392 * allow hundreds of instruction cycles (per word) in the target.
393 */
394 int embeddedice_receive(struct arm_jtag *jtag_info, uint32_t *data, uint32_t size)
395 {
396 struct scan_field fields[3];
397 uint8_t field1_out[1];
398 uint8_t field2_out[1];
399
400 jtag_set_end_state(TAP_IDLE);
401 arm_jtag_scann(jtag_info, 0x2);
402 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
403
404 fields[0].tap = jtag_info->tap;
405 fields[0].num_bits = 32;
406 fields[0].out_value = NULL;
407 fields[0].in_value = NULL;
408
409 fields[1].tap = jtag_info->tap;
410 fields[1].num_bits = 5;
411 fields[1].out_value = field1_out;
412 fields[1].out_value[0] = eice_regs[EICE_COMMS_DATA].addr;
413 fields[1].in_value = NULL;
414
415 fields[2].tap = jtag_info->tap;
416 fields[2].num_bits = 1;
417 fields[2].out_value = field2_out;
418 fields[2].out_value[0] = 0;
419 fields[2].in_value = NULL;
420
421 jtag_add_dr_scan(3, fields, jtag_get_end_state());
422
423 while (size > 0)
424 {
425 /* when reading the last item, set the register address to the DCC control reg,
426 * to avoid reading additional data from the DCC data reg
427 */
428 if (size == 1)
429 fields[1].out_value[0] = eice_regs[EICE_COMMS_CTRL].addr;
430
431 fields[0].in_value = (uint8_t *)data;
432 jtag_add_dr_scan(3, fields, jtag_get_end_state());
433 jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)data);
434
435 data++;
436 size--;
437 }
438
439 return jtag_execute_queue();
440 }
441
442 /**
443 * Queue a read for an EmbeddedICE register into the register cache,
444 * not checking the value read.
445 */
446 int embeddedice_read_reg(struct reg *reg)
447 {
448 return embeddedice_read_reg_w_check(reg, NULL, NULL);
449 }
450
451 /**
452 * Queue a write for an EmbeddedICE register, updating the register cache.
453 * Uses embeddedice_write_reg().
454 */
455 void embeddedice_set_reg(struct reg *reg, uint32_t value)
456 {
457 embeddedice_write_reg(reg, value);
458
459 buf_set_u32(reg->value, 0, reg->size, value);
460 reg->valid = 1;
461 reg->dirty = 0;
462
463 }
464
465 /**
466 * Write an EmbeddedICE register, updating the register cache.
467 * Uses embeddedice_set_reg(); not queued.
468 */
469 int embeddedice_set_reg_w_exec(struct reg *reg, uint8_t *buf)
470 {
471 int retval;
472
473 embeddedice_set_reg(reg, buf_get_u32(buf, 0, reg->size));
474 if ((retval = jtag_execute_queue()) != ERROR_OK)
475 LOG_ERROR("register write failed");
476 return retval;
477 }
478
479 /**
480 * Queue a write for an EmbeddedICE register, bypassing the register cache.
481 */
482 void embeddedice_write_reg(struct reg *reg, uint32_t value)
483 {
484 struct embeddedice_reg *ice_reg = reg->arch_info;
485
486 LOG_DEBUG("%i: 0x%8.8" PRIx32 "", ice_reg->addr, value);
487
488 jtag_set_end_state(TAP_IDLE);
489 arm_jtag_scann(ice_reg->jtag_info, 0x2);
490
491 arm_jtag_set_instr(ice_reg->jtag_info, ice_reg->jtag_info->intest_instr, NULL);
492
493 uint8_t reg_addr = ice_reg->addr & 0x1f;
494 embeddedice_write_reg_inner(ice_reg->jtag_info->tap, reg_addr, value);
495 }
496
497 /**
498 * Queue a write for an EmbeddedICE register, using cached value.
499 * Uses embeddedice_write_reg().
500 */
501 void embeddedice_store_reg(struct reg *reg)
502 {
503 embeddedice_write_reg(reg, buf_get_u32(reg->value, 0, reg->size));
504 }
505
506 /**
507 * Send a block of size 32-bit words to the DCC.
508 * We assume the target is always going to be fast enough (relative to
509 * the JTAG clock) that the debugger won't need to poll the handshake
510 * bit. The JTAG clock is usually at least six times slower than the
511 * functional clock, so the 50+ JTAG clocks needed to receive the word
512 * allow hundreds of instruction cycles (per word) in the target.
513 */
514 int embeddedice_send(struct arm_jtag *jtag_info, uint32_t *data, uint32_t size)
515 {
516 struct scan_field fields[3];
517 uint8_t field0_out[4];
518 uint8_t field1_out[1];
519 uint8_t field2_out[1];
520
521 jtag_set_end_state(TAP_IDLE);
522 arm_jtag_scann(jtag_info, 0x2);
523 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
524
525 fields[0].tap = jtag_info->tap;
526 fields[0].num_bits = 32;
527 fields[0].out_value = field0_out;
528 fields[0].in_value = NULL;
529
530 fields[1].tap = jtag_info->tap;
531 fields[1].num_bits = 5;
532 fields[1].out_value = field1_out;
533 fields[1].out_value[0] = eice_regs[EICE_COMMS_DATA].addr;
534 fields[1].in_value = NULL;
535
536 fields[2].tap = jtag_info->tap;
537 fields[2].num_bits = 1;
538 fields[2].out_value = field2_out;
539 fields[2].out_value[0] = 1;
540
541 fields[2].in_value = NULL;
542
543 while (size > 0)
544 {
545 buf_set_u32(fields[0].out_value, 0, 32, *data);
546 jtag_add_dr_scan(3, fields, jtag_get_end_state());
547
548 data++;
549 size--;
550 }
551
552 /* call to jtag_execute_queue() intentionally omitted */
553 return ERROR_OK;
554 }
555
556 /**
557 * Poll DCC control register until read or write handshake completes.
558 */
559 int embeddedice_handshake(struct arm_jtag *jtag_info, int hsbit, uint32_t timeout)
560 {
561 struct scan_field fields[3];
562 uint8_t field0_in[4];
563 uint8_t field1_out[1];
564 uint8_t field2_out[1];
565 int retval;
566 uint32_t hsact;
567 struct timeval lap;
568 struct timeval now;
569
570 if (hsbit == EICE_COMM_CTRL_WBIT)
571 hsact = 1;
572 else if (hsbit == EICE_COMM_CTRL_RBIT)
573 hsact = 0;
574 else
575 return ERROR_INVALID_ARGUMENTS;
576
577 jtag_set_end_state(TAP_IDLE);
578 arm_jtag_scann(jtag_info, 0x2);
579 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
580
581 fields[0].tap = jtag_info->tap;
582 fields[0].num_bits = 32;
583 fields[0].out_value = NULL;
584 fields[0].in_value = field0_in;
585
586 fields[1].tap = jtag_info->tap;
587 fields[1].num_bits = 5;
588 fields[1].out_value = field1_out;
589 fields[1].out_value[0] = eice_regs[EICE_COMMS_DATA].addr;
590 fields[1].in_value = NULL;
591
592 fields[2].tap = jtag_info->tap;
593 fields[2].num_bits = 1;
594 fields[2].out_value = field2_out;
595 fields[2].out_value[0] = 0;
596 fields[2].in_value = NULL;
597
598 jtag_add_dr_scan(3, fields, jtag_get_end_state());
599 gettimeofday(&lap, NULL);
600 do {
601 jtag_add_dr_scan(3, fields, jtag_get_end_state());
602 if ((retval = jtag_execute_queue()) != ERROR_OK)
603 return retval;
604
605 if (buf_get_u32(field0_in, hsbit, 1) == hsact)
606 return ERROR_OK;
607
608 gettimeofday(&now, NULL);
609 } while ((uint32_t)((now.tv_sec - lap.tv_sec) * 1000
610 + (now.tv_usec - lap.tv_usec) / 1000) <= timeout);
611
612 return ERROR_TARGET_TIMEOUT;
613 }
614
615 #ifndef HAVE_JTAG_MINIDRIVER_H
616 /**
617 * This is an inner loop of the open loop DCC write of data to target
618 */
619 void embeddedice_write_dcc(struct jtag_tap *tap,
620 int reg_addr, uint8_t *buffer, int little, int count)
621 {
622 int i;
623
624 for (i = 0; i < count; i++)
625 {
626 embeddedice_write_reg_inner(tap, reg_addr,
627 fast_target_buffer_get_u32(buffer, little));
628 buffer += 4;
629 }
630 }
631 #else
632 /* provided by minidriver */
633 #endif

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)