- "flash write_binary" is now "flash write_bank" to clarify the focus of the
[fw/openocd] / src / flash / flash.c
1 /***************************************************************************\r
2  *   Copyright (C) 2005 by Dominic Rath                                    *\r
3  *   Dominic.Rath@gmx.de                                                   *\r
4  *                                                                         *\r
5  *   This program is free software; you can redistribute it and/or modify  *\r
6  *   it under the terms of the GNU General Public License as published by  *\r
7  *   the Free Software Foundation; either version 2 of the License, or     *\r
8  *   (at your option) any later version.                                   *\r
9  *                                                                         *\r
10  *   This program is distributed in the hope that it will be useful,       *\r
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
13  *   GNU General Public License for more details.                          *\r
14  *                                                                         *\r
15  *   You should have received a copy of the GNU General Public License     *\r
16  *   along with this program; if not, write to the                         *\r
17  *   Free Software Foundation, Inc.,                                       *\r
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
19  ***************************************************************************/\r
20 #ifdef HAVE_CONFIG_H\r
21 #include "config.h"\r
22 #endif\r
23 \r
24 #include "flash.h"\r
25 #include "command.h"\r
26 #include "target.h"\r
27 #include "time_support.h"\r
28 #include "fileio.h"\r
29 #include "image.h"\r
30 #include "log.h"\r
31 \r
32 #include <string.h>\r
33 #include <unistd.h>\r
34 #include <stdlib.h>\r
35 #include <sys/types.h>\r
36 #include <sys/stat.h>\r
37 #include <errno.h>\r
38 #include <inttypes.h>\r
39 \r
40 /* command handlers */\r
41 int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
42 int handle_flash_banks_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
43 int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
44 int handle_flash_probe_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
45 int handle_flash_erase_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
46 int handle_flash_erase_address_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
47 int handle_flash_protect_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
48 int handle_flash_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
49 int handle_flash_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
50 int handle_flash_write_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
51 int handle_flash_write_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
52 int handle_flash_protect_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
53 int handle_flash_auto_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
54 flash_bank_t *get_flash_bank_by_addr(target_t *target, u32 addr);\r
55 \r
56 /* flash drivers\r
57  */\r
58 extern flash_driver_t lpc2000_flash;\r
59 extern flash_driver_t cfi_flash;\r
60 extern flash_driver_t at91sam7_flash;\r
61 extern flash_driver_t str7x_flash;\r
62 extern flash_driver_t str9x_flash;\r
63 extern flash_driver_t stellaris_flash;\r
64 extern flash_driver_t str9xpec_flash;\r
65 extern flash_driver_t stm32x_flash;\r
66 extern flash_driver_t tms470_flash;\r
67 \r
68 flash_driver_t *flash_drivers[] =\r
69 {\r
70         &lpc2000_flash,\r
71         &cfi_flash,\r
72         &at91sam7_flash,\r
73         &str7x_flash,\r
74         &str9x_flash,\r
75         &stellaris_flash,\r
76         &str9xpec_flash,\r
77         &stm32x_flash,\r
78         &tms470_flash,\r
79         NULL,\r
80 };\r
81 \r
82 flash_bank_t *flash_banks;\r
83 static  command_t *flash_cmd;\r
84 static int auto_erase = 0;\r
85 \r
86 /* wafer thin wrapper for invoking the flash driver */\r
87 static int flash_driver_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)\r
88 {\r
89         int retval=ERROR_OK;\r
90         if (bank->target->state != TARGET_HALTED)\r
91         {\r
92                 ERROR("target not halted - aborting flash write");\r
93                 retval=ERROR_TARGET_NOT_HALTED;\r
94         } else\r
95         {\r
96                 retval=bank->driver->write(bank, buffer, offset, count);\r
97         }\r
98         if (retval!=ERROR_OK)\r
99         {\r
100                 ERROR("Writing to flash bank at address 0x%08x at offset 0x%8.8x", bank->base, offset);\r
101         }\r
102         return retval;\r
103 }\r
104 \r
105 static int flash_driver_erase(struct flash_bank_s *bank, int first, int last)\r
106 {\r
107         int retval=ERROR_OK;\r
108         if (bank->target->state != TARGET_HALTED)\r
109         {\r
110                 ERROR("target not halted - aborting flash erase");\r
111                 retval=ERROR_TARGET_NOT_HALTED;\r
112         } else if ((first < 0) || (last < first) || (last >= bank->num_sectors))\r
113         {\r
114                 ERROR("invalid flash sector");\r
115                 retval=ERROR_FLASH_SECTOR_INVALID;\r
116         } else          \r
117         {\r
118                 retval=bank->driver->erase(bank, first, last);\r
119         }\r
120         if (retval!=ERROR_OK)\r
121         {\r
122                 ERROR("Failed erasing banks %d to %d", first, last);\r
123         }\r
124         return retval;\r
125 }\r
126 \r
127 int flash_driver_protect(struct flash_bank_s *bank, int set, int first, int last)\r
128 {\r
129         int retval;\r
130         if (bank->target->state != TARGET_HALTED)\r
131         {\r
132                 ERROR("target not halted - aborting flash erase");\r
133                 retval=ERROR_TARGET_NOT_HALTED;\r
134         } else if ((first < 0) || (last < first) || (last >= bank->num_sectors))\r
135         {\r
136                 ERROR("invalid flash sector");\r
137                 retval=ERROR_FLASH_SECTOR_INVALID;\r
138         } else          \r
139         {\r
140                 retval=bank->driver->protect(bank, set, first, last);\r
141         }\r
142         if (retval!=ERROR_OK)\r
143         {\r
144                 ERROR("Failed protecting banks %d to %d", first, last);\r
145         }\r
146         return retval;\r
147 }\r
148 \r
149 \r
150 int flash_register_commands(struct command_context_s *cmd_ctx)\r
151 {\r
152         flash_cmd = register_command(cmd_ctx, NULL, "flash", NULL, COMMAND_ANY, NULL);\r
153         \r
154         register_command(cmd_ctx, flash_cmd, "bank", handle_flash_bank_command, COMMAND_CONFIG, "flash_bank <driver> <base> <size> <chip_width> <bus_width> <target> [driver_options ...]");\r
155         register_command(cmd_ctx, flash_cmd, "auto_erase", handle_flash_auto_erase_command, COMMAND_ANY,\r
156                                                  "auto erase flash sectors <on|off>");\r
157         return ERROR_OK;\r
158 }\r
159 \r
160 int flash_init_drivers(struct command_context_s *cmd_ctx)\r
161 {\r
162         if (flash_banks)\r
163         {\r
164                 register_command(cmd_ctx, flash_cmd, "banks", handle_flash_banks_command, COMMAND_EXEC,\r
165                                                  "list configured flash banks ");\r
166                 register_command(cmd_ctx, flash_cmd, "info", handle_flash_info_command, COMMAND_EXEC,\r
167                                                  "print info about flash bank <num>");\r
168                 register_command(cmd_ctx, flash_cmd, "probe", handle_flash_probe_command, COMMAND_EXEC,\r
169                                                  "identify flash bank <num>");\r
170                 register_command(cmd_ctx, flash_cmd, "erase_check", handle_flash_erase_check_command, COMMAND_EXEC,\r
171                                                  "check erase state of sectors in flash bank <num>");\r
172                 register_command(cmd_ctx, flash_cmd, "protect_check", handle_flash_protect_check_command, COMMAND_EXEC,\r
173                                                  "check protection state of sectors in flash bank <num>");\r
174                 register_command(cmd_ctx, flash_cmd, "erase_sector", handle_flash_erase_command, COMMAND_EXEC,\r
175                                                  "erase sectors at <bank> <first> <last>");\r
176                 register_command(cmd_ctx, flash_cmd, "erase_address", handle_flash_erase_address_command, COMMAND_EXEC,\r
177                                                  "erase address range <address> <length>");\r
178                 register_command(cmd_ctx, flash_cmd, "write_bank", handle_flash_write_bank_command, COMMAND_EXEC,\r
179                                                  "write binary data to <bank> <file> <offset>");\r
180                 register_command(cmd_ctx, flash_cmd, "write_image", handle_flash_write_image_command, COMMAND_EXEC,\r
181                                                  "write_image <file> [offset] [type]");\r
182                 register_command(cmd_ctx, flash_cmd, "protect", handle_flash_protect_command, COMMAND_EXEC,\r
183                                                  "set protection of sectors at <bank> <first> <last> <on|off>");\r
184         }\r
185         \r
186         return ERROR_OK;\r
187 }\r
188 \r
189 flash_bank_t *get_flash_bank_by_num_noprobe(int num)\r
190 {\r
191         flash_bank_t *p;\r
192         int i = 0;\r
193 \r
194         for (p = flash_banks; p; p = p->next)\r
195         {\r
196                 if (i++ == num)\r
197                 {\r
198                         return p;\r
199                 }\r
200         }\r
201         ERROR("Flash bank %d does not exist", num);\r
202         return NULL;\r
203 }\r
204 \r
205 flash_bank_t *get_flash_bank_by_num(int num)\r
206 {\r
207         flash_bank_t *p = get_flash_bank_by_num_noprobe(num);\r
208         int retval;\r
209         \r
210         if (p == NULL)\r
211                 return NULL;\r
212         \r
213         retval = p->driver->auto_probe(p);\r
214         \r
215         if (retval != ERROR_OK)\r
216         {\r
217                 ERROR("auto_probe failed %d\n", retval);\r
218                 return NULL;\r
219         }\r
220         return p;\r
221 }\r
222 \r
223 int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
224 {\r
225         int i;\r
226         int found = 0;\r
227         target_t *target;\r
228                 \r
229         if (argc < 6)\r
230         {\r
231                 return ERROR_COMMAND_SYNTAX_ERROR;\r
232         }\r
233         \r
234         if ((target = get_target_by_num(strtoul(args[5], NULL, 0))) == NULL)\r
235         {\r
236                 ERROR("target %lu not defined", strtoul(args[5], NULL, 0));\r
237                 return ERROR_OK;\r
238         }\r
239         \r
240         for (i = 0; flash_drivers[i]; i++)\r
241         {\r
242                 if (strcmp(args[0], flash_drivers[i]->name) == 0)\r
243                 {\r
244                         flash_bank_t *p, *c;\r
245                         \r
246                         /* register flash specific commands */\r
247                         if (flash_drivers[i]->register_commands(cmd_ctx) != ERROR_OK)\r
248                         {\r
249                                 ERROR("couldn't register '%s' commands", args[0]);\r
250                                 exit(-1);\r
251                         }\r
252                         \r
253                         c = malloc(sizeof(flash_bank_t));\r
254                         c->target = target;\r
255                         c->driver = flash_drivers[i];\r
256                         c->driver_priv = NULL;\r
257                         c->base = strtoul(args[1], NULL, 0);\r
258                         c->size = strtoul(args[2], NULL, 0);\r
259                         c->chip_width = strtoul(args[3], NULL, 0);\r
260                         c->bus_width = strtoul(args[4], NULL, 0);\r
261                         c->num_sectors = 0;\r
262                         c->sectors = NULL;\r
263                         c->next = NULL;\r
264                         \r
265                         if (flash_drivers[i]->flash_bank_command(cmd_ctx, cmd, args, argc, c) != ERROR_OK)\r
266                         {\r
267                                 ERROR("'%s' driver rejected flash bank at 0x%8.8x", args[0], c->base);\r
268                                 free(c);\r
269                                 return ERROR_OK;\r
270                         }\r
271                         \r
272                         /* put flash bank in linked list */\r
273                         if (flash_banks)\r
274                         {\r
275                                 /* find last flash bank */\r
276                                 for (p = flash_banks; p && p->next; p = p->next);\r
277                                 if (p)\r
278                                         p->next = c;\r
279                         }\r
280                         else\r
281                         {\r
282                                 flash_banks = c;\r
283                         }\r
284                         \r
285                         found = 1;\r
286                 }\r
287         }\r
288                 \r
289         /* no matching flash driver found */\r
290         if (!found)\r
291         {\r
292                 ERROR("flash driver '%s' not found", args[0]);\r
293                 exit(-1);\r
294         }\r
295         \r
296         return ERROR_OK;\r
297 }\r
298 \r
299 int handle_flash_banks_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
300 {\r
301         flash_bank_t *p;\r
302         int i = 0;\r
303         \r
304         if (!flash_banks)\r
305         {\r
306                 command_print(cmd_ctx, "no flash banks configured");\r
307                 return ERROR_OK;\r
308         }\r
309         \r
310         for (p = flash_banks; p; p = p->next)\r
311         {\r
312                 command_print(cmd_ctx, "#%i: %s at 0x%8.8x, size 0x%8.8x, buswidth %i, chipwidth %i",\r
313                                           i++, p->driver->name, p->base, p->size, p->bus_width, p->chip_width);\r
314         }\r
315         \r
316         return ERROR_OK;\r
317 }\r
318 \r
319 int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
320 {\r
321         flash_bank_t *p;\r
322         int i = 0;\r
323         int j = 0;\r
324                 \r
325         if (argc != 1)\r
326         {\r
327                 return ERROR_COMMAND_SYNTAX_ERROR;\r
328         }\r
329         \r
330         for (p = flash_banks; p; p = p->next, i++)\r
331         {\r
332                 if (i == strtoul(args[0], NULL, 0))\r
333                 {\r
334                         char buf[1024];\r
335                         \r
336                         /* attempt auto probe */\r
337                         p->driver->auto_probe(p);\r
338                         \r
339                         command_print(cmd_ctx, "#%i: %s at 0x%8.8x, size 0x%8.8x, buswidth %i, chipwidth %i",\r
340                                                 i, p->driver->name, p->base, p->size, p->bus_width, p->chip_width);\r
341                         for (j = 0; j < p->num_sectors; j++)\r
342                         {\r
343                                 char *erase_state, *protect_state;\r
344                                 \r
345                                 if (p->sectors[j].is_erased == 0)\r
346                                         erase_state = "not erased";\r
347                                 else if (p->sectors[j].is_erased == 1)\r
348                                         erase_state = "erased";\r
349                                 else\r
350                                         erase_state = "erase state unknown";\r
351                                 \r
352                                 if (p->sectors[j].is_protected == 0)\r
353                                         protect_state = "not protected";\r
354                                 else if (p->sectors[j].is_protected == 1)\r
355                                         protect_state = "protected";\r
356                                 else\r
357                                         protect_state = "protection state unknown";\r
358 \r
359                                 command_print(cmd_ctx, "\t#%i: 0x%8.8x (0x%x %ikB) %s, %s",\r
360                                                         j, p->sectors[j].offset, p->sectors[j].size, p->sectors[j].size>>10,\r
361                                                         erase_state, protect_state);\r
362                         }\r
363                         \r
364                         p->driver->info(p, buf, 1024);\r
365                         command_print(cmd_ctx, "%s", buf);\r
366                 }\r
367         }\r
368         \r
369         return ERROR_OK;\r
370 }\r
371 \r
372 int handle_flash_probe_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
373 {\r
374         flash_bank_t *p;\r
375         int retval;\r
376                 \r
377         if (argc != 1)\r
378         {\r
379                 return ERROR_COMMAND_SYNTAX_ERROR;\r
380         }\r
381         \r
382         p = get_flash_bank_by_num_noprobe(strtoul(args[0], NULL, 0));\r
383         if (p)\r
384         {\r
385                 if ((retval = p->driver->probe(p)) == ERROR_OK)\r
386                 {\r
387                         command_print(cmd_ctx, "flash '%s' found at 0x%8.8x", p->driver->name, p->base);\r
388                 }\r
389                 else if (retval == ERROR_FLASH_BANK_INVALID)\r
390                 {\r
391                         command_print(cmd_ctx, "probing failed for flash bank '#%s' at 0x%8.8x",\r
392                                                   args[0], p->base);\r
393                 }\r
394                 else\r
395                 {\r
396                         command_print(cmd_ctx, "unknown error when probing flash bank '#%s' at 0x%8.8x",\r
397                                                   args[0], p->base);\r
398                 }\r
399         }\r
400         else\r
401         {\r
402                 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);\r
403         }\r
404         \r
405         return ERROR_OK;\r
406 }\r
407 \r
408 int handle_flash_erase_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
409 {\r
410         flash_bank_t *p;\r
411         int retval;\r
412                 \r
413         if (argc != 1)\r
414         {\r
415                 return ERROR_COMMAND_SYNTAX_ERROR;\r
416         }\r
417         \r
418         p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));\r
419         if (p)\r
420         {\r
421                 if ((retval = p->driver->erase_check(p)) == ERROR_OK)\r
422                 {\r
423                         command_print(cmd_ctx, "successfully checked erase state", p->driver->name, p->base);\r
424                 }\r
425                 else\r
426                 {\r
427                         command_print(cmd_ctx, "unknown error when checking erase state of flash bank #%s at 0x%8.8x",\r
428                                 args[0], p->base);\r
429                 }\r
430         }\r
431         \r
432         return ERROR_OK;\r
433 }\r
434 \r
435 int handle_flash_erase_address_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
436 {\r
437         flash_bank_t *p;\r
438         int retval;\r
439         int address;\r
440         int length;\r
441         duration_t duration;\r
442         char *duration_text;\r
443         \r
444         target_t *target = get_current_target(cmd_ctx);\r
445 \r
446         if (argc != 2)\r
447         {\r
448                 return ERROR_COMMAND_SYNTAX_ERROR;\r
449         }\r
450         \r
451         address = strtoul(args[0], NULL, 0);\r
452         length = strtoul(args[1], NULL, 0);\r
453         if (length <= 0)\r
454         {\r
455                 command_print(cmd_ctx, "Length must be >0");\r
456                 return ERROR_COMMAND_SYNTAX_ERROR;\r
457         }\r
458 \r
459         p = get_flash_bank_by_addr(target, address);\r
460         if (p == NULL)\r
461         {\r
462                 return ERROR_COMMAND_SYNTAX_ERROR;\r
463         }\r
464         \r
465         /* We can't know if we did a resume + halt, in which case we no longer know the erased state */\r
466         flash_set_dirty();\r
467         \r
468         duration_start_measure(&duration);\r
469         \r
470         if ((retval = flash_erase_address_range(target, address, length)) == ERROR_OK)\r
471         {\r
472                 duration_stop_measure(&duration, &duration_text);       \r
473                 command_print(cmd_ctx, "erased address 0x%8.8x length %i in %s", address, length, duration_text);\r
474                 free(duration_text);\r
475         }\r
476         \r
477         return retval;\r
478 }\r
479 \r
480 int handle_flash_protect_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
481 {\r
482         flash_bank_t *p;\r
483         int retval;\r
484                 \r
485         if (argc != 1)\r
486         {\r
487                 return ERROR_COMMAND_SYNTAX_ERROR;\r
488         }\r
489         \r
490         p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));\r
491         if (p)\r
492         {\r
493                 if ((retval = p->driver->protect_check(p)) == ERROR_OK)\r
494                 {\r
495                         command_print(cmd_ctx, "successfully checked protect state");\r
496                 }\r
497                 else if (retval == ERROR_FLASH_OPERATION_FAILED)\r
498                 {\r
499                         command_print(cmd_ctx, "checking protection state failed (possibly unsupported) by flash #%s at 0x%8.8x", args[0], p->base);\r
500                 }\r
501                 else\r
502                 {\r
503                         command_print(cmd_ctx, "unknown error when checking protection state of flash bank '#%s' at 0x%8.8x", args[0], p->base);\r
504                 }\r
505         }\r
506         else\r
507         {\r
508                 return ERROR_COMMAND_SYNTAX_ERROR;\r
509         }\r
510         \r
511         return ERROR_OK;\r
512 }\r
513 \r
514 int handle_flash_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
515 {\r
516         if (argc > 2)\r
517         {\r
518                 int first = strtoul(args[1], NULL, 0);\r
519                 int last = strtoul(args[2], NULL, 0);\r
520                 int retval;\r
521                 flash_bank_t *p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));\r
522                 duration_t duration;\r
523                 char *duration_text;\r
524         \r
525                 duration_start_measure(&duration);\r
526         \r
527                 if (!p)\r
528                 {\r
529                         return ERROR_COMMAND_SYNTAX_ERROR;\r
530                 }\r
531                 \r
532                 if ((retval = flash_driver_erase(p, first, last)) == ERROR_OK)\r
533                 {\r
534                         duration_stop_measure(&duration, &duration_text);       \r
535                         \r
536                         command_print(cmd_ctx, "erased sectors %i through %i on flash bank %i in %s", first, last, strtoul(args[0], 0, 0), duration_text);\r
537                         free(duration_text);\r
538                 }\r
539         }\r
540         else\r
541         {\r
542                 return ERROR_COMMAND_SYNTAX_ERROR;\r
543         }\r
544 \r
545         return ERROR_OK;\r
546 }\r
547 \r
548 int handle_flash_protect_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
549 {\r
550         if (argc > 3)\r
551         {\r
552                 int first = strtoul(args[1], NULL, 0);\r
553                 int last = strtoul(args[2], NULL, 0);\r
554                 int set;\r
555                 int retval;\r
556                 flash_bank_t *p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));\r
557                 if (!p)\r
558                 {\r
559                         command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);\r
560                         return ERROR_OK;\r
561                 }\r
562                 \r
563                 if (strcmp(args[3], "on") == 0)\r
564                         set = 1;\r
565                 else if (strcmp(args[3], "off") == 0)\r
566                         set = 0;\r
567                 else\r
568                 {\r
569                         return ERROR_COMMAND_SYNTAX_ERROR;\r
570                 }\r
571                 \r
572                 retval = flash_driver_protect(p, set, first, last);\r
573                 if (retval == ERROR_OK)\r
574                 {\r
575                         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));\r
576                 }\r
577         }\r
578         else\r
579         {\r
580                 return ERROR_COMMAND_SYNTAX_ERROR;\r
581 \r
582         }\r
583 \r
584         return ERROR_OK;\r
585 }\r
586 \r
587 int handle_flash_write_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
588 {\r
589         target_t *target = get_current_target(cmd_ctx);\r
590         \r
591         image_t image;\r
592         u32 written;\r
593         \r
594         duration_t duration;\r
595         char *duration_text;\r
596         \r
597         int retval;\r
598 \r
599         if (argc < 1)\r
600         {\r
601                 return ERROR_COMMAND_SYNTAX_ERROR;\r
602 \r
603         }\r
604         \r
605         if (!target)\r
606         {\r
607                 ERROR("no target selected");\r
608                 return ERROR_OK;\r
609         }\r
610         \r
611         duration_start_measure(&duration);\r
612         \r
613         if (argc >= 2)\r
614         {\r
615                 image.base_address_set = 1;\r
616                 image.base_address = strtoul(args[1], NULL, 0);\r
617         }\r
618         else\r
619         {\r
620                 image.base_address_set = 0;\r
621                 image.base_address = 0x0;\r
622         }\r
623         \r
624         image.start_address_set = 0;\r
625 \r
626         retval = image_open(&image, args[0], (argc == 3) ? args[2] : NULL);\r
627         if (retval != ERROR_OK)\r
628         {\r
629                 command_print(cmd_ctx, "image_open error: %s", image.error_str);\r
630                 return retval;\r
631         }\r
632         \r
633         retval = flash_write(target, &image, &written, auto_erase);\r
634 \r
635         if (retval != ERROR_OK)\r
636         {\r
637                 image_close(&image);\r
638                 return retval;\r
639         }\r
640         \r
641         duration_stop_measure(&duration, &duration_text);\r
642         if (retval == ERROR_OK)\r
643         {\r
644         command_print(cmd_ctx, "wrote %u byte from file %s in %s (%f kb/s)",\r
645                 written, args[0], duration_text,\r
646                 (float)written / 1024.0 / ((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0)));\r
647         }\r
648         free(duration_text);\r
649 \r
650         image_close(&image);\r
651         \r
652         return retval;\r
653 }\r
654 \r
655 int handle_flash_write_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
656 {\r
657         u32 offset;\r
658         u8 *buffer;\r
659         u32 buf_cnt;\r
660 \r
661         fileio_t fileio;\r
662         \r
663         duration_t duration;\r
664         char *duration_text;\r
665         \r
666         int retval;\r
667         flash_bank_t *p;\r
668 \r
669         if (argc != 3)\r
670         {\r
671                 return ERROR_COMMAND_SYNTAX_ERROR;\r
672         }\r
673         \r
674         duration_start_measure(&duration);\r
675         \r
676         offset = strtoul(args[2], NULL, 0);\r
677         p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));\r
678         if (!p)\r
679         {\r
680                 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);\r
681                 return ERROR_OK;\r
682         }\r
683         \r
684         if (fileio_open(&fileio, args[1], FILEIO_READ, FILEIO_BINARY) != ERROR_OK)\r
685         {\r
686                 command_print(cmd_ctx, "flash write_binary error: %s", fileio.error_str);\r
687                 return ERROR_OK;\r
688         }\r
689         \r
690         buffer = malloc(fileio.size);\r
691         if (fileio_read(&fileio, fileio.size, buffer, &buf_cnt) != ERROR_OK)\r
692         {\r
693                 command_print(cmd_ctx, "flash write_binary error: %s", fileio.error_str);\r
694                 return ERROR_OK;\r
695         }\r
696         \r
697         retval = flash_driver_write(p, buffer, offset, buf_cnt);\r
698                 \r
699         free(buffer);\r
700         \r
701         duration_stop_measure(&duration, &duration_text);\r
702         if (retval!=ERROR_OK)\r
703         {\r
704         command_print(cmd_ctx, "wrote  %"PRIi64" byte from file %s to flash bank %i at offset 0x%8.8x in %s (%f kb/s)",\r
705                 fileio.size, args[1], strtoul(args[0], NULL, 0), offset, duration_text,\r
706                 (float)fileio.size / 1024.0 / ((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0)));\r
707         }\r
708         free(duration_text);\r
709 \r
710         fileio_close(&fileio);\r
711         \r
712         return retval;\r
713 }\r
714 \r
715 void flash_set_dirty(void)\r
716 {\r
717         flash_bank_t *c;\r
718         int i;\r
719         \r
720         /* set all flash to require erasing */\r
721         for (c = flash_banks; c; c = c->next)\r
722         {\r
723                 for (i = 0; i < c->num_sectors; i++)\r
724                 {\r
725                         c->sectors[i].is_erased = 0; \r
726                 }\r
727         }\r
728 }\r
729 \r
730 /* lookup flash bank by address */\r
731 flash_bank_t *get_flash_bank_by_addr(target_t *target, u32 addr)\r
732 {\r
733         flash_bank_t *c;\r
734 \r
735         /* cycle through bank list */\r
736         for (c = flash_banks; c; c = c->next)\r
737         {\r
738                 int retval;\r
739                 retval = c->driver->auto_probe(c);\r
740                 \r
741                 if (retval != ERROR_OK)\r
742                 {\r
743                         ERROR("auto_probe failed %d\n", retval);\r
744                         return NULL;\r
745                 }\r
746                 /* check whether address belongs to this flash bank */\r
747                 if ((addr >= c->base) && (addr < c->base + c->size) && target == c->target)\r
748                         return c;\r
749         }\r
750         ERROR("No flash at address 0x%08x\n", addr);\r
751         return NULL;\r
752 }\r
753 \r
754 /* erase given flash region, selects proper bank according to target and address */\r
755 int flash_erase_address_range(target_t *target, u32 addr, u32 length)\r
756 {\r
757         flash_bank_t *c;\r
758         int first = -1;\r
759         int last = -1;\r
760         int i;\r
761         \r
762         if ((c = get_flash_bank_by_addr(target, addr)) == NULL)\r
763                 return ERROR_FLASH_DST_OUT_OF_BANK; /* no corresponding bank found */\r
764 \r
765         if (c->size == 0 || c->num_sectors == 0)\r
766                 return ERROR_FLASH_BANK_INVALID;\r
767         \r
768         if (length == 0)\r
769         {\r
770                 /* special case, erase whole bank when length is zero */\r
771                 if (addr != c->base)\r
772                         return ERROR_FLASH_DST_BREAKS_ALIGNMENT;\r
773                 \r
774                 return flash_driver_erase(c, 0, c->num_sectors - 1);\r
775         }\r
776 \r
777         /* check whether it fits */\r
778         if (addr + length > c->base + c->size)\r
779                 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;\r
780         \r
781         addr -= c->base;\r
782         \r
783         for (i = 0; i < c->num_sectors; i++)\r
784         {               \r
785                 /* check whether sector overlaps with the given range and is not yet erased */\r
786                 if (addr < c->sectors[i].offset + c->sectors[i].size && addr + length > c->sectors[i].offset && c->sectors[i].is_erased != 1) {\r
787                         /* if first is not set yet then this is the first sector */\r
788                         if (first == -1)\r
789                                 first = i;\r
790                         last = i; /* and it is the last one so far in any case */\r
791                 }\r
792         }\r
793         \r
794         if( first == -1 || last == -1 )\r
795                 return ERROR_OK;\r
796         \r
797         return flash_driver_erase(c, first, last);\r
798 }\r
799 \r
800 /* write (optional verify) an image to flash memory of the given target */\r
801 int flash_write(target_t *target, image_t *image, u32 *written, int erase)\r
802 {\r
803         int retval;\r
804 \r
805         int section;\r
806         u32 section_offset;\r
807         flash_bank_t *c;\r
808         \r
809         section = 0;\r
810         section_offset = 0;\r
811 \r
812         if (written)\r
813                 *written = 0;\r
814         \r
815         if (erase)\r
816         {\r
817                 /* assume all sectors need erasing - stops any problems\r
818                  * when flash_write is called multiple times */\r
819                 \r
820                 flash_set_dirty();\r
821         }\r
822         \r
823         /* loop until we reach end of the image */\r
824         while (section < image->num_sections)\r
825         {\r
826                 u32 buffer_size;\r
827                 u8 *buffer;\r
828                 int section_first;\r
829                 int section_last;\r
830                 u32 run_address = image->sections[section].base_address + section_offset;\r
831                 u32 run_size = image->sections[section].size - section_offset;\r
832 \r
833                 if (image->sections[section].size ==  0)\r
834                 {\r
835                         WARNING("empty section %d", section);\r
836                         section++;\r
837                         section_offset = 0;\r
838                         continue;\r
839                 }\r
840 \r
841                 /* find the corresponding flash bank */\r
842                 if ((c = get_flash_bank_by_addr(target, run_address)) == NULL)\r
843                 {\r
844                         section++; /* and skip it */\r
845                         section_offset = 0;\r
846                         continue;\r
847                 }\r
848 \r
849                 /* collect consecutive sections which fall into the same bank */\r
850                 section_first = section;\r
851                 section_last = section;\r
852                 while ((run_address + run_size < c->base + c->size)\r
853                                 && (section_last + 1 < image->num_sections))\r
854                 {\r
855                         if (image->sections[section_last + 1].base_address < (run_address + run_size))\r
856                         {\r
857                                 DEBUG("section %d out of order(very slightly surprising, but supported)", section_last + 1);\r
858                                 break;\r
859                         }\r
860                         if (image->sections[section_last + 1].base_address != (run_address + run_size))\r
861                                 break;\r
862                         run_size += image->sections[++section_last].size;\r
863                 }\r
864 \r
865                 /* fit the run into bank constraints */\r
866                 if (run_address + run_size > c->base + c->size)\r
867                         run_size = c->base + c->size - run_address;\r
868 \r
869                 /* allocate buffer */\r
870                 buffer = malloc(run_size);\r
871                 buffer_size = 0;\r
872 \r
873                 /* read sections to the buffer */\r
874                 while (buffer_size < run_size)\r
875                 {\r
876                         u32 size_read;\r
877                         \r
878                         if (buffer_size - run_size <= image->sections[section].size - section_offset)\r
879                                 size_read = buffer_size - run_size;\r
880                         else\r
881                                 size_read = image->sections[section].size - section_offset;\r
882                         \r
883                         if ((retval = image_read_section(image, section, section_offset,\r
884                                         size_read, buffer + buffer_size, &size_read)) != ERROR_OK || size_read == 0)\r
885                         {\r
886                                 free(buffer);\r
887                                 \r
888                                 return retval;\r
889                         }\r
890 \r
891                         buffer_size += size_read;\r
892                         section_offset += size_read;\r
893 \r
894                         if (section_offset >= image->sections[section].size)\r
895                         {\r
896                                 section++;\r
897                                 section_offset = 0;\r
898                         }\r
899                 }\r
900 \r
901                 retval = ERROR_OK;\r
902                 \r
903                 if (erase)\r
904                 {\r
905                         /* calculate and erase sectors */\r
906                         retval = flash_erase_address_range( target, run_address, run_size );\r
907                 }\r
908                 \r
909                 if (retval == ERROR_OK)\r
910                 {\r
911                         /* write flash sectors */\r
912                         retval = flash_driver_write(c, buffer, run_address - c->base, run_size);\r
913                 }\r
914                 \r
915                 free(buffer);\r
916 \r
917                 if (retval != ERROR_OK)\r
918                 {\r
919                                 return retval; /* abort operation */\r
920                         }\r
921 \r
922                 if (written != NULL)\r
923                         *written += run_size; /* add run size to total written counter */\r
924         }\r
925 \r
926         return ERROR_OK;\r
927 }\r
928 \r
929 int handle_flash_auto_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
930 {\r
931         if (argc != 1)\r
932         {\r
933                 return ERROR_COMMAND_SYNTAX_ERROR;\r
934 \r
935         }\r
936         \r
937         if (strcmp(args[0], "on") == 0)\r
938                 auto_erase = 1;\r
939         else if (strcmp(args[0], "off") == 0)\r
940                 auto_erase = 0;\r
941         else \r
942                 return ERROR_COMMAND_SYNTAX_ERROR;\r
943         \r
944         return ERROR_OK;\r
945 }\r