a0d0f4ef042f7ed6d3297ee4405b6605762a76ef
[openocd.git] / src / target / arm_adi_v5.c
1 /***************************************************************************
2 * Copyright (C) 2006 by Magnus Lundin *
3 * lundin@mlu.mine.nu *
4 * *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
7 * *
8 * Copyright (C) 2009-2010 by Oyvind Harboe *
9 * oyvind.harboe@zylin.com *
10 * *
11 * Copyright (C) 2009-2010 by David Brownell *
12 * *
13 * Copyright (C) 2013 by Andreas Fritiofson *
14 * andreas.fritiofson@gmail.com *
15 * *
16 * This program is free software; you can redistribute it and/or modify *
17 * it under the terms of the GNU General Public License as published by *
18 * the Free Software Foundation; either version 2 of the License, or *
19 * (at your option) any later version. *
20 * *
21 * This program is distributed in the hope that it will be useful, *
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
24 * GNU General Public License for more details. *
25 * *
26 * You should have received a copy of the GNU General Public License *
27 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
28 ***************************************************************************/
29
30 /**
31 * @file
32 * This file implements support for the ARM Debug Interface version 5 (ADIv5)
33 * debugging architecture. Compared with previous versions, this includes
34 * a low pin-count Serial Wire Debug (SWD) alternative to JTAG for message
35 * transport, and focusses on memory mapped resources as defined by the
36 * CoreSight architecture.
37 *
38 * A key concept in ADIv5 is the Debug Access Port, or DAP. A DAP has two
39 * basic components: a Debug Port (DP) transporting messages to and from a
40 * debugger, and an Access Port (AP) accessing resources. Three types of DP
41 * are defined. One uses only JTAG for communication, and is called JTAG-DP.
42 * One uses only SWD for communication, and is called SW-DP. The third can
43 * use either SWD or JTAG, and is called SWJ-DP. The most common type of AP
44 * is used to access memory mapped resources and is called a MEM-AP. Also a
45 * JTAG-AP is also defined, bridging to JTAG resources; those are uncommon.
46 *
47 * This programming interface allows DAP pipelined operations through a
48 * transaction queue. This primarily affects AP operations (such as using
49 * a MEM-AP to access memory or registers). If the current transaction has
50 * not finished by the time the next one must begin, and the ORUNDETECT bit
51 * is set in the DP_CTRL_STAT register, the SSTICKYORUN status is set and
52 * further AP operations will fail. There are two basic methods to avoid
53 * such overrun errors. One involves polling for status instead of using
54 * transaction piplining. The other involves adding delays to ensure the
55 * AP has enough time to complete one operation before starting the next
56 * one. (For JTAG these delays are controlled by memaccess_tck.)
57 */
58
59 /*
60 * Relevant specifications from ARM include:
61 *
62 * ARM(tm) Debug Interface v5 Architecture Specification ARM IHI 0031A
63 * CoreSight(tm) v1.0 Architecture Specification ARM IHI 0029B
64 *
65 * CoreSight(tm) DAP-Lite TRM, ARM DDI 0316D
66 * Cortex-M3(tm) TRM, ARM DDI 0337G
67 */
68
69 #ifdef HAVE_CONFIG_H
70 #include "config.h"
71 #endif
72
73 #include "jtag/interface.h"
74 #include "arm.h"
75 #include "arm_adi_v5.h"
76 #include <helper/jep106.h>
77 #include <helper/time_support.h>
78 #include <helper/list.h>
79
80 /* ARM ADI Specification requires at least 10 bits used for TAR autoincrement */
81
82 /*
83 uint32_t tar_block_size(uint32_t address)
84 Return the largest block starting at address that does not cross a tar block size alignment boundary
85 */
86 static uint32_t max_tar_block_size(uint32_t tar_autoincr_block, uint32_t address)
87 {
88 return tar_autoincr_block - ((tar_autoincr_block - 1) & address);
89 }
90
91 /***************************************************************************
92 * *
93 * DP and MEM-AP register access through APACC and DPACC *
94 * *
95 ***************************************************************************/
96
97 static int mem_ap_setup_csw(struct adiv5_ap *ap, uint32_t csw)
98 {
99 csw = csw | CSW_DBGSWENABLE | CSW_MASTER_DEBUG | CSW_HPROT |
100 ap->csw_default;
101
102 if (csw != ap->csw_value) {
103 /* LOG_DEBUG("DAP: Set CSW %x",csw); */
104 int retval = dap_queue_ap_write(ap, MEM_AP_REG_CSW, csw);
105 if (retval != ERROR_OK)
106 return retval;
107 ap->csw_value = csw;
108 }
109 return ERROR_OK;
110 }
111
112 static int mem_ap_setup_tar(struct adiv5_ap *ap, uint32_t tar)
113 {
114 if (!ap->tar_valid || tar != ap->tar_value) {
115 /* LOG_DEBUG("DAP: Set TAR %x",tar); */
116 int retval = dap_queue_ap_write(ap, MEM_AP_REG_TAR, tar);
117 if (retval != ERROR_OK)
118 return retval;
119 ap->tar_value = tar;
120 ap->tar_valid = true;
121 }
122 return ERROR_OK;
123 }
124
125 static int mem_ap_read_tar(struct adiv5_ap *ap, uint32_t *tar)
126 {
127 int retval = dap_queue_ap_read(ap, MEM_AP_REG_TAR, tar);
128 if (retval != ERROR_OK) {
129 ap->tar_valid = false;
130 return retval;
131 }
132
133 retval = dap_run(ap->dap);
134 if (retval != ERROR_OK) {
135 ap->tar_valid = false;
136 return retval;
137 }
138
139 ap->tar_value = *tar;
140 ap->tar_valid = true;
141 return ERROR_OK;
142 }
143
144 static uint32_t mem_ap_get_tar_increment(struct adiv5_ap *ap)
145 {
146 switch (ap->csw_value & CSW_ADDRINC_MASK) {
147 case CSW_ADDRINC_SINGLE:
148 switch (ap->csw_value & CSW_SIZE_MASK) {
149 case CSW_8BIT:
150 return 1;
151 case CSW_16BIT:
152 return 2;
153 case CSW_32BIT:
154 return 4;
155 }
156 case CSW_ADDRINC_PACKED:
157 return 4;
158 }
159 return 0;
160 }
161
162 /* mem_ap_update_tar_cache is called after an access to MEM_AP_REG_DRW
163 */
164 static void mem_ap_update_tar_cache(struct adiv5_ap *ap)
165 {
166 if (!ap->tar_valid)
167 return;
168
169 uint32_t inc = mem_ap_get_tar_increment(ap);
170 if (inc >= max_tar_block_size(ap->tar_autoincr_block, ap->tar_value))
171 ap->tar_valid = false;
172 else
173 ap->tar_value += inc;
174 }
175
176 /**
177 * Queue transactions setting up transfer parameters for the
178 * currently selected MEM-AP.
179 *
180 * Subsequent transfers using registers like MEM_AP_REG_DRW or MEM_AP_REG_BD2
181 * initiate data reads or writes using memory or peripheral addresses.
182 * If the CSW is configured for it, the TAR may be automatically
183 * incremented after each transfer.
184 *
185 * @param ap The MEM-AP.
186 * @param csw MEM-AP Control/Status Word (CSW) register to assign. If this
187 * matches the cached value, the register is not changed.
188 * @param tar MEM-AP Transfer Address Register (TAR) to assign. If this
189 * matches the cached address, the register is not changed.
190 *
191 * @return ERROR_OK if the transaction was properly queued, else a fault code.
192 */
193 static int mem_ap_setup_transfer(struct adiv5_ap *ap, uint32_t csw, uint32_t tar)
194 {
195 int retval;
196 retval = mem_ap_setup_csw(ap, csw);
197 if (retval != ERROR_OK)
198 return retval;
199 retval = mem_ap_setup_tar(ap, tar);
200 if (retval != ERROR_OK)
201 return retval;
202 return ERROR_OK;
203 }
204
205 /**
206 * Asynchronous (queued) read of a word from memory or a system register.
207 *
208 * @param ap The MEM-AP to access.
209 * @param address Address of the 32-bit word to read; it must be
210 * readable by the currently selected MEM-AP.
211 * @param value points to where the word will be stored when the
212 * transaction queue is flushed (assuming no errors).
213 *
214 * @return ERROR_OK for success. Otherwise a fault code.
215 */
216 int mem_ap_read_u32(struct adiv5_ap *ap, uint32_t address,
217 uint32_t *value)
218 {
219 int retval;
220
221 /* Use banked addressing (REG_BDx) to avoid some link traffic
222 * (updating TAR) when reading several consecutive addresses.
223 */
224 retval = mem_ap_setup_transfer(ap, CSW_32BIT | CSW_ADDRINC_OFF,
225 address & 0xFFFFFFF0);
226 if (retval != ERROR_OK)
227 return retval;
228
229 return dap_queue_ap_read(ap, MEM_AP_REG_BD0 | (address & 0xC), value);
230 }
231
232 /**
233 * Synchronous read of a word from memory or a system register.
234 * As a side effect, this flushes any queued transactions.
235 *
236 * @param ap The MEM-AP to access.
237 * @param address Address of the 32-bit word to read; it must be
238 * readable by the currently selected MEM-AP.
239 * @param value points to where the result will be stored.
240 *
241 * @return ERROR_OK for success; *value holds the result.
242 * Otherwise a fault code.
243 */
244 int mem_ap_read_atomic_u32(struct adiv5_ap *ap, uint32_t address,
245 uint32_t *value)
246 {
247 int retval;
248
249 retval = mem_ap_read_u32(ap, address, value);
250 if (retval != ERROR_OK)
251 return retval;
252
253 return dap_run(ap->dap);
254 }
255
256 /**
257 * Asynchronous (queued) write of a word to memory or a system register.
258 *
259 * @param ap The MEM-AP to access.
260 * @param address Address to be written; it must be writable by
261 * the currently selected MEM-AP.
262 * @param value Word that will be written to the address when transaction
263 * queue is flushed (assuming no errors).
264 *
265 * @return ERROR_OK for success. Otherwise a fault code.
266 */
267 int mem_ap_write_u32(struct adiv5_ap *ap, uint32_t address,
268 uint32_t value)
269 {
270 int retval;
271
272 /* Use banked addressing (REG_BDx) to avoid some link traffic
273 * (updating TAR) when writing several consecutive addresses.
274 */
275 retval = mem_ap_setup_transfer(ap, CSW_32BIT | CSW_ADDRINC_OFF,
276 address & 0xFFFFFFF0);
277 if (retval != ERROR_OK)
278 return retval;
279
280 return dap_queue_ap_write(ap, MEM_AP_REG_BD0 | (address & 0xC),
281 value);
282 }
283
284 /**
285 * Synchronous write of a word to memory or a system register.
286 * As a side effect, this flushes any queued transactions.
287 *
288 * @param ap The MEM-AP to access.
289 * @param address Address to be written; it must be writable by
290 * the currently selected MEM-AP.
291 * @param value Word that will be written.
292 *
293 * @return ERROR_OK for success; the data was written. Otherwise a fault code.
294 */
295 int mem_ap_write_atomic_u32(struct adiv5_ap *ap, uint32_t address,
296 uint32_t value)
297 {
298 int retval = mem_ap_write_u32(ap, address, value);
299
300 if (retval != ERROR_OK)
301 return retval;
302
303 return dap_run(ap->dap);
304 }
305
306 /**
307 * Synchronous write of a block of memory, using a specific access size.
308 *
309 * @param ap The MEM-AP to access.
310 * @param buffer The data buffer to write. No particular alignment is assumed.
311 * @param size Which access size to use, in bytes. 1, 2 or 4.
312 * @param count The number of writes to do (in size units, not bytes).
313 * @param address Address to be written; it must be writable by the currently selected MEM-AP.
314 * @param addrinc Whether the target address should be increased for each write or not. This
315 * should normally be true, except when writing to e.g. a FIFO.
316 * @return ERROR_OK on success, otherwise an error code.
317 */
318 static int mem_ap_write(struct adiv5_ap *ap, const uint8_t *buffer, uint32_t size, uint32_t count,
319 uint32_t address, bool addrinc)
320 {
321 struct adiv5_dap *dap = ap->dap;
322 size_t nbytes = size * count;
323 const uint32_t csw_addrincr = addrinc ? CSW_ADDRINC_SINGLE : CSW_ADDRINC_OFF;
324 uint32_t csw_size;
325 uint32_t addr_xor;
326 int retval;
327
328 /* TI BE-32 Quirks mode:
329 * Writes on big-endian TMS570 behave very strangely. Observed behavior:
330 * size write address bytes written in order
331 * 4 TAR ^ 0 (val >> 24), (val >> 16), (val >> 8), (val)
332 * 2 TAR ^ 2 (val >> 8), (val)
333 * 1 TAR ^ 3 (val)
334 * For example, if you attempt to write a single byte to address 0, the processor
335 * will actually write a byte to address 3.
336 *
337 * To make writes of size < 4 work as expected, we xor a value with the address before
338 * setting the TAP, and we set the TAP after every transfer rather then relying on
339 * address increment. */
340
341 if (size == 4) {
342 csw_size = CSW_32BIT;
343 addr_xor = 0;
344 } else if (size == 2) {
345 csw_size = CSW_16BIT;
346 addr_xor = dap->ti_be_32_quirks ? 2 : 0;
347 } else if (size == 1) {
348 csw_size = CSW_8BIT;
349 addr_xor = dap->ti_be_32_quirks ? 3 : 0;
350 } else {
351 return ERROR_TARGET_UNALIGNED_ACCESS;
352 }
353
354 if (ap->unaligned_access_bad && (address % size != 0))
355 return ERROR_TARGET_UNALIGNED_ACCESS;
356
357 while (nbytes > 0) {
358 uint32_t this_size = size;
359
360 /* Select packed transfer if possible */
361 if (addrinc && ap->packed_transfers && nbytes >= 4
362 && max_tar_block_size(ap->tar_autoincr_block, address) >= 4) {
363 this_size = 4;
364 retval = mem_ap_setup_csw(ap, csw_size | CSW_ADDRINC_PACKED);
365 } else {
366 retval = mem_ap_setup_csw(ap, csw_size | csw_addrincr);
367 }
368
369 if (retval != ERROR_OK)
370 break;
371
372 retval = mem_ap_setup_tar(ap, address ^ addr_xor);
373 if (retval != ERROR_OK)
374 return retval;
375
376 /* How many source bytes each transfer will consume, and their location in the DRW,
377 * depends on the type of transfer and alignment. See ARM document IHI0031C. */
378 uint32_t outvalue = 0;
379 if (dap->ti_be_32_quirks) {
380 switch (this_size) {
381 case 4:
382 outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor);
383 outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor);
384 outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor);
385 outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor);
386 break;
387 case 2:
388 outvalue |= (uint32_t)*buffer++ << 8 * (1 ^ (address++ & 3) ^ addr_xor);
389 outvalue |= (uint32_t)*buffer++ << 8 * (1 ^ (address++ & 3) ^ addr_xor);
390 break;
391 case 1:
392 outvalue |= (uint32_t)*buffer++ << 8 * (0 ^ (address++ & 3) ^ addr_xor);
393 break;
394 }
395 } else {
396 switch (this_size) {
397 case 4:
398 outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
399 outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
400 /* fallthrough */
401 case 2:
402 outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
403 /* fallthrough */
404 case 1:
405 outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
406 }
407 }
408
409 nbytes -= this_size;
410
411 retval = dap_queue_ap_write(ap, MEM_AP_REG_DRW, outvalue);
412 if (retval != ERROR_OK)
413 break;
414
415 mem_ap_update_tar_cache(ap);
416 }
417
418 /* REVISIT: Might want to have a queued version of this function that does not run. */
419 if (retval == ERROR_OK)
420 retval = dap_run(dap);
421
422 if (retval != ERROR_OK) {
423 uint32_t tar;
424 if (mem_ap_read_tar(ap, &tar) == ERROR_OK)
425 LOG_ERROR("Failed to write memory at 0x%08"PRIx32, tar);
426 else
427 LOG_ERROR("Failed to write memory and, additionally, failed to find out where");
428 }
429
430 return retval;
431 }
432
433 /**
434 * Synchronous read of a block of memory, using a specific access size.
435 *
436 * @param ap The MEM-AP to access.
437 * @param buffer The data buffer to receive the data. No particular alignment is assumed.
438 * @param size Which access size to use, in bytes. 1, 2 or 4.
439 * @param count The number of reads to do (in size units, not bytes).
440 * @param address Address to be read; it must be readable by the currently selected MEM-AP.
441 * @param addrinc Whether the target address should be increased after each read or not. This
442 * should normally be true, except when reading from e.g. a FIFO.
443 * @return ERROR_OK on success, otherwise an error code.
444 */
445 static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint32_t count,
446 uint32_t adr, bool addrinc)
447 {
448 struct adiv5_dap *dap = ap->dap;
449 size_t nbytes = size * count;
450 const uint32_t csw_addrincr = addrinc ? CSW_ADDRINC_SINGLE : CSW_ADDRINC_OFF;
451 uint32_t csw_size;
452 uint32_t address = adr;
453 int retval;
454
455 /* TI BE-32 Quirks mode:
456 * Reads on big-endian TMS570 behave strangely differently than writes.
457 * They read from the physical address requested, but with DRW byte-reversed.
458 * For example, a byte read from address 0 will place the result in the high bytes of DRW.
459 * Also, packed 8-bit and 16-bit transfers seem to sometimes return garbage in some bytes,
460 * so avoid them. */
461
462 if (size == 4)
463 csw_size = CSW_32BIT;
464 else if (size == 2)
465 csw_size = CSW_16BIT;
466 else if (size == 1)
467 csw_size = CSW_8BIT;
468 else
469 return ERROR_TARGET_UNALIGNED_ACCESS;
470
471 if (ap->unaligned_access_bad && (adr % size != 0))
472 return ERROR_TARGET_UNALIGNED_ACCESS;
473
474 /* Allocate buffer to hold the sequence of DRW reads that will be made. This is a significant
475 * over-allocation if packed transfers are going to be used, but determining the real need at
476 * this point would be messy. */
477 uint32_t *read_buf = malloc(count * sizeof(uint32_t));
478 uint32_t *read_ptr = read_buf;
479 if (read_buf == NULL) {
480 LOG_ERROR("Failed to allocate read buffer");
481 return ERROR_FAIL;
482 }
483
484 /* Queue up all reads. Each read will store the entire DRW word in the read buffer. How many
485 * useful bytes it contains, and their location in the word, depends on the type of transfer
486 * and alignment. */
487 while (nbytes > 0) {
488 uint32_t this_size = size;
489
490 /* Select packed transfer if possible */
491 if (addrinc && ap->packed_transfers && nbytes >= 4
492 && max_tar_block_size(ap->tar_autoincr_block, address) >= 4) {
493 this_size = 4;
494 retval = mem_ap_setup_csw(ap, csw_size | CSW_ADDRINC_PACKED);
495 } else {
496 retval = mem_ap_setup_csw(ap, csw_size | csw_addrincr);
497 }
498 if (retval != ERROR_OK)
499 break;
500
501 retval = mem_ap_setup_tar(ap, address);
502 if (retval != ERROR_OK)
503 break;
504
505 retval = dap_queue_ap_read(ap, MEM_AP_REG_DRW, read_ptr++);
506 if (retval != ERROR_OK)
507 break;
508
509 nbytes -= this_size;
510 address += this_size;
511
512 mem_ap_update_tar_cache(ap);
513 }
514
515 if (retval == ERROR_OK)
516 retval = dap_run(dap);
517
518 /* Restore state */
519 address = adr;
520 nbytes = size * count;
521 read_ptr = read_buf;
522
523 /* If something failed, read TAR to find out how much data was successfully read, so we can
524 * at least give the caller what we have. */
525 if (retval != ERROR_OK) {
526 uint32_t tar;
527 if (mem_ap_read_tar(ap, &tar) == ERROR_OK) {
528 /* TAR is incremented after failed transfer on some devices (eg Cortex-M4) */
529 LOG_ERROR("Failed to read memory at 0x%08"PRIx32, tar);
530 if (nbytes > tar - address)
531 nbytes = tar - address;
532 } else {
533 LOG_ERROR("Failed to read memory and, additionally, failed to find out where");
534 nbytes = 0;
535 }
536 }
537
538 /* Replay loop to populate caller's buffer from the correct word and byte lane */
539 while (nbytes > 0) {
540 uint32_t this_size = size;
541
542 if (addrinc && ap->packed_transfers && nbytes >= 4
543 && max_tar_block_size(ap->tar_autoincr_block, address) >= 4) {
544 this_size = 4;
545 }
546
547 if (dap->ti_be_32_quirks) {
548 switch (this_size) {
549 case 4:
550 *buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));
551 *buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));
552 /* fallthrough */
553 case 2:
554 *buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));
555 /* fallthrough */
556 case 1:
557 *buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));
558 }
559 } else {
560 switch (this_size) {
561 case 4:
562 *buffer++ = *read_ptr >> 8 * (address++ & 3);
563 *buffer++ = *read_ptr >> 8 * (address++ & 3);
564 /* fallthrough */
565 case 2:
566 *buffer++ = *read_ptr >> 8 * (address++ & 3);
567 /* fallthrough */
568 case 1:
569 *buffer++ = *read_ptr >> 8 * (address++ & 3);
570 }
571 }
572
573 read_ptr++;
574 nbytes -= this_size;
575 }
576
577 free(read_buf);
578 return retval;
579 }
580
581 int mem_ap_read_buf(struct adiv5_ap *ap,
582 uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address)
583 {
584 return mem_ap_read(ap, buffer, size, count, address, true);
585 }
586
587 int mem_ap_write_buf(struct adiv5_ap *ap,
588 const uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address)
589 {
590 return mem_ap_write(ap, buffer, size, count, address, true);
591 }
592
593 int mem_ap_read_buf_noincr(struct adiv5_ap *ap,
594 uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address)
595 {
596 return mem_ap_read(ap, buffer, size, count, address, false);
597 }
598
599 int mem_ap_write_buf_noincr(struct adiv5_ap *ap,
600 const uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address)
601 {
602 return mem_ap_write(ap, buffer, size, count, address, false);
603 }
604
605 /*--------------------------------------------------------------------------*/
606
607
608 #define DAP_POWER_DOMAIN_TIMEOUT (10)
609
610 /* FIXME don't import ... just initialize as
611 * part of DAP transport setup
612 */
613 extern const struct dap_ops jtag_dp_ops;
614
615 /*--------------------------------------------------------------------------*/
616
617 /**
618 * Create a new DAP
619 */
620 struct adiv5_dap *dap_init(void)
621 {
622 struct adiv5_dap *dap = calloc(1, sizeof(struct adiv5_dap));
623 int i;
624 /* Set up with safe defaults */
625 for (i = 0; i <= 255; i++) {
626 dap->ap[i].dap = dap;
627 dap->ap[i].ap_num = i;
628 /* memaccess_tck max is 255 */
629 dap->ap[i].memaccess_tck = 255;
630 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
631 dap->ap[i].tar_autoincr_block = (1<<10);
632 }
633 INIT_LIST_HEAD(&dap->cmd_journal);
634 return dap;
635 }
636
637 /**
638 * Invalidate cached DP select and cached TAR and CSW of all APs
639 */
640 void dap_invalidate_cache(struct adiv5_dap *dap)
641 {
642 dap->select = DP_SELECT_INVALID;
643 dap->last_read = NULL;
644
645 int i;
646 for (i = 0; i <= 255; i++) {
647 /* force csw and tar write on the next mem-ap access */
648 dap->ap[i].tar_valid = false;
649 dap->ap[i].csw_value = 0;
650 }
651 }
652
653 /**
654 * Initialize a DAP. This sets up the power domains, prepares the DP
655 * for further use and activates overrun checking.
656 *
657 * @param dap The DAP being initialized.
658 */
659 int dap_dp_init(struct adiv5_dap *dap)
660 {
661 int retval;
662
663 LOG_DEBUG(" ");
664 /* JTAG-DP or SWJ-DP, in JTAG mode
665 * ... for SWD mode this is patched as part
666 * of link switchover
667 * FIXME: This should already be setup by the respective transport specific DAP creation.
668 */
669 if (!dap->ops)
670 dap->ops = &jtag_dp_ops;
671
672 dap_invalidate_cache(dap);
673
674 for (size_t i = 0; i < 30; i++) {
675 /* DP initialization */
676
677 retval = dap_dp_read_atomic(dap, DP_CTRL_STAT, NULL);
678 if (retval == ERROR_OK)
679 break;
680 }
681
682 retval = dap_queue_dp_write(dap, DP_CTRL_STAT, SSTICKYERR);
683 if (retval != ERROR_OK)
684 return retval;
685
686 retval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL);
687 if (retval != ERROR_OK)
688 return retval;
689
690 dap->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ;
691 retval = dap_queue_dp_write(dap, DP_CTRL_STAT, dap->dp_ctrl_stat);
692 if (retval != ERROR_OK)
693 return retval;
694
695 /* Check that we have debug power domains activated */
696 LOG_DEBUG("DAP: wait CDBGPWRUPACK");
697 retval = dap_dp_poll_register(dap, DP_CTRL_STAT,
698 CDBGPWRUPACK, CDBGPWRUPACK,
699 DAP_POWER_DOMAIN_TIMEOUT);
700 if (retval != ERROR_OK)
701 return retval;
702
703 LOG_DEBUG("DAP: wait CSYSPWRUPACK");
704 retval = dap_dp_poll_register(dap, DP_CTRL_STAT,
705 CSYSPWRUPACK, CSYSPWRUPACK,
706 DAP_POWER_DOMAIN_TIMEOUT);
707 if (retval != ERROR_OK)
708 return retval;
709
710 retval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL);
711 if (retval != ERROR_OK)
712 return retval;
713
714 /* With debug power on we can activate OVERRUN checking */
715 dap->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ | CORUNDETECT;
716 retval = dap_queue_dp_write(dap, DP_CTRL_STAT, dap->dp_ctrl_stat);
717 if (retval != ERROR_OK)
718 return retval;
719 retval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL);
720 if (retval != ERROR_OK)
721 return retval;
722
723 retval = dap_run(dap);
724 if (retval != ERROR_OK)
725 return retval;
726
727 return retval;
728 }
729
730 /**
731 * Initialize a DAP. This sets up the power domains, prepares the DP
732 * for further use, and arranges to use AP #0 for all AP operations
733 * until dap_ap-select() changes that policy.
734 *
735 * @param ap The MEM-AP being initialized.
736 */
737 int mem_ap_init(struct adiv5_ap *ap)
738 {
739 /* check that we support packed transfers */
740 uint32_t csw, cfg;
741 int retval;
742 struct adiv5_dap *dap = ap->dap;
743
744 ap->tar_valid = false;
745 ap->csw_value = 0; /* force csw and tar write */
746 retval = mem_ap_setup_transfer(ap, CSW_8BIT | CSW_ADDRINC_PACKED, 0);
747 if (retval != ERROR_OK)
748 return retval;
749
750 retval = dap_queue_ap_read(ap, MEM_AP_REG_CSW, &csw);
751 if (retval != ERROR_OK)
752 return retval;
753
754 retval = dap_queue_ap_read(ap, MEM_AP_REG_CFG, &cfg);
755 if (retval != ERROR_OK)
756 return retval;
757
758 retval = dap_run(dap);
759 if (retval != ERROR_OK)
760 return retval;
761
762 if (csw & CSW_ADDRINC_PACKED)
763 ap->packed_transfers = true;
764 else
765 ap->packed_transfers = false;
766
767 /* Packed transfers on TI BE-32 processors do not work correctly in
768 * many cases. */
769 if (dap->ti_be_32_quirks)
770 ap->packed_transfers = false;
771
772 LOG_DEBUG("MEM_AP Packed Transfers: %s",
773 ap->packed_transfers ? "enabled" : "disabled");
774
775 /* The ARM ADI spec leaves implementation-defined whether unaligned
776 * memory accesses work, only work partially, or cause a sticky error.
777 * On TI BE-32 processors, reads seem to return garbage in some bytes
778 * and unaligned writes seem to cause a sticky error.
779 * TODO: it would be nice to have a way to detect whether unaligned
780 * operations are supported on other processors. */
781 ap->unaligned_access_bad = dap->ti_be_32_quirks;
782
783 LOG_DEBUG("MEM_AP CFG: large data %d, long address %d, big-endian %d",
784 !!(cfg & 0x04), !!(cfg & 0x02), !!(cfg & 0x01));
785
786 return ERROR_OK;
787 }
788
789 /* CID interpretation -- see ARM IHI 0029B section 3
790 * and ARM IHI 0031A table 13-3.
791 */
792 static const char *class_description[16] = {
793 "Reserved", "ROM table", "Reserved", "Reserved",
794 "Reserved", "Reserved", "Reserved", "Reserved",
795 "Reserved", "CoreSight component", "Reserved", "Peripheral Test Block",
796 "Reserved", "OptimoDE DESS",
797 "Generic IP component", "PrimeCell or System component"
798 };
799
800 static bool is_dap_cid_ok(uint32_t cid)
801 {
802 return (cid & 0xffff0fff) == 0xb105000d;
803 }
804
805 /*
806 * This function checks the ID for each access port to find the requested Access Port type
807 */
808 int dap_find_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adiv5_ap **ap_out)
809 {
810 int ap_num;
811
812 /* Maximum AP number is 255 since the SELECT register is 8 bits */
813 for (ap_num = 0; ap_num <= 255; ap_num++) {
814
815 /* read the IDR register of the Access Port */
816 uint32_t id_val = 0;
817
818 int retval = dap_queue_ap_read(dap_ap(dap, ap_num), AP_REG_IDR, &id_val);
819 if (retval != ERROR_OK)
820 return retval;
821
822 retval = dap_run(dap);
823
824 /* IDR bits:
825 * 31-28 : Revision
826 * 27-24 : JEDEC bank (0x4 for ARM)
827 * 23-17 : JEDEC code (0x3B for ARM)
828 * 16-13 : Class (0b1000=Mem-AP)
829 * 12-8 : Reserved
830 * 7-4 : AP Variant (non-zero for JTAG-AP)
831 * 3-0 : AP Type (0=JTAG-AP 1=AHB-AP 2=APB-AP 4=AXI-AP)
832 */
833
834 /* Reading register for a non-existant AP should not cause an error,
835 * but just to be sure, try to continue searching if an error does happen.
836 */
837 if ((retval == ERROR_OK) && /* Register read success */
838 ((id_val & IDR_JEP106) == IDR_JEP106_ARM) && /* Jedec codes match */
839 ((id_val & IDR_TYPE) == type_to_find)) { /* type matches*/
840
841 LOG_DEBUG("Found %s at AP index: %d (IDR=0x%08" PRIX32 ")",
842 (type_to_find == AP_TYPE_AHB_AP) ? "AHB-AP" :
843 (type_to_find == AP_TYPE_APB_AP) ? "APB-AP" :
844 (type_to_find == AP_TYPE_AXI_AP) ? "AXI-AP" :
845 (type_to_find == AP_TYPE_JTAG_AP) ? "JTAG-AP" : "Unknown",
846 ap_num, id_val);
847
848 *ap_out = &dap->ap[ap_num];
849 return ERROR_OK;
850 }
851 }
852
853 LOG_DEBUG("No %s found",
854 (type_to_find == AP_TYPE_AHB_AP) ? "AHB-AP" :
855 (type_to_find == AP_TYPE_APB_AP) ? "APB-AP" :
856 (type_to_find == AP_TYPE_AXI_AP) ? "AXI-AP" :
857 (type_to_find == AP_TYPE_JTAG_AP) ? "JTAG-AP" : "Unknown");
858 return ERROR_FAIL;
859 }
860
861 int dap_get_debugbase(struct adiv5_ap *ap,
862 uint32_t *dbgbase, uint32_t *apid)
863 {
864 struct adiv5_dap *dap = ap->dap;
865 int retval;
866
867 retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE, dbgbase);
868 if (retval != ERROR_OK)
869 return retval;
870 retval = dap_queue_ap_read(ap, AP_REG_IDR, apid);
871 if (retval != ERROR_OK)
872 return retval;
873 retval = dap_run(dap);
874 if (retval != ERROR_OK)
875 return retval;
876
877 return ERROR_OK;
878 }
879
880 int dap_lookup_cs_component(struct adiv5_ap *ap,
881 uint32_t dbgbase, uint8_t type, uint32_t *addr, int32_t *idx)
882 {
883 uint32_t romentry, entry_offset = 0, component_base, devtype;
884 int retval;
885
886 *addr = 0;
887
888 do {
889 retval = mem_ap_read_atomic_u32(ap, (dbgbase&0xFFFFF000) |
890 entry_offset, &romentry);
891 if (retval != ERROR_OK)
892 return retval;
893
894 component_base = (dbgbase & 0xFFFFF000)
895 + (romentry & 0xFFFFF000);
896
897 if (romentry & 0x1) {
898 uint32_t c_cid1;
899 retval = mem_ap_read_atomic_u32(ap, component_base | 0xff4, &c_cid1);
900 if (retval != ERROR_OK) {
901 LOG_ERROR("Can't read component with base address 0x%" PRIx32
902 ", the corresponding core might be turned off", component_base);
903 return retval;
904 }
905 if (((c_cid1 >> 4) & 0x0f) == 1) {
906 retval = dap_lookup_cs_component(ap, component_base,
907 type, addr, idx);
908 if (retval == ERROR_OK)
909 break;
910 if (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
911 return retval;
912 }
913
914 retval = mem_ap_read_atomic_u32(ap,
915 (component_base & 0xfffff000) | 0xfcc,
916 &devtype);
917 if (retval != ERROR_OK)
918 return retval;
919 if ((devtype & 0xff) == type) {
920 if (!*idx) {
921 *addr = component_base;
922 break;
923 } else
924 (*idx)--;
925 }
926 }
927 entry_offset += 4;
928 } while (romentry > 0);
929
930 if (!*addr)
931 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
932
933 return ERROR_OK;
934 }
935
936 static int dap_read_part_id(struct adiv5_ap *ap, uint32_t component_base, uint32_t *cid, uint64_t *pid)
937 {
938 assert((component_base & 0xFFF) == 0);
939 assert(ap != NULL && cid != NULL && pid != NULL);
940
941 uint32_t cid0, cid1, cid2, cid3;
942 uint32_t pid0, pid1, pid2, pid3, pid4;
943 int retval;
944
945 /* IDs are in last 4K section */
946 retval = mem_ap_read_u32(ap, component_base + 0xFE0, &pid0);
947 if (retval != ERROR_OK)
948 return retval;
949 retval = mem_ap_read_u32(ap, component_base + 0xFE4, &pid1);
950 if (retval != ERROR_OK)
951 return retval;
952 retval = mem_ap_read_u32(ap, component_base + 0xFE8, &pid2);
953 if (retval != ERROR_OK)
954 return retval;
955 retval = mem_ap_read_u32(ap, component_base + 0xFEC, &pid3);
956 if (retval != ERROR_OK)
957 return retval;
958 retval = mem_ap_read_u32(ap, component_base + 0xFD0, &pid4);
959 if (retval != ERROR_OK)
960 return retval;
961 retval = mem_ap_read_u32(ap, component_base + 0xFF0, &cid0);
962 if (retval != ERROR_OK)
963 return retval;
964 retval = mem_ap_read_u32(ap, component_base + 0xFF4, &cid1);
965 if (retval != ERROR_OK)
966 return retval;
967 retval = mem_ap_read_u32(ap, component_base + 0xFF8, &cid2);
968 if (retval != ERROR_OK)
969 return retval;
970 retval = mem_ap_read_u32(ap, component_base + 0xFFC, &cid3);
971 if (retval != ERROR_OK)
972 return retval;
973
974 retval = dap_run(ap->dap);
975 if (retval != ERROR_OK)
976 return retval;
977
978 *cid = (cid3 & 0xff) << 24
979 | (cid2 & 0xff) << 16
980 | (cid1 & 0xff) << 8
981 | (cid0 & 0xff);
982 *pid = (uint64_t)(pid4 & 0xff) << 32
983 | (pid3 & 0xff) << 24
984 | (pid2 & 0xff) << 16
985 | (pid1 & 0xff) << 8
986 | (pid0 & 0xff);
987
988 return ERROR_OK;
989 }
990
991 /* The designer identity code is encoded as:
992 * bits 11:8 : JEP106 Bank (number of continuation codes), only valid when bit 7 is 1.
993 * bit 7 : Set when bits 6:0 represent a JEP106 ID and cleared when bits 6:0 represent
994 * a legacy ASCII Identity Code.
995 * bits 6:0 : JEP106 Identity Code (without parity) or legacy ASCII code according to bit 7.
996 * JEP106 is a standard available from jedec.org
997 */
998
999 /* Part number interpretations are from Cortex
1000 * core specs, the CoreSight components TRM
1001 * (ARM DDI 0314H), CoreSight System Design
1002 * Guide (ARM DGI 0012D) and ETM specs; also
1003 * from chip observation (e.g. TI SDTI).
1004 */
1005
1006 /* The legacy code only used the part number field to identify CoreSight peripherals.
1007 * This meant that the same part number from two different manufacturers looked the same.
1008 * It is desirable for all future additions to identify with both part number and JEP106.
1009 * "ANY_ID" is a wildcard (any JEP106) only to preserve legacy behavior for legacy entries.
1010 */
1011
1012 #define ANY_ID 0x1000
1013
1014 #define ARM_ID 0x4BB
1015
1016 static const struct {
1017 uint16_t designer_id;
1018 uint16_t part_num;
1019 const char *type;
1020 const char *full;
1021 } dap_partnums[] = {
1022 { ARM_ID, 0x000, "Cortex-M3 SCS", "(System Control Space)", },
1023 { ARM_ID, 0x001, "Cortex-M3 ITM", "(Instrumentation Trace Module)", },
1024 { ARM_ID, 0x002, "Cortex-M3 DWT", "(Data Watchpoint and Trace)", },
1025 { ARM_ID, 0x003, "Cortex-M3 FPB", "(Flash Patch and Breakpoint)", },
1026 { ARM_ID, 0x008, "Cortex-M0 SCS", "(System Control Space)", },
1027 { ARM_ID, 0x00a, "Cortex-M0 DWT", "(Data Watchpoint and Trace)", },
1028 { ARM_ID, 0x00b, "Cortex-M0 BPU", "(Breakpoint Unit)", },
1029 { ARM_ID, 0x00c, "Cortex-M4 SCS", "(System Control Space)", },
1030 { ARM_ID, 0x00d, "CoreSight ETM11", "(Embedded Trace)", },
1031 { ARM_ID, 0x00e, "Cortex-M7 FPB", "(Flash Patch and Breakpoint)", },
1032 { ARM_ID, 0x490, "Cortex-A15 GIC", "(Generic Interrupt Controller)", },
1033 { ARM_ID, 0x4a1, "Cortex-A53 ROM", "(v8 Memory Map ROM Table)", },
1034 { ARM_ID, 0x4a2, "Cortex-A57 ROM", "(ROM Table)", },
1035 { ARM_ID, 0x4a3, "Cortex-A53 ROM", "(v7 Memory Map ROM Table)", },
1036 { ARM_ID, 0x4a4, "Cortex-A72 ROM", "(ROM Table)", },
1037 { ARM_ID, 0x4af, "Cortex-A15 ROM", "(ROM Table)", },
1038 { ARM_ID, 0x4c0, "Cortex-M0+ ROM", "(ROM Table)", },
1039 { ARM_ID, 0x4c3, "Cortex-M3 ROM", "(ROM Table)", },
1040 { ARM_ID, 0x4c4, "Cortex-M4 ROM", "(ROM Table)", },
1041 { ARM_ID, 0x4c7, "Cortex-M7 PPB ROM", "(Private Peripheral Bus ROM Table)", },
1042 { ARM_ID, 0x4c8, "Cortex-M7 ROM", "(ROM Table)", },
1043 { ARM_ID, 0x470, "Cortex-M1 ROM", "(ROM Table)", },
1044 { ARM_ID, 0x471, "Cortex-M0 ROM", "(ROM Table)", },
1045 { ARM_ID, 0x906, "CoreSight CTI", "(Cross Trigger)", },
1046 { ARM_ID, 0x907, "CoreSight ETB", "(Trace Buffer)", },
1047 { ARM_ID, 0x908, "CoreSight CSTF", "(Trace Funnel)", },
1048 { ARM_ID, 0x909, "CoreSight ATBR", "(Advanced Trace Bus Replicator)", },
1049 { ARM_ID, 0x910, "CoreSight ETM9", "(Embedded Trace)", },
1050 { ARM_ID, 0x912, "CoreSight TPIU", "(Trace Port Interface Unit)", },
1051 { ARM_ID, 0x913, "CoreSight ITM", "(Instrumentation Trace Macrocell)", },
1052 { ARM_ID, 0x914, "CoreSight SWO", "(Single Wire Output)", },
1053 { ARM_ID, 0x917, "CoreSight HTM", "(AHB Trace Macrocell)", },
1054 { ARM_ID, 0x920, "CoreSight ETM11", "(Embedded Trace)", },
1055 { ARM_ID, 0x921, "Cortex-A8 ETM", "(Embedded Trace)", },
1056 { ARM_ID, 0x922, "Cortex-A8 CTI", "(Cross Trigger)", },
1057 { ARM_ID, 0x923, "Cortex-M3 TPIU", "(Trace Port Interface Unit)", },
1058 { ARM_ID, 0x924, "Cortex-M3 ETM", "(Embedded Trace)", },
1059 { ARM_ID, 0x925, "Cortex-M4 ETM", "(Embedded Trace)", },
1060 { ARM_ID, 0x930, "Cortex-R4 ETM", "(Embedded Trace)", },
1061 { ARM_ID, 0x931, "Cortex-R5 ETM", "(Embedded Trace)", },
1062 { ARM_ID, 0x932, "CoreSight MTB-M0+", "(Micro Trace Buffer)", },
1063 { ARM_ID, 0x941, "CoreSight TPIU-Lite", "(Trace Port Interface Unit)", },
1064 { ARM_ID, 0x950, "Cortex-A9 PTM", "(Program Trace Macrocell)", },
1065 { ARM_ID, 0x955, "Cortex-A5 ETM", "(Embedded Trace)", },
1066 { ARM_ID, 0x95a, "Cortex-A72 ETM", "(Embedded Trace)", },
1067 { ARM_ID, 0x95b, "Cortex-A17 PTM", "(Program Trace Macrocell)", },
1068 { ARM_ID, 0x95d, "Cortex-A53 ETM", "(Embedded Trace)", },
1069 { ARM_ID, 0x95e, "Cortex-A57 ETM", "(Embedded Trace)", },
1070 { ARM_ID, 0x95f, "Cortex-A15 PTM", "(Program Trace Macrocell)", },
1071 { ARM_ID, 0x961, "CoreSight TMC", "(Trace Memory Controller)", },
1072 { ARM_ID, 0x962, "CoreSight STM", "(System Trace Macrocell)", },
1073 { ARM_ID, 0x975, "Cortex-M7 ETM", "(Embedded Trace)", },
1074 { ARM_ID, 0x9a0, "CoreSight PMU", "(Performance Monitoring Unit)", },
1075 { ARM_ID, 0x9a1, "Cortex-M4 TPIU", "(Trace Port Interface Unit)", },
1076 { ARM_ID, 0x9a4, "CoreSight GPR", "(Granular Power Requester)", },
1077 { ARM_ID, 0x9a5, "Cortex-A5 PMU", "(Performance Monitor Unit)", },
1078 { ARM_ID, 0x9a7, "Cortex-A7 PMU", "(Performance Monitor Unit)", },
1079 { ARM_ID, 0x9a8, "Cortex-A53 CTI", "(Cross Trigger)", },
1080 { ARM_ID, 0x9a9, "Cortex-M7 TPIU", "(Trace Port Interface Unit)", },
1081 { ARM_ID, 0x9ae, "Cortex-A17 PMU", "(Performance Monitor Unit)", },
1082 { ARM_ID, 0x9af, "Cortex-A15 PMU", "(Performance Monitor Unit)", },
1083 { ARM_ID, 0x9b7, "Cortex-R7 PMU", "(Performance Monitoring Unit)", },
1084 { ARM_ID, 0x9d3, "Cortex-A53 PMU", "(Performance Monitor Unit)", },
1085 { ARM_ID, 0x9d7, "Cortex-A57 PMU", "(Performance Monitor Unit)", },
1086 { ARM_ID, 0x9d8, "Cortex-A72 PMU", "(Performance Monitor Unit)", },
1087 { ARM_ID, 0xc05, "Cortex-A5 Debug", "(Debug Unit)", },
1088 { ARM_ID, 0xc07, "Cortex-A7 Debug", "(Debug Unit)", },
1089 { ARM_ID, 0xc08, "Cortex-A8 Debug", "(Debug Unit)", },
1090 { ARM_ID, 0xc09, "Cortex-A9 Debug", "(Debug Unit)", },
1091 { ARM_ID, 0xc0e, "Cortex-A17 Debug", "(Debug Unit)", },
1092 { ARM_ID, 0xc0f, "Cortex-A15 Debug", "(Debug Unit)", },
1093 { ARM_ID, 0xc14, "Cortex-R4 Debug", "(Debug Unit)", },
1094 { ARM_ID, 0xc15, "Cortex-R5 Debug", "(Debug Unit)", },
1095 { ARM_ID, 0xc17, "Cortex-R7 Debug", "(Debug Unit)", },
1096 { ARM_ID, 0xd03, "Cortex-A53 Debug", "(Debug Unit)", },
1097 { ARM_ID, 0xd07, "Cortex-A57 Debug", "(Debug Unit)", },
1098 { ARM_ID, 0xd08, "Cortex-A72 Debug", "(Debug Unit)", },
1099 { 0x097, 0x9af, "MSP432 ROM", "(ROM Table)" },
1100 { 0x09f, 0xcd0, "Atmel CPU with DSU", "(CPU)" },
1101 { 0x0c1, 0x1db, "XMC4500 ROM", "(ROM Table)" },
1102 { 0x0c1, 0x1df, "XMC4700/4800 ROM", "(ROM Table)" },
1103 { 0x0c1, 0x1ed, "XMC1000 ROM", "(ROM Table)" },
1104 { 0x0E5, 0x000, "SHARC+/Blackfin+", "", },
1105 { 0x0F0, 0x440, "Qualcomm QDSS Component v1", "(Qualcomm Designed CoreSight Component v1)", },
1106 /* legacy comment: 0x113: what? */
1107 { ANY_ID, 0x120, "TI SDTI", "(System Debug Trace Interface)", }, /* from OMAP3 memmap */
1108 { ANY_ID, 0x343, "TI DAPCTL", "", }, /* from OMAP3 memmap */
1109 };
1110
1111 static int dap_rom_display(struct command_context *cmd_ctx,
1112 struct adiv5_ap *ap, uint32_t dbgbase, int depth)
1113 {
1114 int retval;
1115 uint64_t pid;
1116 uint32_t cid;
1117 char tabs[16] = "";
1118
1119 if (depth > 16) {
1120 command_print(cmd_ctx, "\tTables too deep");
1121 return ERROR_FAIL;
1122 }
1123
1124 if (depth)
1125 snprintf(tabs, sizeof(tabs), "[L%02d] ", depth);
1126
1127 uint32_t base_addr = dbgbase & 0xFFFFF000;
1128 command_print(cmd_ctx, "\t\tComponent base address 0x%08" PRIx32, base_addr);
1129
1130 retval = dap_read_part_id(ap, base_addr, &cid, &pid);
1131 if (retval != ERROR_OK) {
1132 command_print(cmd_ctx, "\t\tCan't read component, the corresponding core might be turned off");
1133 return ERROR_OK; /* Don't abort recursion */
1134 }
1135
1136 if (!is_dap_cid_ok(cid)) {
1137 command_print(cmd_ctx, "\t\tInvalid CID 0x%08" PRIx32, cid);
1138 return ERROR_OK; /* Don't abort recursion */
1139 }
1140
1141 /* component may take multiple 4K pages */
1142 uint32_t size = (pid >> 36) & 0xf;
1143 if (size > 0)
1144 command_print(cmd_ctx, "\t\tStart address 0x%08" PRIx32, (uint32_t)(base_addr - 0x1000 * size));
1145
1146 command_print(cmd_ctx, "\t\tPeripheral ID 0x%010" PRIx64, pid);
1147
1148 uint8_t class = (cid >> 12) & 0xf;
1149 uint16_t part_num = pid & 0xfff;
1150 uint16_t designer_id = ((pid >> 32) & 0xf) << 8 | ((pid >> 12) & 0xff);
1151
1152 if (designer_id & 0x80) {
1153 /* JEP106 code */
1154 command_print(cmd_ctx, "\t\tDesigner is 0x%03" PRIx16 ", %s",
1155 designer_id, jep106_manufacturer(designer_id >> 8, designer_id & 0x7f));
1156 } else {
1157 /* Legacy ASCII ID, clear invalid bits */
1158 designer_id &= 0x7f;
1159 command_print(cmd_ctx, "\t\tDesigner ASCII code 0x%02" PRIx16 ", %s",
1160 designer_id, designer_id == 0x41 ? "ARM" : "<unknown>");
1161 }
1162
1163 /* default values to be overwritten upon finding a match */
1164 const char *type = "Unrecognized";
1165 const char *full = "";
1166
1167 /* search dap_partnums[] array for a match */
1168 for (unsigned entry = 0; entry < ARRAY_SIZE(dap_partnums); entry++) {
1169
1170 if ((dap_partnums[entry].designer_id != designer_id) && (dap_partnums[entry].designer_id != ANY_ID))
1171 continue;
1172
1173 if (dap_partnums[entry].part_num != part_num)
1174 continue;
1175
1176 type = dap_partnums[entry].type;
1177 full = dap_partnums[entry].full;
1178 break;
1179 }
1180
1181 command_print(cmd_ctx, "\t\tPart is 0x%" PRIx16", %s %s", part_num, type, full);
1182 command_print(cmd_ctx, "\t\tComponent class is 0x%" PRIx8 ", %s", class, class_description[class]);
1183
1184 if (class == 1) { /* ROM Table */
1185 uint32_t memtype;
1186 retval = mem_ap_read_atomic_u32(ap, base_addr | 0xFCC, &memtype);
1187 if (retval != ERROR_OK)
1188 return retval;
1189
1190 if (memtype & 0x01)
1191 command_print(cmd_ctx, "\t\tMEMTYPE system memory present on bus");
1192 else
1193 command_print(cmd_ctx, "\t\tMEMTYPE system memory not present: dedicated debug bus");
1194
1195 /* Read ROM table entries from base address until we get 0x00000000 or reach the reserved area */
1196 for (uint16_t entry_offset = 0; entry_offset < 0xF00; entry_offset += 4) {
1197 uint32_t romentry;
1198 retval = mem_ap_read_atomic_u32(ap, base_addr | entry_offset, &romentry);
1199 if (retval != ERROR_OK)
1200 return retval;
1201 command_print(cmd_ctx, "\t%sROMTABLE[0x%x] = 0x%" PRIx32 "",
1202 tabs, entry_offset, romentry);
1203 if (romentry & 0x01) {
1204 /* Recurse */
1205 retval = dap_rom_display(cmd_ctx, ap, base_addr + (romentry & 0xFFFFF000), depth + 1);
1206 if (retval != ERROR_OK)
1207 return retval;
1208 } else if (romentry != 0) {
1209 command_print(cmd_ctx, "\t\tComponent not present");
1210 } else {
1211 command_print(cmd_ctx, "\t%s\tEnd of ROM table", tabs);
1212 break;
1213 }
1214 }
1215 } else if (class == 9) { /* CoreSight component */
1216 const char *major = "Reserved", *subtype = "Reserved";
1217
1218 uint32_t devtype;
1219 retval = mem_ap_read_atomic_u32(ap, base_addr | 0xFCC, &devtype);
1220 if (retval != ERROR_OK)
1221 return retval;
1222 unsigned minor = (devtype >> 4) & 0x0f;
1223 switch (devtype & 0x0f) {
1224 case 0:
1225 major = "Miscellaneous";
1226 switch (minor) {
1227 case 0:
1228 subtype = "other";
1229 break;
1230 case 4:
1231 subtype = "Validation component";
1232 break;
1233 }
1234 break;
1235 case 1:
1236 major = "Trace Sink";
1237 switch (minor) {
1238 case 0:
1239 subtype = "other";
1240 break;
1241 case 1:
1242 subtype = "Port";
1243 break;
1244 case 2:
1245 subtype = "Buffer";
1246 break;
1247 case 3:
1248 subtype = "Router";
1249 break;
1250 }
1251 break;
1252 case 2:
1253 major = "Trace Link";
1254 switch (minor) {
1255 case 0:
1256 subtype = "other";
1257 break;
1258 case 1:
1259 subtype = "Funnel, router";
1260 break;
1261 case 2:
1262 subtype = "Filter";
1263 break;
1264 case 3:
1265 subtype = "FIFO, buffer";
1266 break;
1267 }
1268 break;
1269 case 3:
1270 major = "Trace Source";
1271 switch (minor) {
1272 case 0:
1273 subtype = "other";
1274 break;
1275 case 1:
1276 subtype = "Processor";
1277 break;
1278 case 2:
1279 subtype = "DSP";
1280 break;
1281 case 3:
1282 subtype = "Engine/Coprocessor";
1283 break;
1284 case 4:
1285 subtype = "Bus";
1286 break;
1287 case 6:
1288 subtype = "Software";
1289 break;
1290 }
1291 break;
1292 case 4:
1293 major = "Debug Control";
1294 switch (minor) {
1295 case 0:
1296 subtype = "other";
1297 break;
1298 case 1:
1299 subtype = "Trigger Matrix";
1300 break;
1301 case 2:
1302 subtype = "Debug Auth";
1303 break;
1304 case 3:
1305 subtype = "Power Requestor";
1306 break;
1307 }
1308 break;
1309 case 5:
1310 major = "Debug Logic";
1311 switch (minor) {
1312 case 0:
1313 subtype = "other";
1314 break;
1315 case 1:
1316 subtype = "Processor";
1317 break;
1318 case 2:
1319 subtype = "DSP";
1320 break;
1321 case 3:
1322 subtype = "Engine/Coprocessor";
1323 break;
1324 case 4:
1325 subtype = "Bus";
1326 break;
1327 case 5:
1328 subtype = "Memory";
1329 break;
1330 }
1331 break;
1332 case 6:
1333 major = "Perfomance Monitor";
1334 switch (minor) {
1335 case 0:
1336 subtype = "other";
1337 break;
1338 case 1:
1339 subtype = "Processor";
1340 break;
1341 case 2:
1342 subtype = "DSP";
1343 break;
1344 case 3:
1345 subtype = "Engine/Coprocessor";
1346 break;
1347 case 4:
1348 subtype = "Bus";
1349 break;
1350 case 5:
1351 subtype = "Memory";
1352 break;
1353 }
1354 break;
1355 }
1356 command_print(cmd_ctx, "\t\tType is 0x%02" PRIx8 ", %s, %s",
1357 (uint8_t)(devtype & 0xff),
1358 major, subtype);
1359 /* REVISIT also show 0xfc8 DevId */
1360 }
1361
1362 return ERROR_OK;
1363 }
1364
1365 static int dap_info_command(struct command_context *cmd_ctx,
1366 struct adiv5_ap *ap)
1367 {
1368 int retval;
1369 uint32_t dbgbase, apid;
1370 uint8_t mem_ap;
1371
1372 /* Now we read ROM table ID registers, ref. ARM IHI 0029B sec */
1373 retval = dap_get_debugbase(ap, &dbgbase, &apid);
1374 if (retval != ERROR_OK)
1375 return retval;
1376
1377 command_print(cmd_ctx, "AP ID register 0x%8.8" PRIx32, apid);
1378 if (apid == 0) {
1379 command_print(cmd_ctx, "No AP found at this ap 0x%x", ap->ap_num);
1380 return ERROR_FAIL;
1381 }
1382
1383 switch (apid & (IDR_JEP106 | IDR_TYPE)) {
1384 case IDR_JEP106_ARM | AP_TYPE_JTAG_AP:
1385 command_print(cmd_ctx, "\tType is JTAG-AP");
1386 break;
1387 case IDR_JEP106_ARM | AP_TYPE_AHB_AP:
1388 command_print(cmd_ctx, "\tType is MEM-AP AHB");
1389 break;
1390 case IDR_JEP106_ARM | AP_TYPE_APB_AP:
1391 command_print(cmd_ctx, "\tType is MEM-AP APB");
1392 break;
1393 case IDR_JEP106_ARM | AP_TYPE_AXI_AP:
1394 command_print(cmd_ctx, "\tType is MEM-AP AXI");
1395 break;
1396 default:
1397 command_print(cmd_ctx, "\tUnknown AP type");
1398 break;
1399 }
1400
1401 /* NOTE: a MEM-AP may have a single CoreSight component that's
1402 * not a ROM table ... or have no such components at all.
1403 */
1404 mem_ap = (apid & IDR_CLASS) == AP_CLASS_MEM_AP;
1405 if (mem_ap) {
1406 command_print(cmd_ctx, "MEM-AP BASE 0x%8.8" PRIx32, dbgbase);
1407
1408 if (dbgbase == 0xFFFFFFFF || (dbgbase & 0x3) == 0x2) {
1409 command_print(cmd_ctx, "\tNo ROM table present");
1410 } else {
1411 if (dbgbase & 0x01)
1412 command_print(cmd_ctx, "\tValid ROM table present");
1413 else
1414 command_print(cmd_ctx, "\tROM table in legacy format");
1415
1416 dap_rom_display(cmd_ctx, ap, dbgbase & 0xFFFFF000, 0);
1417 }
1418 }
1419
1420 return ERROR_OK;
1421 }
1422
1423 int adiv5_jim_configure(struct target *target, Jim_GetOptInfo *goi)
1424 {
1425 struct adiv5_private_config *pc;
1426 const char *arg;
1427 jim_wide ap_num;
1428 int e;
1429
1430 /* check if argv[0] is for us */
1431 arg = Jim_GetString(goi->argv[0], NULL);
1432 if (strcmp(arg, "-ap-num"))
1433 return JIM_CONTINUE;
1434
1435 e = Jim_GetOpt_String(goi, &arg, NULL);
1436 if (e != JIM_OK)
1437 return e;
1438
1439 if (goi->argc == 0) {
1440 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-ap-num ?ap-number? ...");
1441 return JIM_ERR;
1442 }
1443
1444 e = Jim_GetOpt_Wide(goi, &ap_num);
1445 if (e != JIM_OK)
1446 return e;
1447
1448 if (target->private_config == NULL) {
1449 pc = calloc(1, sizeof(struct adiv5_private_config));
1450 target->private_config = pc;
1451 pc->ap_num = ap_num;
1452 }
1453
1454
1455 return JIM_OK;
1456 }
1457
1458 COMMAND_HANDLER(handle_dap_info_command)
1459 {
1460 struct target *target = get_current_target(CMD_CTX);
1461 struct arm *arm = target_to_arm(target);
1462 struct adiv5_dap *dap = arm->dap;
1463 uint32_t apsel;
1464
1465 switch (CMD_ARGC) {
1466 case 0:
1467 apsel = dap->apsel;
1468 break;
1469 case 1:
1470 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
1471 if (apsel >= 256)
1472 return ERROR_COMMAND_SYNTAX_ERROR;
1473 break;
1474 default:
1475 return ERROR_COMMAND_SYNTAX_ERROR;
1476 }
1477
1478 return dap_info_command(CMD_CTX, &dap->ap[apsel]);
1479 }
1480
1481 COMMAND_HANDLER(dap_baseaddr_command)
1482 {
1483 struct target *target = get_current_target(CMD_CTX);
1484 struct arm *arm = target_to_arm(target);
1485 struct adiv5_dap *dap = arm->dap;
1486
1487 uint32_t apsel, baseaddr;
1488 int retval;
1489
1490 switch (CMD_ARGC) {
1491 case 0:
1492 apsel = dap->apsel;
1493 break;
1494 case 1:
1495 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
1496 /* AP address is in bits 31:24 of DP_SELECT */
1497 if (apsel >= 256)
1498 return ERROR_COMMAND_SYNTAX_ERROR;
1499 break;
1500 default:
1501 return ERROR_COMMAND_SYNTAX_ERROR;
1502 }
1503
1504 /* NOTE: assumes we're talking to a MEM-AP, which
1505 * has a base address. There are other kinds of AP,
1506 * though they're not common for now. This should
1507 * use the ID register to verify it's a MEM-AP.
1508 */
1509 retval = dap_queue_ap_read(dap_ap(dap, apsel), MEM_AP_REG_BASE, &baseaddr);
1510 if (retval != ERROR_OK)
1511 return retval;
1512 retval = dap_run(dap);
1513 if (retval != ERROR_OK)
1514 return retval;
1515
1516 command_print(CMD_CTX, "0x%8.8" PRIx32, baseaddr);
1517
1518 return retval;
1519 }
1520
1521 COMMAND_HANDLER(dap_memaccess_command)
1522 {
1523 struct target *target = get_current_target(CMD_CTX);
1524 struct arm *arm = target_to_arm(target);
1525 struct adiv5_dap *dap = arm->dap;
1526
1527 uint32_t memaccess_tck;
1528
1529 switch (CMD_ARGC) {
1530 case 0:
1531 memaccess_tck = dap->ap[dap->apsel].memaccess_tck;
1532 break;
1533 case 1:
1534 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], memaccess_tck);
1535 break;
1536 default:
1537 return ERROR_COMMAND_SYNTAX_ERROR;
1538 }
1539 dap->ap[dap->apsel].memaccess_tck = memaccess_tck;
1540
1541 command_print(CMD_CTX, "memory bus access delay set to %" PRIi32 " tck",
1542 dap->ap[dap->apsel].memaccess_tck);
1543
1544 return ERROR_OK;
1545 }
1546
1547 COMMAND_HANDLER(dap_apsel_command)
1548 {
1549 struct target *target = get_current_target(CMD_CTX);
1550 struct arm *arm = target_to_arm(target);
1551 struct adiv5_dap *dap = arm->dap;
1552
1553 uint32_t apsel, apid;
1554 int retval;
1555
1556 switch (CMD_ARGC) {
1557 case 0:
1558 apsel = dap->apsel;
1559 break;
1560 case 1:
1561 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
1562 /* AP address is in bits 31:24 of DP_SELECT */
1563 if (apsel >= 256)
1564 return ERROR_COMMAND_SYNTAX_ERROR;
1565 break;
1566 default:
1567 return ERROR_COMMAND_SYNTAX_ERROR;
1568 }
1569
1570 dap->apsel = apsel;
1571
1572 retval = dap_queue_ap_read(dap_ap(dap, apsel), AP_REG_IDR, &apid);
1573 if (retval != ERROR_OK)
1574 return retval;
1575 retval = dap_run(dap);
1576 if (retval != ERROR_OK)
1577 return retval;
1578
1579 command_print(CMD_CTX, "ap %" PRIi32 " selected, identification register 0x%8.8" PRIx32,
1580 apsel, apid);
1581
1582 return retval;
1583 }
1584
1585 COMMAND_HANDLER(dap_apcsw_command)
1586 {
1587 struct target *target = get_current_target(CMD_CTX);
1588 struct arm *arm = target_to_arm(target);
1589 struct adiv5_dap *dap = arm->dap;
1590
1591 uint32_t apcsw = dap->ap[dap->apsel].csw_default, sprot = 0;
1592
1593 switch (CMD_ARGC) {
1594 case 0:
1595 command_print(CMD_CTX, "apsel %" PRIi32 " selected, csw 0x%8.8" PRIx32,
1596 (dap->apsel), apcsw);
1597 break;
1598 case 1:
1599 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], sprot);
1600 /* AP address is in bits 31:24 of DP_SELECT */
1601 if (sprot > 1)
1602 return ERROR_COMMAND_SYNTAX_ERROR;
1603 if (sprot)
1604 apcsw |= CSW_SPROT;
1605 else
1606 apcsw &= ~CSW_SPROT;
1607 break;
1608 default:
1609 return ERROR_COMMAND_SYNTAX_ERROR;
1610 }
1611 dap->ap[dap->apsel].csw_default = apcsw;
1612
1613 return 0;
1614 }
1615
1616
1617
1618 COMMAND_HANDLER(dap_apid_command)
1619 {
1620 struct target *target = get_current_target(CMD_CTX);
1621 struct arm *arm = target_to_arm(target);
1622 struct adiv5_dap *dap = arm->dap;
1623
1624 uint32_t apsel, apid;
1625 int retval;
1626
1627 switch (CMD_ARGC) {
1628 case 0:
1629 apsel = dap->apsel;
1630 break;
1631 case 1:
1632 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
1633 /* AP address is in bits 31:24 of DP_SELECT */
1634 if (apsel >= 256)
1635 return ERROR_COMMAND_SYNTAX_ERROR;
1636 break;
1637 default:
1638 return ERROR_COMMAND_SYNTAX_ERROR;
1639 }
1640
1641 retval = dap_queue_ap_read(dap_ap(dap, apsel), AP_REG_IDR, &apid);
1642 if (retval != ERROR_OK)
1643 return retval;
1644 retval = dap_run(dap);
1645 if (retval != ERROR_OK)
1646 return retval;
1647
1648 command_print(CMD_CTX, "0x%8.8" PRIx32, apid);
1649
1650 return retval;
1651 }
1652
1653 COMMAND_HANDLER(dap_apreg_command)
1654 {
1655 struct target *target = get_current_target(CMD_CTX);
1656 struct arm *arm = target_to_arm(target);
1657 struct adiv5_dap *dap = arm->dap;
1658
1659 uint32_t apsel, reg, value;
1660 int retval;
1661
1662 if (CMD_ARGC < 2 || CMD_ARGC > 3)
1663 return ERROR_COMMAND_SYNTAX_ERROR;
1664
1665 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
1666 /* AP address is in bits 31:24 of DP_SELECT */
1667 if (apsel >= 256)
1668 return ERROR_COMMAND_SYNTAX_ERROR;
1669
1670 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], reg);
1671 if (reg >= 256 || (reg & 3))
1672 return ERROR_COMMAND_SYNTAX_ERROR;
1673
1674 if (CMD_ARGC == 3) {
1675 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);
1676 retval = dap_queue_ap_write(dap_ap(dap, apsel), reg, value);
1677 } else {
1678 retval = dap_queue_ap_read(dap_ap(dap, apsel), reg, &value);
1679 }
1680 if (retval == ERROR_OK)
1681 retval = dap_run(dap);
1682
1683 if (retval != ERROR_OK)
1684 return retval;
1685
1686 if (CMD_ARGC == 2)
1687 command_print(CMD_CTX, "0x%08" PRIx32, value);
1688
1689 return retval;
1690 }
1691
1692 COMMAND_HANDLER(dap_ti_be_32_quirks_command)
1693 {
1694 struct target *target = get_current_target(CMD_CTX);
1695 struct arm *arm = target_to_arm(target);
1696 struct adiv5_dap *dap = arm->dap;
1697
1698 uint32_t enable = dap->ti_be_32_quirks;
1699
1700 switch (CMD_ARGC) {
1701 case 0:
1702 break;
1703 case 1:
1704 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], enable);
1705 if (enable > 1)
1706 return ERROR_COMMAND_SYNTAX_ERROR;
1707 break;
1708 default:
1709 return ERROR_COMMAND_SYNTAX_ERROR;
1710 }
1711 dap->ti_be_32_quirks = enable;
1712 command_print(CMD_CTX, "TI BE-32 quirks mode %s",
1713 enable ? "enabled" : "disabled");
1714
1715 return 0;
1716 }
1717
1718 static const struct command_registration dap_commands[] = {
1719 {
1720 .name = "info",
1721 .handler = handle_dap_info_command,
1722 .mode = COMMAND_EXEC,
1723 .help = "display ROM table for MEM-AP "
1724 "(default currently selected AP)",
1725 .usage = "[ap_num]",
1726 },
1727 {
1728 .name = "apsel",
1729 .handler = dap_apsel_command,
1730 .mode = COMMAND_EXEC,
1731 .help = "Set the currently selected AP (default 0) "
1732 "and display the result",
1733 .usage = "[ap_num]",
1734 },
1735 {
1736 .name = "apcsw",
1737 .handler = dap_apcsw_command,
1738 .mode = COMMAND_EXEC,
1739 .help = "Set csw access bit ",
1740 .usage = "[sprot]",
1741 },
1742
1743 {
1744 .name = "apid",
1745 .handler = dap_apid_command,
1746 .mode = COMMAND_EXEC,
1747 .help = "return ID register from AP "
1748 "(default currently selected AP)",
1749 .usage = "[ap_num]",
1750 },
1751 {
1752 .name = "apreg",
1753 .handler = dap_apreg_command,
1754 .mode = COMMAND_EXEC,
1755 .help = "read/write a register from AP "
1756 "(reg is byte address of a word register, like 0 4 8...)",
1757 .usage = "ap_num reg [value]",
1758 },
1759 {
1760 .name = "baseaddr",
1761 .handler = dap_baseaddr_command,
1762 .mode = COMMAND_EXEC,
1763 .help = "return debug base address from MEM-AP "
1764 "(default currently selected AP)",
1765 .usage = "[ap_num]",
1766 },
1767 {
1768 .name = "memaccess",
1769 .handler = dap_memaccess_command,
1770 .mode = COMMAND_EXEC,
1771 .help = "set/get number of extra tck for MEM-AP memory "
1772 "bus access [0-255]",
1773 .usage = "[cycles]",
1774 },
1775 {
1776 .name = "ti_be_32_quirks",
1777 .handler = dap_ti_be_32_quirks_command,
1778 .mode = COMMAND_CONFIG,
1779 .help = "set/get quirks mode for TI TMS450/TMS570 processors",
1780 .usage = "[enable]",
1781 },
1782 COMMAND_REGISTRATION_DONE
1783 };
1784
1785 const struct command_registration dap_command_handlers[] = {
1786 {
1787 .name = "dap",
1788 .mode = COMMAND_EXEC,
1789 .help = "DAP command group",
1790 .usage = "",
1791 .chain = dap_commands,
1792 },
1793 COMMAND_REGISTRATION_DONE
1794 };

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)