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

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)