Blame view

common/cmd_flash.c 18.5 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

2abbe0754   wdenk   * Patch by Nicola...
14
15
16
  #ifdef CONFIG_HAS_DATAFLASH
  #include <dataflash.h>
  #endif
c000808b6   Alexander Stein   CONFIG_CMD_JFFS2 ...
17
  #if defined(CONFIG_CMD_MTDPARTS)
700a0c648   Wolfgang Denk   Add common (with ...
18
  #include <jffs2/jffs2.h>
445093d17   Wolfgang Denk   Fix "par[t]ition"...
19
  /* partition handling routines */
700a0c648   Wolfgang Denk   Add common (with ...
20
  int mtdparts_init(void);
68d7d6510   Stefan Roese   Separate mtdparts...
21
  int mtd_id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num);
700a0c648   Wolfgang Denk   Add common (with ...
22
23
24
  int find_dev_and_part(const char *id, struct mtd_device **dev,
  		u8 *part_num, struct part_info **part);
  #endif
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
25
  #ifndef CONFIG_SYS_NO_FLASH
3c29975e9   Stefan Roese   cfi_flash: Remove...
26
27
  #include <flash.h>
  #include <mtd/cfi_flash.h>
38a24a612   wdenk   Initial revision
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
  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...
50
  abbrev_spec (char *str, flash_info_t ** pinfo, int *psf, int *psl)
38a24a612   wdenk   Initial revision
51
  {
bdccc4fed   wdenk   * Map ISP1362 USB...
52
53
54
  	flash_info_t *fp;
  	int bank, first, last;
  	char *p, *ep;
38a24a612   wdenk   Initial revision
55

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

bdccc4fed   wdenk   * Map ISP1362 USB...
60
61
  	bank = simple_strtoul (str, &ep, 10);
  	if (ep == str || *ep != '\0' ||
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
62
  		bank < 1 || bank > CONFIG_SYS_MAX_FLASH_BANKS ||
bdccc4fed   wdenk   * Map ISP1362 USB...
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
  		(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
82

bdccc4fed   wdenk   * Map ISP1362 USB...
83
84
85
86
87
88
  	*pinfo = fp;
  	*psf = first;
  	*psl = last;
  
  	return 1;
  }
f530187db   Wolfgang Denk   Add new argument ...
89
  /*
3f0cf51da   Bartlomiej Sieka   flash: factor out...
90
91
92
93
94
95
96
97
98
99
100
   * 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...
101
  	for (bank = 0; bank < CONFIG_SYS_MAX_FLASH_BANKS && !found; ++bank) {
3f0cf51da   Bartlomiej Sieka   flash: factor out...
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
  		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...
122
  		/* error, address not in flash */
3f0cf51da   Bartlomiej Sieka   flash: factor out...
123
124
125
126
127
128
129
130
131
  		printf("Error: end address (0x%08lx) not in flash!
  ", *addr);
  		return 1;
  	}
  
  	return 0;
  }
  
  /*
f530187db   Wolfgang Denk   Add new argument ...
132
133
134
135
   * 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
136
   * 2. <cmd> start +length - operate on <'start', start + length)
f530187db   Wolfgang Denk   Add new argument ...
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
   * 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_...
152
  	char len_used; /* indicates if the "start +length" form used */
2c61f14c6   Wolfgang Denk   Fix compile probl...
153

f530187db   Wolfgang Denk   Add new argument ...
154
155
156
  	*addr_first = simple_strtoul(arg1, &ep, 16);
  	if (ep == arg1 || *ep != '\0')
  		return -1;
bb74140de   Heiko Schocher   Fixes common/cmd_...
157
  	len_used = 0;
f530187db   Wolfgang Denk   Add new argument ...
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
  	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...
180
  		if (flash_sect_roundb(addr_last) > 0)
f530187db   Wolfgang Denk   Add new argument ...
181
  			return -1;
f530187db   Wolfgang Denk   Add new argument ...
182
183
184
185
  	} /* "start +length" from used */
  
  	return 1;
  }
bdccc4fed   wdenk   * Map ISP1362 USB...
186
187
188
189
190
191
192
193
194
195
  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...
196
  	for (bank=0; bank < CONFIG_SYS_MAX_FLASH_BANKS; ++bank) {
bdccc4fed   wdenk   * Map ISP1362 USB...
197
198
199
  		s_first[bank] = -1;	/* first sector to erase	*/
  		s_last [bank] = -1;	/* last  sector to erase	*/
  	}
d0ff51ba5   Wolfgang Denk   Code cleanup: fix...
200
  	for (bank=0,info = &flash_info[0];
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
201
  	     (bank < CONFIG_SYS_MAX_FLASH_BANKS) && (addr_first <= addr_last);
bdccc4fed   wdenk   * Map ISP1362 USB...
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
  	     ++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
217

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

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

bdccc4fed   wdenk   * Map ISP1362 USB...
225
226
227
228
229
230
231
232
233
234
235
236
  			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...
237
  					puts ("Error: end address"
bdccc4fed   wdenk   * Map ISP1362 USB...
238
239
240
241
242
243
244
  						" not on sector boundary
  ");
  					rcode = 1;
  					break;
  				}
  			}
  			if (s_last[bank] < s_first[bank]) {
4b9206ed5   wdenk   * Patches by Thom...
245
  				puts ("Error: end sector"
bdccc4fed   wdenk   * Map ISP1362 USB...
246
247
248
249
250
251
252
253
  					" 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...
254
255
256
257
258
  		} 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 ...
259
  		} else if (s_last[bank] >= 0) {
4b9206ed5   wdenk   * Patches by Thom...
260
  			puts ("Error: cannot span across banks when they are"
2d5b561e2   wdenk   * Make sure HUSH ...
261
262
263
264
  			       " mapped in reverse order
  ");
  			rcode = 1;
  			break;
bdccc4fed   wdenk   * Map ISP1362 USB...
265
266
  		}
  	}
38a24a612   wdenk   Initial revision
267

bdccc4fed   wdenk   * Map ISP1362 USB...
268
  	return rcode;
38a24a612   wdenk   Initial revision
269
  }
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
270
  #endif /* CONFIG_SYS_NO_FLASH */
