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

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)