1 /***************************************************************************
2 * Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com> *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
21 * To have flash memory mapped in CPU memory space, the SMI controller
22 * have to be in "HW mode". This requires following constraints:
23 * 1) The command "reset init" have to initialize SMI controller and put
25 * 2) every command in this file have to return to prompt in HW mode. */
33 #include <jtag/jtag.h>
34 #include <helper/time_support.h>
36 #define JTAG_ID_3XX_6XX (0x07926041)
38 #define SMI_READ_REG(a) (_SMI_READ_REG(a))
39 #define _SMI_READ_REG(a) \
44 __a = target_read_u32(target, io_base + (a), &__v); \
45 if (__a != ERROR_OK) \
50 #define SMI_WRITE_REG(a,v) \
54 __r = target_write_u32(target, io_base + (a), (v)); \
55 if (__r != ERROR_OK) \
59 #define SMI_POLL_TFF(timeout) \
63 __r = poll_tff(target, io_base, timeout); \
64 if (__r != ERROR_OK) \
68 #define SMI_SET_SW_MODE() SMI_WRITE_REG(SMI_CR1, \
69 SMI_READ_REG(SMI_CR1) | SMI_SW_MODE)
70 #define SMI_SET_HWWB_MODE() SMI_WRITE_REG(SMI_CR1, \
71 (SMI_READ_REG(SMI_CR1) | SMI_WB_MODE) & ~SMI_SW_MODE)
72 #define SMI_SET_HW_MODE() SMI_WRITE_REG(SMI_CR1, \
73 SMI_READ_REG(SMI_CR1) & ~(SMI_SW_MODE | SMI_WB_MODE))
74 #define SMI_CLEAR_TFF() SMI_WRITE_REG(SMI_SR, ~SMI_TFF)
76 #define SMI_BANK_SIZE (0x01000000)
78 #define SMI_BASE_3XX_6XX (0xf8000000)
79 #define SMI_CFGREG_3XX_6XX (0xfc000000)
81 /* #define SMI_BASE_13XX (0xe6000000) */
82 /* #define SMI_CFGREG_13XX (0xea000000) */
84 #define SMI_CR1 (0x00) /* Control register 1 */
85 #define SMI_CR2 (0x04) /* Control register 2 */
86 #define SMI_SR (0x08) /* Status register */
87 #define SMI_TR (0x0c) /* TX */
88 #define SMI_RR (0x10) /* RX */
90 /* fields in SMI_CR1 */
91 #define SMI_SW_MODE 0x10000000 /* set to enable SW Mode */
92 #define SMI_WB_MODE 0x20000000 /* Write Burst Mode */
94 /* fields in SMI_CR2 */
95 #define SMI_TX_LEN_1 0x00000001 /* data length = 1 byte */
96 #define SMI_TX_LEN_4 0x00000004 /* data length = 4 byte */
97 #define SMI_RX_LEN_3 0x00000030 /* data length = 3 byte */
98 #define SMI_SEND 0x00000080 /* Send data */
99 #define SMI_RSR 0x00000400 /* reads status reg */
100 #define SMI_WE 0x00000800 /* Write Enable */
101 #define SMI_SEL_BANK0 0x00000000 /* Select Bank0 */
102 #define SMI_SEL_BANK1 0x00001000 /* Select Bank1 */
103 #define SMI_SEL_BANK2 0x00002000 /* Select Bank2 */
104 #define SMI_SEL_BANK3 0x00003000 /* Select Bank3 */
106 /* fields in SMI_SR */
107 #define SMI_WIP_BIT 0x00000001 /* WIP Bit of SPI SR on SMI SR */
108 #define SMI_WEL_BIT 0x00000002 /* WEL Bit of SPI SR on SMI SR */
109 #define SMI_TFF 0x00000100 /* Transfer Finished Flag */
112 #define SMI_READ_ID 0x0000009F /* Read Flash Identification */
115 #define SMI_CMD_TIMEOUT (100)
116 #define SMI_PROBE_TIMEOUT (100)
117 #define SMI_MAX_TIMEOUT (3000)
119 /* data structure to maintain flash ids from different vendors */
120 struct flash_device
{
125 unsigned long sectorsize
;
126 unsigned long size_in_bytes
;
129 #define FLASH_ID(n, es, id, psize, ssize, size) \
135 .sectorsize = ssize, \
136 .size_in_bytes = size \
139 static struct flash_device flash_devices
[] = {
140 /* name, erase_cmd, device_id, pagesize, sectorsize, size_in_bytes */
141 FLASH_ID("st m25p05", 0xd8, 0x00102020, 0x80, 0x8000, 0x10000),
142 FLASH_ID("st m25p10", 0xd8, 0x00112020, 0x80, 0x8000, 0x20000),
143 FLASH_ID("st m25p20", 0xd8, 0x00122020, 0x100, 0x10000, 0x40000),
144 FLASH_ID("st m25p40", 0xd8, 0x00132020, 0x100, 0x10000, 0x80000),
145 FLASH_ID("st m25p80", 0xd8, 0x00142020, 0x100, 0x10000, 0x100000),
146 FLASH_ID("st m25p16", 0xd8, 0x00152020, 0x100, 0x10000, 0x200000),
147 FLASH_ID("st m25p32", 0xd8, 0x00162020, 0x100, 0x10000, 0x400000),
148 FLASH_ID("st m25p64", 0xd8, 0x00172020, 0x100, 0x10000, 0x800000),
149 FLASH_ID("st m25p128", 0xd8, 0x00182020, 0x100, 0x40000, 0x1000000),
150 FLASH_ID("st m45pe10", 0xd8, 0x00114020, 0x100, 0x10000, 0x20000),
151 FLASH_ID("st m45pe20", 0xd8, 0x00124020, 0x100, 0x10000, 0x40000),
152 FLASH_ID("st m45pe40", 0xd8, 0x00134020, 0x100, 0x10000, 0x80000),
153 FLASH_ID("st m45pe80", 0xd8, 0x00144020, 0x100, 0x10000, 0x100000),
154 FLASH_ID("sp s25fl004", 0xd8, 0x00120201, 0x100, 0x10000, 0x80000),
155 FLASH_ID("sp s25fl008", 0xd8, 0x00130201, 0x100, 0x10000, 0x100000),
156 FLASH_ID("sp s25fl016", 0xd8, 0x00140201, 0x100, 0x10000, 0x200000),
157 FLASH_ID("sp s25fl032", 0xd8, 0x00150201, 0x100, 0x10000, 0x400000),
158 FLASH_ID("sp s25fl064", 0xd8, 0x00160201, 0x100, 0x10000, 0x800000),
159 FLASH_ID("atmel 25f512", 0x52, 0x0065001f, 0x80, 0x8000, 0x10000),
160 FLASH_ID("atmel 25f1024", 0x52, 0x0060001f, 0x100, 0x8000, 0x20000),
161 FLASH_ID("atmel 25f2048", 0x52, 0x0063001f, 0x100, 0x10000, 0x40000),
162 FLASH_ID("atmel 25f4096", 0x52, 0x0064001f, 0x100, 0x10000, 0x80000),
163 FLASH_ID("atmel 25fs040", 0xd7, 0x0004661f, 0x100, 0x10000, 0x80000),
164 FLASH_ID("mac 25l512", 0xd8, 0x001020c2, 0x010, 0x10000, 0x10000),
165 FLASH_ID("mac 25l1005", 0xd8, 0x001120c2, 0x010, 0x10000, 0x20000),
166 FLASH_ID("mac 25l2005", 0xd8, 0x001220c2, 0x010, 0x10000, 0x40000),
167 FLASH_ID("mac 25l4005", 0xd8, 0x001320c2, 0x010, 0x10000, 0x80000),
168 FLASH_ID("mac 25l8005", 0xd8, 0x001420c2, 0x010, 0x10000, 0x100000),
169 FLASH_ID("mac 25l1605", 0xd8, 0x001520c2, 0x100, 0x10000, 0x200000),
170 FLASH_ID("mac 25l3205", 0xd8, 0x001620c2, 0x100, 0x10000, 0x400000),
171 FLASH_ID("mac 25l6405", 0xd8, 0x001720c2, 0x100, 0x10000, 0x800000),
172 FLASH_ID(NULL
, 0, 0, 0, 0, 0)
175 FLASH_BANK_COMMAND_HANDLER(spearsmi_flash_bank_command
)
177 struct spearsmi_flash_bank
*spearsmi_info
;
179 LOG_DEBUG(__FUNCTION__
);
183 LOG_WARNING("incomplete flash_bank spearsmi configuration");
184 return ERROR_FLASH_BANK_INVALID
;
187 spearsmi_info
= malloc(sizeof(struct spearsmi_flash_bank
));
188 if (spearsmi_info
== NULL
)
190 LOG_ERROR("not enough memory");
194 bank
->driver_priv
= spearsmi_info
;
195 spearsmi_info
->probed
= 0;
200 /* Poll transmit finished flag */
202 static int poll_tff(struct target
*target
, uint32_t io_base
, int timeout
)
206 if (SMI_READ_REG(SMI_SR
) & SMI_TFF
)
209 endtime
= timeval_ms() + timeout
;
212 if (SMI_READ_REG(SMI_SR
) & SMI_TFF
)
214 } while (timeval_ms() < endtime
);
216 LOG_ERROR("Timeout while polling TFF");
217 return ERROR_FLASH_OPERATION_FAILED
;
220 static int read_status_reg(struct flash_bank
*bank
, uint32_t *status
)
222 struct target
*target
= bank
->target
;
223 struct spearsmi_flash_bank
*spearsmi_info
= bank
->driver_priv
;
224 uint32_t io_base
= spearsmi_info
->io_base
;
226 /* clear transmit finished flag */
230 SMI_WRITE_REG(SMI_CR2
, spearsmi_info
->bank_num
| SMI_RSR
);
232 /* Poll transmit finished flag */
233 SMI_POLL_TFF(SMI_CMD_TIMEOUT
);
235 /* clear transmit finished flag */
238 /* Check write enabled */
239 *status
= SMI_READ_REG(SMI_SR
) & 0x0000ffff;
241 /* clean-up SMI_CR2 */
242 SMI_WRITE_REG(SMI_CR2
, 0); /* AB: Required ? */
247 /* check for WIP (write in progress) bit in status register */
249 static int wait_till_ready(struct flash_bank
*bank
, int timeout
)
255 endtime
= timeval_ms() + timeout
;
257 /* read flash status register */
258 retval
= read_status_reg(bank
, &status
);
259 if (retval
!= ERROR_OK
)
262 if ((status
& SMI_WIP_BIT
) == 0)
265 } while (timeval_ms() < endtime
);
267 LOG_ERROR("timeout");
271 static int smi_write_enable(struct flash_bank
*bank
)
273 struct target
*target
= bank
->target
;
274 struct spearsmi_flash_bank
*spearsmi_info
= bank
->driver_priv
;
275 uint32_t io_base
= spearsmi_info
->io_base
;
279 /* Enter in HW mode */
280 SMI_SET_HW_MODE(); /* AB: is this correct ?*/
282 /* clear transmit finished flag */
285 /* Send write enable command */
286 SMI_WRITE_REG(SMI_CR2
, spearsmi_info
->bank_num
| SMI_WE
);
288 /* Poll transmit finished flag */
289 SMI_POLL_TFF(SMI_CMD_TIMEOUT
);
291 /* read flash status register */
292 retval
= read_status_reg(bank
, &status
);
293 if (retval
!= ERROR_OK
)
296 /* Check write enabled */
297 if ((status
& SMI_WEL_BIT
) == 0)
299 LOG_ERROR("Cannot enable write to flash. Status=0x%08" PRIx32
, status
);
306 static uint32_t erase_command(struct spearsmi_flash_bank
*spearsmi_info
,
314 cmd
.x
[0] = spearsmi_info
->dev
->erase_cmd
;
315 cmd
.x
[1] = offset
>> 16;
316 cmd
.x
[2] = offset
>> 8;
322 static int smi_erase_sector(struct flash_bank
*bank
, int sector
)
324 struct target
*target
= bank
->target
;
325 struct spearsmi_flash_bank
*spearsmi_info
= bank
->driver_priv
;
326 uint32_t io_base
= spearsmi_info
->io_base
;
330 retval
= smi_write_enable(bank
);
331 if (retval
!= ERROR_OK
)
334 /* Switch to SW mode to send sector erase command */
337 /* clear transmit finished flag */
340 /* send erase command */
341 cmd
= erase_command(spearsmi_info
, bank
->sectors
[sector
].offset
);
342 SMI_WRITE_REG(SMI_TR
, cmd
);
343 SMI_WRITE_REG(SMI_CR2
, spearsmi_info
->bank_num
| SMI_SEND
| SMI_TX_LEN_4
);
345 /* Poll transmit finished flag */
346 SMI_POLL_TFF(SMI_CMD_TIMEOUT
);
348 /* poll WIP for end of self timed Sector Erase cycle */
349 retval
= wait_till_ready(bank
, SMI_MAX_TIMEOUT
);
350 if (retval
!= ERROR_OK
)
356 static int spearsmi_erase(struct flash_bank
*bank
, int first
, int last
)
358 struct target
*target
= bank
->target
;
359 struct spearsmi_flash_bank
*spearsmi_info
= bank
->driver_priv
;
360 uint32_t io_base
= spearsmi_info
->io_base
;
361 int retval
= ERROR_OK
;
364 LOG_DEBUG("%s: from sector %d to sector %d", __FUNCTION__
, first
, last
);
366 if (target
->state
!= TARGET_HALTED
)
368 LOG_ERROR("Target not halted");
369 return ERROR_TARGET_NOT_HALTED
;
372 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
))
374 LOG_ERROR("Flash sector invalid");
375 return ERROR_FLASH_SECTOR_INVALID
;
378 if (!(spearsmi_info
->probed
))
380 LOG_ERROR("Flash bank not probed");
381 return ERROR_FLASH_BANK_NOT_PROBED
;
384 for (sector
= first
; sector
<= last
; sector
++)
386 if (bank
->sectors
[sector
].is_protected
)
388 LOG_ERROR("Flash sector %d protected", sector
);
393 for (sector
= first
; sector
<= last
; sector
++)
395 retval
= smi_erase_sector(bank
, sector
);
396 if (retval
!= ERROR_OK
)
401 /* Switch to HW mode before return to prompt */
406 static int spearsmi_protect(struct flash_bank
*bank
, int set
,
411 for (sector
= first
; sector
<= last
; sector
++)
412 bank
->sectors
[sector
].is_protected
= set
;
416 static int smi_write_buffer(struct flash_bank
*bank
, uint8_t *buffer
,
417 uint32_t address
, uint32_t len
)
419 struct target
*target
= bank
->target
;
420 struct spearsmi_flash_bank
*spearsmi_info
= bank
->driver_priv
;
421 uint32_t io_base
= spearsmi_info
->io_base
;
424 LOG_DEBUG("%s: address=0x%08" PRIx32
" len=0x%08" PRIx32
,
425 __FUNCTION__
, address
, len
);
427 retval
= smi_write_enable(bank
);
428 if (retval
!= ERROR_OK
)
431 /* HW mode, write burst mode */
434 retval
= target_write_buffer(target
, address
, len
, buffer
);
435 if (retval
!= ERROR_OK
)
441 static int spearsmi_write(struct flash_bank
*bank
, uint8_t *buffer
,
442 uint32_t offset
, uint32_t count
)
444 struct target
*target
= bank
->target
;
445 struct spearsmi_flash_bank
*spearsmi_info
= bank
->driver_priv
;
446 uint32_t io_base
= spearsmi_info
->io_base
;
447 uint32_t cur_count
, page_size
, page_offset
;
449 int retval
= ERROR_OK
;
451 LOG_DEBUG("%s: offset=0x%08" PRIx32
" count=0x%08" PRIx32
,
452 __FUNCTION__
, offset
, count
);
454 if (target
->state
!= TARGET_HALTED
)
456 LOG_ERROR("Target not halted");
457 return ERROR_TARGET_NOT_HALTED
;
460 if (offset
+ count
> spearsmi_info
->dev
->size_in_bytes
)
462 LOG_WARNING("Write pasts end of flash. Extra data discarded.");
463 count
= spearsmi_info
->dev
->size_in_bytes
- offset
;
466 /* Check sector protection */
467 for (sector
= 0; sector
< bank
->num_sectors
; sector
++)
469 /* Start offset in or before this sector? */
470 /* End offset in or behind this sector? */
472 (bank
->sectors
[sector
].offset
+ bank
->sectors
[sector
].size
))
473 && ((offset
+ count
- 1) >= bank
->sectors
[sector
].offset
)
474 && bank
->sectors
[sector
].is_protected
)
476 LOG_ERROR("Flash sector %d protected", sector
);
481 page_size
= spearsmi_info
->dev
->pagesize
;
483 /* unaligned buffer head */
484 if (count
> 0 && (offset
& 3) != 0)
486 cur_count
= 4 - (offset
& 3);
487 if (cur_count
> count
)
489 retval
= smi_write_buffer(bank
, buffer
, bank
->base
+ offset
,
491 if (retval
!= ERROR_OK
)
498 page_offset
= offset
% page_size
;
499 /* central part, aligned words */
502 /* clip block at page boundary */
503 if (page_offset
+ count
> page_size
)
504 cur_count
= page_size
- page_offset
;
506 cur_count
= count
& ~3;
508 retval
= smi_write_buffer(bank
, buffer
, bank
->base
+ offset
,
510 if (retval
!= ERROR_OK
)
523 retval
= smi_write_buffer(bank
, buffer
, bank
->base
+ offset
, count
);
526 /* Switch to HW mode before return to prompt */
531 /* Return ID of flash device */
532 /* On exit, SW mode is kept */
533 static int read_flash_id(struct flash_bank
*bank
, uint32_t *id
)
535 struct target
*target
= bank
->target
;
536 struct spearsmi_flash_bank
*spearsmi_info
= bank
->driver_priv
;
537 uint32_t io_base
= spearsmi_info
->io_base
;
540 if (target
->state
!= TARGET_HALTED
)
542 LOG_ERROR("Target not halted");
543 return ERROR_TARGET_NOT_HALTED
;
547 retval
= wait_till_ready(bank
, SMI_PROBE_TIMEOUT
);
548 if (retval
!= ERROR_OK
)
551 /* enter in SW mode */
554 /* clear transmit finished flag */
557 /* Require read flash ID */
558 SMI_WRITE_REG(SMI_TR
, SMI_READ_ID
);
559 SMI_WRITE_REG(SMI_CR2
,
560 spearsmi_info
->bank_num
| SMI_SEND
| SMI_RX_LEN_3
| SMI_TX_LEN_1
);
562 /* Poll transmit finished flag */
563 SMI_POLL_TFF(SMI_CMD_TIMEOUT
);
565 /* clear transmit finished flag */
569 *id
= SMI_READ_REG(SMI_RR
) & 0x00ffffff;
573 static int spearsmi_probe(struct flash_bank
*bank
)
575 struct target
*target
= bank
->target
;
576 struct spearsmi_flash_bank
*spearsmi_info
= bank
->driver_priv
;
578 struct flash_sector
*sectors
;
579 uint32_t id
= 0; /* silence uninitialized warning */
582 if (spearsmi_info
->probed
)
584 spearsmi_info
->probed
= 0;
586 /* check for SPEAr device */
587 switch (target
->tap
->idcode
)
589 case JTAG_ID_3XX_6XX
:
591 spearsmi_info
->io_base
= SMI_CFGREG_3XX_6XX
;
594 case SMI_BASE_3XX_6XX
:
595 spearsmi_info
->bank_num
= SMI_SEL_BANK0
;
597 case SMI_BASE_3XX_6XX
+ SMI_BANK_SIZE
:
598 spearsmi_info
->bank_num
= SMI_SEL_BANK1
;
600 case SMI_BASE_3XX_6XX
+ 2*SMI_BANK_SIZE
:
601 spearsmi_info
->bank_num
= SMI_SEL_BANK2
;
603 case SMI_BASE_3XX_6XX
+ 3*SMI_BANK_SIZE
:
604 spearsmi_info
->bank_num
= SMI_SEL_BANK3
;
607 LOG_ERROR("Invalid base address 0x%" PRIx32
, bank
->base
);
613 LOG_ERROR("0x%" PRIx32
" is invalid id for SPEAr device",
614 target
->tap
->idcode
);
617 io_base
= spearsmi_info
->io_base
;
619 /* read and decode flash ID; returns in SW mode */
620 retval
= read_flash_id(bank
, &id
);
622 if (retval
!= ERROR_OK
)
625 for (struct flash_device
*p
= flash_devices
; p
->name
; p
++)
626 if (p
->device_id
== id
) {
627 spearsmi_info
->dev
= p
;
631 if (!spearsmi_info
->dev
)
633 LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32
")", id
);
637 LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32
")",
638 spearsmi_info
->dev
->name
, spearsmi_info
->dev
->device_id
);
640 /* Set correct size value */
641 bank
->size
= spearsmi_info
->dev
->size_in_bytes
;
643 /* create and fill sectors array */
645 spearsmi_info
->dev
->size_in_bytes
/ spearsmi_info
->dev
->sectorsize
;
646 sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
649 LOG_ERROR("not enough memory");
653 for (int sector
= 0; sector
< bank
->num_sectors
; sector
++)
655 sectors
[sector
].offset
= sector
* spearsmi_info
->dev
->sectorsize
;
656 sectors
[sector
].size
= spearsmi_info
->dev
->sectorsize
;
657 sectors
[sector
].is_erased
= -1;
658 sectors
[sector
].is_protected
= 1;
661 bank
->sectors
= sectors
;
662 spearsmi_info
->probed
= 1;
666 static int spearsmi_auto_probe(struct flash_bank
*bank
)
668 struct spearsmi_flash_bank
*spearsmi_info
= bank
->driver_priv
;
669 if (spearsmi_info
->probed
)
671 return spearsmi_probe(bank
);
674 static int spearsmi_protect_check(struct flash_bank
*bank
)
676 /* Nothing to do. Protection is only handled in SW. */
680 static int get_spearsmi_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
682 struct spearsmi_flash_bank
*spearsmi_info
= bank
->driver_priv
;
685 if (!(spearsmi_info
->probed
))
687 printed
= snprintf(buf
, buf_size
,
688 "\nSPEAr SMI flash bank not probed yet\n");
692 printed
= snprintf(buf
, buf_size
, "\nSPEAr SMI flash information:\n"
693 " Device \'%s\' (ID 0x%08x)\n",
694 spearsmi_info
->dev
->name
, spearsmi_info
->dev
->device_id
);
701 struct flash_driver spearsmi_flash
= {
703 .flash_bank_command
= spearsmi_flash_bank_command
,
704 .erase
= spearsmi_erase
,
705 .protect
= spearsmi_protect
,
706 .write
= spearsmi_write
,
707 .read
= default_flash_read
,
708 .probe
= spearsmi_probe
,
709 .auto_probe
= spearsmi_auto_probe
,
710 .erase_check
= default_flash_blank_check
,
711 .protect_check
= spearsmi_protect_check
,
712 .info
= get_spearsmi_info
,
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)