openocd: src: fix incorrect SPDX tags
[openocd.git] / src / flash / nor / stm32h7x.c
1 /***************************************************************************
2 * Copyright (C) 2017 by STMicroelectronics *
3 * *
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. *
8 * *
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. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
16 ***************************************************************************/
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20
21 #include "imp.h"
22 #include <helper/binarybuffer.h>
23 #include <target/algorithm.h>
24 #include <target/cortex_m.h>
25
26
27 /* Erase time can be as high as 1000ms, 10x this and it's toast... */
28 #define FLASH_ERASE_TIMEOUT 10000
29 #define FLASH_WRITE_TIMEOUT 5
30
31 /* RM 433 */
32 /* Same Flash registers for both banks, */
33 /* access depends on Flash Base address */
34 #define FLASH_ACR 0x00
35 #define FLASH_KEYR 0x04
36 #define FLASH_OPTKEYR 0x08
37 #define FLASH_CR 0x0C
38 #define FLASH_SR 0x10
39 #define FLASH_CCR 0x14
40 #define FLASH_OPTCR 0x18
41 #define FLASH_OPTSR_CUR 0x1C
42 #define FLASH_OPTSR_PRG 0x20
43 #define FLASH_OPTCCR 0x24
44 #define FLASH_WPSN_CUR 0x38
45 #define FLASH_WPSN_PRG 0x3C
46
47
48 /* FLASH_CR register bits */
49 #define FLASH_LOCK (1 << 0)
50 #define FLASH_PG (1 << 1)
51 #define FLASH_SER (1 << 2)
52 #define FLASH_BER (1 << 3)
53 #define FLASH_PSIZE_8 (0 << 4)
54 #define FLASH_PSIZE_16 (1 << 4)
55 #define FLASH_PSIZE_32 (2 << 4)
56 #define FLASH_PSIZE_64 (3 << 4)
57 #define FLASH_FW (1 << 6)
58 #define FLASH_START (1 << 7)
59
60 /* FLASH_SR register bits */
61 #define FLASH_BSY (1 << 0) /* Operation in progress */
62 #define FLASH_QW (1 << 2) /* Operation queue in progress */
63 #define FLASH_WRPERR (1 << 17) /* Write protection error */
64 #define FLASH_PGSERR (1 << 18) /* Programming sequence error */
65 #define FLASH_STRBERR (1 << 19) /* Strobe error */
66 #define FLASH_INCERR (1 << 21) /* Inconsistency error */
67 #define FLASH_OPERR (1 << 22) /* Operation error */
68 #define FLASH_RDPERR (1 << 23) /* Read Protection error */
69 #define FLASH_RDSERR (1 << 24) /* Secure Protection error */
70 #define FLASH_SNECCERR (1 << 25) /* Single ECC error */
71 #define FLASH_DBECCERR (1 << 26) /* Double ECC error */
72
73 #define FLASH_ERROR (FLASH_WRPERR | FLASH_PGSERR | FLASH_STRBERR | FLASH_INCERR | FLASH_OPERR | \
74 FLASH_RDPERR | FLASH_RDSERR | FLASH_SNECCERR | FLASH_DBECCERR)
75
76 /* FLASH_OPTCR register bits */
77 #define OPT_LOCK (1 << 0)
78 #define OPT_START (1 << 1)
79
80 /* FLASH_OPTSR register bits */
81 #define OPT_BSY (1 << 0)
82 #define OPT_RDP_POS 8
83 #define OPT_RDP_MASK (0xff << OPT_RDP_POS)
84 #define OPT_OPTCHANGEERR (1 << 30)
85
86 /* FLASH_OPTCCR register bits */
87 #define OPT_CLR_OPTCHANGEERR (1 << 30)
88
89 /* register unlock keys */
90 #define KEY1 0x45670123
91 #define KEY2 0xCDEF89AB
92
93 /* option register unlock key */
94 #define OPTKEY1 0x08192A3B
95 #define OPTKEY2 0x4C5D6E7F
96
97 #define DBGMCU_IDCODE_REGISTER 0x5C001000
98 #define FLASH_BANK0_ADDRESS 0x08000000
99 #define FLASH_BANK1_ADDRESS 0x08100000
100 #define FLASH_REG_BASE_B0 0x52002000
101 #define FLASH_REG_BASE_B1 0x52002100
102
103 /* Supported device IDs */
104 #define DEVID_STM32H74_H75XX 0x450
105 #define DEVID_STM32H7A_H7BXX 0x480
106 #define DEVID_STM32H72_H73XX 0x483
107
108 struct stm32h7x_rev {
109 uint16_t rev;
110 const char *str;
111 };
112
113 /* stm32h7x_part_info permits the store each device information and specificities.
114 * the default unit is byte unless the suffix '_kb' is used. */
115
116 struct stm32h7x_part_info {
117 uint16_t id;
118 const char *device_str;
119 const struct stm32h7x_rev *revs;
120 size_t num_revs;
121 unsigned int page_size_kb;
122 unsigned int block_size; /* flash write word size in bytes */
123 uint16_t max_flash_size_kb;
124 bool has_dual_bank;
125 uint16_t max_bank_size_kb; /* Used when has_dual_bank is true */
126 uint32_t fsize_addr; /* Location of FSIZE register */
127 uint32_t wps_group_size; /* write protection group sectors' count */
128 uint32_t wps_mask;
129 /* function to compute flash_cr register values */
130 uint32_t (*compute_flash_cr)(uint32_t cmd, int snb);
131 };
132
133 struct stm32h7x_flash_bank {
134 bool probed;
135 uint32_t idcode;
136 uint32_t user_bank_size;
137 uint32_t flash_regs_base; /* Address of flash reg controller */
138 const struct stm32h7x_part_info *part_info;
139 };
140
141 enum stm32h7x_opt_rdp {
142 OPT_RDP_L0 = 0xaa,
143 OPT_RDP_L1 = 0x00,
144 OPT_RDP_L2 = 0xcc
145 };
146
147 static const struct stm32h7x_rev stm32h74_h75xx_revs[] = {
148 { 0x1000, "A" }, { 0x1001, "Z" }, { 0x1003, "Y" }, { 0x2001, "X" }, { 0x2003, "V" },
149 };
150
151 static const struct stm32h7x_rev stm32h7a_h7bxx_revs[] = {
152 { 0x1000, "A"},
153 };
154
155 static const struct stm32h7x_rev stm32h72_h73xx_revs[] = {
156 { 0x1000, "A" }, { 0x1001, "Z" },
157 };
158
159 static uint32_t stm32h74_h75xx_compute_flash_cr(uint32_t cmd, int snb)
160 {
161 return cmd | (snb << 8);
162 }
163
164 static uint32_t stm32h7a_h7bxx_compute_flash_cr(uint32_t cmd, int snb)
165 {
166 /* save FW and START bits, to be right shifted by 2 bits later */
167 const uint32_t tmp = cmd & (FLASH_FW | FLASH_START);
168
169 /* mask parallelism (ignored), FW and START bits */
170 cmd &= ~(FLASH_PSIZE_64 | FLASH_FW | FLASH_START);
171
172 return cmd | (tmp >> 2) | (snb << 6);
173 }
174
175 static const struct stm32h7x_part_info stm32h7x_parts[] = {
176 {
177 .id = DEVID_STM32H74_H75XX,
178 .revs = stm32h74_h75xx_revs,
179 .num_revs = ARRAY_SIZE(stm32h74_h75xx_revs),
180 .device_str = "STM32H74x/75x",
181 .page_size_kb = 128,
182 .block_size = 32,
183 .max_flash_size_kb = 2048,
184 .max_bank_size_kb = 1024,
185 .has_dual_bank = true,
186 .fsize_addr = 0x1FF1E880,
187 .wps_group_size = 1,
188 .wps_mask = 0xFF,
189 .compute_flash_cr = stm32h74_h75xx_compute_flash_cr,
190 },
191 {
192 .id = DEVID_STM32H7A_H7BXX,
193 .revs = stm32h7a_h7bxx_revs,
194 .num_revs = ARRAY_SIZE(stm32h7a_h7bxx_revs),
195 .device_str = "STM32H7Ax/7Bx",
196 .page_size_kb = 8,
197 .block_size = 16,
198 .max_flash_size_kb = 2048,
199 .max_bank_size_kb = 1024,
200 .has_dual_bank = true,
201 .fsize_addr = 0x08FFF80C,
202 .wps_group_size = 4,
203 .wps_mask = 0xFFFFFFFF,
204 .compute_flash_cr = stm32h7a_h7bxx_compute_flash_cr,
205 },
206 {
207 .id = DEVID_STM32H72_H73XX,
208 .revs = stm32h72_h73xx_revs,
209 .num_revs = ARRAY_SIZE(stm32h72_h73xx_revs),
210 .device_str = "STM32H72x/73x",
211 .page_size_kb = 128,
212 .block_size = 32,
213 .max_flash_size_kb = 1024,
214 .max_bank_size_kb = 1024,
215 .has_dual_bank = false,
216 .fsize_addr = 0x1FF1E880,
217 .wps_group_size = 1,
218 .wps_mask = 0xFF,
219 .compute_flash_cr = stm32h74_h75xx_compute_flash_cr,
220 },
221 };
222
223 /* flash bank stm32x <base> <size> 0 0 <target#> */
224
225 FLASH_BANK_COMMAND_HANDLER(stm32x_flash_bank_command)
226 {
227 struct stm32h7x_flash_bank *stm32x_info;
228
229 if (CMD_ARGC < 6)
230 return ERROR_COMMAND_SYNTAX_ERROR;
231
232 stm32x_info = malloc(sizeof(struct stm32h7x_flash_bank));
233 bank->driver_priv = stm32x_info;
234
235 stm32x_info->probed = false;
236 stm32x_info->user_bank_size = bank->size;
237
238 return ERROR_OK;
239 }
240
241 static inline uint32_t stm32x_get_flash_reg(struct flash_bank *bank, uint32_t reg_offset)
242 {
243 struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
244 return reg_offset + stm32x_info->flash_regs_base;
245 }
246
247 static inline int stm32x_read_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t *value)
248 {
249 uint32_t reg_addr = stm32x_get_flash_reg(bank, reg_offset);
250 int retval = target_read_u32(bank->target, reg_addr, value);
251
252 if (retval != ERROR_OK)
253 LOG_ERROR("error while reading from address 0x%" PRIx32, reg_addr);
254
255 return retval;
256 }
257
258 static inline int stm32x_write_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t value)
259 {
260 uint32_t reg_addr = stm32x_get_flash_reg(bank, reg_offset);
261 int retval = target_write_u32(bank->target, reg_addr, value);
262
263 if (retval != ERROR_OK)
264 LOG_ERROR("error while writing to address 0x%" PRIx32, reg_addr);
265
266 return retval;
267 }
268
269 static inline int stm32x_get_flash_status(struct flash_bank *bank, uint32_t *status)
270 {
271 return stm32x_read_flash_reg(bank, FLASH_SR, status);
272 }
273
274 static int stm32x_wait_flash_op_queue(struct flash_bank *bank, int timeout)
275 {
276 uint32_t status;
277 int retval;
278
279 /* wait for flash operations completion */
280 for (;;) {
281 retval = stm32x_get_flash_status(bank, &status);
282 if (retval != ERROR_OK)
283 return retval;
284
285 if ((status & FLASH_QW) == 0)
286 break;
287
288 if (timeout-- <= 0) {
289 LOG_ERROR("wait_flash_op_queue, time out expired, status: 0x%" PRIx32, status);
290 return ERROR_FAIL;
291 }
292 alive_sleep(1);
293 }
294
295 if (status & FLASH_WRPERR) {
296 LOG_ERROR("wait_flash_op_queue, WRPERR detected");
297 retval = ERROR_FAIL;
298 }
299
300 /* Clear error + EOP flags but report errors */
301 if (status & FLASH_ERROR) {
302 if (retval == ERROR_OK)
303 retval = ERROR_FAIL;
304 /* If this operation fails, we ignore it and report the original retval */
305 stm32x_write_flash_reg(bank, FLASH_CCR, status);
306 }
307 return retval;
308 }
309
310 static int stm32x_unlock_reg(struct flash_bank *bank)
311 {
312 uint32_t ctrl;
313
314 /* first check if not already unlocked
315 * otherwise writing on FLASH_KEYR will fail
316 */
317 int retval = stm32x_read_flash_reg(bank, FLASH_CR, &ctrl);
318 if (retval != ERROR_OK)
319 return retval;
320
321 if ((ctrl & FLASH_LOCK) == 0)
322 return ERROR_OK;
323
324 /* unlock flash registers for bank */
325 retval = stm32x_write_flash_reg(bank, FLASH_KEYR, KEY1);
326 if (retval != ERROR_OK)
327 return retval;
328
329 retval = stm32x_write_flash_reg(bank, FLASH_KEYR, KEY2);
330 if (retval != ERROR_OK)
331 return retval;
332
333 retval = stm32x_read_flash_reg(bank, FLASH_CR, &ctrl);
334 if (retval != ERROR_OK)
335 return retval;
336
337 if (ctrl & FLASH_LOCK) {
338 LOG_ERROR("flash not unlocked STM32_FLASH_CRx: 0x%" PRIx32, ctrl);
339 return ERROR_TARGET_FAILURE;
340 }
341 return ERROR_OK;
342 }
343
344 static int stm32x_unlock_option_reg(struct flash_bank *bank)
345 {
346 uint32_t ctrl;
347
348 int retval = stm32x_read_flash_reg(bank, FLASH_OPTCR, &ctrl);
349 if (retval != ERROR_OK)
350 return retval;
351
352 if ((ctrl & OPT_LOCK) == 0)
353 return ERROR_OK;
354
355 /* unlock option registers */
356 retval = stm32x_write_flash_reg(bank, FLASH_OPTKEYR, OPTKEY1);
357 if (retval != ERROR_OK)
358 return retval;
359
360 retval = stm32x_write_flash_reg(bank, FLASH_OPTKEYR, OPTKEY2);
361 if (retval != ERROR_OK)
362 return retval;
363
364 retval = stm32x_read_flash_reg(bank, FLASH_OPTCR, &ctrl);
365 if (retval != ERROR_OK)
366 return retval;
367
368 if (ctrl & OPT_LOCK) {
369 LOG_ERROR("options not unlocked STM32_FLASH_OPTCR: 0x%" PRIx32, ctrl);
370 return ERROR_TARGET_FAILURE;
371 }
372
373 return ERROR_OK;
374 }
375
376 static inline int stm32x_lock_reg(struct flash_bank *bank)
377 {
378 return stm32x_write_flash_reg(bank, FLASH_CR, FLASH_LOCK);
379 }
380
381 static inline int stm32x_lock_option_reg(struct flash_bank *bank)
382 {
383 return stm32x_write_flash_reg(bank, FLASH_OPTCR, OPT_LOCK);
384 }
385
386 static int stm32x_write_option(struct flash_bank *bank, uint32_t reg_offset, uint32_t value)
387 {
388 int retval, retval2;
389
390 /* unlock option bytes for modification */
391 retval = stm32x_unlock_option_reg(bank);
392 if (retval != ERROR_OK)
393 goto flash_options_lock;
394
395 /* write option bytes */
396 retval = stm32x_write_flash_reg(bank, reg_offset, value);
397 if (retval != ERROR_OK)
398 goto flash_options_lock;
399
400 /* Remove OPT error flag before programming */
401 retval = stm32x_write_flash_reg(bank, FLASH_OPTCCR, OPT_CLR_OPTCHANGEERR);
402 if (retval != ERROR_OK)
403 goto flash_options_lock;
404
405 /* start programming cycle */
406 retval = stm32x_write_flash_reg(bank, FLASH_OPTCR, OPT_START);
407 if (retval != ERROR_OK)
408 goto flash_options_lock;
409
410 /* wait for completion */
411 int timeout = FLASH_ERASE_TIMEOUT;
412 uint32_t status;
413 for (;;) {
414 retval = stm32x_read_flash_reg(bank, FLASH_OPTSR_CUR, &status);
415 if (retval != ERROR_OK) {
416 LOG_ERROR("stm32x_options_program: failed to read FLASH_OPTSR_CUR");
417 goto flash_options_lock;
418 }
419 if ((status & OPT_BSY) == 0)
420 break;
421
422 if (timeout-- <= 0) {
423 LOG_ERROR("waiting for OBL launch, time out expired, OPTSR: 0x%" PRIx32, status);
424 retval = ERROR_FAIL;
425 goto flash_options_lock;
426 }
427 alive_sleep(1);
428 }
429
430 /* check for failure */
431 if (status & OPT_OPTCHANGEERR) {
432 LOG_ERROR("error changing option bytes (OPTCHANGEERR=1)");
433 retval = ERROR_FLASH_OPERATION_FAILED;
434 }
435
436 flash_options_lock:
437 retval2 = stm32x_lock_option_reg(bank);
438 if (retval2 != ERROR_OK)
439 LOG_ERROR("error during the lock of flash options");
440
441 return (retval == ERROR_OK) ? retval2 : retval;
442 }
443
444 static int stm32x_modify_option(struct flash_bank *bank, uint32_t reg_offset, uint32_t value, uint32_t mask)
445 {
446 uint32_t data;
447
448 int retval = stm32x_read_flash_reg(bank, reg_offset, &data);
449 if (retval != ERROR_OK)
450 return retval;
451
452 data = (data & ~mask) | (value & mask);
453
454 return stm32x_write_option(bank, reg_offset, data);
455 }
456
457 static int stm32x_protect_check(struct flash_bank *bank)
458 {
459 uint32_t protection;
460
461 /* read 'write protection' settings */
462 int retval = stm32x_read_flash_reg(bank, FLASH_WPSN_CUR, &protection);
463 if (retval != ERROR_OK) {
464 LOG_DEBUG("unable to read WPSN_CUR register");
465 return retval;
466 }
467
468 for (unsigned int i = 0; i < bank->num_prot_blocks; i++)
469 bank->prot_blocks[i].is_protected = protection & (1 << i) ? 0 : 1;
470
471 return ERROR_OK;
472 }
473
474 static int stm32x_erase(struct flash_bank *bank, unsigned int first,
475 unsigned int last)
476 {
477 struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
478 int retval, retval2;
479
480 assert(first < bank->num_sectors);
481 assert(last < bank->num_sectors);
482
483 if (bank->target->state != TARGET_HALTED)
484 return ERROR_TARGET_NOT_HALTED;
485
486 retval = stm32x_unlock_reg(bank);
487 if (retval != ERROR_OK)
488 goto flash_lock;
489
490 /*
491 Sector Erase
492 To erase a sector, follow the procedure below:
493 1. Check that no Flash memory operation is ongoing by checking the QW bit in the
494 FLASH_SR register
495 2. Set the SER bit and select the sector
496 you wish to erase (SNB) in the FLASH_CR register
497 3. Set the STRT bit in the FLASH_CR register
498 4. Wait for flash operations completion
499 */
500 for (unsigned int i = first; i <= last; i++) {
501 LOG_DEBUG("erase sector %u", i);
502 retval = stm32x_write_flash_reg(bank, FLASH_CR,
503 stm32x_info->part_info->compute_flash_cr(FLASH_SER | FLASH_PSIZE_64, i));
504 if (retval != ERROR_OK) {
505 LOG_ERROR("Error erase sector %u", i);
506 goto flash_lock;
507 }
508 retval = stm32x_write_flash_reg(bank, FLASH_CR,
509 stm32x_info->part_info->compute_flash_cr(FLASH_SER | FLASH_PSIZE_64 | FLASH_START, i));
510 if (retval != ERROR_OK) {
511 LOG_ERROR("Error erase sector %u", i);
512 goto flash_lock;
513 }
514 retval = stm32x_wait_flash_op_queue(bank, FLASH_ERASE_TIMEOUT);
515
516 if (retval != ERROR_OK) {
517 LOG_ERROR("erase time-out or operation error sector %u", i);
518 goto flash_lock;
519 }
520 }
521
522 flash_lock:
523 retval2 = stm32x_lock_reg(bank);
524 if (retval2 != ERROR_OK)
525 LOG_ERROR("error during the lock of flash");
526
527 return (retval == ERROR_OK) ? retval2 : retval;
528 }
529
530 static int stm32x_protect(struct flash_bank *bank, int set, unsigned int first,
531 unsigned int last)
532 {
533 struct target *target = bank->target;
534 struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
535 uint32_t protection;
536
537 if (target->state != TARGET_HALTED) {
538 LOG_ERROR("Target not halted");
539 return ERROR_TARGET_NOT_HALTED;
540 }
541
542 /* read 'write protection' settings */
543 int retval = stm32x_read_flash_reg(bank, FLASH_WPSN_CUR, &protection);
544 if (retval != ERROR_OK) {
545 LOG_DEBUG("unable to read WPSN_CUR register");
546 return retval;
547 }
548
549 for (unsigned int i = first; i <= last; i++) {
550 if (set)
551 protection &= ~(1 << i);
552 else
553 protection |= (1 << i);
554 }
555
556 /* apply WRPSN mask */
557 protection &= stm32x_info->part_info->wps_mask;
558
559 LOG_DEBUG("stm32x_protect, option_bytes written WPSN 0x%" PRIx32, protection);
560
561 /* apply new option value */
562 return stm32x_write_option(bank, FLASH_WPSN_PRG, protection);
563 }
564
565 static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer,
566 uint32_t offset, uint32_t count)
567 {
568 struct target *target = bank->target;
569 struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
570 /*
571 * If the size of the data part of the buffer is not a multiple of .block_size, we get
572 * "corrupted fifo read" pointer in target_run_flash_async_algorithm()
573 */
574 uint32_t data_size = 512 * stm32x_info->part_info->block_size;
575 uint32_t buffer_size = 8 + data_size;
576 struct working_area *write_algorithm;
577 struct working_area *source;
578 uint32_t address = bank->base + offset;
579 struct reg_param reg_params[6];
580 struct armv7m_algorithm armv7m_info;
581 int retval = ERROR_OK;
582
583 static const uint8_t stm32x_flash_write_code[] = {
584 #include "../../../contrib/loaders/flash/stm32/stm32h7x.inc"
585 };
586
587 if (target_alloc_working_area(target, sizeof(stm32x_flash_write_code),
588 &write_algorithm) != ERROR_OK) {
589 LOG_WARNING("no working area available, can't do block memory writes");
590 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
591 }
592
593 retval = target_write_buffer(target, write_algorithm->address,
594 sizeof(stm32x_flash_write_code),
595 stm32x_flash_write_code);
596 if (retval != ERROR_OK) {
597 target_free_working_area(target, write_algorithm);
598 return retval;
599 }
600
601 /* memory buffer */
602 while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
603 data_size /= 2;
604 buffer_size = 8 + data_size;
605 if (data_size <= 256) {
606 /* we already allocated the writing code, but failed to get a
607 * buffer, free the algorithm */
608 target_free_working_area(target, write_algorithm);
609
610 LOG_WARNING("no large enough working area available, can't do block memory writes");
611 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
612 }
613 }
614
615 LOG_DEBUG("target_alloc_working_area_try : buffer_size -> 0x%" PRIx32, buffer_size);
616
617 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
618 armv7m_info.core_mode = ARM_MODE_THREAD;
619
620 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* buffer start, status (out) */
621 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* buffer end */
622 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* target address */
623 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT); /* count of words (word size = .block_size (bytes) */
624 init_reg_param(&reg_params[4], "r4", 32, PARAM_OUT); /* word size in bytes */
625 init_reg_param(&reg_params[5], "r5", 32, PARAM_OUT); /* flash reg base */
626
627 buf_set_u32(reg_params[0].value, 0, 32, source->address);
628 buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);
629 buf_set_u32(reg_params[2].value, 0, 32, address);
630 buf_set_u32(reg_params[3].value, 0, 32, count);
631 buf_set_u32(reg_params[4].value, 0, 32, stm32x_info->part_info->block_size);
632 buf_set_u32(reg_params[5].value, 0, 32, stm32x_info->flash_regs_base);
633
634 retval = target_run_flash_async_algorithm(target,
635 buffer,
636 count,
637 stm32x_info->part_info->block_size,
638 0, NULL,
639 ARRAY_SIZE(reg_params), reg_params,
640 source->address, source->size,
641 write_algorithm->address, 0,
642 &armv7m_info);
643
644 if (retval == ERROR_FLASH_OPERATION_FAILED) {
645 LOG_ERROR("error executing stm32h7x flash write algorithm");
646
647 uint32_t flash_sr = buf_get_u32(reg_params[0].value, 0, 32);
648
649 if (flash_sr & FLASH_WRPERR)
650 LOG_ERROR("flash memory write protected");
651
652 if ((flash_sr & FLASH_ERROR) != 0) {
653 LOG_ERROR("flash write failed, FLASH_SR = 0x%08" PRIx32, flash_sr);
654 /* Clear error + EOP flags but report errors */
655 stm32x_write_flash_reg(bank, FLASH_CCR, flash_sr);
656 retval = ERROR_FAIL;
657 }
658 }
659
660 target_free_working_area(target, source);
661 target_free_working_area(target, write_algorithm);
662
663 destroy_reg_param(&reg_params[0]);
664 destroy_reg_param(&reg_params[1]);
665 destroy_reg_param(&reg_params[2]);
666 destroy_reg_param(&reg_params[3]);
667 destroy_reg_param(&reg_params[4]);
668 destroy_reg_param(&reg_params[5]);
669 return retval;
670 }
671
672 static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer,
673 uint32_t offset, uint32_t count)
674 {
675 struct target *target = bank->target;
676 struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
677 uint32_t address = bank->base + offset;
678 int retval, retval2;
679
680 if (bank->target->state != TARGET_HALTED) {
681 LOG_ERROR("Target not halted");
682 return ERROR_TARGET_NOT_HALTED;
683 }
684
685 /* should be enforced via bank->write_start_alignment */
686 assert(!(offset % stm32x_info->part_info->block_size));
687
688 /* should be enforced via bank->write_end_alignment */
689 assert(!(count % stm32x_info->part_info->block_size));
690
691 retval = stm32x_unlock_reg(bank);
692 if (retval != ERROR_OK)
693 goto flash_lock;
694
695 uint32_t blocks_remaining = count / stm32x_info->part_info->block_size;
696
697 /* multiple words (n * .block_size) to be programmed in block */
698 if (blocks_remaining) {
699 retval = stm32x_write_block(bank, buffer, offset, blocks_remaining);
700 if (retval != ERROR_OK) {
701 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
702 /* if block write failed (no sufficient working area),
703 * we use normal (slow) dword accesses */
704 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
705 }
706 } else {
707 buffer += blocks_remaining * stm32x_info->part_info->block_size;
708 address += blocks_remaining * stm32x_info->part_info->block_size;
709 blocks_remaining = 0;
710 }
711 if ((retval != ERROR_OK) && (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE))
712 goto flash_lock;
713 }
714
715 /*
716 Standard programming
717 The Flash memory programming sequence is as follows:
718 1. Check that no main Flash memory operation is ongoing by checking the QW bit in the
719 FLASH_SR register.
720 2. Set the PG bit in the FLASH_CR register
721 3. 8 x Word access (or Force Write FW)
722 4. Wait for flash operations completion
723 */
724 while (blocks_remaining > 0) {
725 retval = stm32x_write_flash_reg(bank, FLASH_CR,
726 stm32x_info->part_info->compute_flash_cr(FLASH_PG | FLASH_PSIZE_64, 0));
727 if (retval != ERROR_OK)
728 goto flash_lock;
729
730 retval = target_write_buffer(target, address, stm32x_info->part_info->block_size, buffer);
731 if (retval != ERROR_OK)
732 goto flash_lock;
733
734 retval = stm32x_wait_flash_op_queue(bank, FLASH_WRITE_TIMEOUT);
735 if (retval != ERROR_OK)
736 goto flash_lock;
737
738 buffer += stm32x_info->part_info->block_size;
739 address += stm32x_info->part_info->block_size;
740 blocks_remaining--;
741 }
742
743 flash_lock:
744 retval2 = stm32x_lock_reg(bank);
745 if (retval2 != ERROR_OK)
746 LOG_ERROR("error during the lock of flash");
747
748 return (retval == ERROR_OK) ? retval2 : retval;
749 }
750
751 static int stm32x_read_id_code(struct flash_bank *bank, uint32_t *id)
752 {
753 /* read stm32 device id register */
754 int retval = target_read_u32(bank->target, DBGMCU_IDCODE_REGISTER, id);
755 if (retval != ERROR_OK)
756 return retval;
757 return ERROR_OK;
758 }
759
760 static int stm32x_probe(struct flash_bank *bank)
761 {
762 struct target *target = bank->target;
763 struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
764 uint16_t flash_size_in_kb;
765 uint32_t device_id;
766
767 stm32x_info->probed = false;
768 stm32x_info->part_info = NULL;
769
770 if (!target_was_examined(target)) {
771 LOG_ERROR("Target not examined yet");
772 return ERROR_TARGET_NOT_EXAMINED;
773 }
774
775 int retval = stm32x_read_id_code(bank, &stm32x_info->idcode);
776 if (retval != ERROR_OK)
777 return retval;
778
779 LOG_DEBUG("device id = 0x%08" PRIx32, stm32x_info->idcode);
780
781 device_id = stm32x_info->idcode & 0xfff;
782
783 for (unsigned int n = 0; n < ARRAY_SIZE(stm32h7x_parts); n++) {
784 if (device_id == stm32h7x_parts[n].id)
785 stm32x_info->part_info = &stm32h7x_parts[n];
786 }
787 if (!stm32x_info->part_info) {
788 LOG_WARNING("Cannot identify target as a STM32H7xx family.");
789 return ERROR_FAIL;
790 } else {
791 LOG_INFO("Device: %s", stm32x_info->part_info->device_str);
792 }
793
794 /* update the address of controller */
795 if (bank->base == FLASH_BANK0_ADDRESS)
796 stm32x_info->flash_regs_base = FLASH_REG_BASE_B0;
797 else if (bank->base == FLASH_BANK1_ADDRESS)
798 stm32x_info->flash_regs_base = FLASH_REG_BASE_B1;
799 else {
800 LOG_WARNING("Flash register base not defined for bank %u", bank->bank_number);
801 return ERROR_FAIL;
802 }
803 LOG_DEBUG("flash_regs_base: 0x%" PRIx32, stm32x_info->flash_regs_base);
804
805 /* get flash size from target */
806 /* STM32H74x/H75x, the second core (Cortex-M4) cannot read the flash size */
807 retval = ERROR_FAIL;
808 if (device_id == DEVID_STM32H74_H75XX
809 && cortex_m_get_partno_safe(target) == CORTEX_M4_PARTNO)
810 LOG_WARNING("%s cannot read the flash size register", target_name(target));
811 else
812 retval = target_read_u16(target, stm32x_info->part_info->fsize_addr, &flash_size_in_kb);
813
814 if (retval != ERROR_OK) {
815 /* read error when device has invalid value, set max flash size */
816 flash_size_in_kb = stm32x_info->part_info->max_flash_size_kb;
817 LOG_INFO("assuming %" PRIu16 "k flash", flash_size_in_kb);
818 } else
819 LOG_INFO("flash size probed value %" PRIu16 "k", flash_size_in_kb);
820
821 /* setup bank size */
822 const uint32_t bank1_base = FLASH_BANK0_ADDRESS;
823 const uint32_t bank2_base = bank1_base + stm32x_info->part_info->max_bank_size_kb * 1024;
824 bool has_dual_bank = stm32x_info->part_info->has_dual_bank;
825
826 switch (device_id) {
827 case DEVID_STM32H74_H75XX:
828 case DEVID_STM32H7A_H7BXX:
829 /* For STM32H74x/75x and STM32H7Ax/Bx
830 * - STM32H7xxxI devices contains dual bank, 1 Mbyte each
831 * - STM32H7xxxG devices contains dual bank, 512 Kbyte each
832 * - STM32H7xxxB devices contains single bank, 128 Kbyte
833 * - the second bank starts always from 0x08100000
834 */
835 if (flash_size_in_kb == 128)
836 has_dual_bank = false;
837 else
838 /* flash size is 2M or 1M */
839 flash_size_in_kb /= 2;
840 break;
841 case DEVID_STM32H72_H73XX:
842 break;
843 default:
844 LOG_ERROR("unsupported device");
845 return ERROR_FAIL;
846 }
847
848 if (has_dual_bank) {
849 LOG_INFO("STM32H7 flash has dual banks");
850 if (bank->base != bank1_base && bank->base != bank2_base) {
851 LOG_ERROR("STM32H7 flash bank base address config is incorrect. "
852 TARGET_ADDR_FMT " but should rather be 0x%" PRIx32 " or 0x%" PRIx32,
853 bank->base, bank1_base, bank2_base);
854 return ERROR_FAIL;
855 }
856 } else {
857 LOG_INFO("STM32H7 flash has a single bank");
858 if (bank->base == bank2_base) {
859 LOG_ERROR("this device has a single bank only");
860 return ERROR_FAIL;
861 } else if (bank->base != bank1_base) {
862 LOG_ERROR("STM32H7 flash bank base address config is incorrect. "
863 TARGET_ADDR_FMT " but should be 0x%" PRIx32,
864 bank->base, bank1_base);
865 return ERROR_FAIL;
866 }
867 }
868
869 LOG_INFO("Bank (%u) size is %" PRIu16 " kb, base address is " TARGET_ADDR_FMT,
870 bank->bank_number, flash_size_in_kb, bank->base);
871
872 /* if the user sets the size manually then ignore the probed value
873 * this allows us to work around devices that have an invalid flash size register value */
874 if (stm32x_info->user_bank_size) {
875 LOG_INFO("ignoring flash probed value, using configured bank size");
876 flash_size_in_kb = stm32x_info->user_bank_size / 1024;
877 } else if (flash_size_in_kb == 0xffff) {
878 /* die flash size */
879 flash_size_in_kb = stm32x_info->part_info->max_flash_size_kb;
880 }
881
882 /* did we assign flash size? */
883 assert(flash_size_in_kb != 0xffff);
884 bank->size = flash_size_in_kb * 1024;
885 bank->write_start_alignment = stm32x_info->part_info->block_size;
886 bank->write_end_alignment = stm32x_info->part_info->block_size;
887
888 /* setup sectors */
889 bank->num_sectors = flash_size_in_kb / stm32x_info->part_info->page_size_kb;
890 assert(bank->num_sectors > 0);
891
892 free(bank->sectors);
893
894 bank->sectors = alloc_block_array(0, stm32x_info->part_info->page_size_kb * 1024,
895 bank->num_sectors);
896
897 if (!bank->sectors) {
898 LOG_ERROR("failed to allocate bank sectors");
899 return ERROR_FAIL;
900 }
901
902 /* setup protection blocks */
903 const uint32_t wpsn = stm32x_info->part_info->wps_group_size;
904 assert(bank->num_sectors % wpsn == 0);
905
906 bank->num_prot_blocks = bank->num_sectors / wpsn;
907 assert(bank->num_prot_blocks > 0);
908
909 free(bank->prot_blocks);
910
911 bank->prot_blocks = alloc_block_array(0, stm32x_info->part_info->page_size_kb * wpsn * 1024,
912 bank->num_prot_blocks);
913
914 if (!bank->prot_blocks) {
915 LOG_ERROR("failed to allocate bank prot_block");
916 return ERROR_FAIL;
917 }
918
919 stm32x_info->probed = true;
920 return ERROR_OK;
921 }
922
923 static int stm32x_auto_probe(struct flash_bank *bank)
924 {
925 struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
926
927 if (stm32x_info->probed)
928 return ERROR_OK;
929
930 return stm32x_probe(bank);
931 }
932
933 /* This method must return a string displaying information about the bank */
934 static int stm32x_get_info(struct flash_bank *bank, struct command_invocation *cmd)
935 {
936 struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
937 const struct stm32h7x_part_info *info = stm32x_info->part_info;
938
939 if (!stm32x_info->probed) {
940 int retval = stm32x_probe(bank);
941 if (retval != ERROR_OK) {
942 command_print_sameline(cmd, "Unable to find bank information.");
943 return retval;
944 }
945 }
946
947 if (info) {
948 const char *rev_str = NULL;
949 uint16_t rev_id = stm32x_info->idcode >> 16;
950
951 for (unsigned int i = 0; i < info->num_revs; i++)
952 if (rev_id == info->revs[i].rev)
953 rev_str = info->revs[i].str;
954
955 if (rev_str) {
956 command_print_sameline(cmd, "%s - Rev: %s",
957 stm32x_info->part_info->device_str, rev_str);
958 } else {
959 command_print_sameline(cmd,
960 "%s - Rev: unknown (0x%04" PRIx16 ")",
961 stm32x_info->part_info->device_str, rev_id);
962 }
963 } else {
964 command_print_sameline(cmd, "Cannot identify target as a STM32H7x");
965 return ERROR_FAIL;
966 }
967 return ERROR_OK;
968 }
969
970 static int stm32x_set_rdp(struct flash_bank *bank, enum stm32h7x_opt_rdp new_rdp)
971 {
972 struct target *target = bank->target;
973 uint32_t optsr, cur_rdp;
974 int retval;
975
976 if (target->state != TARGET_HALTED) {
977 LOG_ERROR("Target not halted");
978 return ERROR_TARGET_NOT_HALTED;
979 }
980
981 retval = stm32x_read_flash_reg(bank, FLASH_OPTSR_PRG, &optsr);
982
983 if (retval != ERROR_OK) {
984 LOG_DEBUG("unable to read FLASH_OPTSR_PRG register");
985 return retval;
986 }
987
988 /* get current RDP, and check if there is a change */
989 cur_rdp = (optsr & OPT_RDP_MASK) >> OPT_RDP_POS;
990 if (new_rdp == cur_rdp) {
991 LOG_INFO("the requested RDP value is already programmed");
992 return ERROR_OK;
993 }
994
995 switch (new_rdp) {
996 case OPT_RDP_L0:
997 LOG_WARNING("unlocking the entire flash device");
998 break;
999 case OPT_RDP_L1:
1000 LOG_WARNING("locking the entire flash device");
1001 break;
1002 case OPT_RDP_L2:
1003 LOG_WARNING("locking the entire flash device, irreversible");
1004 break;
1005 }
1006
1007 /* apply new RDP */
1008 optsr = (optsr & ~OPT_RDP_MASK) | (new_rdp << OPT_RDP_POS);
1009
1010 /* apply new option value */
1011 return stm32x_write_option(bank, FLASH_OPTSR_PRG, optsr);
1012 }
1013
1014 COMMAND_HANDLER(stm32x_handle_lock_command)
1015 {
1016 if (CMD_ARGC < 1)
1017 return ERROR_COMMAND_SYNTAX_ERROR;
1018
1019 struct flash_bank *bank;
1020 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1021 if (retval != ERROR_OK)
1022 return retval;
1023
1024 retval = stm32x_set_rdp(bank, OPT_RDP_L1);
1025
1026 if (retval != ERROR_OK)
1027 command_print(CMD, "%s failed to lock device", bank->driver->name);
1028 else
1029 command_print(CMD, "%s locked", bank->driver->name);
1030
1031 return retval;
1032 }
1033
1034 COMMAND_HANDLER(stm32x_handle_unlock_command)
1035 {
1036 if (CMD_ARGC < 1)
1037 return ERROR_COMMAND_SYNTAX_ERROR;
1038
1039 struct flash_bank *bank;
1040 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1041 if (retval != ERROR_OK)
1042 return retval;
1043
1044 retval = stm32x_set_rdp(bank, OPT_RDP_L0);
1045
1046 if (retval != ERROR_OK)
1047 command_print(CMD, "%s failed to unlock device", bank->driver->name);
1048 else
1049 command_print(CMD, "%s unlocked", bank->driver->name);
1050
1051 return retval;
1052 }
1053
1054 static int stm32x_mass_erase(struct flash_bank *bank)
1055 {
1056 int retval, retval2;
1057 struct target *target = bank->target;
1058 struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
1059
1060 if (target->state != TARGET_HALTED) {
1061 LOG_ERROR("Target not halted");
1062 return ERROR_TARGET_NOT_HALTED;
1063 }
1064
1065 retval = stm32x_unlock_reg(bank);
1066 if (retval != ERROR_OK)
1067 goto flash_lock;
1068
1069 /* mass erase flash memory bank */
1070 retval = stm32x_write_flash_reg(bank, FLASH_CR,
1071 stm32x_info->part_info->compute_flash_cr(FLASH_BER | FLASH_PSIZE_64, 0));
1072 if (retval != ERROR_OK)
1073 goto flash_lock;
1074
1075 retval = stm32x_write_flash_reg(bank, FLASH_CR,
1076 stm32x_info->part_info->compute_flash_cr(FLASH_BER | FLASH_PSIZE_64 | FLASH_START, 0));
1077 if (retval != ERROR_OK)
1078 goto flash_lock;
1079
1080 retval = stm32x_wait_flash_op_queue(bank, 30000);
1081 if (retval != ERROR_OK)
1082 goto flash_lock;
1083
1084 flash_lock:
1085 retval2 = stm32x_lock_reg(bank);
1086 if (retval2 != ERROR_OK)
1087 LOG_ERROR("error during the lock of flash");
1088
1089 return (retval == ERROR_OK) ? retval2 : retval;
1090 }
1091
1092 COMMAND_HANDLER(stm32x_handle_mass_erase_command)
1093 {
1094 if (CMD_ARGC < 1) {
1095 command_print(CMD, "stm32h7x mass_erase <bank>");
1096 return ERROR_COMMAND_SYNTAX_ERROR;
1097 }
1098
1099 struct flash_bank *bank;
1100 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1101 if (retval != ERROR_OK)
1102 return retval;
1103
1104 retval = stm32x_mass_erase(bank);
1105 if (retval == ERROR_OK)
1106 command_print(CMD, "stm32h7x mass erase complete");
1107 else
1108 command_print(CMD, "stm32h7x mass erase failed");
1109
1110 return retval;
1111 }
1112
1113 COMMAND_HANDLER(stm32x_handle_option_read_command)
1114 {
1115 if (CMD_ARGC < 2) {
1116 command_print(CMD, "stm32h7x option_read <bank> <option_reg offset>");
1117 return ERROR_COMMAND_SYNTAX_ERROR;
1118 }
1119
1120 struct flash_bank *bank;
1121 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1122 if (retval != ERROR_OK)
1123 return retval;
1124
1125 uint32_t reg_offset, value;
1126
1127 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], reg_offset);
1128 retval = stm32x_read_flash_reg(bank, reg_offset, &value);
1129 if (retval != ERROR_OK)
1130 return retval;
1131
1132 command_print(CMD, "Option Register: <0x%" PRIx32 "> = 0x%" PRIx32,
1133 stm32x_get_flash_reg(bank, reg_offset), value);
1134
1135 return retval;
1136 }
1137
1138 COMMAND_HANDLER(stm32x_handle_option_write_command)
1139 {
1140 if (CMD_ARGC < 3) {
1141 command_print(CMD, "stm32h7x option_write <bank> <option_reg offset> <value> [mask]");
1142 return ERROR_COMMAND_SYNTAX_ERROR;
1143 }
1144
1145 struct flash_bank *bank;
1146 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1147 if (retval != ERROR_OK)
1148 return retval;
1149
1150 uint32_t reg_offset, value, mask = 0xffffffff;
1151
1152 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], reg_offset);
1153 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);
1154 if (CMD_ARGC > 3)
1155 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], mask);
1156
1157 return stm32x_modify_option(bank, reg_offset, value, mask);
1158 }
1159
1160 static const struct command_registration stm32h7x_exec_command_handlers[] = {
1161 {
1162 .name = "lock",
1163 .handler = stm32x_handle_lock_command,
1164 .mode = COMMAND_EXEC,
1165 .usage = "bank_id",
1166 .help = "Lock entire flash device.",
1167 },
1168 {
1169 .name = "unlock",
1170 .handler = stm32x_handle_unlock_command,
1171 .mode = COMMAND_EXEC,
1172 .usage = "bank_id",
1173 .help = "Unlock entire protected flash device.",
1174 },
1175 {
1176 .name = "mass_erase",
1177 .handler = stm32x_handle_mass_erase_command,
1178 .mode = COMMAND_EXEC,
1179 .usage = "bank_id",
1180 .help = "Erase entire flash device.",
1181 },
1182 {
1183 .name = "option_read",
1184 .handler = stm32x_handle_option_read_command,
1185 .mode = COMMAND_EXEC,
1186 .usage = "bank_id reg_offset",
1187 .help = "Read and display device option bytes.",
1188 },
1189 {
1190 .name = "option_write",
1191 .handler = stm32x_handle_option_write_command,
1192 .mode = COMMAND_EXEC,
1193 .usage = "bank_id reg_offset value [mask]",
1194 .help = "Write device option bit fields with provided value.",
1195 },
1196 COMMAND_REGISTRATION_DONE
1197 };
1198
1199 static const struct command_registration stm32h7x_command_handlers[] = {
1200 {
1201 .name = "stm32h7x",
1202 .mode = COMMAND_ANY,
1203 .help = "stm32h7x flash command group",
1204 .usage = "",
1205 .chain = stm32h7x_exec_command_handlers,
1206 },
1207 COMMAND_REGISTRATION_DONE
1208 };
1209
1210 const struct flash_driver stm32h7x_flash = {
1211 .name = "stm32h7x",
1212 .commands = stm32h7x_command_handlers,
1213 .flash_bank_command = stm32x_flash_bank_command,
1214 .erase = stm32x_erase,
1215 .protect = stm32x_protect,
1216 .write = stm32x_write,
1217 .read = default_flash_read,
1218 .probe = stm32x_probe,
1219 .auto_probe = stm32x_auto_probe,
1220 .erase_check = default_flash_blank_check,
1221 .protect_check = stm32x_protect_check,
1222 .info = stm32x_get_info,
1223 .free_driver_priv = default_flash_free_driver_priv,
1224 };

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)