jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / flash / nor / tcl.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> *
5 * Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com> *
6 * Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> *
7 * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
8 * Copyright (C) 2017-2018 Tomas Vanek <vanekt@fbl.cz> *
9 ***************************************************************************/
10 #ifdef HAVE_CONFIG_H
11 #include "config.h"
12 #endif
13 #include "imp.h"
14 #include <helper/time_support.h>
15 #include <target/image.h>
16
17 /**
18 * @file
19 * Implements Tcl commands used to access NOR flash facilities.
20 */
21
22 COMMAND_HELPER(flash_command_get_bank_probe_optional, unsigned int name_index,
23 struct flash_bank **bank, bool do_probe)
24 {
25 const char *name = CMD_ARGV[name_index];
26 int retval;
27 if (do_probe) {
28 retval = get_flash_bank_by_name(name, bank);
29 } else {
30 *bank = get_flash_bank_by_name_noprobe(name);
31 retval = ERROR_OK;
32 }
33
34 if (retval != ERROR_OK)
35 return retval;
36 if (*bank)
37 return ERROR_OK;
38
39 unsigned bank_num;
40 COMMAND_PARSE_NUMBER(uint, name, bank_num);
41
42 if (do_probe) {
43 return get_flash_bank_by_num(bank_num, bank);
44 } else {
45 *bank = get_flash_bank_by_num_noprobe(bank_num);
46 retval = (bank) ? ERROR_OK : ERROR_FAIL;
47 return retval;
48 }
49 }
50
51 COMMAND_HELPER(flash_command_get_bank, unsigned name_index,
52 struct flash_bank **bank)
53 {
54 return CALL_COMMAND_HANDLER(flash_command_get_bank_probe_optional,
55 name_index, bank, true);
56 }
57
58 COMMAND_HANDLER(handle_flash_info_command)
59 {
60 struct flash_bank *p;
61 int j = 0;
62 int retval;
63 bool show_sectors = false;
64 bool prot_block_available;
65
66 if (CMD_ARGC < 1 || CMD_ARGC > 2)
67 return ERROR_COMMAND_SYNTAX_ERROR;
68
69 if (CMD_ARGC == 2) {
70 if (strcmp("sectors", CMD_ARGV[1]) == 0)
71 show_sectors = true;
72 else
73 return ERROR_COMMAND_SYNTAX_ERROR;
74 }
75
76 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
77 if (retval != ERROR_OK)
78 return retval;
79
80 if (p) {
81 int num_blocks;
82 struct flash_sector *block_array;
83
84 /* attempt auto probe */
85 retval = p->driver->auto_probe(p);
86 if (retval != ERROR_OK)
87 return retval;
88
89 /* If the driver does not implement protection, we show the default
90 * state of is_protected array - usually protection state unknown */
91 if (!p->driver->protect_check) {
92 retval = ERROR_FLASH_OPER_UNSUPPORTED;
93 } else {
94 /* We must query the hardware to avoid printing stale information! */
95 retval = p->driver->protect_check(p);
96 if (retval != ERROR_OK && retval != ERROR_FLASH_OPER_UNSUPPORTED)
97 return retval;
98 }
99 if (retval == ERROR_FLASH_OPER_UNSUPPORTED)
100 LOG_INFO("Flash protection check is not implemented.");
101
102 command_print(CMD,
103 "#%u : %s at " TARGET_ADDR_FMT ", size 0x%8.8" PRIx32
104 ", buswidth %u, chipwidth %u",
105 p->bank_number,
106 p->driver->name,
107 p->base,
108 p->size,
109 p->bus_width,
110 p->chip_width);
111
112 prot_block_available = p->num_prot_blocks && p->prot_blocks;
113 if (!show_sectors && prot_block_available) {
114 block_array = p->prot_blocks;
115 num_blocks = p->num_prot_blocks;
116 } else {
117 block_array = p->sectors;
118 num_blocks = p->num_sectors;
119 }
120
121 for (j = 0; j < num_blocks; j++) {
122 char *protect_state = "";
123
124 if (block_array[j].is_protected == 0)
125 protect_state = "not protected";
126 else if (block_array[j].is_protected == 1)
127 protect_state = "protected";
128 else if (!show_sectors || !prot_block_available)
129 protect_state = "protection state unknown";
130
131 command_print(CMD,
132 "\t#%3i: 0x%8.8" PRIx32 " (0x%" PRIx32 " %" PRIu32 "kB) %s",
133 j,
134 block_array[j].offset,
135 block_array[j].size,
136 block_array[j].size >> 10,
137 protect_state);
138 }
139
140 if (p->driver->info) {
141 /* Let the flash driver print extra custom info */
142 retval = p->driver->info(p, CMD);
143 command_print_sameline(CMD, "\n");
144 if (retval != ERROR_OK)
145 LOG_ERROR("error retrieving flash info");
146 }
147 }
148
149 return retval;
150 }
151
152 COMMAND_HANDLER(handle_flash_probe_command)
153 {
154 struct flash_bank *p;
155 int retval;
156
157 if (CMD_ARGC != 1)
158 return ERROR_COMMAND_SYNTAX_ERROR;
159
160 retval = CALL_COMMAND_HANDLER(flash_command_get_bank_probe_optional, 0, &p, false);
161 if (retval != ERROR_OK)
162 return retval;
163
164 if (p) {
165 retval = p->driver->probe(p);
166 if (retval == ERROR_OK)
167 command_print(CMD,
168 "flash '%s' found at " TARGET_ADDR_FMT,
169 p->driver->name,
170 p->base);
171 } else {
172 command_print(CMD, "flash bank '#%s' is out of bounds", CMD_ARGV[0]);
173 retval = ERROR_FAIL;
174 }
175
176 return retval;
177 }
178
179 COMMAND_HANDLER(handle_flash_erase_check_command)
180 {
181 bool blank = true;
182 if (CMD_ARGC != 1)
183 return ERROR_COMMAND_SYNTAX_ERROR;
184
185 struct flash_bank *p;
186 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
187 if (retval != ERROR_OK)
188 return retval;
189
190 retval = p->driver->erase_check(p);
191 if (retval == ERROR_OK)
192 command_print(CMD, "successfully checked erase state");
193 else {
194 command_print(CMD,
195 "unknown error when checking erase state of flash bank #%s at "
196 TARGET_ADDR_FMT,
197 CMD_ARGV[0],
198 p->base);
199 }
200
201 for (unsigned int j = 0; j < p->num_sectors; j++) {
202 char *erase_state;
203
204 if (p->sectors[j].is_erased == 0)
205 erase_state = "not erased";
206 else if (p->sectors[j].is_erased == 1)
207 continue;
208 else
209 erase_state = "erase state unknown";
210
211 blank = false;
212 command_print(CMD,
213 "\t#%3i: 0x%8.8" PRIx32 " (0x%" PRIx32 " %" PRIu32 "kB) %s",
214 j,
215 p->sectors[j].offset,
216 p->sectors[j].size,
217 p->sectors[j].size >> 10,
218 erase_state);
219 }
220
221 if (blank)
222 command_print(CMD, "\tBank is erased");
223 return retval;
224 }
225
226 COMMAND_HANDLER(handle_flash_erase_address_command)
227 {
228 struct flash_bank *p;
229 int retval = ERROR_OK;
230 target_addr_t address;
231 uint32_t length;
232 bool do_pad = false;
233 bool do_unlock = false;
234 struct target *target = get_current_target(CMD_CTX);
235
236 while (CMD_ARGC >= 3) {
237 /* Optionally pad out the address range to block/sector
238 * boundaries. We can't know if there's data in that part
239 * of the flash; only do padding if we're told to.
240 */
241 if (strcmp("pad", CMD_ARGV[0]) == 0)
242 do_pad = true;
243 else if (strcmp("unlock", CMD_ARGV[0]) == 0)
244 do_unlock = true;
245 else
246 return ERROR_COMMAND_SYNTAX_ERROR;
247 CMD_ARGC--;
248 CMD_ARGV++;
249 }
250 if (CMD_ARGC != 2)
251 return ERROR_COMMAND_SYNTAX_ERROR;
252
253 COMMAND_PARSE_ADDRESS(CMD_ARGV[0], address);
254 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);
255
256 if (length <= 0) {
257 command_print(CMD, "Length must be >0");
258 return ERROR_COMMAND_SYNTAX_ERROR;
259 }
260
261 retval = get_flash_bank_by_addr(target, address, true, &p);
262 if (retval != ERROR_OK)
263 return retval;
264
265 /* We can't know if we did a resume + halt, in which case we no longer know the erased state
266 **/
267 flash_set_dirty();
268
269 struct duration bench;
270 duration_start(&bench);
271
272 if (do_unlock)
273 retval = flash_unlock_address_range(target, address, length);
274
275 if (retval == ERROR_OK)
276 retval = flash_erase_address_range(target, do_pad, address, length);
277
278 if ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) {
279 command_print(CMD, "erased address " TARGET_ADDR_FMT " (length %" PRIu32 ")"
280 " in %fs (%0.3f KiB/s)", address, length,
281 duration_elapsed(&bench), duration_kbps(&bench, length));
282 }
283
284 return retval;
285 }
286
287 COMMAND_HANDLER(handle_flash_erase_command)
288 {
289 if (CMD_ARGC != 3)
290 return ERROR_COMMAND_SYNTAX_ERROR;
291
292 uint32_t first;
293 uint32_t last;
294
295 struct flash_bank *p;
296 int retval;
297
298 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
299 if (retval != ERROR_OK)
300 return retval;
301
302 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], first);
303 if (strcmp(CMD_ARGV[2], "last") == 0)
304 last = p->num_sectors - 1;
305 else
306 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], last);
307
308 if (!(first <= last)) {
309 command_print(CMD, "ERROR: "
310 "first sector must be <= last");
311 return ERROR_FAIL;
312 }
313
314 if (!(last <= (p->num_sectors - 1))) {
315 command_print(CMD, "ERROR: "
316 "last sector must be <= %u",
317 p->num_sectors - 1);
318 return ERROR_FAIL;
319 }
320
321 struct duration bench;
322 duration_start(&bench);
323
324 retval = flash_driver_erase(p, first, last);
325
326 if ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) {
327 command_print(CMD, "erased sectors %" PRIu32 " "
328 "through %" PRIu32 " on flash bank %u "
329 "in %fs", first, last, p->bank_number, duration_elapsed(&bench));
330 }
331
332 return retval;
333 }
334
335 COMMAND_HANDLER(handle_flash_protect_command)
336 {
337 if (CMD_ARGC != 4)
338 return ERROR_COMMAND_SYNTAX_ERROR;
339
340 uint32_t first;
341 uint32_t last;
342
343 struct flash_bank *p;
344 int retval;
345 int num_blocks;
346
347 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
348 if (retval != ERROR_OK)
349 return retval;
350
351 if (p->num_prot_blocks)
352 num_blocks = p->num_prot_blocks;
353 else
354 num_blocks = p->num_sectors;
355
356 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], first);
357 if (strcmp(CMD_ARGV[2], "last") == 0)
358 last = num_blocks - 1;
359 else
360 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], last);
361
362 bool set;
363 COMMAND_PARSE_ON_OFF(CMD_ARGV[3], set);
364
365 if (!(first <= last)) {
366 command_print(CMD, "ERROR: "
367 "first %s must be <= last",
368 (p->num_prot_blocks) ? "block" : "sector");
369 return ERROR_FAIL;
370 }
371
372 if (!(last <= (uint32_t)(num_blocks - 1))) {
373 command_print(CMD, "ERROR: "
374 "last %s must be <= %d",
375 (p->num_prot_blocks) ? "block" : "sector",
376 num_blocks - 1);
377 return ERROR_FAIL;
378 }
379
380 retval = flash_driver_protect(p, set, first, last);
381 if (retval == ERROR_OK) {
382 command_print(CMD, "%s protection for %s %" PRIu32
383 " through %" PRIu32 " on flash bank %d",
384 (set) ? "set" : "cleared",
385 (p->num_prot_blocks) ? "blocks" : "sectors",
386 first, last, p->bank_number);
387 }
388
389 return retval;
390 }
391
392 COMMAND_HANDLER(handle_flash_write_image_command)
393 {
394 struct target *target = get_current_target(CMD_CTX);
395
396 struct image image;
397 uint32_t written;
398
399 int retval;
400
401 /* flash auto-erase is disabled by default*/
402 int auto_erase = 0;
403 bool auto_unlock = false;
404
405 while (CMD_ARGC) {
406 if (strcmp(CMD_ARGV[0], "erase") == 0) {
407 auto_erase = 1;
408 CMD_ARGV++;
409 CMD_ARGC--;
410 command_print(CMD, "auto erase enabled");
411 } else if (strcmp(CMD_ARGV[0], "unlock") == 0) {
412 auto_unlock = true;
413 CMD_ARGV++;
414 CMD_ARGC--;
415 command_print(CMD, "auto unlock enabled");
416 } else
417 break;
418 }
419
420 if (CMD_ARGC < 1)
421 return ERROR_COMMAND_SYNTAX_ERROR;
422
423 if (!target) {
424 LOG_ERROR("no target selected");
425 return ERROR_FAIL;
426 }
427
428 struct duration bench;
429 duration_start(&bench);
430
431 if (CMD_ARGC >= 2) {
432 image.base_address_set = true;
433 COMMAND_PARSE_NUMBER(llong, CMD_ARGV[1], image.base_address);
434 } else {
435 image.base_address_set = false;
436 image.base_address = 0x0;
437 }
438
439 image.start_address_set = false;
440
441 retval = image_open(&image, CMD_ARGV[0], (CMD_ARGC == 3) ? CMD_ARGV[2] : NULL);
442 if (retval != ERROR_OK)
443 return retval;
444
445 retval = flash_write_unlock_verify(target, &image, &written, auto_erase,
446 auto_unlock, true, false);
447 if (retval != ERROR_OK) {
448 image_close(&image);
449 return retval;
450 }
451
452 if ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) {
453 command_print(CMD, "wrote %" PRIu32 " bytes from file %s "
454 "in %fs (%0.3f KiB/s)", written, CMD_ARGV[0],
455 duration_elapsed(&bench), duration_kbps(&bench, written));
456 }
457
458 image_close(&image);
459
460 return retval;
461 }
462
463 COMMAND_HANDLER(handle_flash_verify_image_command)
464 {
465 struct target *target = get_current_target(CMD_CTX);
466
467 struct image image;
468 uint32_t verified;
469
470 int retval;
471
472 if (CMD_ARGC < 1)
473 return ERROR_COMMAND_SYNTAX_ERROR;
474
475 if (!target) {
476 LOG_ERROR("no target selected");
477 return ERROR_FAIL;
478 }
479
480 struct duration bench;
481 duration_start(&bench);
482
483 if (CMD_ARGC >= 2) {
484 image.base_address_set = 1;
485 COMMAND_PARSE_NUMBER(llong, CMD_ARGV[1], image.base_address);
486 } else {
487 image.base_address_set = 0;
488 image.base_address = 0x0;
489 }
490
491 image.start_address_set = 0;
492
493 retval = image_open(&image, CMD_ARGV[0], (CMD_ARGC == 3) ? CMD_ARGV[2] : NULL);
494 if (retval != ERROR_OK)
495 return retval;
496
497 retval = flash_write_unlock_verify(target, &image, &verified, false,
498 false, false, true);
499 if (retval != ERROR_OK) {
500 image_close(&image);
501 return retval;
502 }
503
504 if ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) {
505 command_print(CMD, "verified %" PRIu32 " bytes from file %s "
506 "in %fs (%0.3f KiB/s)", verified, CMD_ARGV[0],
507 duration_elapsed(&bench), duration_kbps(&bench, verified));
508 }
509
510 image_close(&image);
511
512 return retval;
513 }
514
515 COMMAND_HANDLER(handle_flash_fill_command)
516 {
517 target_addr_t address;
518 uint64_t pattern;
519 uint32_t count;
520 struct target *target = get_current_target(CMD_CTX);
521 unsigned i;
522 uint32_t wordsize;
523 int retval;
524
525 if (CMD_ARGC != 3)
526 return ERROR_COMMAND_SYNTAX_ERROR;
527
528 COMMAND_PARSE_ADDRESS(CMD_ARGV[0], address);
529 COMMAND_PARSE_NUMBER(u64, CMD_ARGV[1], pattern);
530 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], count);
531
532 struct flash_bank *bank;
533 retval = get_flash_bank_by_addr(target, address, true, &bank);
534 if (retval != ERROR_OK)
535 return retval;
536
537 switch (CMD_NAME[4]) {
538 case 'd':
539 wordsize = 8;
540 break;
541 case 'w':
542 wordsize = 4;
543 break;
544 case 'h':
545 wordsize = 2;
546 break;
547 case 'b':
548 wordsize = 1;
549 break;
550 default:
551 return ERROR_COMMAND_SYNTAX_ERROR;
552 }
553
554 if ((wordsize < sizeof(pattern)) && (pattern >> (8 * wordsize) != 0)) {
555 command_print(CMD, "Fill pattern 0x%" PRIx64 " does not fit within %" PRIu32 "-byte word", pattern, wordsize);
556 return ERROR_FAIL;
557 }
558
559 if (count == 0)
560 return ERROR_OK;
561
562 if (address + count * wordsize > bank->base + bank->size) {
563 LOG_ERROR("Cannot cross flash bank borders");
564 return ERROR_FAIL;
565 }
566
567 uint32_t size_bytes = count * wordsize;
568 target_addr_t aligned_start = flash_write_align_start(bank, address);
569 target_addr_t end_addr = address + size_bytes - 1;
570 target_addr_t aligned_end = flash_write_align_end(bank, end_addr);
571 uint32_t aligned_size = aligned_end + 1 - aligned_start;
572 uint32_t padding_at_start = address - aligned_start;
573 uint32_t padding_at_end = aligned_end - end_addr;
574
575 uint8_t *buffer = malloc(aligned_size);
576 if (!buffer)
577 return ERROR_FAIL;
578
579 if (padding_at_start) {
580 memset(buffer, bank->default_padded_value, padding_at_start);
581 LOG_WARNING("Start address " TARGET_ADDR_FMT
582 " breaks the required alignment of flash bank %s",
583 address, bank->name);
584 LOG_WARNING("Padding %" PRIu32 " bytes from " TARGET_ADDR_FMT,
585 padding_at_start, aligned_start);
586 }
587
588 uint8_t *ptr = buffer + padding_at_start;
589
590 switch (wordsize) {
591 case 8:
592 for (i = 0; i < count; i++, ptr += wordsize)
593 target_buffer_set_u64(target, ptr, pattern);
594 break;
595 case 4:
596 for (i = 0; i < count; i++, ptr += wordsize)
597 target_buffer_set_u32(target, ptr, pattern);
598 break;
599 case 2:
600 for (i = 0; i < count; i++, ptr += wordsize)
601 target_buffer_set_u16(target, ptr, pattern);
602 break;
603 case 1:
604 memset(ptr, pattern, count);
605 ptr += count;
606 break;
607 default:
608 LOG_ERROR("BUG: can't happen");
609 exit(-1);
610 }
611
612 if (padding_at_end) {
613 memset(ptr, bank->default_padded_value, padding_at_end);
614 LOG_INFO("Padding at " TARGET_ADDR_FMT " with %" PRIu32
615 " bytes (bank write end alignment)",
616 end_addr + 1, padding_at_end);
617 }
618
619 struct duration bench;
620 duration_start(&bench);
621
622 retval = flash_driver_write(bank, buffer, aligned_start - bank->base, aligned_size);
623 if (retval != ERROR_OK)
624 goto done;
625
626 retval = flash_driver_read(bank, buffer, address - bank->base, size_bytes);
627 if (retval != ERROR_OK)
628 goto done;
629
630 for (i = 0, ptr = buffer; i < count; i++) {
631 uint64_t readback = 0;
632
633 switch (wordsize) {
634 case 8:
635 readback = target_buffer_get_u64(target, ptr);
636 break;
637 case 4:
638 readback = target_buffer_get_u32(target, ptr);
639 break;
640 case 2:
641 readback = target_buffer_get_u16(target, ptr);
642 break;
643 case 1:
644 readback = *ptr;
645 break;
646 }
647 if (readback != pattern) {
648 LOG_ERROR(
649 "Verification error address " TARGET_ADDR_FMT
650 ", read back 0x%02" PRIx64 ", expected 0x%02" PRIx64,
651 address + i * wordsize, readback, pattern);
652 retval = ERROR_FAIL;
653 goto done;
654 }
655 ptr += wordsize;
656 }
657
658 if ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) {
659 command_print(CMD, "wrote %" PRIu32 " bytes to " TARGET_ADDR_FMT
660 " in %fs (%0.3f KiB/s)", size_bytes, address,
661 duration_elapsed(&bench), duration_kbps(&bench, size_bytes));
662 }
663
664 done:
665 free(buffer);
666
667 return retval;
668 }
669
670 COMMAND_HANDLER(handle_flash_md_command)
671 {
672 int retval;
673
674 if (CMD_ARGC < 1 || CMD_ARGC > 2)
675 return ERROR_COMMAND_SYNTAX_ERROR;
676
677 target_addr_t address;
678 COMMAND_PARSE_ADDRESS(CMD_ARGV[0], address);
679
680 uint32_t count = 1;
681 if (CMD_ARGC == 2)
682 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], count);
683
684 unsigned int wordsize;
685 switch (CMD_NAME[2]) {
686 case 'w':
687 wordsize = 4;
688 break;
689 case 'h':
690 wordsize = 2;
691 break;
692 case 'b':
693 wordsize = 1;
694 break;
695 default:
696 return ERROR_COMMAND_SYNTAX_ERROR;
697 }
698
699 if (count == 0)
700 return ERROR_OK;
701
702 struct target *target = get_current_target(CMD_CTX);
703 struct flash_bank *bank;
704 retval = get_flash_bank_by_addr(target, address, true, &bank);
705 if (retval != ERROR_OK)
706 return retval;
707
708 uint32_t offset = address - bank->base;
709 uint32_t sizebytes = count * wordsize;
710 if (offset + sizebytes > bank->size) {
711 command_print(CMD, "Cannot cross flash bank borders");
712 return ERROR_FAIL;
713 }
714
715 uint8_t *buffer = calloc(count, wordsize);
716 if (!buffer) {
717 command_print(CMD, "No memory for flash read buffer");
718 return ERROR_FAIL;
719 }
720
721 retval = flash_driver_read(bank, buffer, offset, sizebytes);
722 if (retval == ERROR_OK)
723 target_handle_md_output(CMD, target, address, wordsize, count, buffer);
724
725 free(buffer);
726
727 return retval;
728 }
729
730
731 COMMAND_HANDLER(handle_flash_write_bank_command)
732 {
733 uint32_t offset;
734 uint8_t *buffer;
735 size_t length;
736 struct fileio *fileio;
737
738 if (CMD_ARGC < 2 || CMD_ARGC > 3)
739 return ERROR_COMMAND_SYNTAX_ERROR;
740
741 struct duration bench;
742 duration_start(&bench);
743
744 struct flash_bank *bank;
745 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
746 if (retval != ERROR_OK)
747 return retval;
748
749 offset = 0;
750
751 if (CMD_ARGC > 2)
752 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
753
754 if (offset > bank->size) {
755 LOG_ERROR("Offset 0x%8.8" PRIx32 " is out of range of the flash bank",
756 offset);
757 return ERROR_COMMAND_ARGUMENT_INVALID;
758 }
759
760 if (fileio_open(&fileio, CMD_ARGV[1], FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
761 return ERROR_FAIL;
762
763 size_t filesize;
764 retval = fileio_size(fileio, &filesize);
765 if (retval != ERROR_OK) {
766 fileio_close(fileio);
767 return retval;
768 }
769
770 length = MIN(filesize, bank->size - offset);
771
772 if (!length) {
773 LOG_INFO("Nothing to write to flash bank");
774 fileio_close(fileio);
775 return ERROR_OK;
776 }
777
778 if (length != filesize)
779 LOG_INFO("File content exceeds flash bank size. Only writing the "
780 "first %zu bytes of the file", length);
781
782 target_addr_t start_addr = bank->base + offset;
783 target_addr_t aligned_start = flash_write_align_start(bank, start_addr);
784 target_addr_t end_addr = start_addr + length - 1;
785 target_addr_t aligned_end = flash_write_align_end(bank, end_addr);
786 uint32_t aligned_size = aligned_end + 1 - aligned_start;
787 uint32_t padding_at_start = start_addr - aligned_start;
788 uint32_t padding_at_end = aligned_end - end_addr;
789
790 buffer = malloc(aligned_size);
791 if (!buffer) {
792 fileio_close(fileio);
793 LOG_ERROR("Out of memory");
794 return ERROR_FAIL;
795 }
796
797 if (padding_at_start) {
798 memset(buffer, bank->default_padded_value, padding_at_start);
799 LOG_WARNING("Start offset 0x%08" PRIx32
800 " breaks the required alignment of flash bank %s",
801 offset, bank->name);
802 LOG_WARNING("Padding %" PRIu32 " bytes from " TARGET_ADDR_FMT,
803 padding_at_start, aligned_start);
804 }
805
806 uint8_t *ptr = buffer + padding_at_start;
807 size_t buf_cnt;
808 if (fileio_read(fileio, length, ptr, &buf_cnt) != ERROR_OK) {
809 free(buffer);
810 fileio_close(fileio);
811 return ERROR_FAIL;
812 }
813
814 if (buf_cnt != length) {
815 LOG_ERROR("Short read");
816 free(buffer);
817 fileio_close(fileio);
818 return ERROR_FAIL;
819 }
820
821 ptr += length;
822
823 if (padding_at_end) {
824 memset(ptr, bank->default_padded_value, padding_at_end);
825 LOG_INFO("Padding at " TARGET_ADDR_FMT " with %" PRIu32
826 " bytes (bank write end alignment)",
827 end_addr + 1, padding_at_end);
828 }
829
830 retval = flash_driver_write(bank, buffer, aligned_start - bank->base, aligned_size);
831
832 free(buffer);
833
834 if ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) {
835 command_print(CMD, "wrote %zu bytes from file %s to flash bank %u"
836 " at offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
837 length, CMD_ARGV[1], bank->bank_number, offset,
838 duration_elapsed(&bench), duration_kbps(&bench, length));
839 }
840
841 fileio_close(fileio);
842
843 return retval;
844 }
845
846 COMMAND_HANDLER(handle_flash_read_bank_command)
847 {
848 uint32_t offset;
849 uint8_t *buffer;
850 struct fileio *fileio;
851 uint32_t length;
852 size_t written;
853
854 if (CMD_ARGC < 2 || CMD_ARGC > 4)
855 return ERROR_COMMAND_SYNTAX_ERROR;
856
857 struct duration bench;
858 duration_start(&bench);
859
860 struct flash_bank *p;
861 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
862
863 if (retval != ERROR_OK)
864 return retval;
865
866 offset = 0;
867
868 if (CMD_ARGC > 2)
869 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
870
871 if (offset > p->size) {
872 LOG_ERROR("Offset 0x%8.8" PRIx32 " is out of range of the flash bank",
873 offset);
874 return ERROR_COMMAND_ARGUMENT_INVALID;
875 }
876
877 length = p->size - offset;
878
879 if (CMD_ARGC > 3)
880 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], length);
881
882 if (offset + length > p->size) {
883 LOG_ERROR("Length of %" PRIu32 " bytes with offset 0x%8.8" PRIx32
884 " is out of range of the flash bank", length, offset);
885 return ERROR_COMMAND_ARGUMENT_INVALID;
886 }
887
888 buffer = malloc(length);
889 if (!buffer) {
890 LOG_ERROR("Out of memory");
891 return ERROR_FAIL;
892 }
893
894 retval = flash_driver_read(p, buffer, offset, length);
895 if (retval != ERROR_OK) {
896 LOG_ERROR("Read error");
897 free(buffer);
898 return retval;
899 }
900
901 retval = fileio_open(&fileio, CMD_ARGV[1], FILEIO_WRITE, FILEIO_BINARY);
902 if (retval != ERROR_OK) {
903 LOG_ERROR("Could not open file");
904 free(buffer);
905 return retval;
906 }
907
908 retval = fileio_write(fileio, length, buffer, &written);
909 fileio_close(fileio);
910 free(buffer);
911 if (retval != ERROR_OK) {
912 LOG_ERROR("Could not write file");
913 return ERROR_FAIL;
914 }
915
916 if (duration_measure(&bench) == ERROR_OK)
917 command_print(CMD, "wrote %zd bytes to file %s from flash bank %u"
918 " at offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
919 written, CMD_ARGV[1], p->bank_number, offset,
920 duration_elapsed(&bench), duration_kbps(&bench, written));
921
922 return retval;
923 }
924
925
926 COMMAND_HANDLER(handle_flash_verify_bank_command)
927 {
928 uint32_t offset;
929 uint8_t *buffer_file, *buffer_flash;
930 struct fileio *fileio;
931 size_t read_cnt;
932 size_t filesize;
933 size_t length;
934 int differ;
935
936 if (CMD_ARGC < 2 || CMD_ARGC > 3)
937 return ERROR_COMMAND_SYNTAX_ERROR;
938
939 struct duration bench;
940 duration_start(&bench);
941
942 struct flash_bank *p;
943 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
944 if (retval != ERROR_OK)
945 return retval;
946
947 offset = 0;
948
949 if (CMD_ARGC > 2)
950 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
951
952 if (offset > p->size) {
953 LOG_ERROR("Offset 0x%8.8" PRIx32 " is out of range of the flash bank",
954 offset);
955 return ERROR_COMMAND_ARGUMENT_INVALID;
956 }
957
958 retval = fileio_open(&fileio, CMD_ARGV[1], FILEIO_READ, FILEIO_BINARY);
959 if (retval != ERROR_OK) {
960 LOG_ERROR("Could not open file");
961 return retval;
962 }
963
964 retval = fileio_size(fileio, &filesize);
965 if (retval != ERROR_OK) {
966 fileio_close(fileio);
967 return retval;
968 }
969
970 length = MIN(filesize, p->size - offset);
971
972 if (!length) {
973 LOG_INFO("Nothing to compare with flash bank");
974 fileio_close(fileio);
975 return ERROR_OK;
976 }
977
978 if (length != filesize)
979 LOG_INFO("File content exceeds flash bank size. Only comparing the "
980 "first %zu bytes of the file", length);
981
982 buffer_file = malloc(length);
983 if (!buffer_file) {
984 LOG_ERROR("Out of memory");
985 fileio_close(fileio);
986 return ERROR_FAIL;
987 }
988
989 retval = fileio_read(fileio, length, buffer_file, &read_cnt);
990 fileio_close(fileio);
991 if (retval != ERROR_OK) {
992 LOG_ERROR("File read failure");
993 free(buffer_file);
994 return retval;
995 }
996
997 if (read_cnt != length) {
998 LOG_ERROR("Short read");
999 free(buffer_file);
1000 return ERROR_FAIL;
1001 }
1002
1003 buffer_flash = malloc(length);
1004 if (!buffer_flash) {
1005 LOG_ERROR("Out of memory");
1006 free(buffer_file);
1007 return ERROR_FAIL;
1008 }
1009
1010 retval = flash_driver_read(p, buffer_flash, offset, length);
1011 if (retval != ERROR_OK) {
1012 LOG_ERROR("Flash read error");
1013 free(buffer_flash);
1014 free(buffer_file);
1015 return retval;
1016 }
1017
1018 if (duration_measure(&bench) == ERROR_OK)
1019 command_print(CMD, "read %zd bytes from file %s and flash bank %u"
1020 " at offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
1021 length, CMD_ARGV[1], p->bank_number, offset,
1022 duration_elapsed(&bench), duration_kbps(&bench, length));
1023
1024 differ = memcmp(buffer_file, buffer_flash, length);
1025 command_print(CMD, "contents %s", differ ? "differ" : "match");
1026 if (differ) {
1027 uint32_t t;
1028 int diffs = 0;
1029 for (t = 0; t < length; t++) {
1030 if (buffer_flash[t] == buffer_file[t])
1031 continue;
1032 command_print(CMD, "diff %d address 0x%08" PRIx32 ". Was 0x%02x instead of 0x%02x",
1033 diffs, t + offset, buffer_flash[t], buffer_file[t]);
1034 if (diffs++ >= 127) {
1035 command_print(CMD, "More than 128 errors, the rest are not printed.");
1036 break;
1037 }
1038 keep_alive();
1039 }
1040 }
1041 free(buffer_flash);
1042 free(buffer_file);
1043
1044 return differ ? ERROR_FAIL : ERROR_OK;
1045 }
1046
1047 void flash_set_dirty(void)
1048 {
1049 struct flash_bank *c;
1050
1051 /* set all flash to require erasing */
1052 for (c = flash_bank_list(); c; c = c->next) {
1053 for (unsigned int i = 0; i < c->num_sectors; i++)
1054 c->sectors[i].is_erased = 0;
1055 }
1056 }
1057
1058 COMMAND_HANDLER(handle_flash_padded_value_command)
1059 {
1060 if (CMD_ARGC != 2)
1061 return ERROR_COMMAND_SYNTAX_ERROR;
1062
1063 struct flash_bank *p;
1064 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
1065 if (retval != ERROR_OK)
1066 return retval;
1067
1068 COMMAND_PARSE_NUMBER(u8, CMD_ARGV[1], p->default_padded_value);
1069
1070 command_print(CMD, "Default padded value set to 0x%" PRIx8 " for flash bank %u",
1071 p->default_padded_value, p->bank_number);
1072
1073 return retval;
1074 }
1075
1076 static const struct command_registration flash_exec_command_handlers[] = {
1077 {
1078 .name = "probe",
1079 .handler = handle_flash_probe_command,
1080 .mode = COMMAND_EXEC,
1081 .usage = "bank_id",
1082 .help = "Identify a flash bank.",
1083 },
1084 {
1085 .name = "info",
1086 .handler = handle_flash_info_command,
1087 .mode = COMMAND_EXEC,
1088 .usage = "bank_id ['sectors']",
1089 .help = "Print information about a flash bank.",
1090 },
1091 {
1092 .name = "erase_check",
1093 .handler = handle_flash_erase_check_command,
1094 .mode = COMMAND_EXEC,
1095 .usage = "bank_id",
1096 .help = "Check erase state of all blocks in a "
1097 "flash bank.",
1098 },
1099 {
1100 .name = "erase_sector",
1101 .handler = handle_flash_erase_command,
1102 .mode = COMMAND_EXEC,
1103 .usage = "bank_id first_sector_num (last_sector_num|'last')",
1104 .help = "Erase a range of sectors in a flash bank.",
1105 },
1106 {
1107 .name = "erase_address",
1108 .handler = handle_flash_erase_address_command,
1109 .mode = COMMAND_EXEC,
1110 .usage = "['pad'] ['unlock'] address length",
1111 .help = "Erase flash sectors starting at address and "
1112 "continuing for length bytes. If 'pad' is specified, "
1113 "data outside that range may also be erased: the start "
1114 "address may be decreased, and length increased, so "
1115 "that all of the first and last sectors are erased. "
1116 "If 'unlock' is specified, then the flash is unprotected "
1117 "before erasing.",
1118
1119 },
1120 {
1121 .name = "filld",
1122 .handler = handle_flash_fill_command,
1123 .mode = COMMAND_EXEC,
1124 .usage = "address value n",
1125 .help = "Fill n double-words with 64-bit value, starting at "
1126 "word address. (No autoerase.)",
1127 },
1128 {
1129 .name = "fillw",
1130 .handler = handle_flash_fill_command,
1131 .mode = COMMAND_EXEC,
1132 .usage = "address value n",
1133 .help = "Fill n words with 32-bit value, starting at "
1134 "word address. (No autoerase.)",
1135 },
1136 {
1137 .name = "fillh",
1138 .handler = handle_flash_fill_command,
1139 .mode = COMMAND_EXEC,
1140 .usage = "address value n",
1141 .help = "Fill n halfwords with 16-bit value, starting at "
1142 "word address. (No autoerase.)",
1143 },
1144 {
1145 .name = "fillb",
1146 .handler = handle_flash_fill_command,
1147 .mode = COMMAND_EXEC,
1148 .usage = "address value n",
1149 .help = "Fill n bytes with 8-bit value, starting at "
1150 "word address. (No autoerase.)",
1151 },
1152 {
1153 .name = "mdb",
1154 .handler = handle_flash_md_command,
1155 .mode = COMMAND_EXEC,
1156 .usage = "address [count]",
1157 .help = "Display bytes from flash.",
1158 },
1159 {
1160 .name = "mdh",
1161 .handler = handle_flash_md_command,
1162 .mode = COMMAND_EXEC,
1163 .usage = "address [count]",
1164 .help = "Display half-words from flash.",
1165 },
1166 {
1167 .name = "mdw",
1168 .handler = handle_flash_md_command,
1169 .mode = COMMAND_EXEC,
1170 .usage = "address [count]",
1171 .help = "Display words from flash.",
1172 },
1173 {
1174 .name = "write_bank",
1175 .handler = handle_flash_write_bank_command,
1176 .mode = COMMAND_EXEC,
1177 .usage = "bank_id filename [offset]",
1178 .help = "Write binary data from file to flash bank. Allow optional "
1179 "offset from beginning of the bank (defaults to zero).",
1180 },
1181 {
1182 .name = "write_image",
1183 .handler = handle_flash_write_image_command,
1184 .mode = COMMAND_EXEC,
1185 .usage = "[erase] [unlock] filename [offset [file_type]]",
1186 .help = "Write an image to flash. Optionally first unprotect "
1187 "and/or erase the region to be used. Allow optional "
1188 "offset from beginning of bank (defaults to zero)",
1189 },
1190 {
1191 .name = "verify_image",
1192 .handler = handle_flash_verify_image_command,
1193 .mode = COMMAND_EXEC,
1194 .usage = "filename [offset [file_type]]",
1195 .help = "Verify an image against flash. Allow optional "
1196 "offset from beginning of bank (defaults to zero)",
1197 },
1198 {
1199 .name = "read_bank",
1200 .handler = handle_flash_read_bank_command,
1201 .mode = COMMAND_EXEC,
1202 .usage = "bank_id filename [offset [length]]",
1203 .help = "Read binary data from flash bank to file. Allow optional "
1204 "offset from beginning of the bank (defaults to zero).",
1205 },
1206 {
1207 .name = "verify_bank",
1208 .handler = handle_flash_verify_bank_command,
1209 .mode = COMMAND_EXEC,
1210 .usage = "bank_id filename [offset]",
1211 .help = "Compare the contents of a file with the contents of the "
1212 "flash bank. Allow optional offset from beginning of the bank "
1213 "(defaults to zero).",
1214 },
1215 {
1216 .name = "protect",
1217 .handler = handle_flash_protect_command,
1218 .mode = COMMAND_EXEC,
1219 .usage = "bank_id first_block [last_block|'last'] "
1220 "('on'|'off')",
1221 .help = "Turn protection on or off for a range of protection "
1222 "blocks or sectors in a given flash bank. "
1223 "See 'flash info' output for a list of blocks.",
1224 },
1225 {
1226 .name = "padded_value",
1227 .handler = handle_flash_padded_value_command,
1228 .mode = COMMAND_EXEC,
1229 .usage = "bank_id value",
1230 .help = "Set default flash padded value",
1231 },
1232 COMMAND_REGISTRATION_DONE
1233 };
1234
1235 static int flash_init_drivers(struct command_context *cmd_ctx)
1236 {
1237 if (!flash_bank_list())
1238 return ERROR_OK;
1239
1240 return register_commands(cmd_ctx, "flash", flash_exec_command_handlers);
1241 }
1242
1243 COMMAND_HANDLER(handle_flash_bank_command)
1244 {
1245 if (CMD_ARGC < 7) {
1246 LOG_ERROR("usage: flash bank <name> <driver> "
1247 "<base> <size> <chip_width> <bus_width> <target>");
1248 return ERROR_COMMAND_SYNTAX_ERROR;
1249 }
1250 /* save bank name and advance arguments for compatibility */
1251 const char *bank_name = *CMD_ARGV++;
1252 CMD_ARGC--;
1253
1254 struct target *target = get_target(CMD_ARGV[5]);
1255 if (!target) {
1256 LOG_ERROR("target '%s' not defined", CMD_ARGV[5]);
1257 return ERROR_FAIL;
1258 }
1259
1260 const char *driver_name = CMD_ARGV[0];
1261 const struct flash_driver *driver = flash_driver_find_by_name(driver_name);
1262 if (!driver) {
1263 /* no matching flash driver found */
1264 LOG_ERROR("flash driver '%s' not found", driver_name);
1265 return ERROR_FAIL;
1266 }
1267
1268 /* check the flash bank name is unique */
1269 if (get_flash_bank_by_name_noprobe(bank_name)) {
1270 /* flash bank name already exists */
1271 LOG_ERROR("flash bank name '%s' already exists", bank_name);
1272 return ERROR_FAIL;
1273 }
1274
1275 /* register flash specific commands */
1276 if (driver->commands) {
1277 int retval = register_commands(CMD_CTX, NULL, driver->commands);
1278 if (retval != ERROR_OK) {
1279 LOG_ERROR("couldn't register '%s' commands",
1280 driver_name);
1281 return ERROR_FAIL;
1282 }
1283 }
1284
1285 struct flash_bank *c = calloc(1, sizeof(*c));
1286 c->name = strdup(bank_name);
1287 c->target = target;
1288 c->driver = driver;
1289 COMMAND_PARSE_NUMBER(target_addr, CMD_ARGV[1], c->base);
1290 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], c->size);
1291 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[3], c->chip_width);
1292 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[4], c->bus_width);
1293 c->default_padded_value = c->erased_value = 0xff;
1294 c->minimal_write_gap = FLASH_WRITE_GAP_SECTOR;
1295
1296 int retval;
1297 retval = CALL_COMMAND_HANDLER(driver->flash_bank_command, c);
1298 if (retval != ERROR_OK) {
1299 LOG_ERROR("'%s' driver rejected flash bank at " TARGET_ADDR_FMT
1300 "; usage: %s", driver_name, c->base, driver->usage);
1301 free(c);
1302 return retval;
1303 }
1304
1305 if (!driver->usage)
1306 LOG_DEBUG("'%s' driver usage field missing", driver_name);
1307
1308 flash_bank_add(c);
1309
1310 return ERROR_OK;
1311 }
1312
1313 COMMAND_HANDLER(handle_flash_banks_command)
1314 {
1315 if (CMD_ARGC != 0)
1316 return ERROR_COMMAND_SYNTAX_ERROR;
1317
1318 unsigned n = 0;
1319 for (struct flash_bank *p = flash_bank_list(); p; p = p->next, n++) {
1320 command_print(CMD, "#%d : %s (%s) at " TARGET_ADDR_FMT ", size 0x%8.8" PRIx32 ", "
1321 "buswidth %u, chipwidth %u", p->bank_number,
1322 p->name, p->driver->name, p->base, p->size,
1323 p->bus_width, p->chip_width);
1324 }
1325 return ERROR_OK;
1326 }
1327
1328 COMMAND_HANDLER(handle_flash_list)
1329 {
1330 if (CMD_ARGC != 0)
1331 return ERROR_COMMAND_SYNTAX_ERROR;
1332
1333 for (struct flash_bank *p = flash_bank_list(); p; p = p->next) {
1334 command_print(CMD,
1335 "{\n"
1336 " name %s\n"
1337 " driver %s\n"
1338 " base " TARGET_ADDR_FMT "\n"
1339 " size 0x%" PRIx32 "\n"
1340 " bus_width %u\n"
1341 " chip_width %u\n"
1342 " target %s\n"
1343 "}",
1344 p->name, p->driver->name, p->base, p->size, p->bus_width, p->chip_width,
1345 target_name(p->target));
1346 }
1347
1348 return ERROR_OK;
1349 }
1350
1351 COMMAND_HANDLER(handle_flash_init_command)
1352 {
1353 if (CMD_ARGC != 0)
1354 return ERROR_COMMAND_SYNTAX_ERROR;
1355
1356 static bool flash_initialized;
1357 if (flash_initialized) {
1358 LOG_INFO("'flash init' has already been called");
1359 return ERROR_OK;
1360 }
1361 flash_initialized = true;
1362
1363 LOG_DEBUG("Initializing flash devices...");
1364 return flash_init_drivers(CMD_CTX);
1365 }
1366
1367 static const struct command_registration flash_config_command_handlers[] = {
1368 {
1369 .name = "bank",
1370 .handler = handle_flash_bank_command,
1371 .mode = COMMAND_CONFIG,
1372 .usage = "bank_id driver_name base_address size_bytes "
1373 "chip_width_bytes bus_width_bytes target "
1374 "[driver_options ...]",
1375 .help = "Define a new bank with the given name, "
1376 "using the specified NOR flash driver.",
1377 },
1378 {
1379 .name = "init",
1380 .mode = COMMAND_CONFIG,
1381 .handler = handle_flash_init_command,
1382 .help = "Initialize flash devices.",
1383 .usage = "",
1384 },
1385 {
1386 .name = "banks",
1387 .mode = COMMAND_ANY,
1388 .handler = handle_flash_banks_command,
1389 .help = "Display table with information about flash banks.",
1390 .usage = "",
1391 },
1392 {
1393 .name = "list",
1394 .mode = COMMAND_ANY,
1395 .handler = handle_flash_list,
1396 .help = "Returns a list of details about the flash banks.",
1397 .usage = "",
1398 },
1399 COMMAND_REGISTRATION_DONE
1400 };
1401 static const struct command_registration flash_command_handlers[] = {
1402 {
1403 .name = "flash",
1404 .mode = COMMAND_ANY,
1405 .help = "NOR flash command group",
1406 .chain = flash_config_command_handlers,
1407 .usage = "",
1408 },
1409 COMMAND_REGISTRATION_DONE
1410 };
1411
1412 int flash_register_commands(struct command_context *cmd_ctx)
1413 {
1414 return register_commands(cmd_ctx, NULL, flash_command_handlers);
1415 }

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)