]>
git.ipfire.org Git - u-boot.git/blob - common/cmd_flash.c
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 * See file CREDITS for list of people who contributed to this
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
31 #ifdef CONFIG_HAS_DATAFLASH
32 #include <dataflash.h>
35 #if (CONFIG_COMMANDS & CFG_CMD_FLASH)
37 extern flash_info_t flash_info
[]; /* info for FLASH chips */
40 * The user interface starts numbering for Flash banks with 1
41 * for historical reasons.
45 * this routine looks for an abbreviated flash range specification.
46 * the syntax is B:SF[-SL], where B is the bank number, SF is the first
47 * sector to erase, and SL is the last sector to erase (defaults to SF).
48 * bank numbers start at 1 to be consistent with other specs, sector numbers
51 * returns: 1 - correct spec; *pinfo, *psf and *psl are
53 * 0 - doesn't look like an abbreviated spec
54 * -1 - looks like an abbreviated spec, but got
55 * a parsing error, a number out of range,
56 * or an invalid flash bank.
59 abbrev_spec(char *str
, flash_info_t
**pinfo
, int *psf
, int *psl
)
62 int bank
, first
, last
;
65 if ((p
= strchr(str
, ':')) == NULL
)
69 bank
= simple_strtoul(str
, &ep
, 10);
70 if (ep
== str
|| *ep
!= '\0' ||
71 bank
< 1 || bank
> CFG_MAX_FLASH_BANKS
||
72 (fp
= &flash_info
[bank
- 1])->flash_id
== FLASH_UNKNOWN
)
76 if ((p
= strchr(str
, '-')) != NULL
)
79 first
= simple_strtoul(str
, &ep
, 10);
80 if (ep
== str
|| *ep
!= '\0' || first
>= fp
->sector_count
)
84 last
= simple_strtoul(p
, &ep
, 10);
85 if (ep
== p
|| *ep
!= '\0' ||
86 last
< first
|| last
>= fp
->sector_count
)
98 int do_flinfo ( cmd_tbl_t
*cmdtp
, int flag
, int argc
, char *argv
[])
102 #ifdef CONFIG_HAS_DATAFLASH
103 dataflash_print_info();
106 if (argc
== 1) { /* print info for all FLASH banks */
107 for (bank
=0; bank
<CFG_MAX_FLASH_BANKS
; ++bank
) {
108 printf ("\nBank # %ld: ", bank
+1);
110 flash_print_info (&flash_info
[bank
]);
115 bank
= simple_strtoul(argv
[1], NULL
, 16);
116 if ((bank
< 1) || (bank
> CFG_MAX_FLASH_BANKS
)) {
117 printf ("Only FLASH Banks # 1 ... # %d supported\n",
118 CFG_MAX_FLASH_BANKS
);
121 printf ("\nBank # %ld: ", bank
);
122 flash_print_info (&flash_info
[bank
-1]);
125 int do_flerase (cmd_tbl_t
*cmdtp
, int flag
, int argc
, char *argv
[])
128 ulong bank
, addr_first
, addr_last
;
129 int n
, sect_first
, sect_last
;
133 printf ("Usage:\n%s\n", cmdtp
->usage
);
137 if (strcmp(argv
[1], "all") == 0) {
138 for (bank
=1; bank
<=CFG_MAX_FLASH_BANKS
; ++bank
) {
139 printf ("Erase Flash Bank # %ld ", bank
);
140 info
= &flash_info
[bank
-1];
141 rcode
= flash_erase (info
, 0, info
->sector_count
-1);
146 if ((n
= abbrev_spec(argv
[1], &info
, §_first
, §_last
)) != 0) {
148 printf("Bad sector specification\n");
151 printf ("Erase Flash Sectors %d-%d in Bank # %d ",
152 sect_first
, sect_last
, (info
-flash_info
)+1);
153 rcode
= flash_erase(info
, sect_first
, sect_last
);
158 printf ("Usage:\n%s\n", cmdtp
->usage
);
162 if (strcmp(argv
[1], "bank") == 0) {
163 bank
= simple_strtoul(argv
[2], NULL
, 16);
164 if ((bank
< 1) || (bank
> CFG_MAX_FLASH_BANKS
)) {
165 printf ("Only FLASH Banks # 1 ... # %d supported\n",
166 CFG_MAX_FLASH_BANKS
);
169 printf ("Erase Flash Bank # %ld ", bank
);
170 info
= &flash_info
[bank
-1];
171 rcode
= flash_erase (info
, 0, info
->sector_count
-1);
175 addr_first
= simple_strtoul(argv
[1], NULL
, 16);
176 addr_last
= simple_strtoul(argv
[2], NULL
, 16);
178 if (addr_first
>= addr_last
) {
179 printf ("Usage:\n%s\n", cmdtp
->usage
);
183 printf ("Erase Flash from 0x%08lx to 0x%08lx ", addr_first
, addr_last
);
184 rcode
= flash_sect_erase(addr_first
, addr_last
);
188 int flash_sect_erase (ulong addr_first
, ulong addr_last
)
198 for (bank
=0,info
=&flash_info
[0]; bank
< CFG_MAX_FLASH_BANKS
; ++bank
, ++info
) {
202 if (info
->flash_id
== FLASH_UNKNOWN
) {
206 b_end
= info
->start
[0] + info
->size
- 1; /* bank end addr */
208 s_first
= -1; /* first sector to erase */
209 s_last
= -1; /* last sector to erase */
211 for (sect
=0; sect
< info
->sector_count
; ++sect
) {
212 ulong end
; /* last address in current sect */
215 s_end
= info
->sector_count
- 1;
217 end
= (sect
== s_end
) ? b_end
: info
->start
[sect
+ 1] - 1;
219 if (addr_first
> end
)
221 if (addr_last
< info
->start
[sect
])
224 if (addr_first
== info
->start
[sect
]) {
227 if (addr_last
== end
) {
231 if (s_first
>=0 && s_first
<=s_last
) {
232 erased
+= s_last
- s_first
+ 1;
233 rcode
= flash_erase (info
, s_first
, s_last
);
237 printf ("Erased %d sectors\n", erased
);
239 printf ("Error: start and/or end address"
240 " not on sector boundary\n");
247 int do_protect (cmd_tbl_t
*cmdtp
, int flag
, int argc
, char *argv
[])
250 ulong bank
, addr_first
, addr_last
;
251 int i
, p
, n
, sect_first
, sect_last
;
255 printf ("Usage:\n%s\n", cmdtp
->usage
);
259 if (strcmp(argv
[1], "off") == 0)
261 else if (strcmp(argv
[1], "on") == 0)
264 printf ("Usage:\n%s\n", cmdtp
->usage
);
268 if (strcmp(argv
[2], "all") == 0) {
269 for (bank
=1; bank
<=CFG_MAX_FLASH_BANKS
; ++bank
) {
270 info
= &flash_info
[bank
-1];
271 if (info
->flash_id
== FLASH_UNKNOWN
) {
274 printf ("%sProtect Flash Bank # %ld\n",
275 p
? "" : "Un-", bank
);
277 for (i
=0; i
<info
->sector_count
; ++i
) {
278 #if defined(CFG_FLASH_PROTECTION)
279 if (flash_real_protect(info
, i
, p
))
283 info
->protect
[i
] = p
;
284 #endif /* CFG_FLASH_PROTECTION */
288 #if defined(CFG_FLASH_PROTECTION)
289 if (!rcode
) puts (" done\n");
290 #endif /* CFG_FLASH_PROTECTION */
295 if ((n
= abbrev_spec(argv
[2], &info
, §_first
, §_last
)) != 0) {
297 printf("Bad sector specification\n");
300 printf("%sProtect Flash Sectors %d-%d in Bank # %d\n",
301 p
? "" : "Un-", sect_first
, sect_last
,
302 (info
-flash_info
)+1);
303 for (i
= sect_first
; i
<= sect_last
; i
++) {
304 #if defined(CFG_FLASH_PROTECTION)
305 if (flash_real_protect(info
, i
, p
))
309 info
->protect
[i
] = p
;
310 #endif /* CFG_FLASH_PROTECTION */
313 #if defined(CFG_FLASH_PROTECTION)
314 if (!rcode
) puts (" done\n");
315 #endif /* CFG_FLASH_PROTECTION */
321 printf ("Usage:\n%s\n", cmdtp
->usage
);
325 if (strcmp(argv
[2], "bank") == 0) {
326 bank
= simple_strtoul(argv
[3], NULL
, 16);
327 if ((bank
< 1) || (bank
> CFG_MAX_FLASH_BANKS
)) {
328 printf ("Only FLASH Banks # 1 ... # %d supported\n",
329 CFG_MAX_FLASH_BANKS
);
332 printf ("%sProtect Flash Bank # %ld\n",
333 p
? "" : "Un-", bank
);
334 info
= &flash_info
[bank
-1];
336 if (info
->flash_id
== FLASH_UNKNOWN
) {
337 printf ("missing or unknown FLASH type\n");
340 for (i
=0; i
<info
->sector_count
; ++i
) {
341 #if defined(CFG_FLASH_PROTECTION)
342 if (flash_real_protect(info
, i
, p
))
346 info
->protect
[i
] = p
;
347 #endif /* CFG_FLASH_PROTECTION */
350 #if defined(CFG_FLASH_PROTECTION)
351 if (!rcode
) puts (" done\n");
352 #endif /* CFG_FLASH_PROTECTION */
357 addr_first
= simple_strtoul(argv
[2], NULL
, 16);
358 addr_last
= simple_strtoul(argv
[3], NULL
, 16);
360 if (addr_first
>= addr_last
) {
361 printf ("Usage:\n%s\n", cmdtp
->usage
);
364 rcode
= flash_sect_protect (p
, addr_first
, addr_last
);
369 int flash_sect_protect (int p
, ulong addr_first
, ulong addr_last
)
379 for (bank
=0,info
=&flash_info
[0]; bank
< CFG_MAX_FLASH_BANKS
; ++bank
, ++info
) {
383 if (info
->flash_id
== FLASH_UNKNOWN
) {
387 b_end
= info
->start
[0] + info
->size
- 1; /* bank end addr */
389 s_first
= -1; /* first sector to erase */
390 s_last
= -1; /* last sector to erase */
392 for (sect
=0; sect
< info
->sector_count
; ++sect
) {
393 ulong end
; /* last address in current sect */
396 s_end
= info
->sector_count
- 1;
398 end
= (sect
== s_end
) ? b_end
: info
->start
[sect
+ 1] - 1;
400 if (addr_first
> end
)
402 if (addr_last
< info
->start
[sect
])
405 if (addr_first
== info
->start
[sect
]) {
408 if (addr_last
== end
) {
412 if (s_first
>=0 && s_first
<=s_last
) {
413 protected += s_last
- s_first
+ 1;
414 for (i
=s_first
; i
<=s_last
; ++i
) {
415 #if defined(CFG_FLASH_PROTECTION)
416 if (flash_real_protect(info
, i
, p
))
420 info
->protect
[i
] = p
;
421 #endif /* CFG_FLASH_PROTECTION */
424 #if defined(CFG_FLASH_PROTECTION)
425 if (!rcode
) putc ('\n');
426 #endif /* CFG_FLASH_PROTECTION */
430 printf ("%sProtected %d sectors\n",
431 p
? "" : "Un-", protected);
433 printf ("Error: start and/or end address"
434 " not on sector boundary\n");
441 /**************************************************/
443 cmd_tbl_t
U_BOOT_CMD(FLINFO
) = MK_CMD_ENTRY(
444 "flinfo", 2, 1, do_flinfo
,
445 "flinfo - print FLASH memory information\n",
446 "\n - print information for all FLASH memory banks\n"
447 "flinfo N\n - print information for FLASH memory bank # N\n"
450 cmd_tbl_t
U_BOOT_CMD(ERASE
) = MK_CMD_ENTRY(
451 "erase", 3, 1, do_flerase
,
452 "erase - erase FLASH memory\n",
454 " - erase FLASH from addr 'start' to addr 'end'\n"
455 "erase N:SF[-SL]\n - erase sectors SF-SL in FLASH bank # N\n"
456 "erase bank N\n - erase FLASH bank # N\n"
457 "erase all\n - erase all FLASH banks\n"
460 cmd_tbl_t
U_BOOT_CMD(PROTECT
) = MK_CMD_ENTRY(
461 "protect", 4, 1, do_protect
,
462 "protect - enable or disable FLASH write protection\n",
464 " - protect FLASH from addr 'start' to addr 'end'\n"
465 "protect on N:SF[-SL]\n"
466 " - protect sectors SF-SL in FLASH bank # N\n"
467 "protect on bank N\n - protect FLASH bank # N\n"
468 "protect on all\n - protect all FLASH banks\n"
469 "protect off start end\n"
470 " - make FLASH from addr 'start' to addr 'end' writable\n"
471 "protect off N:SF[-SL]\n"
472 " - make sectors SF-SL writable in FLASH bank # N\n"
473 "protect off bank N\n - make FLASH bank # N writable\n"
474 "protect off all\n - make all FLASH banks writable\n"
477 #endif /* CFG_CMD_FLASH */