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

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)