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

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)