flash: fix error handling
[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         buffer = malloc(fileio.size);
608         size_t buf_cnt;
609         if (fileio_read(&fileio, fileio.size, buffer, &buf_cnt) != ERROR_OK)
610         {
611                 free(buffer);
612                 fileio_close(&fileio);
613                 return ERROR_OK;
614         }
615
616         retval = flash_driver_write(p, buffer, offset, buf_cnt);
617
618         free(buffer);
619         buffer = NULL;
620
621         if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK))
622         {
623                 command_print(CMD_CTX, "wrote %ld bytes from file %s to flash bank %u"
624                                 " at offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
625                                 (long)fileio.size, CMD_ARGV[1], p->bank_number, offset,
626                                 duration_elapsed(&bench), duration_kbps(&bench, fileio.size));
627         }
628
629         fileio_close(&fileio);
630
631         return retval;
632 }
633
634 void flash_set_dirty(void)
635 {
636         struct flash_bank *c;
637         int i;
638
639         /* set all flash to require erasing */
640         for (c = flash_bank_list(); c; c = c->next)
641         {
642                 for (i = 0; i < c->num_sectors; i++)
643                 {
644                         c->sectors[i].is_erased = 0;
645                 }
646         }
647 }
648
649 static const struct command_registration flash_exec_command_handlers[] = {
650         {
651                 .name = "probe",
652                 .handler = handle_flash_probe_command,
653                 .mode = COMMAND_EXEC,
654                 .usage = "bank_id",
655                 .help = "Identify a flash bank.",
656         },
657         {
658                 .name = "info",
659                 .handler = handle_flash_info_command,
660                 .mode = COMMAND_EXEC,
661                 .usage = "bank_id",
662                 .help = "Print information about a flash bank.",
663         },
664         {
665                 .name = "erase_check",
666                 .handler = handle_flash_erase_check_command,
667                 .mode = COMMAND_EXEC,
668                 .usage = "bank_id",
669                 .help = "Check erase state of all blocks in a "
670                         "flash bank.",
671         },
672         {
673                 .name = "erase_sector",
674                 .handler = handle_flash_erase_command,
675                 .mode = COMMAND_EXEC,
676                 .usage = "bank_id first_sector_num last_sector_num",
677                 .help = "Erase a range of sectors in a flash bank.",
678         },
679         {
680                 .name = "erase_address",
681                 .handler = handle_flash_erase_address_command,
682                 .mode = COMMAND_EXEC,
683                 .usage = "['pad'] ['unlock'] address length",
684                 .help = "Erase flash sectors starting at address and "
685                         "continuing for length bytes.  If 'pad' is specified, "
686                         "data outside that range may also be erased: the start "
687                         "address may be decreased, and length increased, so "
688                         "that all of the first and last sectors are erased. "
689                         "If 'unlock' is specified, then the flash is unprotected "
690                         "before erasing.",
691
692         },
693         {
694                 .name = "fillw",
695                 .handler = handle_flash_fill_command,
696                 .mode = COMMAND_EXEC,
697                 .usage = "address value n",
698                 .help = "Fill n words with 32-bit value, starting at "
699                         "word address.  (No autoerase.)",
700         },
701         {
702                 .name = "fillh",
703                 .handler = handle_flash_fill_command,
704                 .mode = COMMAND_EXEC,
705                 .usage = "address value n",
706                 .help = "Fill n halfwords with 16-bit value, starting at "
707                         "word address.  (No autoerase.)",
708         },
709         {
710                 .name = "fillb",
711                 .handler = handle_flash_fill_command,
712                 .mode = COMMAND_EXEC,
713                 .usage = "address value n",
714                 .help = "Fill n bytes with 8-bit value, starting at "
715                         "word address.  (No autoerase.)",
716         },
717         {
718                 .name = "write_bank",
719                 .handler = handle_flash_write_bank_command,
720                 .mode = COMMAND_EXEC,
721                 .usage = "bank_id filename offset",
722                 .help = "Write binary data from file to flash bank, "
723                         "starting at specified byte offset from the "
724                         "beginning of the bank.",
725         },
726         {
727                 .name = "write_image",
728                 .handler = handle_flash_write_image_command,
729                 .mode = COMMAND_EXEC,
730                 .usage = "[erase] [unlock] filename [offset [file_type]]",
731                 .help = "Write an image to flash.  Optionally first unprotect "
732                         "and/or erase the region to be used.  Allow optional "
733                         "offset from beginning of bank (defaults to zero)",
734         },
735         {
736                 .name = "protect",
737                 .handler = handle_flash_protect_command,
738                 .mode = COMMAND_EXEC,
739                 .usage = "bank_id first_sector [last_sector|'last'] "
740                         "('on'|'off')",
741                 .help = "Turn protection on or off for a range of sectors "
742                         "in a given flash bank.",
743         },
744         COMMAND_REGISTRATION_DONE
745 };
746
747 static int flash_init_drivers(struct command_context *cmd_ctx)
748 {
749         if (!flash_bank_list())
750                 return ERROR_OK;
751
752         struct command *parent = command_find_in_context(cmd_ctx, "flash");
753         return register_commands(cmd_ctx, parent, flash_exec_command_handlers);
754 }
755
756
757 COMMAND_HANDLER(handle_flash_bank_command)
758 {
759         if (CMD_ARGC < 7)
760         {
761                 LOG_ERROR("usage: flash bank <name> <driver> "
762                                 "<base> <size> <chip_width> <bus_width> <target>");
763                 return ERROR_COMMAND_SYNTAX_ERROR;
764         }
765         // save bank name and advance arguments for compatibility
766         const char *bank_name = *CMD_ARGV++;
767         CMD_ARGC--;
768
769         struct target *target;
770         if ((target = get_target(CMD_ARGV[5])) == NULL)
771         {
772                 LOG_ERROR("target '%s' not defined", CMD_ARGV[5]);
773                 return ERROR_FAIL;
774         }
775
776         const char *driver_name = CMD_ARGV[0];
777         struct flash_driver *driver = flash_driver_find_by_name(driver_name);
778         if (NULL == driver)
779         {
780                 /* no matching flash driver found */
781                 LOG_ERROR("flash driver '%s' not found", driver_name);
782                 return ERROR_FAIL;
783         }
784
785         /* check the flash bank name is unique */
786         if (get_flash_bank_by_name_noprobe(bank_name) != NULL)
787         {
788                 /* flash bank name already exists  */
789                 LOG_ERROR("flash bank name '%s' already exists", bank_name);
790                 return ERROR_FAIL;
791         }
792
793         /* register flash specific commands */
794         if (NULL != driver->commands)
795         {
796                 int retval = register_commands(CMD_CTX, NULL,
797                                 driver->commands);
798                 if (ERROR_OK != retval)
799                 {
800                         LOG_ERROR("couldn't register '%s' commands",
801                                         driver_name);
802                         return ERROR_FAIL;
803                 }
804         }
805
806         struct flash_bank *c = malloc(sizeof(*c));
807         c->name = strdup(bank_name);
808         c->target = target;
809         c->driver = driver;
810         c->driver_priv = NULL;
811         COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], c->base);
812         COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], c->size);
813         COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], c->chip_width);
814         COMMAND_PARSE_NUMBER(int, CMD_ARGV[4], c->bus_width);
815         c->num_sectors = 0;
816         c->sectors = NULL;
817         c->next = NULL;
818
819         int retval;
820         retval = CALL_COMMAND_HANDLER(driver->flash_bank_command, c);
821         if (ERROR_OK != retval)
822         {
823                 LOG_ERROR("'%s' driver rejected flash bank at 0x%8.8" PRIx32,
824                                 driver_name, c->base);
825                 free(c);
826                 return retval;
827         }
828
829         flash_bank_add(c);
830
831         return ERROR_OK;
832 }
833
834 COMMAND_HANDLER(handle_flash_banks_command)
835 {
836         if (CMD_ARGC != 0)
837                 return ERROR_INVALID_ARGUMENTS;
838
839         unsigned n = 0;
840         for (struct flash_bank *p = flash_bank_list(); p; p = p->next, n++)
841         {
842                 LOG_USER("#%" PRIu32 " : %s at 0x%8.8" PRIx32 ", size 0x%8.8" PRIx32 ", "
843                         "buswidth %u, chipwidth %u", p->bank_number,
844                         p->driver->name, p->base, p->size,
845                         p->bus_width, p->chip_width);
846         }
847         return ERROR_OK;
848 }
849
850 static int jim_flash_list(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
851 {
852         if (argc != 1)
853         {
854                 Jim_WrongNumArgs(interp, 1, argv,
855                                 "no arguments to 'flash list' command");
856                 return JIM_ERR;
857         }
858
859         Jim_Obj *list = Jim_NewListObj(interp, NULL, 0);
860
861         for (struct flash_bank *p = flash_bank_list(); p; p = p->next)
862         {
863                 Jim_Obj *elem = Jim_NewListObj(interp, NULL, 0);
864
865                 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "name", -1));
866                 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, p->driver->name, -1));
867                 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "base", -1));
868                 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->base));
869                 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "size", -1));
870                 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->size));
871                 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "bus_width", -1));
872                 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->bus_width));
873                 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "chip_width", -1));
874                 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->chip_width));
875
876                 Jim_ListAppendElement(interp, list, elem);
877         }
878
879         Jim_SetResult(interp, list);
880
881         return JIM_OK;
882 }
883
884
885 COMMAND_HANDLER(handle_flash_init_command)
886 {
887         if (CMD_ARGC != 0)
888                 return ERROR_COMMAND_SYNTAX_ERROR;
889
890         static bool flash_initialized = false;
891         if (flash_initialized)
892         {
893                 LOG_INFO("'flash init' has already been called");
894                 return ERROR_OK;
895         }
896         flash_initialized = true;
897
898         LOG_DEBUG("Initializing flash devices...");
899         return flash_init_drivers(CMD_CTX);
900 }
901
902 static const struct command_registration flash_config_command_handlers[] = {
903         {
904                 .name = "bank",
905                 .handler = handle_flash_bank_command,
906                 .mode = COMMAND_CONFIG,
907                 .usage = "bank_id driver_name base_address size_bytes "
908                         "chip_width_bytes bus_width_bytes target "
909                         "[driver_options ...]",
910                 .help = "Define a new bank with the given name, "
911                         "using the specified NOR flash driver.",
912         },
913         {
914                 .name = "init",
915                 .mode = COMMAND_CONFIG,
916                 .handler = handle_flash_init_command,
917                 .help = "Initialize flash devices.",
918         },
919         {
920                 .name = "banks",
921                 .mode = COMMAND_ANY,
922                 .handler = handle_flash_banks_command,
923                 .help = "Display table with information about flash banks.",
924         },
925         {
926                 .name = "list",
927                 .mode = COMMAND_ANY,
928                 .jim_handler = jim_flash_list,
929                 .help = "Returns a list of details about the flash banks.",
930         },
931         COMMAND_REGISTRATION_DONE
932 };
933 static const struct command_registration flash_command_handlers[] = {
934         {
935                 .name = "flash",
936                 .mode = COMMAND_ANY,
937                 .help = "NOR flash command group",
938                 .chain = flash_config_command_handlers,
939         },
940         COMMAND_REGISTRATION_DONE
941 };
942
943 int flash_register_commands(struct command_context *cmd_ctx)
944 {
945         return register_commands(cmd_ctx, NULL, flash_command_handlers);
946 }