flash: add error handling to get_flash_by_addr/name
[openocd.git] / src / flash / nor / tcl.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> *
3 * Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com> *
4 * Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> *
5 * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 ***************************************************************************/
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 #include "imp.h"
26 #include <helper/time_support.h>
27 #include <target/image.h>
28
29 /**
30 * @file
31 * Implements Tcl commands used to access NOR flash facilities.
32 */
33
34 COMMAND_HELPER(flash_command_get_bank, unsigned name_index,
35 struct flash_bank **bank)
36 {
37 const char *name = CMD_ARGV[name_index];
38 int retval = get_flash_bank_by_name(name, bank);
39 if (retval != ERROR_OK)
40 return retval;
41 if (*bank)
42 return ERROR_OK;
43
44 unsigned bank_num;
45 COMMAND_PARSE_NUMBER(uint, name, bank_num);
46
47 return get_flash_bank_by_num(bank_num, bank);
48 }
49
50
51 COMMAND_HANDLER(handle_flash_info_command)
52 {
53 struct flash_bank *p;
54 int j = 0;
55 int retval;
56
57 if (CMD_ARGC != 1)
58 return ERROR_COMMAND_SYNTAX_ERROR;
59
60 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
61 if (retval != ERROR_OK)
62 return retval;
63
64 if (p != NULL)
65 {
66 char buf[1024];
67
68 /* attempt auto probe */
69 if ((retval = p->driver->auto_probe(p)) != ERROR_OK)
70 return retval;
71
72 /* We must query the hardware to avoid printing stale information! */
73 retval = p->driver->protect_check(p);
74 if (retval != ERROR_OK)
75 return retval;
76
77 command_print(CMD_CTX,
78 "#%" PRIu32 " : %s at 0x%8.8" PRIx32 ", size 0x%8.8" PRIx32 ", buswidth %i, chipwidth %i",
79 p->bank_number,
80 p->driver->name,
81 p->base,
82 p->size,
83 p->bus_width,
84 p->chip_width);
85 for (j = 0; j < p->num_sectors; j++)
86 {
87 char *protect_state;
88
89 if (p->sectors[j].is_protected == 0)
90 protect_state = "not protected";
91 else if (p->sectors[j].is_protected == 1)
92 protect_state = "protected";
93 else
94 protect_state = "protection state unknown";
95
96 command_print(CMD_CTX,
97 "\t#%3i: 0x%8.8" PRIx32 " (0x%" PRIx32 " %" PRIi32 "kB) %s",
98 j,
99 p->sectors[j].offset,
100 p->sectors[j].size,
101 p->sectors[j].size >> 10,
102 protect_state);
103 }
104
105 *buf = '\0'; /* initialize buffer, otherwise it migh contain garbage if driver function fails */
106 retval = p->driver->info(p, buf, sizeof(buf));
107 command_print(CMD_CTX, "%s", buf);
108 if (retval != ERROR_OK)
109 LOG_ERROR("error retrieving flash info (%d)", retval);
110 }
111
112 return ERROR_OK;
113 }
114
115 COMMAND_HANDLER(handle_flash_probe_command)
116 {
117 struct flash_bank *p;
118 int retval;
119
120 if (CMD_ARGC != 1)
121 {
122 return ERROR_COMMAND_SYNTAX_ERROR;
123 }
124
125 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
126 if (retval != ERROR_OK)
127 return retval;
128
129 if (p)
130 {
131 if ((retval = p->driver->probe(p)) == ERROR_OK)
132 {
133 command_print(CMD_CTX, "flash '%s' found at 0x%8.8" PRIx32, p->driver->name, p->base);
134 }
135 else if (retval == ERROR_FLASH_BANK_INVALID)
136 {
137 command_print(CMD_CTX, "probing failed for flash bank '#%s' at 0x%8.8" PRIx32,
138 CMD_ARGV[0], p->base);
139 }
140 else
141 {
142 command_print(CMD_CTX, "unknown error when probing flash bank '#%s' at 0x%8.8" PRIx32,
143 CMD_ARGV[0], p->base);
144 }
145 }
146 else
147 {
148 command_print(CMD_CTX, "flash bank '#%s' is out of bounds", CMD_ARGV[0]);
149 }
150
151 return ERROR_OK;
152 }
153
154 COMMAND_HANDLER(handle_flash_erase_check_command)
155 {
156 if (CMD_ARGC != 1)
157 {
158 return ERROR_COMMAND_SYNTAX_ERROR;
159 }
160
161 struct flash_bank *p;
162 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
163 if (ERROR_OK != retval)
164 return retval;
165
166 int j;
167 if ((retval = p->driver->erase_check(p)) == ERROR_OK)
168 {
169 command_print(CMD_CTX, "successfully checked erase state");
170 }
171 else
172 {
173 command_print(CMD_CTX, "unknown error when checking erase state of flash bank #%s at 0x%8.8" PRIx32,
174 CMD_ARGV[0], p->base);
175 }
176
177 for (j = 0; j < p->num_sectors; j++)
178 {
179 char *erase_state;
180
181 if (p->sectors[j].is_erased == 0)
182 erase_state = "not erased";
183 else if (p->sectors[j].is_erased == 1)
184 erase_state = "erased";
185 else
186 erase_state = "erase state unknown";
187
188 command_print(CMD_CTX,
189 "\t#%3i: 0x%8.8" PRIx32 " (0x%" PRIx32 " %" PRIi32 "kB) %s",
190 j,
191 p->sectors[j].offset,
192 p->sectors[j].size,
193 p->sectors[j].size >> 10,
194 erase_state);
195 }
196
197 return ERROR_OK;
198 }
199
200 COMMAND_HANDLER(handle_flash_erase_address_command)
201 {
202 struct flash_bank *p;
203 int retval = ERROR_OK;
204 uint32_t address;
205 uint32_t length;
206 bool do_pad = false;
207 bool do_unlock = false;
208 struct target *target = get_current_target(CMD_CTX);
209
210 while (CMD_ARGC >= 3)
211 {
212 /* Optionally pad out the address range to block/sector
213 * boundaries. We can't know if there's data in that part
214 * of the flash; only do padding if we're told to.
215 */
216 if (strcmp("pad", CMD_ARGV[0]) == 0)
217 {
218 do_pad = true;
219 } else if (strcmp("unlock", CMD_ARGV[0]) == 0)
220 {
221 do_unlock = true;
222 } else
223 {
224 return ERROR_COMMAND_SYNTAX_ERROR;
225 }
226 CMD_ARGC--;
227 CMD_ARGV++;
228 }
229 if (CMD_ARGC != 2)
230 {
231 return ERROR_COMMAND_SYNTAX_ERROR;
232 }
233
234 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
235 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);
236
237 if (length <= 0)
238 {
239 command_print(CMD_CTX, "Length must be >0");
240 return ERROR_COMMAND_SYNTAX_ERROR;
241 }
242
243 retval = get_flash_bank_by_addr(target, address, true, &p);
244 if (retval != ERROR_OK)
245 return retval;
246
247 /* We can't know if we did a resume + halt, in which case we no longer know the erased state */
248 flash_set_dirty();
249
250 struct duration bench;
251 duration_start(&bench);
252
253 if (do_unlock)
254 {
255 retval = flash_unlock_address_range(target, address, length);
256 }
257
258 if (retval == ERROR_OK)
259 {
260 retval = flash_erase_address_range(target, do_pad, address, length);
261 }
262
263 if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK))
264 {
265 command_print(CMD_CTX, "erased address 0x%8.8x (length %i)"
266 " in %fs (%0.3f KiB/s)", address, length,
267 duration_elapsed(&bench), duration_kbps(&bench, length));
268 }
269
270 return retval;
271 }
272
273 static int flash_check_sector_parameters(struct command_context *cmd_ctx,
274 uint32_t first, uint32_t last, uint32_t num_sectors)
275 {
276 if (!(first <= last)) {
277 command_print(cmd_ctx, "ERROR: "
278 "first sector must be <= last sector");
279 return ERROR_FAIL;
280 }
281
282 if (!(last <= (num_sectors - 1))) {
283 command_print(cmd_ctx, "ERROR: last sector must be <= %d",
284 (int) num_sectors - 1);
285 return ERROR_FAIL;
286 }
287
288 return ERROR_OK;
289 }
290
291 COMMAND_HANDLER(handle_flash_erase_command)
292 {
293 if (CMD_ARGC != 3)
294 return ERROR_COMMAND_SYNTAX_ERROR;
295
296 uint32_t first;
297 uint32_t last;
298
299 struct flash_bank *p;
300 int retval;
301
302 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
303 if (retval != ERROR_OK)
304 return retval;
305
306 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], first);
307 if (strcmp(CMD_ARGV[2], "last") == 0)
308 last = p->num_sectors - 1;
309 else
310 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], last);
311
312 if ((retval = flash_check_sector_parameters(CMD_CTX,
313 first, last, p->num_sectors)) != ERROR_OK)
314 return retval;
315
316 struct duration bench;
317 duration_start(&bench);
318
319 retval = flash_driver_erase(p, first, last);
320
321 if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK))
322 {
323 command_print(CMD_CTX, "erased sectors %" PRIu32 " "
324 "through %" PRIu32" on flash bank %" PRIu32 " "
325 "in %fs", first, last, p->bank_number, duration_elapsed(&bench));
326 }
327
328 return ERROR_OK;
329 }
330
331 COMMAND_HANDLER(handle_flash_protect_command)
332 {
333 if (CMD_ARGC != 4)
334 return ERROR_COMMAND_SYNTAX_ERROR;
335
336 uint32_t first;
337 uint32_t last;
338
339 struct flash_bank *p;
340 int retval;
341
342 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
343 if (retval != ERROR_OK)
344 return retval;
345
346 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], first);
347 if (strcmp(CMD_ARGV[2], "last") == 0)
348 last = p->num_sectors - 1;
349 else
350 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], last);
351
352 bool set;
353 COMMAND_PARSE_ON_OFF(CMD_ARGV[3], set);
354
355 if ((retval = flash_check_sector_parameters(CMD_CTX,
356 first, last, p->num_sectors)) != ERROR_OK)
357 return retval;
358
359 retval = flash_driver_protect(p, set, first, last);
360 if (retval == ERROR_OK) {
361 command_print(CMD_CTX, "%s protection for sectors %i "
362 "through %i on flash bank %" PRIu32 "",
363 (set) ? "set" : "cleared", (int) first,
364 (int) last, p->bank_number);
365 }
366
367 return ERROR_OK;
368 }
369
370 COMMAND_HANDLER(handle_flash_write_image_command)
371 {
372 struct target *target = get_current_target(CMD_CTX);
373
374 struct image image;
375 uint32_t written;
376
377 int retval;
378
379 if (CMD_ARGC < 1)
380 {
381 return ERROR_COMMAND_SYNTAX_ERROR;
382 }
383
384 /* flash auto-erase is disabled by default*/
385 int auto_erase = 0;
386 bool auto_unlock = false;
387
388 for (;;)
389 {
390 if (strcmp(CMD_ARGV[0], "erase") == 0)
391 {
392 auto_erase = 1;
393 CMD_ARGV++;
394 CMD_ARGC--;
395 command_print(CMD_CTX, "auto erase enabled");
396 } else if (strcmp(CMD_ARGV[0], "unlock") == 0)
397 {
398 auto_unlock = true;
399 CMD_ARGV++;
400 CMD_ARGC--;
401 command_print(CMD_CTX, "auto unlock enabled");
402 } else
403 {
404 break;
405 }
406 }
407
408 if (CMD_ARGC < 1)
409 {
410 return ERROR_COMMAND_SYNTAX_ERROR;
411 }
412
413 if (!target)
414 {
415 LOG_ERROR("no target selected");
416 return ERROR_FAIL;
417 }
418
419 struct duration bench;
420 duration_start(&bench);
421
422 if (CMD_ARGC >= 2)
423 {
424 image.base_address_set = 1;
425 COMMAND_PARSE_NUMBER(llong, CMD_ARGV[1], image.base_address);
426 }
427 else
428 {
429 image.base_address_set = 0;
430 image.base_address = 0x0;
431 }
432
433 image.start_address_set = 0;
434
435 retval = image_open(&image, CMD_ARGV[0], (CMD_ARGC == 3) ? CMD_ARGV[2] : NULL);
436 if (retval != ERROR_OK)
437 {
438 return retval;
439 }
440
441 retval = flash_write_unlock(target, &image, &written, auto_erase, auto_unlock);
442 if (retval != ERROR_OK)
443 {
444 image_close(&image);
445 return retval;
446 }
447
448 if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK))
449 {
450 command_print(CMD_CTX, "wrote %" PRIu32 " bytes from file %s "
451 "in %fs (%0.3f KiB/s)", written, CMD_ARGV[0],
452 duration_elapsed(&bench), duration_kbps(&bench, written));
453 }
454
455 image_close(&image);
456
457 return retval;
458 }
459
460 COMMAND_HANDLER(handle_flash_fill_command)
461 {
462 int err = ERROR_OK;
463 uint32_t address;
464 uint32_t pattern;
465 uint32_t count;
466 uint32_t wrote = 0;
467 uint32_t cur_size = 0;
468 uint32_t chunk_count;
469 struct target *target = get_current_target(CMD_CTX);
470 uint32_t i;
471 uint32_t wordsize;
472 int retval = ERROR_OK;
473
474 static size_t const chunksize = 1024;
475 uint8_t *chunk = malloc(chunksize);
476 if (chunk == NULL)
477 return ERROR_FAIL;
478
479 uint8_t *readback = malloc(chunksize);
480 if (readback == NULL)
481 {
482 free(chunk);
483 return ERROR_FAIL;
484 }
485
486
487 if (CMD_ARGC != 3)
488 {
489 retval = ERROR_COMMAND_SYNTAX_ERROR;
490 goto done;
491 }
492
493
494 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
495 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], pattern);
496 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], count);
497
498 if (count == 0)
499 goto done;
500
501 switch (CMD_NAME[4])
502 {
503 case 'w':
504 wordsize = 4;
505 break;
506 case 'h':
507 wordsize = 2;
508 break;
509 case 'b':
510 wordsize = 1;
511 break;
512 default:
513 retval = ERROR_COMMAND_SYNTAX_ERROR;
514 goto done;
515 }
516
517 chunk_count = MIN(count, (chunksize / wordsize));
518 switch (wordsize)
519 {
520 case 4:
521 for (i = 0; i < chunk_count; i++)
522 {
523 target_buffer_set_u32(target, chunk + i * wordsize, pattern);
524 }
525 break;
526 case 2:
527 for (i = 0; i < chunk_count; i++)
528 {
529 target_buffer_set_u16(target, chunk + i * wordsize, pattern);
530 }
531 break;
532 case 1:
533 memset(chunk, pattern, chunk_count);
534 break;
535 default:
536 LOG_ERROR("BUG: can't happen");
537 exit(-1);
538 }
539
540 struct duration bench;
541 duration_start(&bench);
542
543 for (wrote = 0; wrote < (count*wordsize); wrote += cur_size)
544 {
545 struct flash_bank *bank;
546
547 retval = get_flash_bank_by_addr(target, address, true, &bank );
548 if (retval != ERROR_OK)
549 goto done;
550
551 cur_size = MIN((count * wordsize - wrote), chunksize);
552 err = flash_driver_write(bank, chunk, address - bank->base + wrote, cur_size);
553 if (err != ERROR_OK)
554 {
555 retval = err;
556 goto done;
557 }
558
559 err = flash_driver_read(bank, readback, address - bank->base + wrote, cur_size);
560 if (err != ERROR_OK)
561 {
562 retval = err;
563 goto done;
564 }
565
566 unsigned i;
567 for (i = 0; i < cur_size; i++)
568 {
569 if (readback[i]!=chunk[i])
570 {
571 LOG_ERROR("Verification error address 0x%08" PRIx32 ", read back 0x%02x, expected 0x%02x",
572 address + wrote + i, readback[i], chunk[i]);
573 retval = ERROR_FAIL;
574 goto done;
575 }
576 }
577 }
578
579 if (duration_measure(&bench) == ERROR_OK)
580 {
581 command_print(CMD_CTX, "wrote %" PRIu32 " bytes to 0x%8.8" PRIx32
582 " in %fs (%0.3f KiB/s)", wrote, address,
583 duration_elapsed(&bench), duration_kbps(&bench, wrote));
584 }
585
586 done:
587 free(readback);
588 free(chunk);
589
590 return retval;
591 }
592
593 COMMAND_HANDLER(handle_flash_write_bank_command)
594 {
595 uint32_t offset;
596 uint8_t *buffer;
597 struct fileio fileio;
598
599 if (CMD_ARGC != 3)
600 return ERROR_COMMAND_SYNTAX_ERROR;
601
602 struct duration bench;
603 duration_start(&bench);
604
605 struct flash_bank *p;
606 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
607 if (ERROR_OK != retval)
608 return retval;
609
610 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
611
612 if (fileio_open(&fileio, CMD_ARGV[1], FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
613 {
614 return ERROR_OK;
615 }
616
617 buffer = malloc(fileio.size);
618 size_t buf_cnt;
619 if (fileio_read(&fileio, fileio.size, buffer, &buf_cnt) != ERROR_OK)
620 {
621 free(buffer);
622 fileio_close(&fileio);
623 return ERROR_OK;
624 }
625
626 retval = flash_driver_write(p, buffer, offset, buf_cnt);
627
628 free(buffer);
629 buffer = NULL;
630
631 if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK))
632 {
633 command_print(CMD_CTX, "wrote %ld bytes from file %s to flash bank %u"
634 " at offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
635 (long)fileio.size, CMD_ARGV[1], p->bank_number, offset,
636 duration_elapsed(&bench), duration_kbps(&bench, fileio.size));
637 }
638
639 fileio_close(&fileio);
640
641 return retval;
642 }
643
644 void flash_set_dirty(void)
645 {
646 struct flash_bank *c;
647 int i;
648
649 /* set all flash to require erasing */
650 for (c = flash_bank_list(); c; c = c->next)
651 {
652 for (i = 0; i < c->num_sectors; i++)
653 {
654 c->sectors[i].is_erased = 0;
655 }
656 }
657 }
658
659 static const struct command_registration flash_exec_command_handlers[] = {
660 {
661 .name = "probe",
662 .handler = handle_flash_probe_command,
663 .mode = COMMAND_EXEC,
664 .usage = "bank_id",
665 .help = "Identify a flash bank.",
666 },
667 {
668 .name = "info",
669 .handler = handle_flash_info_command,
670 .mode = COMMAND_EXEC,
671 .usage = "bank_id",
672 .help = "Print information about a flash bank.",
673 },
674 {
675 .name = "erase_check",
676 .handler = handle_flash_erase_check_command,
677 .mode = COMMAND_EXEC,
678 .usage = "bank_id",
679 .help = "Check erase state of all blocks in a "
680 "flash bank.",
681 },
682 {
683 .name = "erase_sector",
684 .handler = handle_flash_erase_command,
685 .mode = COMMAND_EXEC,
686 .usage = "bank_id first_sector_num last_sector_num",
687 .help = "Erase a range of sectors in a flash bank.",
688 },
689 {
690 .name = "erase_address",
691 .handler = handle_flash_erase_address_command,
692 .mode = COMMAND_EXEC,
693 .usage = "['pad'] ['unlock'] address length",
694 .help = "Erase flash sectors starting at address and "
695 "continuing for length bytes. If 'pad' is specified, "
696 "data outside that range may also be erased: the start "
697 "address may be decreased, and length increased, so "
698 "that all of the first and last sectors are erased. "
699 "If 'unlock' is specified, then the flash is unprotected "
700 "before erasing.",
701
702 },
703 {
704 .name = "fillw",
705 .handler = handle_flash_fill_command,
706 .mode = COMMAND_EXEC,
707 .usage = "address value n",
708 .help = "Fill n words with 32-bit value, starting at "
709 "word address. (No autoerase.)",
710 },
711 {
712 .name = "fillh",
713 .handler = handle_flash_fill_command,
714 .mode = COMMAND_EXEC,
715 .usage = "address value n",
716 .help = "Fill n halfwords with 16-bit value, starting at "
717 "word address. (No autoerase.)",
718 },
719 {
720 .name = "fillb",
721 .handler = handle_flash_fill_command,
722 .mode = COMMAND_EXEC,
723 .usage = "address value n",
724 .help = "Fill n bytes with 8-bit value, starting at "
725 "word address. (No autoerase.)",
726 },
727 {
728 .name = "write_bank",
729 .handler = handle_flash_write_bank_command,
730 .mode = COMMAND_EXEC,
731 .usage = "bank_id filename offset",
732 .help = "Write binary data from file to flash bank, "
733 "starting at specified byte offset from the "
734 "beginning of the bank.",
735 },
736 {
737 .name = "write_image",
738 .handler = handle_flash_write_image_command,
739 .mode = COMMAND_EXEC,
740 .usage = "[erase] [unlock] filename [offset [file_type]]",
741 .help = "Write an image to flash. Optionally first unprotect "
742 "and/or erase the region to be used. Allow optional "
743 "offset from beginning of bank (defaults to zero)",
744 },
745 {
746 .name = "protect",
747 .handler = handle_flash_protect_command,
748 .mode = COMMAND_EXEC,
749 .usage = "bank_id first_sector [last_sector|'last'] "
750 "('on'|'off')",
751 .help = "Turn protection on or off for a range of sectors "
752 "in a given flash bank.",
753 },
754 COMMAND_REGISTRATION_DONE
755 };
756
757 static int flash_init_drivers(struct command_context *cmd_ctx)
758 {
759 if (!flash_bank_list())
760 return ERROR_OK;
761
762 struct command *parent = command_find_in_context(cmd_ctx, "flash");
763 return register_commands(cmd_ctx, parent, flash_exec_command_handlers);
764 }
765
766
767 COMMAND_HANDLER(handle_flash_bank_command)
768 {
769 if (CMD_ARGC < 7)
770 {
771 LOG_ERROR("usage: flash bank <name> <driver> "
772 "<base> <size> <chip_width> <bus_width> <target>");
773 return ERROR_COMMAND_SYNTAX_ERROR;
774 }
775 // save bank name and advance arguments for compatibility
776 const char *bank_name = *CMD_ARGV++;
777 CMD_ARGC--;
778
779 struct target *target;
780 if ((target = get_target(CMD_ARGV[5])) == NULL)
781 {
782 LOG_ERROR("target '%s' not defined", CMD_ARGV[5]);
783 return ERROR_FAIL;
784 }
785
786 const char *driver_name = CMD_ARGV[0];
787 struct flash_driver *driver = flash_driver_find_by_name(driver_name);
788 if (NULL == driver)
789 {
790 /* no matching flash driver found */
791 LOG_ERROR("flash driver '%s' not found", driver_name);
792 return ERROR_FAIL;
793 }
794
795 /* check the flash bank name is unique */
796 if (get_flash_bank_by_name_noprobe(bank_name) != NULL)
797 {
798 /* flash bank name already exists */
799 LOG_ERROR("flash bank name '%s' already exists", bank_name);
800 return ERROR_FAIL;
801 }
802
803 /* register flash specific commands */
804 if (NULL != driver->commands)
805 {
806 int retval = register_commands(CMD_CTX, NULL,
807 driver->commands);
808 if (ERROR_OK != retval)
809 {
810 LOG_ERROR("couldn't register '%s' commands",
811 driver_name);
812 return ERROR_FAIL;
813 }
814 }
815
816 struct flash_bank *c = malloc(sizeof(*c));
817 c->name = strdup(bank_name);
818 c->target = target;
819 c->driver = driver;
820 c->driver_priv = NULL;
821 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], c->base);
822 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], c->size);
823 COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], c->chip_width);
824 COMMAND_PARSE_NUMBER(int, CMD_ARGV[4], c->bus_width);
825 c->num_sectors = 0;
826 c->sectors = NULL;
827 c->next = NULL;
828
829 int retval;
830 retval = CALL_COMMAND_HANDLER(driver->flash_bank_command, c);
831 if (ERROR_OK != retval)
832 {
833 LOG_ERROR("'%s' driver rejected flash bank at 0x%8.8" PRIx32,
834 driver_name, c->base);
835 free(c);
836 return retval;
837 }
838
839 flash_bank_add(c);
840
841 return ERROR_OK;
842 }
843
844 COMMAND_HANDLER(handle_flash_banks_command)
845 {
846 if (CMD_ARGC != 0)
847 return ERROR_INVALID_ARGUMENTS;
848
849 unsigned n = 0;
850 for (struct flash_bank *p = flash_bank_list(); p; p = p->next, n++)
851 {
852 LOG_USER("#%" PRIu32 " : %s at 0x%8.8" PRIx32 ", size 0x%8.8" PRIx32 ", "
853 "buswidth %u, chipwidth %u", p->bank_number,
854 p->driver->name, p->base, p->size,
855 p->bus_width, p->chip_width);
856 }
857 return ERROR_OK;
858 }
859
860 static int jim_flash_list(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
861 {
862 if (argc != 1)
863 {
864 Jim_WrongNumArgs(interp, 1, argv,
865 "no arguments to 'flash list' command");
866 return JIM_ERR;
867 }
868
869 Jim_Obj *list = Jim_NewListObj(interp, NULL, 0);
870
871 for (struct flash_bank *p = flash_bank_list(); p; p = p->next)
872 {
873 Jim_Obj *elem = Jim_NewListObj(interp, NULL, 0);
874
875 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "name", -1));
876 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, p->driver->name, -1));
877 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "base", -1));
878 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->base));
879 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "size", -1));
880 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->size));
881 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "bus_width", -1));
882 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->bus_width));
883 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "chip_width", -1));
884 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->chip_width));
885
886 Jim_ListAppendElement(interp, list, elem);
887 }
888
889 Jim_SetResult(interp, list);
890
891 return JIM_OK;
892 }
893
894
895 COMMAND_HANDLER(handle_flash_init_command)
896 {
897 if (CMD_ARGC != 0)
898 return ERROR_COMMAND_SYNTAX_ERROR;
899
900 static bool flash_initialized = false;
901 if (flash_initialized)
902 {
903 LOG_INFO("'flash init' has already been called");
904 return ERROR_OK;
905 }
906 flash_initialized = true;
907
908 LOG_DEBUG("Initializing flash devices...");
909 return flash_init_drivers(CMD_CTX);
910 }
911
912 static const struct command_registration flash_config_command_handlers[] = {
913 {
914 .name = "bank",
915 .handler = handle_flash_bank_command,
916 .mode = COMMAND_CONFIG,
917 .usage = "bank_id driver_name base_address size_bytes "
918 "chip_width_bytes bus_width_bytes target "
919 "[driver_options ...]",
920 .help = "Define a new bank with the given name, "
921 "using the specified NOR flash driver.",
922 },
923 {
924 .name = "init",
925 .mode = COMMAND_CONFIG,
926 .handler = handle_flash_init_command,
927 .help = "Initialize flash devices.",
928 },
929 {
930 .name = "banks",
931 .mode = COMMAND_ANY,
932 .handler = handle_flash_banks_command,
933 .help = "Display table with information about flash banks.",
934 },
935 {
936 .name = "list",
937 .mode = COMMAND_ANY,
938 .jim_handler = jim_flash_list,
939 .help = "Returns a list of details about the flash banks.",
940 },
941 COMMAND_REGISTRATION_DONE
942 };
943 static const struct command_registration flash_command_handlers[] = {
944 {
945 .name = "flash",
946 .mode = COMMAND_ANY,
947 .help = "NOR flash command group",
948 .chain = flash_config_command_handlers,
949 },
950 COMMAND_REGISTRATION_DONE
951 };
952
953 int flash_register_commands(struct command_context *cmd_ctx)
954 {
955 return register_commands(cmd_ctx, NULL, flash_command_handlers);
956 }

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)