Blame view

cmd/flash.c 17.7 KB
38a24a612   wdenk   Initial revision
1
2
3
4
  /*
   * (C) Copyright 2000
   * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   *
1a4596601   Wolfgang Denk   Add GPL-2.0+ SPDX...
5
   * SPDX-License-Identifier:	GPL-2.0+
38a24a612   wdenk   Initial revision
6
7
8
9
10
11
12
   */
  
  /*
   * FLASH support
   */
  #include <common.h>
  #include <command.h>
8bde7f776   wdenk   * Code cleanup:
13

c000808b6   Alexander Stein   CONFIG_CMD_JFFS2 ...
14
  #if defined(CONFIG_CMD_MTDPARTS)
700a0c648   Wolfgang Denk   Add common (with ...
15
  #include <jffs2/jffs2.h>
445093d17   Wolfgang Denk   Fix "par[t]ition"...
16
  /* partition handling routines */
700a0c648   Wolfgang Denk   Add common (with ...
17
  int mtdparts_init(void);
68d7d6510   Stefan Roese   Separate mtdparts...
18
  int mtd_id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num);
700a0c648   Wolfgang Denk   Add common (with ...
19
20
21
  int find_dev_and_part(const char *id, struct mtd_device **dev,
  		u8 *part_num, struct part_info **part);
  #endif
e856bdcfb   Masahiro Yamada   flash: complete C...
22
  #ifdef CONFIG_MTD_NOR_FLASH
3c29975e9   Stefan Roese   cfi_flash: Remove...
23
24
  #include <flash.h>
  #include <mtd/cfi_flash.h>
38a24a612   wdenk   Initial revision
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  extern flash_info_t flash_info[];	/* info for FLASH chips */
  
  /*
   * The user interface starts numbering for Flash banks with 1
   * for historical reasons.
   */
  
  /*
   * this routine looks for an abbreviated flash range specification.
   * the syntax is B:SF[-SL], where B is the bank number, SF is the first
   * sector to erase, and SL is the last sector to erase (defaults to SF).
   * bank numbers start at 1 to be consistent with other specs, sector numbers
   * start at zero.
   *
   * returns:	1	- correct spec; *pinfo, *psf and *psl are
   *			  set appropriately
   *		0	- doesn't look like an abbreviated spec
   *		-1	- looks like an abbreviated spec, but got
   *			  a parsing error, a number out of range,
   *			  or an invalid flash bank.
   */
  static int
bdccc4fed   wdenk   * Map ISP1362 USB...
47
  abbrev_spec (char *str, flash_info_t ** pinfo, int *psf, int *psl)
38a24a612   wdenk   Initial revision
48
  {
bdccc4fed   wdenk   * Map ISP1362 USB...
49
50
51
  	flash_info_t *fp;
  	int bank, first, last;
  	char *p, *ep;
38a24a612   wdenk   Initial revision
52

bdccc4fed   wdenk   * Map ISP1362 USB...
53
54
55
  	if ((p = strchr (str, ':')) == NULL)
  		return 0;
  	*p++ = '\0';
38a24a612   wdenk   Initial revision
56

bdccc4fed   wdenk   * Map ISP1362 USB...
57
58
  	bank = simple_strtoul (str, &ep, 10);
  	if (ep == str || *ep != '\0' ||
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
59
  		bank < 1 || bank > CONFIG_SYS_MAX_FLASH_BANKS ||
bdccc4fed   wdenk   * Map ISP1362 USB...
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
  		(fp = &flash_info[bank - 1])->flash_id == FLASH_UNKNOWN)
  		return -1;
  
  	str = p;
  	if ((p = strchr (str, '-')) != NULL)
  		*p++ = '\0';
  
  	first = simple_strtoul (str, &ep, 10);
  	if (ep == str || *ep != '\0' || first >= fp->sector_count)
  		return -1;
  
  	if (p != NULL) {
  		last = simple_strtoul (p, &ep, 10);
  		if (ep == p || *ep != '\0' ||
  			last < first || last >= fp->sector_count)
  			return -1;
  	} else {
  		last = first;
  	}
38a24a612   wdenk   Initial revision
79

bdccc4fed   wdenk   * Map ISP1362 USB...
80
81
82
83
84
85
  	*pinfo = fp;
  	*psf = first;
  	*psl = last;
  
  	return 1;
  }
f530187db   Wolfgang Denk   Add new argument ...
86
  /*
3f0cf51da   Bartlomiej Sieka   flash: factor out...
87
88
89
90
91
92
93
94
95
96
97
   * Take *addr in Flash and adjust it to fall on the end of its sector
   */
  int flash_sect_roundb (ulong *addr)
  {
  	flash_info_t *info;
  	ulong bank, sector_end_addr;
  	char found;
  	int i;
  
  	/* find the end addr of the sector where the *addr is */
  	found = 0;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
98
  	for (bank = 0; bank < CONFIG_SYS_MAX_FLASH_BANKS && !found; ++bank) {
3f0cf51da   Bartlomiej Sieka   flash: factor out...
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
  		info = &flash_info[bank];
  		for (i = 0; i < info->sector_count && !found; ++i) {
  			/* get the end address of the sector */
  			if (i == info->sector_count - 1) {
  				sector_end_addr = info->start[0] +
  								info->size - 1;
  			} else {
  				sector_end_addr = info->start[i+1] - 1;
  			}
  
  			if (*addr <= sector_end_addr &&
  						*addr >= info->start[i]) {
  				found = 1;
  				/* adjust *addr if necessary */
  				if (*addr < sector_end_addr)
  					*addr = sector_end_addr;
  			} /* sector */
  		} /* bank */
  	}
  	if (!found) {
162630879   Mike Williams   cleanup: Fix typo...
119
  		/* error, address not in flash */
3f0cf51da   Bartlomiej Sieka   flash: factor out...
120
121
122
123
124
125
126
127
128
  		printf("Error: end address (0x%08lx) not in flash!
  ", *addr);
  		return 1;
  	}
  
  	return 0;
  }
  
  /*
f530187db   Wolfgang Denk   Add new argument ...
129
130
131
132
   * This function computes the start and end addresses for both
   * erase and protect commands. The range of the addresses on which
   * either of the commands is to operate can be given in two forms:
   * 1. <cmd> start end - operate on <'start',  'end')
095b8a379   Wolfgang Denk   Coding style cleanup
133
   * 2. <cmd> start +length - operate on <'start', start + length)
f530187db   Wolfgang Denk   Add new argument ...
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
   * If the second form is used and the end address doesn't fall on the
   * sector boundary, than it will be adjusted to the next sector boundary.
   * If it isn't in the flash, the function will fail (return -1).
   * Input:
   *    arg1, arg2: address specification (i.e. both command arguments)
   * Output:
   *    addr_first, addr_last: computed address range
   * Return:
   *    1: success
   *   -1: failure (bad format, bad address).
  */
  static int
  addr_spec(char *arg1, char *arg2, ulong *addr_first, ulong *addr_last)
  {
  	char *ep;
bb74140de   Heiko Schocher   Fixes common/cmd_...
149
  	char len_used; /* indicates if the "start +length" form used */
2c61f14c6   Wolfgang Denk   Fix compile probl...
150

f530187db   Wolfgang Denk   Add new argument ...
151
152
153
  	*addr_first = simple_strtoul(arg1, &ep, 16);
  	if (ep == arg1 || *ep != '\0')
  		return -1;
bb74140de   Heiko Schocher   Fixes common/cmd_...
154
  	len_used = 0;
f530187db   Wolfgang Denk   Add new argument ...
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
  	if (arg2 && *arg2 == '+'){
  		len_used = 1;
  		++arg2;
  	}
  
  	*addr_last = simple_strtoul(arg2, &ep, 16);
  	if (ep == arg2 || *ep != '\0')
  		return -1;
  
  	if (len_used){
  		/*
  		 * *addr_last has the length, compute correct *addr_last
  		 * XXX watch out for the integer overflow! Right now it is
  		 * checked for in both the callers.
  		 */
  		*addr_last = *addr_first + *addr_last - 1;
  
  		/*
  		 * It may happen that *addr_last doesn't fall on the sector
  		 * boundary. We want to round such an address to the next
  		 * sector boundary, so that the commands don't fail later on.
  		 */
3f0cf51da   Bartlomiej Sieka   flash: factor out...
177
  		if (flash_sect_roundb(addr_last) > 0)
f530187db   Wolfgang Denk   Add new argument ...
178
  			return -1;
f530187db   Wolfgang Denk   Add new argument ...
179
180
181
182
  	} /* "start +length" from used */
  
  	return 1;
  }
bdccc4fed   wdenk   * Map ISP1362 USB...
183
184
185
186
187
188
189
190
191
192
  static int
  flash_fill_sect_ranges (ulong addr_first, ulong addr_last,
  			int *s_first, int *s_last,
  			int *s_count )
  {
  	flash_info_t *info;
  	ulong bank;
  	int rcode = 0;
  
  	*s_count = 0;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
193
  	for (bank=0; bank < CONFIG_SYS_MAX_FLASH_BANKS; ++bank) {
bdccc4fed   wdenk   * Map ISP1362 USB...
194
195
196
  		s_first[bank] = -1;	/* first sector to erase	*/
  		s_last [bank] = -1;	/* last  sector to erase	*/
  	}
d0ff51ba5   Wolfgang Denk   Code cleanup: fix...
197
  	for (bank=0,info = &flash_info[0];
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
198
  	     (bank < CONFIG_SYS_MAX_FLASH_BANKS) && (addr_first <= addr_last);
bdccc4fed   wdenk   * Map ISP1362 USB...
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
  	     ++bank, ++info) {
  		ulong b_end;
  		int sect;
  		short s_end;
  
  		if (info->flash_id == FLASH_UNKNOWN) {
  			continue;
  		}
  
  		b_end = info->start[0] + info->size - 1;	/* bank end addr */
  		s_end = info->sector_count - 1;			/* last sector   */
  
  
  		for (sect=0; sect < info->sector_count; ++sect) {
  			ulong end;	/* last address in current sect	*/
38a24a612   wdenk   Initial revision
214

bdccc4fed   wdenk   * Map ISP1362 USB...
215
  			end = (sect == s_end) ? b_end : info->start[sect + 1] - 1;
38a24a612   wdenk   Initial revision
216

bdccc4fed   wdenk   * Map ISP1362 USB...
217
218
219
220
  			if (addr_first > end)
  				continue;
  			if (addr_last < info->start[sect])
  				continue;
38a24a612   wdenk   Initial revision
221

bdccc4fed   wdenk   * Map ISP1362 USB...
222
223
224
225
226
227
228
229
230
231
232
233
  			if (addr_first == info->start[sect]) {
  				s_first[bank] = sect;
  			}
  			if (addr_last  == end) {
  				s_last[bank]  = sect;
  			}
  		}
  		if (s_first[bank] >= 0) {
  			if (s_last[bank] < 0) {
  				if (addr_last > b_end) {
  					s_last[bank] = s_end;
  				} else {
4b9206ed5   wdenk   * Patches by Thom...
234
  					puts ("Error: end address"
bdccc4fed   wdenk   * Map ISP1362 USB...
235
236
237
238
239
240
241
  						" not on sector boundary
  ");
  					rcode = 1;
  					break;
  				}
  			}
  			if (s_last[bank] < s_first[bank]) {
4b9206ed5   wdenk   * Patches by Thom...
242
  				puts ("Error: end sector"
bdccc4fed   wdenk   * Map ISP1362 USB...
243
244
245
246
247
248
249
250
  					" precedes start sector
  ");
  				rcode = 1;
  				break;
  			}
  			sect = s_last[bank];
  			addr_first = (sect == s_end) ? b_end + 1: info->start[sect + 1];
  			(*s_count) += s_last[bank] - s_first[bank] + 1;
e2ffd59b4   wdenk   * Code cleanup, m...
251
252
253
254
255
  		} else if (addr_first >= info->start[0] && addr_first < b_end) {
  			puts ("Error: start address not on sector boundary
  ");
  			rcode = 1;
  			break;
2d5b561e2   wdenk   * Make sure HUSH ...
256
  		} else if (s_last[bank] >= 0) {
4b9206ed5   wdenk   * Patches by Thom...
257
  			puts ("Error: cannot span across banks when they are"
2d5b561e2   wdenk   * Make sure HUSH ...
258
259
260
261
  			       " mapped in reverse order
  ");
  			rcode = 1;
  			break;
bdccc4fed   wdenk   * Map ISP1362 USB...
262
263
  		}
  	}
38a24a612   wdenk   Initial revision
264

bdccc4fed   wdenk   * Map ISP1362 USB...
265
  	return rcode;
38a24a612   wdenk   Initial revision
266
  }
e856bdcfb   Masahiro Yamada   flash: complete C...
267
  #endif /* CONFIG_MTD_NOR_FLASH */
bdccc4fed   wdenk   * Map ISP1362 USB...
268

088f1b199   Kim Phillips   common/cmd_*.c: s...
269
  static int do_flinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
38a24a612   wdenk   Initial revision
270
  {
e856bdcfb   Masahiro Yamada   flash: complete C...
271
  #ifdef CONFIG_MTD_NOR_FLASH
38a24a612   wdenk   Initial revision
272
  	ulong bank;
880cc4381   Stelian Pop   Fix CFG_NO_FLASH ...
273
  #endif
38a24a612   wdenk   Initial revision
274

e856bdcfb   Masahiro Yamada   flash: complete C...
275
  #ifdef CONFIG_MTD_NOR_FLASH
38a24a612   wdenk   Initial revision
276
  	if (argc == 1) {	/* print info for all FLASH banks */
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
277
  		for (bank=0; bank <CONFIG_SYS_MAX_FLASH_BANKS; ++bank) {
38a24a612   wdenk   Initial revision
278
279
280
281
282
283
284
285
286
  			printf ("
  Bank # %ld: ", bank+1);
  
  			flash_print_info (&flash_info[bank]);
  		}
  		return 0;
  	}
  
  	bank = simple_strtoul(argv[1], NULL, 16);
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
287
  	if ((bank < 1) || (bank > CONFIG_SYS_MAX_FLASH_BANKS)) {
38a24a612   wdenk   Initial revision
288
289
  		printf ("Only FLASH Banks # 1 ... # %d supported
  ",
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
290
  			CONFIG_SYS_MAX_FLASH_BANKS);
38a24a612   wdenk   Initial revision
291
292
293
294
295
  		return 1;
  	}
  	printf ("
  Bank # %ld: ", bank);
  	flash_print_info (&flash_info[bank-1]);
e856bdcfb   Masahiro Yamada   flash: complete C...
296
  #endif /* CONFIG_MTD_NOR_FLASH */
38a24a612   wdenk   Initial revision
297
298
  	return 0;
  }
700a0c648   Wolfgang Denk   Add common (with ...
299

088f1b199   Kim Phillips   common/cmd_*.c: s...
300
  static int do_flerase(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
38a24a612   wdenk   Initial revision
301
  {
e856bdcfb   Masahiro Yamada   flash: complete C...
302
  #ifdef CONFIG_MTD_NOR_FLASH
4f5710f74   Wolfgang Denk   common/cmd_flash....
303
  	flash_info_t *info = NULL;
38a24a612   wdenk   Initial revision
304
  	ulong bank, addr_first, addr_last;
4f5710f74   Wolfgang Denk   common/cmd_flash....
305
  	int n, sect_first = 0, sect_last = 0;
c000808b6   Alexander Stein   CONFIG_CMD_JFFS2 ...
306
  #if defined(CONFIG_CMD_MTDPARTS)
700a0c648   Wolfgang Denk   Add common (with ...
307
308
309
310
  	struct mtd_device *dev;
  	struct part_info *part;
  	u8 dev_type, dev_num, pnum;
  #endif
38a24a612   wdenk   Initial revision
311
  	int rcode = 0;
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
312
  	if (argc < 2)
4c12eeb8b   Simon Glass   Convert cmd_usage...
313
  		return CMD_RET_USAGE;
38a24a612   wdenk   Initial revision
314
315
  
  	if (strcmp(argv[1], "all") == 0) {
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
316
  		for (bank=1; bank<=CONFIG_SYS_MAX_FLASH_BANKS; ++bank) {
38a24a612   wdenk   Initial revision
317
318
319
320
321
322
323
324
325
  			printf ("Erase Flash Bank # %ld ", bank);
  			info = &flash_info[bank-1];
  			rcode = flash_erase (info, 0, info->sector_count-1);
  		}
  		return rcode;
  	}
  
  	if ((n = abbrev_spec(argv[1], &info, &sect_first, &sect_last)) != 0) {
  		if (n < 0) {
4b9206ed5   wdenk   * Patches by Thom...
326
327
  			puts ("Bad sector specification
  ");
38a24a612   wdenk   Initial revision
328
329
  			return 1;
  		}
f2302d443   Stefan Roese   Fix merge problems
330
  		printf ("Erase Flash Sectors %d-%d in Bank # %zu ",
38a24a612   wdenk   Initial revision
331
332
333
334
  			sect_first, sect_last, (info-flash_info)+1);
  		rcode = flash_erase(info, sect_first, sect_last);
  		return rcode;
  	}
c000808b6   Alexander Stein   CONFIG_CMD_JFFS2 ...
335
  #if defined(CONFIG_CMD_MTDPARTS)
700a0c648   Wolfgang Denk   Add common (with ...
336
  	/* erase <part-id> - erase partition */
68d7d6510   Stefan Roese   Separate mtdparts...
337
  	if ((argc == 2) && (mtd_id_parse(argv[1], NULL, &dev_type, &dev_num) == 0)) {
700a0c648   Wolfgang Denk   Add common (with ...
338
339
340
341
342
343
344
  		mtdparts_init();
  		if (find_dev_and_part(argv[1], &dev, &pnum, &part) == 0) {
  			if (dev->id->type == MTD_DEV_TYPE_NOR) {
  				bank = dev->id->num;
  				info = &flash_info[bank];
  				addr_first = part->offset + info->start[0];
  				addr_last = addr_first + part->size - 1;
445093d17   Wolfgang Denk   Fix "par[t]ition"...
345
  				printf ("Erase Flash Partition %s, "
4109df6f7   Kim Phillips   silence misc prin...
346
  						"bank %ld, 0x%08lx - 0x%08lx ",
700a0c648   Wolfgang Denk   Add common (with ...
347
348
349
350
351
352
353
354
355
356
357
358
359
  						argv[1], bank, addr_first,
  						addr_last);
  
  				rcode = flash_sect_erase(addr_first, addr_last);
  				return rcode;
  			}
  
  			printf("cannot erase, not a NOR device
  ");
  			return 1;
  		}
  	}
  #endif
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
360
  	if (argc != 3)
4c12eeb8b   Simon Glass   Convert cmd_usage...
361
  		return CMD_RET_USAGE;
38a24a612   wdenk   Initial revision
362
363
364
  
  	if (strcmp(argv[1], "bank") == 0) {
  		bank = simple_strtoul(argv[2], NULL, 16);
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
365
  		if ((bank < 1) || (bank > CONFIG_SYS_MAX_FLASH_BANKS)) {
38a24a612   wdenk   Initial revision
366
367
  			printf ("Only FLASH Banks # 1 ... # %d supported
  ",
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
368
  				CONFIG_SYS_MAX_FLASH_BANKS);
38a24a612   wdenk   Initial revision
369
370
371
372
373
374
375
  			return 1;
  		}
  		printf ("Erase Flash Bank # %ld ", bank);
  		info = &flash_info[bank-1];
  		rcode = flash_erase (info, 0, info->sector_count-1);
  		return rcode;
  	}
f530187db   Wolfgang Denk   Add new argument ...
376
377
378
379
380
  	if (addr_spec(argv[1], argv[2], &addr_first, &addr_last) < 0){
  		printf ("Bad address format
  ");
  		return 1;
  	}
38a24a612   wdenk   Initial revision
381

47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
382
  	if (addr_first >= addr_last)
4c12eeb8b   Simon Glass   Convert cmd_usage...
383
  		return CMD_RET_USAGE;
38a24a612   wdenk   Initial revision
384

38a24a612   wdenk   Initial revision
385
386
  	rcode = flash_sect_erase(addr_first, addr_last);
  	return rcode;
880cc4381   Stelian Pop   Fix CFG_NO_FLASH ...
387
388
  #else
  	return 0;
e856bdcfb   Masahiro Yamada   flash: complete C...
389
  #endif /* CONFIG_MTD_NOR_FLASH */
38a24a612   wdenk   Initial revision
390
  }
e856bdcfb   Masahiro Yamada   flash: complete C...
391
  #ifdef CONFIG_MTD_NOR_FLASH
38a24a612   wdenk   Initial revision
392
393
394
395
  int flash_sect_erase (ulong addr_first, ulong addr_last)
  {
  	flash_info_t *info;
  	ulong bank;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
396
  	int s_first[CONFIG_SYS_MAX_FLASH_BANKS], s_last[CONFIG_SYS_MAX_FLASH_BANKS];
bdccc4fed   wdenk   * Map ISP1362 USB...
397
398
  	int erased = 0;
  	int planned;
38a24a612   wdenk   Initial revision
399
  	int rcode = 0;
bdccc4fed   wdenk   * Map ISP1362 USB...
400
401
402
403
  	rcode = flash_fill_sect_ranges (addr_first, addr_last,
  					s_first, s_last, &planned );
  
  	if (planned && (rcode == 0)) {
d0ff51ba5   Wolfgang Denk   Code cleanup: fix...
404
  		for (bank=0,info = &flash_info[0];
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
405
  		     (bank < CONFIG_SYS_MAX_FLASH_BANKS) && (rcode == 0);
bdccc4fed   wdenk   * Map ISP1362 USB...
406
407
408
  		     ++bank, ++info) {
  			if (s_first[bank]>=0) {
  				erased += s_last[bank] - s_first[bank] + 1;
013dc8d9b   wdenk   Disable debug pri...
409
  				debug ("Erase Flash from 0x%08lx to 0x%08lx "
bdccc4fed   wdenk   * Map ISP1362 USB...
410
411
412
413
414
415
416
  					"in Bank # %ld ",
  					info->start[s_first[bank]],
  					(s_last[bank] == info->sector_count) ?
  						info->start[0] + info->size - 1:
  						info->start[s_last[bank]+1] - 1,
  					bank+1);
  				rcode = flash_erase (info, s_first[bank], s_last[bank]);
38a24a612   wdenk   Initial revision
417
418
  			}
  		}
de15a06aa   Joe Hershberger   cfi: Make the fla...
419
420
421
  		if (rcode == 0)
  			printf("Erased %d sectors
  ", erased);
bdccc4fed   wdenk   * Map ISP1362 USB...
422
  	} else if (rcode == 0) {
4b9206ed5   wdenk   * Patches by Thom...
423
  		puts ("Error: start and/or end address"
38a24a612   wdenk   Initial revision
424
425
426
427
428
429
  			" not on sector boundary
  ");
  		rcode = 1;
  	}
  	return rcode;
  }
e856bdcfb   Masahiro Yamada   flash: complete C...
430
  #endif /* CONFIG_MTD_NOR_FLASH */
38a24a612   wdenk   Initial revision
431

088f1b199   Kim Phillips   common/cmd_*.c: s...
432
  static int do_protect(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
38a24a612   wdenk   Initial revision
433
  {
5b3901d9a   Marek Vasut   GCC4.6: Squash wa...
434
  	int rcode = 0;
e856bdcfb   Masahiro Yamada   flash: complete C...
435
  #ifdef CONFIG_MTD_NOR_FLASH
4f5710f74   Wolfgang Denk   common/cmd_flash....
436
  	flash_info_t *info = NULL;
880cc4381   Stelian Pop   Fix CFG_NO_FLASH ...
437
  	ulong bank;
4f5710f74   Wolfgang Denk   common/cmd_flash....
438
  	int i, n, sect_first = 0, sect_last = 0;
c000808b6   Alexander Stein   CONFIG_CMD_JFFS2 ...
439
  #if defined(CONFIG_CMD_MTDPARTS)
700a0c648   Wolfgang Denk   Add common (with ...
440
441
442
443
  	struct mtd_device *dev;
  	struct part_info *part;
  	u8 dev_type, dev_num, pnum;
  #endif
e856bdcfb   Masahiro Yamada   flash: complete C...
444
  #endif /* CONFIG_MTD_NOR_FLASH */
c68c03f52   Tuomas Tynkkynen   Drop CONFIG_HAS_D...
445
  #if defined(CONFIG_MTD_NOR_FLASH)
5669ed455   Wolfgang Denk   cmd_flash.c: fix ...
446
  	int p;
5b3901d9a   Marek Vasut   GCC4.6: Squash wa...
447
448
  	ulong addr_first, addr_last;
  #endif
2662b40ca   Stefan Roese   * Changes/fixes f...
449

47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
450
  	if (argc < 3)
4c12eeb8b   Simon Glass   Convert cmd_usage...
451
  		return CMD_RET_USAGE;
38a24a612   wdenk   Initial revision
452

c68c03f52   Tuomas Tynkkynen   Drop CONFIG_HAS_D...
453
  #if defined(CONFIG_MTD_NOR_FLASH)
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
454
  	if (strcmp(argv[1], "off") == 0)
38a24a612   wdenk   Initial revision
455
  		p = 0;
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
456
  	else if (strcmp(argv[1], "on") == 0)
38a24a612   wdenk   Initial revision
457
  		p = 1;
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
458
  	else
4c12eeb8b   Simon Glass   Convert cmd_usage...
459
  		return CMD_RET_USAGE;
5b3901d9a   Marek Vasut   GCC4.6: Squash wa...
460
  #endif
38a24a612   wdenk   Initial revision
461

e856bdcfb   Masahiro Yamada   flash: complete C...
462
  #ifdef CONFIG_MTD_NOR_FLASH
38a24a612   wdenk   Initial revision
463
  	if (strcmp(argv[2], "all") == 0) {
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
464
  		for (bank=1; bank<=CONFIG_SYS_MAX_FLASH_BANKS; ++bank) {
38a24a612   wdenk   Initial revision
465
466
467
468
469
470
471
472
473
  			info = &flash_info[bank-1];
  			if (info->flash_id == FLASH_UNKNOWN) {
  				continue;
  			}
  			printf ("%sProtect Flash Bank # %ld
  ",
  				p ? "" : "Un-", bank);
  
  			for (i=0; i<info->sector_count; ++i) {
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
474
  #if defined(CONFIG_SYS_FLASH_PROTECTION)
38a24a612   wdenk   Initial revision
475
476
477
478
479
  				if (flash_real_protect(info, i, p))
  					rcode = 1;
  				putc ('.');
  #else
  				info->protect[i] = p;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
480
  #endif	/* CONFIG_SYS_FLASH_PROTECTION */
38a24a612   wdenk   Initial revision
481
  			}
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
482
  #if defined(CONFIG_SYS_FLASH_PROTECTION)
bb74140de   Heiko Schocher   Fixes common/cmd_...
483
484
  			if (!rcode) puts (" done
  ");
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
485
  #endif	/* CONFIG_SYS_FLASH_PROTECTION */
bb74140de   Heiko Schocher   Fixes common/cmd_...
486
  		}
38a24a612   wdenk   Initial revision
487
488
489
490
491
  		return rcode;
  	}
  
  	if ((n = abbrev_spec(argv[2], &info, &sect_first, &sect_last)) != 0) {
  		if (n < 0) {
4b9206ed5   wdenk   * Patches by Thom...
492
493
  			puts ("Bad sector specification
  ");
38a24a612   wdenk   Initial revision
494
495
  			return 1;
  		}
f2302d443   Stefan Roese   Fix merge problems
496
497
  		printf("%sProtect Flash Sectors %d-%d in Bank # %zu
  ",
38a24a612   wdenk   Initial revision
498
499
500
  			p ? "" : "Un-", sect_first, sect_last,
  			(info-flash_info)+1);
  		for (i = sect_first; i <= sect_last; i++) {
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
501
  #if defined(CONFIG_SYS_FLASH_PROTECTION)
38a24a612   wdenk   Initial revision
502
503
504
505
506
  			if (flash_real_protect(info, i, p))
  				rcode =  1;
  			putc ('.');
  #else
  			info->protect[i] = p;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
507
  #endif	/* CONFIG_SYS_FLASH_PROTECTION */
38a24a612   wdenk   Initial revision
508
  		}
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
509
  #if defined(CONFIG_SYS_FLASH_PROTECTION)
38a24a612   wdenk   Initial revision
510
511
  		if (!rcode) puts (" done
  ");
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
512
  #endif	/* CONFIG_SYS_FLASH_PROTECTION */
38a24a612   wdenk   Initial revision
513
514
515
  
  		return rcode;
  	}
8f79e4c2d   Wolfgang Denk   Add configuration...
516

c000808b6   Alexander Stein   CONFIG_CMD_JFFS2 ...
517
  #if defined(CONFIG_CMD_MTDPARTS)
700a0c648   Wolfgang Denk   Add common (with ...
518
  	/* protect on/off <part-id> */
68d7d6510   Stefan Roese   Separate mtdparts...
519
  	if ((argc == 3) && (mtd_id_parse(argv[2], NULL, &dev_type, &dev_num) == 0)) {
700a0c648   Wolfgang Denk   Add common (with ...
520
521
522
523
524
525
526
  		mtdparts_init();
  		if (find_dev_and_part(argv[2], &dev, &pnum, &part) == 0) {
  			if (dev->id->type == MTD_DEV_TYPE_NOR) {
  				bank = dev->id->num;
  				info = &flash_info[bank];
  				addr_first = part->offset + info->start[0];
  				addr_last = addr_first + part->size - 1;
445093d17   Wolfgang Denk   Fix "par[t]ition"...
527
  				printf ("%sProtect Flash Partition %s, "
4109df6f7   Kim Phillips   silence misc prin...
528
529
  						"bank %ld, 0x%08lx - 0x%08lx
  ",
700a0c648   Wolfgang Denk   Add common (with ...
530
531
532
533
534
535
536
537
538
539
540
541
542
543
  						p ? "" : "Un", argv[1],
  						bank, addr_first, addr_last);
  
  				rcode = flash_sect_protect (p, addr_first, addr_last);
  				return rcode;
  			}
  
  			printf("cannot %sprotect, not a NOR device
  ",
  					p ? "" : "un");
  			return 1;
  		}
  	}
  #endif
38a24a612   wdenk   Initial revision
544

47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
545
  	if (argc != 4)
4c12eeb8b   Simon Glass   Convert cmd_usage...
546
  		return CMD_RET_USAGE;
38a24a612   wdenk   Initial revision
547
548
549
  
  	if (strcmp(argv[2], "bank") == 0) {
  		bank = simple_strtoul(argv[3], NULL, 16);
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
550
  		if ((bank < 1) || (bank > CONFIG_SYS_MAX_FLASH_BANKS)) {
38a24a612   wdenk   Initial revision
551
552
  			printf ("Only FLASH Banks # 1 ... # %d supported
  ",
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
553
  				CONFIG_SYS_MAX_FLASH_BANKS);
38a24a612   wdenk   Initial revision
554
555
556
557
558
559
560
561
  			return 1;
  		}
  		printf ("%sProtect Flash Bank # %ld
  ",
  			p ? "" : "Un-", bank);
  		info = &flash_info[bank-1];
  
  		if (info->flash_id == FLASH_UNKNOWN) {
4b9206ed5   wdenk   * Patches by Thom...
562
563
  			puts ("missing or unknown FLASH type
  ");
38a24a612   wdenk   Initial revision
564
565
566
  			return 1;
  		}
  		for (i=0; i<info->sector_count; ++i) {
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
567
  #if defined(CONFIG_SYS_FLASH_PROTECTION)
38a24a612   wdenk   Initial revision
568
569
570
571
572
  			if (flash_real_protect(info, i, p))
  				rcode =  1;
  			putc ('.');
  #else
  			info->protect[i] = p;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
573
  #endif	/* CONFIG_SYS_FLASH_PROTECTION */
38a24a612   wdenk   Initial revision
574
  		}
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
575
  #if defined(CONFIG_SYS_FLASH_PROTECTION)
38a24a612   wdenk   Initial revision
576
577
  		if (!rcode) puts (" done
  ");
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
578
  #endif	/* CONFIG_SYS_FLASH_PROTECTION */
38a24a612   wdenk   Initial revision
579
580
581
  
  		return rcode;
  	}
f530187db   Wolfgang Denk   Add new argument ...
582
583
584
585
586
  	if (addr_spec(argv[2], argv[3], &addr_first, &addr_last) < 0){
  		printf("Bad address format
  ");
  		return 1;
  	}
38a24a612   wdenk   Initial revision
587

47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
588
  	if (addr_first >= addr_last)
4c12eeb8b   Simon Glass   Convert cmd_usage...
589
  		return CMD_RET_USAGE;
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
590

38a24a612   wdenk   Initial revision
591
  	rcode = flash_sect_protect (p, addr_first, addr_last);
e856bdcfb   Masahiro Yamada   flash: complete C...
592
  #endif /* CONFIG_MTD_NOR_FLASH */
38a24a612   wdenk   Initial revision
593
594
  	return rcode;
  }
e856bdcfb   Masahiro Yamada   flash: complete C...
595
  #ifdef CONFIG_MTD_NOR_FLASH
38a24a612   wdenk   Initial revision
596
597
598
599
  int flash_sect_protect (int p, ulong addr_first, ulong addr_last)
  {
  	flash_info_t *info;
  	ulong bank;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
600
  	int s_first[CONFIG_SYS_MAX_FLASH_BANKS], s_last[CONFIG_SYS_MAX_FLASH_BANKS];
38a24a612   wdenk   Initial revision
601
  	int protected, i;
bdccc4fed   wdenk   * Map ISP1362 USB...
602
603
  	int planned;
  	int rcode;
38a24a612   wdenk   Initial revision
604

bdccc4fed   wdenk   * Map ISP1362 USB...
605
  	rcode = flash_fill_sect_ranges( addr_first, addr_last, s_first, s_last, &planned );
38a24a612   wdenk   Initial revision
606

bdccc4fed   wdenk   * Map ISP1362 USB...
607
  	protected = 0;
38a24a612   wdenk   Initial revision
608

bdccc4fed   wdenk   * Map ISP1362 USB...
609
  	if (planned && (rcode == 0)) {
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
610
  		for (bank=0,info = &flash_info[0]; bank < CONFIG_SYS_MAX_FLASH_BANKS; ++bank, ++info) {
bdccc4fed   wdenk   * Map ISP1362 USB...
611
  			if (info->flash_id == FLASH_UNKNOWN) {
38a24a612   wdenk   Initial revision
612
  				continue;
38a24a612   wdenk   Initial revision
613
  			}
bdccc4fed   wdenk   * Map ISP1362 USB...
614
615
  
  			if (s_first[bank]>=0 && s_first[bank]<=s_last[bank]) {
abcac8725   stroese   Fix output for "U...
616
617
618
  				debug ("%sProtecting sectors %d..%d in bank %ld
  ",
  					p ? "" : "Un-",
bdccc4fed   wdenk   * Map ISP1362 USB...
619
620
621
  					s_first[bank], s_last[bank], bank+1);
  				protected += s_last[bank] - s_first[bank] + 1;
  				for (i=s_first[bank]; i<=s_last[bank]; ++i) {
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
622
  #if defined(CONFIG_SYS_FLASH_PROTECTION)
bdccc4fed   wdenk   * Map ISP1362 USB...
623
624
625
  					if (flash_real_protect(info, i, p))
  						rcode = 1;
  					putc ('.');
38a24a612   wdenk   Initial revision
626
  #else
bdccc4fed   wdenk   * Map ISP1362 USB...
627
  					info->protect[i] = p;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
628
  #endif	/* CONFIG_SYS_FLASH_PROTECTION */
bdccc4fed   wdenk   * Map ISP1362 USB...
629
  				}
38a24a612   wdenk   Initial revision
630
  			}
2662b40ca   Stefan Roese   * Changes/fixes f...
631
  		}
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
632
  #if defined(CONFIG_SYS_FLASH_PROTECTION)
2662b40ca   Stefan Roese   * Changes/fixes f...
633
634
  		puts (" done
  ");
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
635
  #endif	/* CONFIG_SYS_FLASH_PROTECTION */
38a24a612   wdenk   Initial revision
636

38a24a612   wdenk   Initial revision
637
638
639
  		printf ("%sProtected %d sectors
  ",
  			p ? "" : "Un-", protected);
bdccc4fed   wdenk   * Map ISP1362 USB...
640
  	} else if (rcode == 0) {
4b9206ed5   wdenk   * Patches by Thom...
641
  		puts ("Error: start and/or end address"
38a24a612   wdenk   Initial revision
642
643
644
645
646
647
  			" not on sector boundary
  ");
  		rcode = 1;
  	}
  	return rcode;
  }
e856bdcfb   Masahiro Yamada   flash: complete C...
648
  #endif /* CONFIG_MTD_NOR_FLASH */
38a24a612   wdenk   Initial revision
649

8bde7f776   wdenk   * Code cleanup:
650
651
  
  /**************************************************/
c000808b6   Alexander Stein   CONFIG_CMD_JFFS2 ...
652
  #if defined(CONFIG_CMD_MTDPARTS)
c19c31347   Wolfgang Denk   Fix compiler warn...
653
654
655
656
657
658
659
660
661
662
663
664
665
666
  # define TMP_ERASE	"erase <part-id>
      - erase partition
  "
  # define TMP_PROT_ON	"protect on <part-id>
      - protect partition
  "
  # define TMP_PROT_OFF	"protect off <part-id>
      - make partition writable
  "
  #else
  # define TMP_ERASE	/* empty */
  # define TMP_PROT_ON	/* empty */
  # define TMP_PROT_OFF	/* empty */
  #endif
8bde7f776   wdenk   * Code cleanup:
667

0d4983930   wdenk   Patch by Kenneth ...
668
669
  U_BOOT_CMD(
  	flinfo,    2,    1,    do_flinfo,
2fb2604d5   Peter Tyser   Command usage cle...
670
  	"print FLASH memory information",
8bde7f776   wdenk   * Code cleanup:
671
672
673
  	"
      - print information for all FLASH memory banks
  "
a89c33db9   Wolfgang Denk   General help mess...
674
675
  	"flinfo N
      - print information for FLASH memory bank # N"
8bde7f776   wdenk   * Code cleanup:
676
  );
0d4983930   wdenk   Patch by Kenneth ...
677
  U_BOOT_CMD(
9912121f7   Detlev Zundel   Change 'repeatabl...
678
  	erase,   3,   0,  do_flerase,
2fb2604d5   Peter Tyser   Command usage cle...
679
  	"erase FLASH memory",
8bde7f776   wdenk   * Code cleanup:
680
681
682
683
  	"start end
  "
  	"    - erase FLASH from addr 'start' to addr 'end'
  "
f530187db   Wolfgang Denk   Add new argument ...
684
685
686
687
688
  	"erase start +len
  "
  	"    - erase FLASH from addr 'start' to the end of sect "
  	"w/addr 'start'+'len'-1
  "
8bde7f776   wdenk   * Code cleanup:
689
690
691
692
693
694
  	"erase N:SF[-SL]
      - erase sectors SF-SL in FLASH bank # N
  "
  	"erase bank N
      - erase FLASH bank # N
  "
c19c31347   Wolfgang Denk   Fix compiler warn...
695
  	TMP_ERASE
a89c33db9   Wolfgang Denk   General help mess...
696
697
  	"erase all
      - erase all FLASH banks"
8bde7f776   wdenk   * Code cleanup:
698
  );
0d4983930   wdenk   Patch by Kenneth ...
699
  U_BOOT_CMD(
9912121f7   Detlev Zundel   Change 'repeatabl...
700
  	protect,  4,  0,   do_protect,
2fb2604d5   Peter Tyser   Command usage cle...
701
  	"enable or disable FLASH write protection",
8bde7f776   wdenk   * Code cleanup:
702
703
704
705
  	"on  start end
  "
  	"    - protect FLASH from addr 'start' to addr 'end'
  "
f530187db   Wolfgang Denk   Add new argument ...
706
707
708
709
710
  	"protect on start +len
  "
  	"    - protect FLASH from addr 'start' to end of sect "
  	"w/addr 'start'+'len'-1
  "
8bde7f776   wdenk   * Code cleanup:
711
712
713
714
715
716
717
  	"protect on  N:SF[-SL]
  "
  	"    - protect sectors SF-SL in FLASH bank # N
  "
  	"protect on  bank N
      - protect FLASH bank # N
  "
c19c31347   Wolfgang Denk   Fix compiler warn...
718
  	TMP_PROT_ON
8bde7f776   wdenk   * Code cleanup:
719
720
721
722
723
724
725
  	"protect on  all
      - protect all FLASH banks
  "
  	"protect off start end
  "
  	"    - make FLASH from addr 'start' to addr 'end' writable
  "
f530187db   Wolfgang Denk   Add new argument ...
726
727
728
729
730
  	"protect off start +len
  "
  	"    - make FLASH from addr 'start' to end of sect "
  	"w/addr 'start'+'len'-1 wrtable
  "
8bde7f776   wdenk   * Code cleanup:
731
732
733
734
735
736
737
  	"protect off N:SF[-SL]
  "
  	"    - make sectors SF-SL writable in FLASH bank # N
  "
  	"protect off bank N
      - make FLASH bank # N writable
  "
c19c31347   Wolfgang Denk   Fix compiler warn...
738
  	TMP_PROT_OFF
a89c33db9   Wolfgang Denk   General help mess...
739
740
  	"protect off all
      - make all FLASH banks writable"
8bde7f776   wdenk   * Code cleanup:
741
  );
c19c31347   Wolfgang Denk   Fix compiler warn...
742
743
744
  #undef	TMP_ERASE
  #undef	TMP_PROT_ON
  #undef	TMP_PROT_OFF