Blame view

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

c000808b6   Alexander Stein   CONFIG_CMD_JFFS2 ...
516
  #if defined(CONFIG_CMD_MTDPARTS)
700a0c648   Wolfgang Denk   Add common (with ...
517
  	/* protect on/off <part-id> */
68d7d6510   Stefan Roese   Separate mtdparts...
518
  	if ((argc == 3) && (mtd_id_parse(argv[2], NULL, &dev_type, &dev_num) == 0)) {
700a0c648   Wolfgang Denk   Add common (with ...
519
520
521
522
523
524
525
  		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"...
526
  				printf ("%sProtect Flash Partition %s, "
4109df6f7   Kim Phillips   silence misc prin...
527
528
  						"bank %ld, 0x%08lx - 0x%08lx
  ",
700a0c648   Wolfgang Denk   Add common (with ...
529
530
531
532
533
534
535
536
537
538
539
540
541
542
  						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
543

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

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

38a24a612   wdenk   Initial revision
590
  	rcode = flash_sect_protect (p, addr_first, addr_last);
e856bdcfb   Masahiro Yamada   flash: complete C...
591
  #endif /* CONFIG_MTD_NOR_FLASH */
38a24a612   wdenk   Initial revision
592
593
  	return rcode;
  }
e856bdcfb   Masahiro Yamada   flash: complete C...
594
  #ifdef CONFIG_MTD_NOR_FLASH
38a24a612   wdenk   Initial revision
595
596
597
598
  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...
599
  	int s_first[CONFIG_SYS_MAX_FLASH_BANKS], s_last[CONFIG_SYS_MAX_FLASH_BANKS];
38a24a612   wdenk   Initial revision
600
  	int protected, i;
bdccc4fed   wdenk   * Map ISP1362 USB...
601
602
  	int planned;
  	int rcode;
38a24a612   wdenk   Initial revision
603

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

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

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

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

8bde7f776   wdenk   * Code cleanup:
649
650
  
  /**************************************************/
c000808b6   Alexander Stein   CONFIG_CMD_JFFS2 ...
651
  #if defined(CONFIG_CMD_MTDPARTS)
c19c31347   Wolfgang Denk   Fix compiler warn...
652
653
654
655
656
657
658
659
660
661
662
663
664
665
  # 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:
666

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