- fix incorrect parsing of whitespace in command.c (thanks to Magnus Lundin)
[openocd.git] / src / flash / flash.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "flash.h"
25 #include "command.h"
26 #include "log.h"
27 #include "target.h"
28 #include "time_support.h"
29
30 #include <string.h>
31 #include <unistd.h>
32 #include <stdlib.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <errno.h>
36
37 /* command handlers */
38 int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
39 int handle_flash_banks_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
40 int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
41 int handle_flash_probe_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
42 int handle_flash_erase_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
43 int handle_flash_protect_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
44 int handle_flash_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
45 int handle_flash_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
46 int handle_flash_protect_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
47
48 /* flash drivers
49 */
50 extern flash_driver_t lpc2000_flash;
51 extern flash_driver_t cfi_flash;
52 extern flash_driver_t at91sam7_flash;
53 extern flash_driver_t str7x_flash;
54 extern flash_driver_t str9x_flash;
55
56 flash_driver_t *flash_drivers[] =
57 {
58 &lpc2000_flash,
59 &cfi_flash,
60 &at91sam7_flash,
61 &str7x_flash,
62 &str9x_flash,
63 NULL,
64 };
65
66 flash_bank_t *flash_banks;
67 static command_t *flash_cmd;
68
69 int flash_register_commands(struct command_context_s *cmd_ctx)
70 {
71 flash_cmd = register_command(cmd_ctx, NULL, "flash", NULL, COMMAND_ANY, NULL);
72
73 register_command(cmd_ctx, flash_cmd, "bank", handle_flash_bank_command, COMMAND_CONFIG, NULL);
74
75 return ERROR_OK;
76 }
77
78 int flash_init(struct command_context_s *cmd_ctx)
79 {
80 if (flash_banks)
81 {
82 register_command(cmd_ctx, flash_cmd, "banks", handle_flash_banks_command, COMMAND_EXEC,
83 "list configured flash banks ");
84 register_command(cmd_ctx, flash_cmd, "info", handle_flash_info_command, COMMAND_EXEC,
85 "print info about flash bank <num>");
86 register_command(cmd_ctx, flash_cmd, "probe", handle_flash_probe_command, COMMAND_EXEC,
87 "identify flash bank <num>");
88 register_command(cmd_ctx, flash_cmd, "erase_check", handle_flash_erase_check_command, COMMAND_EXEC,
89 "check erase state of sectors in flash bank <num>");
90 register_command(cmd_ctx, flash_cmd, "protect_check", handle_flash_protect_check_command, COMMAND_EXEC,
91 "check protection state of sectors in flash bank <num>");
92 register_command(cmd_ctx, flash_cmd, "erase", handle_flash_erase_command, COMMAND_EXEC,
93 "erase sectors at <bank> <first> <last>");
94 register_command(cmd_ctx, flash_cmd, "write", handle_flash_write_command, COMMAND_EXEC,
95 "write binary <bank> <file> <offset>");
96 register_command(cmd_ctx, flash_cmd, "protect", handle_flash_protect_command, COMMAND_EXEC,
97 "set protection of sectors at <bank> <first> <last> <on|off>");
98 }
99
100 return ERROR_OK;
101 }
102
103 flash_bank_t *get_flash_bank_by_num(int num)
104 {
105 flash_bank_t *p;
106 int i = 0;
107
108 for (p = flash_banks; p; p = p->next)
109 {
110 if (i++ == num)
111 {
112 return p;
113 }
114 }
115
116 return NULL;
117 }
118
119 /* flash_bank <driver> <base> <size> <chip_width> <bus_width> [driver_options ...]
120 */
121 int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
122 {
123 int i;
124 int found = 0;
125
126 if (argc < 5)
127 {
128 WARNING("incomplete flash_bank configuration");
129 return ERROR_OK;
130 }
131
132 for (i = 0; flash_drivers[i]; i++)
133 {
134 if (strcmp(args[0], flash_drivers[i]->name) == 0)
135 {
136 flash_bank_t *p, *c;
137
138 /* register flash specific commands */
139 if (flash_drivers[i]->register_commands(cmd_ctx) != ERROR_OK)
140 {
141 ERROR("couldn't register '%s' commands", args[0]);
142 exit(-1);
143 }
144
145 c = malloc(sizeof(flash_bank_t));
146 c->driver = flash_drivers[i];
147 c->driver_priv = NULL;
148 c->base = strtoul(args[1], NULL, 0);
149 c->size = strtoul(args[2], NULL, 0);
150 c->chip_width = strtoul(args[3], NULL, 0);
151 c->bus_width = strtoul(args[4], NULL, 0);
152 c->next = NULL;
153
154 if (flash_drivers[i]->flash_bank_command(cmd_ctx, cmd, args, argc, c) != ERROR_OK)
155 {
156 ERROR("'%s' driver rejected flash bank at 0x%8.8x", args[0], c->base);
157 free(c);
158 return ERROR_OK;
159 }
160
161 /* put flash bank in linked list */
162 if (flash_banks)
163 {
164 /* find last flash bank */
165 for (p = flash_banks; p && p->next; p = p->next);
166 if (p)
167 p->next = c;
168 }
169 else
170 {
171 flash_banks = c;
172 }
173
174 found = 1;
175 }
176 }
177
178 /* no matching flash driver found */
179 if (!found)
180 {
181 ERROR("flash driver '%s' not found", args[0]);
182 exit(-1);
183 }
184
185 return ERROR_OK;
186 }
187
188 int handle_flash_banks_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
189 {
190 flash_bank_t *p;
191 int i = 0;
192
193 if (!flash_banks)
194 {
195 command_print(cmd_ctx, "no flash banks configured");
196 return ERROR_OK;
197 }
198
199 for (p = flash_banks; p; p = p->next)
200 {
201 command_print(cmd_ctx, "#%i: %s at 0x%8.8x, size 0x%8.8x, buswidth %i, chipwidth %i",
202 i++, p->driver->name, p->base, p->size, p->bus_width, p->chip_width);
203 }
204
205 return ERROR_OK;
206 }
207
208 int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
209 {
210 flash_bank_t *p;
211 int i = 0;
212 int j = 0;
213
214 if (argc != 1)
215 {
216 command_print(cmd_ctx, "usage: flash info <num>");
217 return ERROR_OK;
218 }
219
220 for (p = flash_banks; p; p = p->next)
221 {
222 if (i++ == strtoul(args[0], NULL, 0))
223 {
224 char buf[1024];
225
226 command_print(cmd_ctx, "#%i: %s at 0x%8.8x, size 0x%8.8x, buswidth %i, chipwidth %i",
227 i, p->driver->name, p->base, p->size, p->bus_width, p->chip_width);
228 for (j = 0; j < p->num_sectors; j++)
229 {
230 char *erase_state, *protect_state;
231
232 if (p->sectors[j].is_erased == 0)
233 erase_state = "not erased";
234 else if (p->sectors[j].is_erased == 1)
235 erase_state = "erased";
236 else
237 erase_state = "erase state unknown";
238
239 if (p->sectors[j].is_protected == 0)
240 protect_state = "not protected";
241 else if (p->sectors[j].is_protected == 1)
242 protect_state = "protected";
243 else
244 protect_state = "protection state unknown";
245
246 command_print(cmd_ctx, "\t#%i: 0x%8.8x (0x%xkB) %s, %s",
247 j, p->sectors[j].offset, p->sectors[j].size,
248 erase_state, protect_state);
249 }
250
251 p->driver->info(p, buf, 1024);
252 command_print(cmd_ctx, "%s", buf);
253 }
254 }
255
256 return ERROR_OK;
257 }
258
259 int handle_flash_probe_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
260 {
261 flash_bank_t *p;
262 int retval;
263
264 if (argc != 1)
265 {
266 command_print(cmd_ctx, "usage: flash probe <num>");
267 return ERROR_OK;
268 }
269
270 p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
271 if (p)
272 {
273 if ((retval = p->driver->probe(p)) == ERROR_OK)
274 {
275 command_print(cmd_ctx, "flash '%s' found at 0x%8.8x", p->driver->name, p->base);
276 }
277 else if (retval == ERROR_FLASH_BANK_INVALID)
278 {
279 command_print(cmd_ctx, "probing failed for flash bank '#%s' at 0x%8.8x",
280 args[0], p->base);
281 }
282 else
283 {
284 command_print(cmd_ctx, "unknown error when probing flash bank '#%s' at 0x%8.8x",
285 args[0], p->base);
286 }
287 }
288 else
289 {
290 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
291 }
292
293 return ERROR_OK;
294 }
295
296 int handle_flash_erase_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
297 {
298 flash_bank_t *p;
299 int retval;
300
301 if (argc != 1)
302 {
303 command_print(cmd_ctx, "usage: flash erase_check <num>");
304 return ERROR_OK;
305 }
306
307 p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
308 if (p)
309 {
310 if ((retval = p->driver->erase_check(p)) == ERROR_OK)
311 {
312 command_print(cmd_ctx, "successfully checked erase state", p->driver->name, p->base);
313 }
314 else
315 {
316 command_print(cmd_ctx, "unknown error when checking erase state of flash bank #%s at 0x%8.8x",
317 args[0], p->base);
318 }
319 }
320 else
321 {
322 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
323 }
324
325 return ERROR_OK;
326 }
327
328 int handle_flash_protect_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
329 {
330 flash_bank_t *p;
331 int retval;
332
333 if (argc != 1)
334 {
335 command_print(cmd_ctx, "usage: flash protect_check <num>");
336 return ERROR_OK;
337 }
338
339 p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
340 if (p)
341 {
342 if ((retval = p->driver->protect_check(p)) == ERROR_OK)
343 {
344 command_print(cmd_ctx, "successfully checked protect state");
345 }
346 else if (retval == ERROR_FLASH_OPERATION_FAILED)
347 {
348 command_print(cmd_ctx, "checking protection state failed (possibly unsupported) by flash #%s at 0x%8.8x", args[0], p->base);
349 }
350 else
351 {
352 command_print(cmd_ctx, "unknown error when checking protection state of flash bank '#%s' at 0x%8.8x", args[0], p->base);
353 }
354 }
355 else
356 {
357 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
358 }
359
360 return ERROR_OK;
361 }
362
363 int handle_flash_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
364 {
365 if (argc > 2)
366 {
367 int first = strtoul(args[1], NULL, 0);
368 int last = strtoul(args[2], NULL, 0);
369 int retval;
370 flash_bank_t *p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
371 struct timeval start, end, duration;
372
373 gettimeofday(&start, NULL);
374
375 if (!p)
376 {
377 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
378 return ERROR_OK;
379 }
380
381 if ((retval = p->driver->erase(p, first, last)) != ERROR_OK)
382 {
383 switch (retval)
384 {
385 case ERROR_TARGET_NOT_HALTED:
386 command_print(cmd_ctx, "can't work with this flash while target is running");
387 break;
388 case ERROR_INVALID_ARGUMENTS:
389 command_print(cmd_ctx, "usage: flash_erase <bank> <first> <last>");
390 break;
391 case ERROR_FLASH_BANK_INVALID:
392 command_print(cmd_ctx, "no '%s' flash found at 0x%8.8x", p->driver->name, p->base);
393 break;
394 case ERROR_FLASH_OPERATION_FAILED:
395 command_print(cmd_ctx, "flash erase error");
396 break;
397 case ERROR_FLASH_SECTOR_INVALID:
398 command_print(cmd_ctx, "sector number(s) invalid");
399 break;
400 case ERROR_OK:
401 command_print(cmd_ctx, "erased flash sectors %i to %i", first, last);
402 break;
403 default:
404 command_print(cmd_ctx, "unknown error");
405 }
406 }
407 else
408 {
409 gettimeofday(&end, NULL);
410 timeval_subtract(&duration, &end, &start);
411
412 command_print(cmd_ctx, "erased sectors %i through %i on flash bank %i in %is %ius", first, last, strtoul(args[0], 0, 0), duration.tv_sec, duration.tv_usec);
413 }
414 }
415 else
416 {
417 command_print(cmd_ctx, "usage: flash erase <bank> <first> <last>");
418 }
419
420 return ERROR_OK;
421 }
422
423 int handle_flash_protect_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
424 {
425 if (argc > 3)
426 {
427 int first = strtoul(args[1], NULL, 0);
428 int last = strtoul(args[2], NULL, 0);
429 int set;
430 int retval;
431 flash_bank_t *p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
432 if (!p)
433 {
434 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
435 return ERROR_OK;
436 }
437
438 if (strcmp(args[3], "on") == 0)
439 set = 1;
440 else if (strcmp(args[3], "off") == 0)
441 set = 0;
442 else
443 {
444 command_print(cmd_ctx, "usage: flash protect <bank> <first> <last> <on|off>");
445 return ERROR_OK;
446 }
447
448 if ((retval = p->driver->protect(p, set, first, last)) != ERROR_OK)
449 {
450 switch (retval)
451 {
452 case ERROR_TARGET_NOT_HALTED:
453 command_print(cmd_ctx, "can't work with this flash while target is running");
454 break;
455 case ERROR_INVALID_ARGUMENTS:
456 command_print(cmd_ctx, "usage: flash protect <bank> <first> <last> <on|off>");
457 break;
458 case ERROR_FLASH_BANK_INVALID:
459 command_print(cmd_ctx, "no '%s' flash found at 0x%8.8x", p->driver->name, p->base);
460 break;
461 case ERROR_FLASH_OPERATION_FAILED:
462 command_print(cmd_ctx, "flash program error");
463 break;
464 case ERROR_FLASH_SECTOR_INVALID:
465 command_print(cmd_ctx, "sector number(s) invalid");
466 break;
467 case ERROR_OK:
468 command_print(cmd_ctx, "protection of flash sectors %i to %i turned %s", first, last, args[3]);
469 break;
470 default:
471 command_print(cmd_ctx, "unknown error");
472 }
473 }
474 else
475 {
476 command_print(cmd_ctx, "%s protection for sectors %i through %i on flash bank %i", (set) ? "set" : "cleared", first, last, strtoul(args[0], 0, 0));
477 }
478 }
479 else
480 {
481 command_print(cmd_ctx, "usage: flash protect <bank> <first> <last> <on|off>");
482 }
483
484 return ERROR_OK;
485 }
486
487 int handle_flash_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
488 {
489 FILE *binary;
490 u32 offset;
491 struct stat binary_stat;
492 u32 binary_size;
493 u8 *buffer;
494 u32 buf_cnt;
495 int retval;
496 flash_bank_t *p;
497 struct timeval start, end, duration;
498
499 gettimeofday(&start, NULL);
500
501 if (argc < 3)
502 {
503 command_print(cmd_ctx, "usage: flash write <bank> <file> <offset>");
504 return ERROR_OK;
505 }
506
507 offset = strtoul(args[2], NULL, 0);
508 p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
509 if (!p)
510 {
511 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
512 return ERROR_OK;
513 }
514
515 if (stat(args[1], &binary_stat) == -1)
516 {
517 ERROR("couldn't stat() %s: %s", args[1], strerror(errno));
518 return ERROR_OK;
519 }
520
521 if (S_ISDIR(binary_stat.st_mode))
522 {
523 ERROR("%s is a directory", args[1]);
524 command_print(cmd_ctx,"%s is a directory", args[1]);
525 return ERROR_OK;
526 }
527
528 if (binary_stat.st_size == 0){
529 ERROR("Empty file %s", args[1]);
530 command_print(cmd_ctx,"Empty file %s", args[1]);
531 return ERROR_OK;
532 }
533
534 if (!(binary = fopen(args[1], "rb")))
535 {
536 ERROR("couldn't open %s: %s", args[1], strerror(errno));
537 command_print(cmd_ctx, "couldn't open %s", args[1]);
538 return ERROR_OK;
539 }
540
541 binary_size = binary_stat.st_size;
542 buffer = malloc(binary_size);
543 buf_cnt = fread(buffer, 1, binary_size, binary);
544
545 if ((retval = p->driver->write(p, buffer, offset, buf_cnt)) != ERROR_OK)
546 {
547 command_print(cmd_ctx, "failed writing file %s to flash bank %i at offset 0x%8.8x",
548 args[1], strtoul(args[0], NULL, 0), strtoul(args[2], NULL, 0));
549 switch (retval)
550 {
551 case ERROR_TARGET_NOT_HALTED:
552 command_print(cmd_ctx, "can't work with this flash while target is running");
553 break;
554 case ERROR_INVALID_ARGUMENTS:
555 command_print(cmd_ctx, "usage: flash write <bank> <file> <offset>");
556 break;
557 case ERROR_FLASH_BANK_INVALID:
558 command_print(cmd_ctx, "no '%s' flash found at 0x%8.8x", p->driver->name, p->base);
559 break;
560 case ERROR_FLASH_OPERATION_FAILED:
561 command_print(cmd_ctx, "flash program error");
562 break;
563 case ERROR_FLASH_DST_BREAKS_ALIGNMENT:
564 command_print(cmd_ctx, "offset breaks required alignment");
565 break;
566 case ERROR_FLASH_DST_OUT_OF_BANK:
567 command_print(cmd_ctx, "destination is out of flash bank (offset and/or file too large)");
568 break;
569 case ERROR_FLASH_SECTOR_NOT_ERASED:
570 command_print(cmd_ctx, "destination sector(s) not erased");
571 break;
572 default:
573 command_print(cmd_ctx, "unknown error");
574 }
575 }
576 else
577 {
578 gettimeofday(&end, NULL);
579 timeval_subtract(&duration, &end, &start);
580
581 command_print(cmd_ctx, "wrote file %s to flash bank %i at offset 0x%8.8x in %is %ius", args[1], strtoul(args[0], NULL, 0), strtoul(args[2], NULL, 0), duration.tv_sec, duration.tv_usec);
582 }
583
584 free(buffer);
585 fclose(binary);
586
587 return ERROR_OK;
588 }

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)