- str9x flash support (Thanks to Spencer Oliver)
[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 }
475 else
476 {
477 command_print(cmd_ctx, "usage: flash protect <bank> <first> <last> <on|off>");
478 }
479
480 return ERROR_OK;
481 }
482
483 int handle_flash_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
484 {
485 FILE *binary;
486 u32 offset;
487 struct stat binary_stat;
488 u32 binary_size;
489 u8 *buffer;
490 u32 buf_cnt;
491 int retval;
492 flash_bank_t *p;
493 struct timeval start, end, duration;
494
495 gettimeofday(&start, NULL);
496
497 if (argc < 3)
498 {
499 command_print(cmd_ctx, "usage: flash write <bank> <file> <offset>");
500 return ERROR_OK;
501 }
502
503 offset = strtoul(args[2], NULL, 0);
504 p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
505 if (!p)
506 {
507 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
508 return ERROR_OK;
509 }
510
511 if (stat(args[1], &binary_stat) == -1)
512 {
513 ERROR("couldn't stat() %s: %s", args[1], strerror(errno));
514 return ERROR_OK;
515 }
516
517 if (S_ISDIR(binary_stat.st_mode))
518 {
519 ERROR("%s is a directory", args[1]);
520 command_print(cmd_ctx,"%s is a directory", args[1]);
521 return ERROR_OK;
522 }
523
524 if (binary_stat.st_size == 0){
525 ERROR("Empty file %s", args[1]);
526 command_print(cmd_ctx,"Empty file %s", args[1]);
527 return ERROR_OK;
528 }
529
530 if (!(binary = fopen(args[1], "rb")))
531 {
532 ERROR("couldn't open %s: %s", args[1], strerror(errno));
533 command_print(cmd_ctx, "couldn't open %s", args[1]);
534 return ERROR_OK;
535 }
536
537 binary_size = binary_stat.st_size;
538 buffer = malloc(binary_size);
539 buf_cnt = fread(buffer, 1, binary_size, binary);
540
541 if ((retval = p->driver->write(p, buffer, offset, buf_cnt)) != ERROR_OK)
542 {
543 command_print(cmd_ctx, "failed writing file %s to flash bank %i at offset 0x%8.8x",
544 args[1], strtoul(args[0], NULL, 0), strtoul(args[2], NULL, 0));
545 switch (retval)
546 {
547 case ERROR_TARGET_NOT_HALTED:
548 command_print(cmd_ctx, "can't work with this flash while target is running");
549 break;
550 case ERROR_INVALID_ARGUMENTS:
551 command_print(cmd_ctx, "usage: flash write <bank> <file> <offset>");
552 break;
553 case ERROR_FLASH_BANK_INVALID:
554 command_print(cmd_ctx, "no '%s' flash found at 0x%8.8x", p->driver->name, p->base);
555 break;
556 case ERROR_FLASH_OPERATION_FAILED:
557 command_print(cmd_ctx, "flash program error");
558 break;
559 case ERROR_FLASH_DST_BREAKS_ALIGNMENT:
560 command_print(cmd_ctx, "offset breaks required alignment");
561 break;
562 case ERROR_FLASH_DST_OUT_OF_BANK:
563 command_print(cmd_ctx, "destination is out of flash bank (offset and/or file too large)");
564 break;
565 case ERROR_FLASH_SECTOR_NOT_ERASED:
566 command_print(cmd_ctx, "destination sector(s) not erased");
567 break;
568 default:
569 command_print(cmd_ctx, "unknown error");
570 }
571 }
572 else
573 {
574 gettimeofday(&end, NULL);
575 timeval_subtract(&duration, &end, &start);
576
577 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);
578 }
579
580 free(buffer);
581 fclose(binary);
582
583 return ERROR_OK;
584 }

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)