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

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)