fileio: fileio_size() can now fail
[fw/openocd] / 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 }