bdccc4fed   wdenk   * Map ISP1362 USB...
271

088f1b199   Kim Phillips   common/cmd_*.c: s...
272
  static int do_flinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
38a24a612   wdenk   Initial revision
273
  {
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
274
  #ifndef CONFIG_SYS_NO_FLASH
38a24a612   wdenk   Initial revision
275
  	ulong bank;
880cc4381   Stelian Pop   Fix CFG_NO_FLASH ...
276
  #endif
38a24a612   wdenk   Initial revision
277

2abbe0754   wdenk   * Patch by Nicola...
278
279
280
  #ifdef CONFIG_HAS_DATAFLASH
  	dataflash_print_info();
  #endif
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
281
  #ifndef CONFIG_SYS_NO_FLASH
38a24a612   wdenk   Initial revision
282
  	if (argc == 1) {	/* print info for all FLASH banks */
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
283
  		for (bank=0; bank <CONFIG_SYS_MAX_FLASH_BANKS; ++bank) {
38a24a612   wdenk   Initial revision
284
285
286
287
288
289
290
291
292
  			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...
293
  	if ((bank < 1) || (bank > CONFIG_SYS_MAX_FLASH_BANKS)) {
38a24a612   wdenk   Initial revision
294
295
  		printf ("Only FLASH Banks # 1 ... # %d supported
  ",
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
296
  			CONFIG_SYS_MAX_FLASH_BANKS);
38a24a612   wdenk   Initial revision
297
298
299
300
301
  		return 1;
  	}
  	printf ("
  Bank # %ld: ", bank);
  	flash_print_info (&flash_info[bank-1]);
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
302
  #endif /* CONFIG_SYS_NO_FLASH */
38a24a612   wdenk   Initial revision
303
304
  	return 0;
  }
700a0c648   Wolfgang Denk   Add common (with ...
305

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

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

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

088f1b199   Kim Phillips   common/cmd_*.c: s...
438
  static int do_protect(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
38a24a612   wdenk   Initial revision
439
  {
5b3901d9a   Marek Vasut   GCC4.6: Squash wa...
440
  	int rcode = 0;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
441
  #ifndef CONFIG_SYS_NO_FLASH
4f5710f74   Wolfgang Denk   common/cmd_flash....
442
  	flash_info_t *info = NULL;
880cc4381   Stelian Pop   Fix CFG_NO_FLASH ...
443
  	ulong bank;
4f5710f74   Wolfgang Denk   common/cmd_flash....
444
  	int i, n, sect_first = 0, sect_last = 0;
c000808b6   Alexander Stein   CONFIG_CMD_JFFS2 ...
445
  #if defined(CONFIG_CMD_MTDPARTS)
700a0c648   Wolfgang Denk   Add common (with ...
446
447
448
449
  	struct mtd_device *dev;
  	struct part_info *part;
  	u8 dev_type, dev_num, pnum;
  #endif
3a26c43e4   Remy Bohmer   Fix build warning...
450
  #endif /* CONFIG_SYS_NO_FLASH */
5779d8d98   wdenk   * Patch by Nicola...
451
452
453
  #ifdef CONFIG_HAS_DATAFLASH
  	int status;
  #endif
5b3901d9a   Marek Vasut   GCC4.6: Squash wa...
454
  #if !defined(CONFIG_SYS_NO_FLASH) || defined(CONFIG_HAS_DATAFLASH)
5669ed455   Wolfgang Denk   cmd_flash.c: fix ...
455
  	int p;
5b3901d9a   Marek Vasut   GCC4.6: Squash wa...
456
457
  	ulong addr_first, addr_last;
  #endif
2662b40ca   Stefan Roese   * Changes/fixes f...
458

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

5b3901d9a   Marek Vasut   GCC4.6: Squash wa...
462
  #if !defined(CONFIG_SYS_NO_FLASH) || defined(CONFIG_HAS_DATAFLASH)
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
463
  	if (strcmp(argv[1], "off") == 0)
38a24a612   wdenk   Initial revision
464
  		p = 0;
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
465
  	else if (strcmp(argv[1], "on") == 0)
38a24a612   wdenk   Initial revision
466
  		p = 1;
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
467
  	else
4c12eeb8b   Simon Glass   Convert cmd_usage...
468
  		return CMD_RET_USAGE;
5b3901d9a   Marek Vasut   GCC4.6: Squash wa...
469
  #endif
38a24a612   wdenk   Initial revision
470

5779d8d98   wdenk   * Patch by Nicola...
471
472
473
474
475
476
477
478
  #ifdef CONFIG_HAS_DATAFLASH
  	if ((strcmp(argv[2], "all") != 0) && (strcmp(argv[2], "bank") != 0)) {
  		addr_first = simple_strtoul(argv[2], NULL, 16);
  		addr_last  = simple_strtoul(argv[3], NULL, 16);
  
  		if (addr_dataflash(addr_first) && addr_dataflash(addr_last)) {
  			status = dataflash_real_protect(p,addr_first,addr_last);
  			if (status < 0){
4b9206ed5   wdenk   * Patches by Thom...
479
480
  				puts ("Bad DataFlash sector specification
  ");
d4ca31c40   wdenk   * Cleanup lowboot...
481
482
483
484
485
  				return 1;
  			}
  			printf("%sProtect %d DataFlash Sectors
  ",
  				p ? "" : "Un-", status);
5779d8d98   wdenk   * Patch by Nicola...
486
487
488
489
  			return 0;
  		}
  	}
  #endif
d4ca31c40   wdenk   * Cleanup lowboot...
490

6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
491
  #ifndef CONFIG_SYS_NO_FLASH
38a24a612   wdenk   Initial revision
492
  	if (strcmp(argv[2], "all") == 0) {
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
493
  		for (bank=1; bank<=CONFIG_SYS_MAX_FLASH_BANKS; ++bank) {
38a24a612   wdenk   Initial revision
494
495
496
497
498
499
500
501
502
  			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...
503
  #if defined(CONFIG_SYS_FLASH_PROTECTION)
38a24a612   wdenk   Initial revision
504
505
506
507
508
  				if (flash_real_protect(info, i, p))
  					rcode = 1;
  				putc ('.');
  #else
  				info->protect[i] = p;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
509
  #endif	/* CONFIG_SYS_FLASH_PROTECTION */
38a24a612   wdenk   Initial revision
510
  			}
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
511
  #if defined(CONFIG_SYS_FLASH_PROTECTION)
bb74140de   Heiko Schocher   Fixes common/cmd_...
512
513
  			if (!rcode) puts (" done
  ");
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
514
  #endif	/* CONFIG_SYS_FLASH_PROTECTION */
bb74140de   Heiko Schocher   Fixes common/cmd_...
515
  		}
38a24a612   wdenk   Initial revision
516
517
518
519
520
  		return rcode;
  	}
  
  	if ((n = abbrev_spec(argv[2], &info, &sect_first, &sect_last)) != 0) {
  		if (n < 0) {
4b9206ed5   wdenk   * Patches by Thom...
521
522
  			puts ("Bad sector specification
  ");
38a24a612   wdenk   Initial revision
523
524
  			return 1;
  		}
f2302d443   Stefan Roese   Fix merge problems
525
526
  		printf("%sProtect Flash Sectors %d-%d in Bank # %zu
  ",
38a24a612   wdenk   Initial revision
527
528
529
  			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...
530
  #if defined(CONFIG_SYS_FLASH_PROTECTION)
38a24a612   wdenk   Initial revision
531
532
533
534
535
  			if (flash_real_protect(info, i, p))
  				rcode =  1;
  			putc ('.');
  #else
  			info->protect[i] = p;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
536
  #endif	/* CONFIG_SYS_FLASH_PROTECTION */
38a24a612   wdenk   Initial revision
537
  		}
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
538
  #if defined(CONFIG_SYS_FLASH_PROTECTION)
38a24a612   wdenk   Initial revision
539
540
  		if (!rcode) puts (" done
  ");
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
541
  #endif	/* CONFIG_SYS_FLASH_PROTECTION */
38a24a612   wdenk   Initial revision
542
543
544
  
  		return rcode;
  	}
8f79e4c2d   Wolfgang Denk   Add configuration...
545

c000808b6   Alexander Stein   CONFIG_CMD_JFFS2 ...
546
  #if defined(CONFIG_CMD_MTDPARTS)
700a0c648   Wolfgang Denk   Add common (with ...
547
  	/* protect on/off <part-id> */
68d7d6510   Stefan Roese   Separate mtdparts...
548
  	if ((argc == 3) && (mtd_id_parse(argv[2], NULL, &dev_type, &dev_num) == 0)) {
700a0c648   Wolfgang Denk   Add common (with ...
549
550
551
552
553
554
555
  		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"...
556
  				printf ("%sProtect Flash Partition %s, "
4109df6f7   Kim Phillips   silence misc prin...
557
558
  						"bank %ld, 0x%08lx - 0x%08lx
  ",
700a0c648   Wolfgang Denk   Add common (with ...
559
560
561
562
563
564
565
566
567
568
569
570
571
572
  						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
573

47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
574
  	if (argc != 4)
4c12eeb8b   Simon Glass   Convert cmd_usage...
575
  		return CMD_RET_USAGE;
38a24a612   wdenk   Initial revision
576
577
578
  
  	if (strcmp(argv[2], "bank") == 0) {
  		bank = simple_strtoul(argv[3], NULL, 16);
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
579
  		if ((bank < 1) || (bank > CONFIG_SYS_MAX_FLASH_BANKS)) {
38a24a612   wdenk   Initial revision
580
581
  			printf ("Only FLASH Banks # 1 ... # %d supported
  ",
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
582
  				CONFIG_SYS_MAX_FLASH_BANKS);
38a24a612   wdenk   Initial revision
583
584
585
586
587
588
589
590
  			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...
591
592
  			puts ("missing or unknown FLASH type
  ");
38a24a612   wdenk   Initial revision
593
594
595
  			return 1;
  		}
  		for (i=0; i<info->sector_count; ++i) {
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
596
  #if defined(CONFIG_SYS_FLASH_PROTECTION)
38a24a612   wdenk   Initial revision
597
598
599
600
601
  			if (flash_real_protect(info, i, p))
  				rcode =  1;
  			putc ('.');
  #else
  			info->protect[i] = p;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
602
  #endif	/* CONFIG_SYS_FLASH_PROTECTION */
38a24a612   wdenk   Initial revision
603
  		}
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
604
  #if defined(CONFIG_SYS_FLASH_PROTECTION)
38a24a612   wdenk   Initial revision
605
606
  		if (!rcode) puts (" done
  ");
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
607
  #endif	/* CONFIG_SYS_FLASH_PROTECTION */
38a24a612   wdenk   Initial revision
608
609
610
  
  		return rcode;
  	}
f530187db   Wolfgang Denk   Add new argument ...
611
612
613
614
615
  	if (addr_spec(argv[2], argv[3], &addr_first, &addr_last) < 0){
  		printf("Bad address format
  ");
  		return 1;
  	}
38a24a612   wdenk   Initial revision
616

47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
617
  	if (addr_first >= addr_last)
4c12eeb8b   Simon Glass   Convert cmd_usage...
618
  		return CMD_RET_USAGE;
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
619

38a24a612   wdenk   Initial revision
620
  	rcode = flash_sect_protect (p, addr_first, addr_last);
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
621
  #endif /* CONFIG_SYS_NO_FLASH */
38a24a612   wdenk   Initial revision
622
623
  	return rcode;
  }
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
624
  #ifndef CONFIG_SYS_NO_FLASH
38a24a612   wdenk   Initial revision
625
626
627
628
  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...
629
  	int s_first[CONFIG_SYS_MAX_FLASH_BANKS], s_last[CONFIG_SYS_MAX_FLASH_BANKS];
38a24a612   wdenk   Initial revision
630
  	int protected, i;
bdccc4fed   wdenk   * Map ISP1362 USB...
631
632
  	int planned;
  	int rcode;
38a24a612   wdenk   Initial revision
633

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

bdccc4fed   wdenk   * Map ISP1362 USB...
636
  	protected = 0;
38a24a612   wdenk   Initial revision
637

bdccc4fed   wdenk   * Map ISP1362 USB...
638
  	if (planned && (rcode == 0)) {
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
639
  		for (bank=0,info = &flash_info[0]; bank < CONFIG_SYS_MAX_FLASH_BANKS; ++bank, ++info) {
bdccc4fed   wdenk   * Map ISP1362 USB...
640
  			if (info->flash_id == FLASH_UNKNOWN) {
38a24a612   wdenk   Initial revision
641
  				continue;
38a24a612   wdenk   Initial revision
642
  			}
bdccc4fed   wdenk   * Map ISP1362 USB...
643
644
  
  			if (s_first[bank]>=0 && s_first[bank]<=s_last[bank]) {
abcac8725   stroese   Fix output for "U...
645
646
647
  				debug ("%sProtecting sectors %d..%d in bank %ld
  ",
  					p ? "" : "Un-",
bdccc4fed   wdenk   * Map ISP1362 USB...
648
649
650
  					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...
651
  #if defined(CONFIG_SYS_FLASH_PROTECTION)
bdccc4fed   wdenk   * Map ISP1362 USB...
652
653
654
  					if (flash_real_protect(info, i, p))
  						rcode = 1;
  					putc ('.');
38a24a612   wdenk   Initial revision
655
  #else
bdccc4fed   wdenk   * Map ISP1362 USB...
656
  					info->protect[i] = p;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
657
  #endif	/* CONFIG_SYS_FLASH_PROTECTION */
bdccc4fed   wdenk   * Map ISP1362 USB...
658
  				}
38a24a612   wdenk   Initial revision
659
  			}
2662b40ca   Stefan Roese   * Changes/fixes f...
660
  		}
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
661
  #if defined(CONFIG_SYS_FLASH_PROTECTION)
2662b40ca   Stefan Roese   * Changes/fixes f...
662
663
  		puts (" done
  ");
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
664
  #endif	/* CONFIG_SYS_FLASH_PROTECTION */
38a24a612   wdenk   Initial revision
665

38a24a612   wdenk   Initial revision
666
667
668
  		printf ("%sProtected %d sectors
  ",
  			p ? "" : "Un-", protected);
bdccc4fed   wdenk   * Map ISP1362 USB...
669
  	} else if (rcode == 0) {
4b9206ed5   wdenk   * Patches by Thom...
670
  		puts ("Error: start and/or end address"
38a24a612   wdenk   Initial revision
671
672
673
674
675
676
  			" not on sector boundary
  ");
  		rcode = 1;
  	}
  	return rcode;
  }
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
677
  #endif /* CONFIG_SYS_NO_FLASH */
38a24a612   wdenk   Initial revision
678

8bde7f776   wdenk   * Code cleanup:
679
680
  
  /**************************************************/
c000808b6   Alexander Stein   CONFIG_CMD_JFFS2 ...
681
  #if defined(CONFIG_CMD_MTDPARTS)
c19c31347   Wolfgang Denk   Fix compiler warn...
682
683
684
685
686
687
688
689
690
691
692
693
694
695
  # 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:
696

0d4983930   wdenk   Patch by Kenneth ...
697
698
  U_BOOT_CMD(
  	flinfo,    2,    1,    do_flinfo,
2fb2604d5   Peter Tyser   Command usage cle...
699
  	"print FLASH memory information",
8bde7f776   wdenk   * Code cleanup:
700
701
702
  	"
      - print information for all FLASH memory banks
  "
a89c33db9   Wolfgang Denk   General help mess...
703
704
  	"flinfo N
      - print information for FLASH memory bank # N"
8bde7f776   wdenk   * Code cleanup:
705
  );
0d4983930   wdenk   Patch by Kenneth ...
706
  U_BOOT_CMD(
9912121f7   Detlev Zundel   Change 'repeatabl...
707
  	erase,   3,   0,  do_flerase,
2fb2604d5   Peter Tyser   Command usage cle...
708
  	"erase FLASH memory",
8bde7f776   wdenk   * Code cleanup:
709
710
711
712
  	"start end
  "
  	"    - erase FLASH from addr 'start' to addr 'end'
  "
f530187db   Wolfgang Denk   Add new argument ...
713
714
715
716
717
  	"erase start +len
  "
  	"    - erase FLASH from addr 'start' to the end of sect "
  	"w/addr 'start'+'len'-1
  "
8bde7f776   wdenk   * Code cleanup:
718
719
720
721
722
723
  	"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...
724
  	TMP_ERASE
a89c33db9   Wolfgang Denk   General help mess...
725
726
  	"erase all
      - erase all FLASH banks"
8bde7f776   wdenk   * Code cleanup:
727
  );
0d4983930   wdenk   Patch by Kenneth ...
728
  U_BOOT_CMD(
9912121f7   Detlev Zundel   Change 'repeatabl...
729
  	protect,  4,  0,   do_protect,
2fb2604d5   Peter Tyser   Command usage cle...
730
  	"enable or disable FLASH write protection",
8bde7f776   wdenk   * Code cleanup:
731
732
733
734
  	"on  start end
  "
  	"    - protect FLASH from addr 'start' to addr 'end'
  "
f530187db   Wolfgang Denk   Add new argument ...
735
736
737
738
739
  	"protect on start +len
  "
  	"    - protect FLASH from addr 'start' to end of sect "
  	"w/addr 'start'+'len'-1
  "
8bde7f776   wdenk   * Code cleanup:
740
741
742
743
744
745
746
  	"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...
747
  	TMP_PROT_ON
8bde7f776   wdenk   * Code cleanup:
748
749
750
751
752
753
754
  	"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 ...
755
756
757
758
759
  	"protect off start +len
  "
  	"    - make FLASH from addr 'start' to end of sect "
  	"w/addr 'start'+'len'-1 wrtable
  "
8bde7f776   wdenk   * Code cleanup:
760
761
762
763
764
765
766
  	"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...
767
  	TMP_PROT_OFF
a89c33db9   Wolfgang Denk   General help mess...
768
769
  	"protect off all
      - make all FLASH banks writable"
8bde7f776   wdenk   * Code cleanup:
770
  );
c19c31347   Wolfgang Denk   Fix compiler warn...
771
772
773
  #undef	TMP_ERASE
  #undef	TMP_PROT_ON
  #undef	TMP_PROT_OFF