Blame view

common/cmd_mem.c 26.9 KB
3863585bb   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+
3863585bb   wdenk   Initial revision
6
7
8
9
10
11
12
13
14
15
   */
  
  /*
   * Memory Functions
   *
   * Copied from FADS ROM, Dan Malek (dmalek@jlc.net)
   */
  
  #include <common.h>
  #include <command.h>
2abbe0754   wdenk   * Patch by Nicola...
16
17
18
  #ifdef CONFIG_HAS_DATAFLASH
  #include <dataflash.h>
  #endif
d20a40de9   Simon Glass   Roll crc32 into h...
19
  #include <hash.h>
a6e6fc610   Sergei Poselenov   Added watchdog tr...
20
  #include <watchdog.h>
0628ab8ec   Simon Glass   sandbox: Change m...
21
  #include <asm/io.h>
15a33e49d   Simon Glass   Add option to dis...
22
23
24
  #include <linux/compiler.h>
  
  DECLARE_GLOBAL_DATA_PTR;
3863585bb   wdenk   Initial revision
25

8e169cc94   Simon Glass   Move CONFIG_SYS_M...
26
27
28
  #ifndef CONFIG_SYS_MEMTEST_SCRATCH
  #define CONFIG_SYS_MEMTEST_SCRATCH 0
  #endif
54841ab50   Wolfgang Denk   Make sure that ar...
29
  static int mod_mem(cmd_tbl_t *, int, int, int, char * const []);
3863585bb   wdenk   Initial revision
30
31
32
33
  
  /* Display values from last command.
   * Memory modify remembered values are different from display memory.
   */
d6efe244e   Mike Frysinger   cmd_mem: localize...
34
35
36
  static uint	dp_last_addr, dp_last_size;
  static uint	dp_last_length = 0x40;
  static uint	mm_last_addr, mm_last_size;
3863585bb   wdenk   Initial revision
37
38
39
40
41
42
43
44
45
  
  static	ulong	base_address = 0;
  
  /* Memory Display
   *
   * Syntax:
   *	md{.b, .w, .l} {addr} {len}
   */
  #define DISP_LINE_LEN	16
088f1b199   Kim Phillips   common/cmd_*.c: s...
46
  static int do_mem_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
3863585bb   wdenk   Initial revision
47
  {
27b207fd0   wdenk   * Implement new m...
48
  	ulong	addr, length;
c95c4280d   Grant Likely   [PATCH 3_9] Move ...
49
50
51
  #if defined(CONFIG_HAS_DATAFLASH)
  	ulong	nbytes, linebytes;
  #endif
27b207fd0   wdenk   * Implement new m...
52
  	int	size;
3863585bb   wdenk   Initial revision
53
54
55
56
57
58
59
60
  	int rc = 0;
  
  	/* We use the last specified parameters, unless new ones are
  	 * entered.
  	 */
  	addr = dp_last_addr;
  	size = dp_last_size;
  	length = dp_last_length;
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
61
  	if (argc < 2)
4c12eeb8b   Simon Glass   Convert cmd_usage...
62
  		return CMD_RET_USAGE;
3863585bb   wdenk   Initial revision
63
64
65
66
67
  
  	if ((flag & CMD_FLAG_REPEAT) == 0) {
  		/* New command specified.  Check for a size specification.
  		 * Defaults to long if no or incorrect specification.
  		 */
27b207fd0   wdenk   * Implement new m...
68
69
  		if ((size = cmd_get_data_size(argv[0], 4)) < 0)
  			return 1;
3863585bb   wdenk   Initial revision
70
71
72
73
74
75
76
77
78
79
80
81
  
  		/* Address is specified since argc > 1
  		*/
  		addr = simple_strtoul(argv[1], NULL, 16);
  		addr += base_address;
  
  		/* If another parameter, it is the length to display.
  		 * Length is the number of objects, not number of bytes.
  		 */
  		if (argc > 2)
  			length = simple_strtoul(argv[2], NULL, 16);
  	}
c95c4280d   Grant Likely   [PATCH 3_9] Move ...
82
  #if defined(CONFIG_HAS_DATAFLASH)
3863585bb   wdenk   Initial revision
83
84
85
86
87
88
89
90
  	/* Print the lines.
  	 *
  	 * We buffer all read data, so we can make sure data is read only
  	 * once, and all accesses are with the specified bus width.
  	 */
  	nbytes = length * size;
  	do {
  		char	linebuf[DISP_LINE_LEN];
c95c4280d   Grant Likely   [PATCH 3_9] Move ...
91
  		void* p;
3863585bb   wdenk   Initial revision
92
  		linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes;
2abbe0754   wdenk   * Patch by Nicola...
93

c95c4280d   Grant Likely   [PATCH 3_9] Move ...
94
95
96
  		rc = read_dataflash(addr, (linebytes/size)*size, linebuf);
  		p = (rc == DATAFLASH_OK) ? linebuf : (void*)addr;
  		print_buffer(addr, p, size, linebytes/size, DISP_LINE_LEN/size);
3863585bb   wdenk   Initial revision
97
  		nbytes -= linebytes;
c95c4280d   Grant Likely   [PATCH 3_9] Move ...
98
  		addr += linebytes;
3863585bb   wdenk   Initial revision
99
100
101
102
103
  		if (ctrlc()) {
  			rc = 1;
  			break;
  		}
  	} while (nbytes > 0);
c95c4280d   Grant Likely   [PATCH 3_9] Move ...
104
  #else
4c727c77e   Mike Frysinger   add support for m...
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
  
  # if defined(CONFIG_BLACKFIN)
  	/* See if we're trying to display L1 inst */
  	if (addr_bfin_on_chip_mem(addr)) {
  		char linebuf[DISP_LINE_LEN];
  		ulong linebytes, nbytes = length * size;
  		do {
  			linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes;
  			memcpy(linebuf, (void *)addr, linebytes);
  			print_buffer(addr, linebuf, size, linebytes/size, DISP_LINE_LEN/size);
  
  			nbytes -= linebytes;
  			addr += linebytes;
  			if (ctrlc()) {
  				rc = 1;
  				break;
  			}
  		} while (nbytes > 0);
  	} else
  # endif
  
  	{
0628ab8ec   Simon Glass   sandbox: Change m...
127
128
  		ulong bytes = size * length;
  		const void *buf = map_sysmem(addr, bytes);
4c727c77e   Mike Frysinger   add support for m...
129
  		/* Print the lines. */
0628ab8ec   Simon Glass   sandbox: Change m...
130
131
132
  		print_buffer(addr, buf, size, length, DISP_LINE_LEN / size);
  		addr += bytes;
  		unmap_sysmem(buf);
4c727c77e   Mike Frysinger   add support for m...
133
  	}
c95c4280d   Grant Likely   [PATCH 3_9] Move ...
134
  #endif
3863585bb   wdenk   Initial revision
135
136
137
138
139
140
  
  	dp_last_addr = addr;
  	dp_last_length = length;
  	dp_last_size = size;
  	return (rc);
  }
088f1b199   Kim Phillips   common/cmd_*.c: s...
141
  static int do_mem_mm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
3863585bb   wdenk   Initial revision
142
143
144
  {
  	return mod_mem (cmdtp, 1, flag, argc, argv);
  }
088f1b199   Kim Phillips   common/cmd_*.c: s...
145
  static int do_mem_nm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
3863585bb   wdenk   Initial revision
146
147
148
  {
  	return mod_mem (cmdtp, 0, flag, argc, argv);
  }
088f1b199   Kim Phillips   common/cmd_*.c: s...
149
  static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
3863585bb   wdenk   Initial revision
150
  {
27b207fd0   wdenk   * Implement new m...
151
152
  	ulong	addr, writeval, count;
  	int	size;
0628ab8ec   Simon Glass   sandbox: Change m...
153
154
  	void *buf;
  	ulong bytes;
3863585bb   wdenk   Initial revision
155

47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
156
  	if ((argc < 3) || (argc > 4))
4c12eeb8b   Simon Glass   Convert cmd_usage...
157
  		return CMD_RET_USAGE;
3863585bb   wdenk   Initial revision
158
159
160
  
  	/* Check for size specification.
  	*/
27b207fd0   wdenk   * Implement new m...
161
162
  	if ((size = cmd_get_data_size(argv[0], 4)) < 1)
  		return 1;
3863585bb   wdenk   Initial revision
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
  
  	/* Address is specified since argc > 1
  	*/
  	addr = simple_strtoul(argv[1], NULL, 16);
  	addr += base_address;
  
  	/* Get the value to write.
  	*/
  	writeval = simple_strtoul(argv[2], NULL, 16);
  
  	/* Count ? */
  	if (argc == 4) {
  		count = simple_strtoul(argv[3], NULL, 16);
  	} else {
  		count = 1;
  	}
0628ab8ec   Simon Glass   sandbox: Change m...
179
180
  	bytes = size * count;
  	buf = map_sysmem(addr, bytes);
3863585bb   wdenk   Initial revision
181
182
  	while (count-- > 0) {
  		if (size == 4)
76698b4e6   York Sun   Fix memory comman...
183
  			*((u32 *)buf) = (u32)writeval;
3863585bb   wdenk   Initial revision
184
  		else if (size == 2)
76698b4e6   York Sun   Fix memory comman...
185
  			*((u16 *)buf) = (u16)writeval;
3863585bb   wdenk   Initial revision
186
  		else
76698b4e6   York Sun   Fix memory comman...
187
  			*((u8 *)buf) = (u8)writeval;
0628ab8ec   Simon Glass   sandbox: Change m...
188
  		buf += size;
3863585bb   wdenk   Initial revision
189
  	}
0628ab8ec   Simon Glass   sandbox: Change m...
190
  	unmap_sysmem(buf);
3863585bb   wdenk   Initial revision
191
192
  	return 0;
  }
4aaf29b2f   stroese   memory commands "...
193
  #ifdef CONFIG_MX_CYCLIC
54841ab50   Wolfgang Denk   Make sure that ar...
194
  int do_mem_mdc ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
4aaf29b2f   stroese   memory commands "...
195
196
197
  {
  	int i;
  	ulong count;
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
198
  	if (argc < 4)
4c12eeb8b   Simon Glass   Convert cmd_usage...
199
  		return CMD_RET_USAGE;
4aaf29b2f   stroese   memory commands "...
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
  
  	count = simple_strtoul(argv[3], NULL, 10);
  
  	for (;;) {
  		do_mem_md (NULL, 0, 3, argv);
  
  		/* delay for <count> ms... */
  		for (i=0; i<count; i++)
  			udelay (1000);
  
  		/* check for ctrl-c to abort... */
  		if (ctrlc()) {
  			puts("Abort
  ");
  			return 0;
  		}
  	}
  
  	return 0;
  }
54841ab50   Wolfgang Denk   Make sure that ar...
220
  int do_mem_mwc ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
4aaf29b2f   stroese   memory commands "...
221
222
223
  {
  	int i;
  	ulong count;
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
224
  	if (argc < 4)
4c12eeb8b   Simon Glass   Convert cmd_usage...
225
  		return CMD_RET_USAGE;
4aaf29b2f   stroese   memory commands "...
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
  
  	count = simple_strtoul(argv[3], NULL, 10);
  
  	for (;;) {
  		do_mem_mw (NULL, 0, 3, argv);
  
  		/* delay for <count> ms... */
  		for (i=0; i<count; i++)
  			udelay (1000);
  
  		/* check for ctrl-c to abort... */
  		if (ctrlc()) {
  			puts("Abort
  ");
  			return 0;
  		}
  	}
  
  	return 0;
  }
  #endif /* CONFIG_MX_CYCLIC */
088f1b199   Kim Phillips   common/cmd_*.c: s...
247
  static int do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
3863585bb   wdenk   Initial revision
248
  {
0628ab8ec   Simon Glass   sandbox: Change m...
249
  	ulong	addr1, addr2, count, ngood, bytes;
27b207fd0   wdenk   * Implement new m...
250
  	int	size;
3863585bb   wdenk   Initial revision
251
  	int     rcode = 0;
054ea170f   Mike Frysinger   cmd_mem: cmp: uni...
252
  	const char *type;
0628ab8ec   Simon Glass   sandbox: Change m...
253
  	const void *buf1, *buf2, *base;
3863585bb   wdenk   Initial revision
254

47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
255
  	if (argc != 4)
4c12eeb8b   Simon Glass   Convert cmd_usage...
256
  		return CMD_RET_USAGE;
3863585bb   wdenk   Initial revision
257
258
259
  
  	/* Check for size specification.
  	*/
27b207fd0   wdenk   * Implement new m...
260
261
  	if ((size = cmd_get_data_size(argv[0], 4)) < 0)
  		return 1;
054ea170f   Mike Frysinger   cmd_mem: cmp: uni...
262
  	type = size == 4 ? "word" : size == 2 ? "halfword" : "byte";
3863585bb   wdenk   Initial revision
263
264
265
266
267
268
269
270
  
  	addr1 = simple_strtoul(argv[1], NULL, 16);
  	addr1 += base_address;
  
  	addr2 = simple_strtoul(argv[2], NULL, 16);
  	addr2 += base_address;
  
  	count = simple_strtoul(argv[3], NULL, 16);
2abbe0754   wdenk   * Patch by Nicola...
271
272
  #ifdef CONFIG_HAS_DATAFLASH
  	if (addr_dataflash(addr1) | addr_dataflash(addr2)){
4b9206ed5   wdenk   * Patches by Thom...
273
274
  		puts ("Comparison with DataFlash space not supported.
  \r");
2abbe0754   wdenk   * Patch by Nicola...
275
276
277
  		return 0;
  	}
  #endif
4c727c77e   Mike Frysinger   add support for m...
278
279
280
281
282
283
284
  #ifdef CONFIG_BLACKFIN
  	if (addr_bfin_on_chip_mem(addr1) || addr_bfin_on_chip_mem(addr2)) {
  		puts ("Comparison with L1 instruction memory not supported.
  \r");
  		return 0;
  	}
  #endif
0628ab8ec   Simon Glass   sandbox: Change m...
285
286
287
  	bytes = size * count;
  	base = buf1 = map_sysmem(addr1, bytes);
  	buf2 = map_sysmem(addr2, bytes);
feb12a1f6   Mike Frysinger   cmd_mem: cmp: con...
288
  	for (ngood = 0; ngood < count; ++ngood) {
054ea170f   Mike Frysinger   cmd_mem: cmp: uni...
289
  		ulong word1, word2;
3863585bb   wdenk   Initial revision
290
  		if (size == 4) {
76698b4e6   York Sun   Fix memory comman...
291
292
  			word1 = *(u32 *)buf1;
  			word2 = *(u32 *)buf2;
054ea170f   Mike Frysinger   cmd_mem: cmp: uni...
293
  		} else if (size == 2) {
76698b4e6   York Sun   Fix memory comman...
294
295
  			word1 = *(u16 *)buf1;
  			word2 = *(u16 *)buf2;
054ea170f   Mike Frysinger   cmd_mem: cmp: uni...
296
  		} else {
76698b4e6   York Sun   Fix memory comman...
297
298
  			word1 = *(u8 *)buf1;
  			word2 = *(u8 *)buf2;
3863585bb   wdenk   Initial revision
299
  		}
054ea170f   Mike Frysinger   cmd_mem: cmp: uni...
300
  		if (word1 != word2) {
0628ab8ec   Simon Glass   sandbox: Change m...
301
  			ulong offset = buf1 - base;
054ea170f   Mike Frysinger   cmd_mem: cmp: uni...
302
303
  			printf("%s at 0x%08lx (%#0*lx) != %s at 0x%08lx (%#0*lx)
  ",
0628ab8ec   Simon Glass   sandbox: Change m...
304
305
  				type, (ulong)(addr1 + offset), size, word1,
  				type, (ulong)(addr2 + offset), size, word2);
054ea170f   Mike Frysinger   cmd_mem: cmp: uni...
306
307
  			rcode = 1;
  			break;
3863585bb   wdenk   Initial revision
308
  		}
054ea170f   Mike Frysinger   cmd_mem: cmp: uni...
309

0628ab8ec   Simon Glass   sandbox: Change m...
310
311
  		buf1 += size;
  		buf2 += size;
eaadb44ed   Stefan Roese   cp/cmp: Add WATCH...
312
313
  
  		/* reset watchdog from time to time */
feb12a1f6   Mike Frysinger   cmd_mem: cmp: con...
314
  		if ((ngood % (64 << 10)) == 0)
eaadb44ed   Stefan Roese   cp/cmp: Add WATCH...
315
  			WATCHDOG_RESET();
3863585bb   wdenk   Initial revision
316
  	}
0628ab8ec   Simon Glass   sandbox: Change m...
317
318
  	unmap_sysmem(buf1);
  	unmap_sysmem(buf2);
3863585bb   wdenk   Initial revision
319

054ea170f   Mike Frysinger   cmd_mem: cmp: uni...
320
321
  	printf("Total of %ld %s(s) were the same
  ", ngood, type);
3863585bb   wdenk   Initial revision
322
323
  	return rcode;
  }
088f1b199   Kim Phillips   common/cmd_*.c: s...
324
  static int do_mem_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
3863585bb   wdenk   Initial revision
325
  {
0628ab8ec   Simon Glass   sandbox: Change m...
326
  	ulong	addr, dest, count, bytes;
27b207fd0   wdenk   * Implement new m...
327
  	int	size;
0628ab8ec   Simon Glass   sandbox: Change m...
328
329
  	const void *src;
  	void *buf;
3863585bb   wdenk   Initial revision
330

47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
331
  	if (argc != 4)
4c12eeb8b   Simon Glass   Convert cmd_usage...
332
  		return CMD_RET_USAGE;
3863585bb   wdenk   Initial revision
333
334
335
  
  	/* Check for size specification.
  	*/
27b207fd0   wdenk   * Implement new m...
336
337
  	if ((size = cmd_get_data_size(argv[0], 4)) < 0)
  		return 1;
3863585bb   wdenk   Initial revision
338
339
340
341
342
343
344
345
346
347
348
349
350
351
  
  	addr = simple_strtoul(argv[1], NULL, 16);
  	addr += base_address;
  
  	dest = simple_strtoul(argv[2], NULL, 16);
  	dest += base_address;
  
  	count = simple_strtoul(argv[3], NULL, 16);
  
  	if (count == 0) {
  		puts ("Zero length ???
  ");
  		return 1;
  	}
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
352
  #ifndef CONFIG_SYS_NO_FLASH
3863585bb   wdenk   Initial revision
353
  	/* check if we are copying to Flash */
2abbe0754   wdenk   * Patch by Nicola...
354
355
  	if ( (addr2info(dest) != NULL)
  #ifdef CONFIG_HAS_DATAFLASH
84d0c2f1e   Kim B. Heino   fix copy from ram...
356
  	   && (!addr_dataflash(dest))
2abbe0754   wdenk   * Patch by Nicola...
357
358
  #endif
  	   ) {
3863585bb   wdenk   Initial revision
359
  		int rc;
4b9206ed5   wdenk   * Patches by Thom...
360
  		puts ("Copy to Flash... ");
3863585bb   wdenk   Initial revision
361

77ddac948   Wolfgang Denk   Cleanup for GCC-4.x
362
  		rc = flash_write ((char *)addr, dest, count*size);
3863585bb   wdenk   Initial revision
363
364
365
366
367
368
369
370
371
  		if (rc != 0) {
  			flash_perror (rc);
  			return (1);
  		}
  		puts ("done
  ");
  		return 0;
  	}
  #endif
2abbe0754   wdenk   * Patch by Nicola...
372
373
374
375
  #ifdef CONFIG_HAS_DATAFLASH
  	/* Check if we are copying from RAM or Flash to DataFlash */
  	if (addr_dataflash(dest) && !addr_dataflash(addr)){
  		int rc;
4b9206ed5   wdenk   * Patches by Thom...
376
  		puts ("Copy to DataFlash... ");
2abbe0754   wdenk   * Patch by Nicola...
377
378
379
380
381
382
383
384
385
386
387
  
  		rc = write_dataflash (dest, addr, count*size);
  
  		if (rc != 1) {
  			dataflash_perror (rc);
  			return (1);
  		}
  		puts ("done
  ");
  		return 0;
  	}
8bde7f776   wdenk   * Code cleanup:
388

2abbe0754   wdenk   * Patch by Nicola...
389
  	/* Check if we are copying from DataFlash to RAM */
880cc4381   Stelian Pop   Fix CFG_NO_FLASH ...
390
  	if (addr_dataflash(addr) && !addr_dataflash(dest)
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
391
  #ifndef CONFIG_SYS_NO_FLASH
880cc4381   Stelian Pop   Fix CFG_NO_FLASH ...
392
393
394
  				 && (addr2info(dest) == NULL)
  #endif
  	   ){
5779d8d98   wdenk   * Patch by Nicola...
395
396
397
  		int rc;
  		rc = read_dataflash(addr, count * size, (char *) dest);
  		if (rc != 1) {
d4ca31c40   wdenk   * Cleanup lowboot...
398
399
400
  			dataflash_perror (rc);
  			return (1);
  		}
2abbe0754   wdenk   * Patch by Nicola...
401
402
403
404
  		return 0;
  	}
  
  	if (addr_dataflash(addr) && addr_dataflash(dest)){
4b9206ed5   wdenk   * Patches by Thom...
405
406
  		puts ("Unsupported combination of source/destination.
  \r");
2abbe0754   wdenk   * Patch by Nicola...
407
408
409
  		return 1;
  	}
  #endif
4c727c77e   Mike Frysinger   add support for m...
410
411
412
413
414
415
416
  #ifdef CONFIG_BLACKFIN
  	/* See if we're copying to/from L1 inst */
  	if (addr_bfin_on_chip_mem(dest) || addr_bfin_on_chip_mem(addr)) {
  		memcpy((void *)dest, (void *)addr, count * size);
  		return 0;
  	}
  #endif
0628ab8ec   Simon Glass   sandbox: Change m...
417
  	bytes = size * count;
53237afe5   Masahiro Yamada   cmd_mem: fix cp c...
418
  	buf = map_sysmem(dest, bytes);
0628ab8ec   Simon Glass   sandbox: Change m...
419
  	src = map_sysmem(addr, bytes);
3863585bb   wdenk   Initial revision
420
421
  	while (count-- > 0) {
  		if (size == 4)
76698b4e6   York Sun   Fix memory comman...
422
  			*((u32 *)buf) = *((u32  *)src);
3863585bb   wdenk   Initial revision
423
  		else if (size == 2)
76698b4e6   York Sun   Fix memory comman...
424
  			*((u16 *)buf) = *((u16 *)src);
3863585bb   wdenk   Initial revision
425
  		else
76698b4e6   York Sun   Fix memory comman...
426
  			*((u8 *)buf) = *((u8 *)src);
0628ab8ec   Simon Glass   sandbox: Change m...
427
428
  		src += size;
  		buf += size;
eaadb44ed   Stefan Roese   cp/cmp: Add WATCH...
429
430
431
432
  
  		/* reset watchdog from time to time */
  		if ((count % (64 << 10)) == 0)
  			WATCHDOG_RESET();
3863585bb   wdenk   Initial revision
433
434
435
  	}
  	return 0;
  }
088f1b199   Kim Phillips   common/cmd_*.c: s...
436
437
  static int do_mem_base(cmd_tbl_t *cmdtp, int flag, int argc,
  		       char * const argv[])
3863585bb   wdenk   Initial revision
438
439
440
441
442
443
444
445
446
447
448
449
  {
  	if (argc > 1) {
  		/* Set new base address.
  		*/
  		base_address = simple_strtoul(argv[1], NULL, 16);
  	}
  	/* Print the current base address.
  	*/
  	printf("Base Address: 0x%08lx
  ", base_address);
  	return 0;
  }
088f1b199   Kim Phillips   common/cmd_*.c: s...
450
451
  static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc,
  		       char * const argv[])
3863585bb   wdenk   Initial revision
452
  {
0628ab8ec   Simon Glass   sandbox: Change m...
453
  	ulong	addr, length, i, bytes;
27b207fd0   wdenk   * Implement new m...
454
  	int	size;
76698b4e6   York Sun   Fix memory comman...
455
456
457
  	volatile u32 *longp;
  	volatile u16 *shortp;
  	volatile u8 *cp;
0628ab8ec   Simon Glass   sandbox: Change m...
458
  	const void *buf;
3863585bb   wdenk   Initial revision
459

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

85de63e2e   Robert P. J. Day   cmd_mem.c: Fix so...
463
464
  	/*
  	 * Check for a size specification.
3863585bb   wdenk   Initial revision
465
466
  	 * Defaults to long if no or incorrect specification.
  	 */
27b207fd0   wdenk   * Implement new m...
467
468
  	if ((size = cmd_get_data_size(argv[0], 4)) < 0)
  		return 1;
3863585bb   wdenk   Initial revision
469
470
471
472
473
474
475
476
  
  	/* Address is always specified.
  	*/
  	addr = simple_strtoul(argv[1], NULL, 16);
  
  	/* Length is the number of objects, not number of bytes.
  	*/
  	length = simple_strtoul(argv[2], NULL, 16);
0628ab8ec   Simon Glass   sandbox: Change m...
477
478
  	bytes = size * length;
  	buf = map_sysmem(addr, bytes);
3863585bb   wdenk   Initial revision
479
480
481
482
483
  	/* We want to optimize the loops to run as fast as possible.
  	 * If we have only one object, just run infinite loops.
  	 */
  	if (length == 1) {
  		if (size == 4) {
76698b4e6   York Sun   Fix memory comman...
484
  			longp = (u32 *)buf;
3863585bb   wdenk   Initial revision
485
486
487
488
  			for (;;)
  				i = *longp;
  		}
  		if (size == 2) {
76698b4e6   York Sun   Fix memory comman...
489
  			shortp = (u16 *)buf;
3863585bb   wdenk   Initial revision
490
491
492
  			for (;;)
  				i = *shortp;
  		}
76698b4e6   York Sun   Fix memory comman...
493
  		cp = (u8 *)buf;
3863585bb   wdenk   Initial revision
494
495
496
497
498
499
  		for (;;)
  			i = *cp;
  	}
  
  	if (size == 4) {
  		for (;;) {
76698b4e6   York Sun   Fix memory comman...
500
  			longp = (u32 *)buf;
3863585bb   wdenk   Initial revision
501
502
  			i = length;
  			while (i-- > 0)
f3b3c3df1   Marek Vasut   GCC4.6: Squash wa...
503
  				*longp++;
3863585bb   wdenk   Initial revision
504
505
506
507
  		}
  	}
  	if (size == 2) {
  		for (;;) {
76698b4e6   York Sun   Fix memory comman...
508
  			shortp = (u16 *)buf;
3863585bb   wdenk   Initial revision
509
510
  			i = length;
  			while (i-- > 0)
f3b3c3df1   Marek Vasut   GCC4.6: Squash wa...
511
  				*shortp++;
3863585bb   wdenk   Initial revision
512
513
514
  		}
  	}
  	for (;;) {
76698b4e6   York Sun   Fix memory comman...
515
  		cp = (u8 *)buf;
3863585bb   wdenk   Initial revision
516
517
  		i = length;
  		while (i-- > 0)
f3b3c3df1   Marek Vasut   GCC4.6: Squash wa...
518
  			*cp++;
3863585bb   wdenk   Initial revision
519
  	}
0628ab8ec   Simon Glass   sandbox: Change m...
520
  	unmap_sysmem(buf);
92765f420   Simon Glass   Fix missing retur...
521
522
  
  	return 0;
3863585bb   wdenk   Initial revision
523
  }
56523f128   wdenk   * Patch by Martin...
524
  #ifdef CONFIG_LOOPW
54841ab50   Wolfgang Denk   Make sure that ar...
525
  int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
56523f128   wdenk   * Patch by Martin...
526
  {
0628ab8ec   Simon Glass   sandbox: Change m...
527
  	ulong	addr, length, i, data, bytes;
56523f128   wdenk   * Patch by Martin...
528
  	int	size;
76698b4e6   York Sun   Fix memory comman...
529
530
531
  	volatile u32 *longp;
  	volatile u16 *shortp;
  	volatile u8 *cp;
0628ab8ec   Simon Glass   sandbox: Change m...
532
  	void *buf;
810509266   wdenk   * Cleanup
533

47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
534
  	if (argc < 4)
4c12eeb8b   Simon Glass   Convert cmd_usage...
535
  		return CMD_RET_USAGE;
56523f128   wdenk   * Patch by Martin...
536

85de63e2e   Robert P. J. Day   cmd_mem.c: Fix so...
537
538
  	/*
  	 * Check for a size specification.
56523f128   wdenk   * Patch by Martin...
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
  	 * Defaults to long if no or incorrect specification.
  	 */
  	if ((size = cmd_get_data_size(argv[0], 4)) < 0)
  		return 1;
  
  	/* Address is always specified.
  	*/
  	addr = simple_strtoul(argv[1], NULL, 16);
  
  	/* Length is the number of objects, not number of bytes.
  	*/
  	length = simple_strtoul(argv[2], NULL, 16);
  
  	/* data to write */
  	data = simple_strtoul(argv[3], NULL, 16);
810509266   wdenk   * Cleanup
554

0628ab8ec   Simon Glass   sandbox: Change m...
555
556
  	bytes = size * length;
  	buf = map_sysmem(addr, bytes);
56523f128   wdenk   * Patch by Martin...
557
558
559
560
561
  	/* We want to optimize the loops to run as fast as possible.
  	 * If we have only one object, just run infinite loops.
  	 */
  	if (length == 1) {
  		if (size == 4) {
76698b4e6   York Sun   Fix memory comman...
562
  			longp = (u32 *)buf;
56523f128   wdenk   * Patch by Martin...
563
564
565
566
  			for (;;)
  				*longp = data;
  					}
  		if (size == 2) {
76698b4e6   York Sun   Fix memory comman...
567
  			shortp = (u16 *)buf;
56523f128   wdenk   * Patch by Martin...
568
569
570
  			for (;;)
  				*shortp = data;
  		}
76698b4e6   York Sun   Fix memory comman...
571
  		cp = (u8 *)buf;
56523f128   wdenk   * Patch by Martin...
572
573
574
575
576
577
  		for (;;)
  			*cp = data;
  	}
  
  	if (size == 4) {
  		for (;;) {
76698b4e6   York Sun   Fix memory comman...
578
  			longp = (u32 *)buf;
56523f128   wdenk   * Patch by Martin...
579
580
581
582
583
584
585
  			i = length;
  			while (i-- > 0)
  				*longp++ = data;
  		}
  	}
  	if (size == 2) {
  		for (;;) {
76698b4e6   York Sun   Fix memory comman...
586
  			shortp = (u16 *)buf;
56523f128   wdenk   * Patch by Martin...
587
588
589
590
591
592
  			i = length;
  			while (i-- > 0)
  				*shortp++ = data;
  		}
  	}
  	for (;;) {
76698b4e6   York Sun   Fix memory comman...
593
  		cp = (u8 *)buf;
56523f128   wdenk   * Patch by Martin...
594
595
596
597
598
599
  		i = length;
  		while (i-- > 0)
  			*cp++ = data;
  	}
  }
  #endif /* CONFIG_LOOPW */
68149e940   Tom Rini   cmd_mem.c: Fix wa...
600
  #ifdef CONFIG_CMD_MEMTEST
5512d5b03   Simon Glass   sandbox: Update m...
601
602
  static ulong mem_test_alt(vu_long *buf, ulong start_addr, ulong end_addr,
  			  vu_long *dummy)
3863585bb   wdenk   Initial revision
603
  {
c9638f50f   Simon Glass   Split out the mem...
604
  	vu_long *addr;
c9638f50f   Simon Glass   Split out the mem...
605
606
607
  	ulong errs = 0;
  	ulong val, readback;
  	int j;
c9638f50f   Simon Glass   Split out the mem...
608
609
610
611
612
613
  	vu_long offset;
  	vu_long test_offset;
  	vu_long pattern;
  	vu_long temp;
  	vu_long anti_pattern;
  	vu_long num_words;
3863585bb   wdenk   Initial revision
614
615
616
617
618
619
620
621
622
623
  	static const ulong bitpattern[] = {
  		0x00000001,	/* single bit */
  		0x00000003,	/* two adjacent bits */
  		0x00000007,	/* three adjacent bits */
  		0x0000000F,	/* four adjacent bits */
  		0x00000005,	/* two non-adjacent bits */
  		0x00000015,	/* three non-adjacent bits */
  		0x00000055,	/* four non-adjacent bits */
  		0xaaaaaaaa,	/* alternating 1/0 */
  	};
3863585bb   wdenk   Initial revision
624

5512d5b03   Simon Glass   sandbox: Update m...
625
  	num_words = (end_addr - start_addr) / sizeof(vu_long);
8c86bbe00   Simon Glass   Reduce casting in...
626

7ecbd4d70   Simon Glass   Fix mtest indenting
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
  	/*
  	 * Data line test: write a pattern to the first
  	 * location, write the 1's complement to a 'parking'
  	 * address (changes the state of the data bus so a
  	 * floating bus doesn't give a false OK), and then
  	 * read the value back. Note that we read it back
  	 * into a variable because the next time we read it,
  	 * it might be right (been there, tough to explain to
  	 * the quality guys why it prints a failure when the
  	 * "is" and "should be" are obviously the same in the
  	 * error message).
  	 *
  	 * Rather than exhaustively testing, we test some
  	 * patterns by shifting '1' bits through a field of
  	 * '0's and '0' bits through a field of '1's (i.e.
  	 * pattern and ~pattern).
  	 */
5512d5b03   Simon Glass   sandbox: Update m...
644
  	addr = buf;
7ecbd4d70   Simon Glass   Fix mtest indenting
645
646
647
  	for (j = 0; j < sizeof(bitpattern) / sizeof(bitpattern[0]); j++) {
  		val = bitpattern[j];
  		for (; val != 0; val <<= 1) {
5512d5b03   Simon Glass   sandbox: Update m...
648
  			*addr = val;
c9638f50f   Simon Glass   Split out the mem...
649
  			*dummy  = ~val; /* clear the test data off the bus */
3863585bb   wdenk   Initial revision
650
  			readback = *addr;
7ecbd4d70   Simon Glass   Fix mtest indenting
651
  			if (readback != val) {
c9638f50f   Simon Glass   Split out the mem...
652
653
654
655
656
  				printf("FAILURE (data line): "
  					"expected %08lx, actual %08lx
  ",
  						val, readback);
  				errs++;
c44d4386e   Simon Glass   Bring mtest putc(...
657
  				if (ctrlc())
51209b1f4   Simon Glass   Use common mtest ...
658
  					return -1;
3863585bb   wdenk   Initial revision
659
660
661
662
  			}
  			*addr  = ~val;
  			*dummy  = val;
  			readback = *addr;
c9638f50f   Simon Glass   Split out the mem...
663
664
665
666
667
668
  			if (readback != ~val) {
  				printf("FAILURE (data line): "
  					"Is %08lx, should be %08lx
  ",
  						readback, ~val);
  				errs++;
c44d4386e   Simon Glass   Bring mtest putc(...
669
  				if (ctrlc())
51209b1f4   Simon Glass   Use common mtest ...
670
  					return -1;
3863585bb   wdenk   Initial revision
671
  			}
3863585bb   wdenk   Initial revision
672
  		}
7ecbd4d70   Simon Glass   Fix mtest indenting
673
  	}
3863585bb   wdenk   Initial revision
674

7ecbd4d70   Simon Glass   Fix mtest indenting
675
676
677
678
679
680
681
682
683
  	/*
  	 * Based on code whose Original Author and Copyright
  	 * information follows: Copyright (c) 1998 by Michael
  	 * Barr. This software is placed into the public
  	 * domain and may be used for any purpose. However,
  	 * this notice must not be changed or removed and no
  	 * warranty is either expressed or implied by its
  	 * publication or distribution.
  	 */
3863585bb   wdenk   Initial revision
684

7ecbd4d70   Simon Glass   Fix mtest indenting
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
  	/*
  	* Address line test
  
  	 * Description: Test the address bus wiring in a
  	 *              memory region by performing a walking
  	 *              1's test on the relevant bits of the
  	 *              address and checking for aliasing.
  	 *              This test will find single-bit
  	 *              address failures such as stuck-high,
  	 *              stuck-low, and shorted pins. The base
  	 *              address and size of the region are
  	 *              selected by the caller.
  
  	 * Notes:	For best results, the selected base
  	 *              address should have enough LSB 0's to
  	 *              guarantee single address bit changes.
  	 *              For example, to test a 64-Kbyte
  	 *              region, select a base address on a
  	 *              64-Kbyte boundary. Also, select the
  	 *              region size as a power-of-two if at
  	 *              all possible.
  	 *
  	 * Returns:     0 if the test succeeds, 1 if the test fails.
  	 */
7ecbd4d70   Simon Glass   Fix mtest indenting
709
710
  	pattern = (vu_long) 0xaaaaaaaa;
  	anti_pattern = (vu_long) 0x55555555;
3863585bb   wdenk   Initial revision
711

5512d5b03   Simon Glass   sandbox: Update m...
712
713
  	debug("%s:%d: length = 0x%.8lx
  ", __func__, __LINE__, num_words);
7ecbd4d70   Simon Glass   Fix mtest indenting
714
715
716
717
  	/*
  	 * Write the default pattern at each of the
  	 * power-of-two offsets.
  	 */
5512d5b03   Simon Glass   sandbox: Update m...
718
719
  	for (offset = 1; offset < num_words; offset <<= 1)
  		addr[offset] = pattern;
3863585bb   wdenk   Initial revision
720

7ecbd4d70   Simon Glass   Fix mtest indenting
721
722
723
724
  	/*
  	 * Check for address bits stuck high.
  	 */
  	test_offset = 0;
5512d5b03   Simon Glass   sandbox: Update m...
725
  	addr[test_offset] = anti_pattern;
3863585bb   wdenk   Initial revision
726

5512d5b03   Simon Glass   sandbox: Update m...
727
728
  	for (offset = 1; offset < num_words; offset <<= 1) {
  		temp = addr[offset];
7ecbd4d70   Simon Glass   Fix mtest indenting
729
  		if (temp != pattern) {
c9638f50f   Simon Glass   Split out the mem...
730
731
  			printf("
  FAILURE: Address bit stuck high @ 0x%.8lx:"
3863585bb   wdenk   Initial revision
732
733
  				" expected 0x%.8lx, actual 0x%.8lx
  ",
102c051fc   David Feng   fix address of er...
734
735
  				start_addr + offset*sizeof(vu_long),
  				pattern, temp);
87b22b778   Paul Gortmaker   mem_mtest: fix er...
736
  			errs++;
c44d4386e   Simon Glass   Bring mtest putc(...
737
  			if (ctrlc())
7ecbd4d70   Simon Glass   Fix mtest indenting
738
  				return -1;
3863585bb   wdenk   Initial revision
739
  		}
7ecbd4d70   Simon Glass   Fix mtest indenting
740
  	}
5512d5b03   Simon Glass   sandbox: Update m...
741
  	addr[test_offset] = pattern;
7ecbd4d70   Simon Glass   Fix mtest indenting
742
  	WATCHDOG_RESET();
3863585bb   wdenk   Initial revision
743

7ecbd4d70   Simon Glass   Fix mtest indenting
744
745
746
  	/*
  	 * Check for addr bits stuck low or shorted.
  	 */
5512d5b03   Simon Glass   sandbox: Update m...
747
748
  	for (test_offset = 1; test_offset < num_words; test_offset <<= 1) {
  		addr[test_offset] = anti_pattern;
3863585bb   wdenk   Initial revision
749

5512d5b03   Simon Glass   sandbox: Update m...
750
751
  		for (offset = 1; offset < num_words; offset <<= 1) {
  			temp = addr[offset];
3863585bb   wdenk   Initial revision
752
  			if ((temp != pattern) && (offset != test_offset)) {
7ecbd4d70   Simon Glass   Fix mtest indenting
753
754
755
756
757
  				printf("
  FAILURE: Address bit stuck low or"
  					" shorted @ 0x%.8lx: expected 0x%.8lx,"
  					" actual 0x%.8lx
  ",
102c051fc   David Feng   fix address of er...
758
759
  					start_addr + offset*sizeof(vu_long),
  					pattern, temp);
7ecbd4d70   Simon Glass   Fix mtest indenting
760
  				errs++;
c44d4386e   Simon Glass   Bring mtest putc(...
761
  				if (ctrlc())
7ecbd4d70   Simon Glass   Fix mtest indenting
762
  					return -1;
3863585bb   wdenk   Initial revision
763
  			}
3863585bb   wdenk   Initial revision
764
  		}
5512d5b03   Simon Glass   sandbox: Update m...
765
  		addr[test_offset] = pattern;
7ecbd4d70   Simon Glass   Fix mtest indenting
766
  	}
3863585bb   wdenk   Initial revision
767

7ecbd4d70   Simon Glass   Fix mtest indenting
768
769
770
771
772
773
774
775
776
777
778
779
  	/*
  	 * Description: Test the integrity of a physical
  	 *		memory device by performing an
  	 *		increment/decrement test over the
  	 *		entire region. In the process every
  	 *		storage bit in the device is tested
  	 *		as a zero and a one. The base address
  	 *		and the size of the region are
  	 *		selected by the caller.
  	 *
  	 * Returns:     0 if the test succeeds, 1 if the test fails.
  	 */
5512d5b03   Simon Glass   sandbox: Update m...
780
  	num_words++;
3863585bb   wdenk   Initial revision
781

7ecbd4d70   Simon Glass   Fix mtest indenting
782
783
784
785
786
  	/*
  	 * Fill memory with a known pattern.
  	 */
  	for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
  		WATCHDOG_RESET();
5512d5b03   Simon Glass   sandbox: Update m...
787
  		addr[offset] = pattern;
7ecbd4d70   Simon Glass   Fix mtest indenting
788
  	}
3863585bb   wdenk   Initial revision
789

7ecbd4d70   Simon Glass   Fix mtest indenting
790
791
792
793
794
  	/*
  	 * Check each location and invert it for the second pass.
  	 */
  	for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
  		WATCHDOG_RESET();
5512d5b03   Simon Glass   sandbox: Update m...
795
  		temp = addr[offset];
7ecbd4d70   Simon Glass   Fix mtest indenting
796
  		if (temp != pattern) {
c9638f50f   Simon Glass   Split out the mem...
797
798
  			printf("
  FAILURE (read/write) @ 0x%.8lx:"
3863585bb   wdenk   Initial revision
799
800
  				" expected 0x%.8lx, actual 0x%.8lx)
  ",
102c051fc   David Feng   fix address of er...
801
802
  				start_addr + offset*sizeof(vu_long),
  				pattern, temp);
87b22b778   Paul Gortmaker   mem_mtest: fix er...
803
  			errs++;
c44d4386e   Simon Glass   Bring mtest putc(...
804
  			if (ctrlc())
51209b1f4   Simon Glass   Use common mtest ...
805
  				return -1;
3863585bb   wdenk   Initial revision
806
  		}
7ecbd4d70   Simon Glass   Fix mtest indenting
807
  		anti_pattern = ~pattern;
5512d5b03   Simon Glass   sandbox: Update m...
808
  		addr[offset] = anti_pattern;
7ecbd4d70   Simon Glass   Fix mtest indenting
809
810
811
812
813
814
815
816
  	}
  
  	/*
  	 * Check each location for the inverted pattern and zero it.
  	 */
  	for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
  		WATCHDOG_RESET();
  		anti_pattern = ~pattern;
5512d5b03   Simon Glass   sandbox: Update m...
817
  		temp = addr[offset];
7ecbd4d70   Simon Glass   Fix mtest indenting
818
  		if (temp != anti_pattern) {
c9638f50f   Simon Glass   Split out the mem...
819
820
  			printf("
  FAILURE (read/write): @ 0x%.8lx:"
3863585bb   wdenk   Initial revision
821
822
  				" expected 0x%.8lx, actual 0x%.8lx)
  ",
102c051fc   David Feng   fix address of er...
823
824
  				start_addr + offset*sizeof(vu_long),
  				anti_pattern, temp);
87b22b778   Paul Gortmaker   mem_mtest: fix er...
825
  			errs++;
c44d4386e   Simon Glass   Bring mtest putc(...
826
  			if (ctrlc())
51209b1f4   Simon Glass   Use common mtest ...
827
  				return -1;
3863585bb   wdenk   Initial revision
828
  		}
5512d5b03   Simon Glass   sandbox: Update m...
829
  		addr[offset] = 0;
7ecbd4d70   Simon Glass   Fix mtest indenting
830
  	}
51209b1f4   Simon Glass   Use common mtest ...
831
832
  
  	return 0;
c9638f50f   Simon Glass   Split out the mem...
833
  }
5512d5b03   Simon Glass   sandbox: Update m...
834
835
  static ulong mem_test_quick(vu_long *buf, ulong start_addr, ulong end_addr,
  			    vu_long pattern, int iteration)
c9638f50f   Simon Glass   Split out the mem...
836
  {
5512d5b03   Simon Glass   sandbox: Update m...
837
  	vu_long *end;
c9638f50f   Simon Glass   Split out the mem...
838
  	vu_long *addr;
c9638f50f   Simon Glass   Split out the mem...
839
  	ulong errs = 0;
5512d5b03   Simon Glass   sandbox: Update m...
840
  	ulong incr, length;
c9638f50f   Simon Glass   Split out the mem...
841
  	ulong val, readback;
3863585bb   wdenk   Initial revision
842

51209b1f4   Simon Glass   Use common mtest ...
843
  	/* Alternate the pattern */
3863585bb   wdenk   Initial revision
844
  	incr = 1;
51209b1f4   Simon Glass   Use common mtest ...
845
846
847
848
849
850
851
852
853
854
855
856
857
  	if (iteration & 1) {
  		incr = -incr;
  		/*
  		 * Flip the pattern each time to make lots of zeros and
  		 * then, the next time, lots of ones.  We decrement
  		 * the "negative" patterns and increment the "positive"
  		 * patterns to preserve this feature.
  		 */
  		if (pattern & 0x80000000)
  			pattern = -pattern;	/* complement & increment */
  		else
  			pattern = ~pattern;
  	}
5512d5b03   Simon Glass   sandbox: Update m...
858
859
  	length = (end_addr - start_addr) / sizeof(ulong);
  	end = buf + length;
7ecbd4d70   Simon Glass   Fix mtest indenting
860
861
862
863
  	printf("\rPattern %08lX  Writing..."
  		"%12s"
  		"\b\b\b\b\b\b\b\b\b\b",
  		pattern, "");
3863585bb   wdenk   Initial revision
864

5512d5b03   Simon Glass   sandbox: Update m...
865
  	for (addr = buf, val = pattern; addr < end; addr++) {
7ecbd4d70   Simon Glass   Fix mtest indenting
866
867
868
869
  		WATCHDOG_RESET();
  		*addr = val;
  		val += incr;
  	}
3863585bb   wdenk   Initial revision
870

7ecbd4d70   Simon Glass   Fix mtest indenting
871
  	puts("Reading...");
3863585bb   wdenk   Initial revision
872

5512d5b03   Simon Glass   sandbox: Update m...
873
  	for (addr = buf, val = pattern; addr < end; addr++) {
7ecbd4d70   Simon Glass   Fix mtest indenting
874
875
876
  		WATCHDOG_RESET();
  		readback = *addr;
  		if (readback != val) {
5512d5b03   Simon Glass   sandbox: Update m...
877
  			ulong offset = addr - buf;
7ecbd4d70   Simon Glass   Fix mtest indenting
878
879
880
881
  			printf("
  Mem error @ 0x%08X: "
  				"found %08lX, expected %08lX
  ",
102c051fc   David Feng   fix address of er...
882
  				(uint)(uintptr_t)(start_addr + offset*sizeof(vu_long)),
5512d5b03   Simon Glass   sandbox: Update m...
883
  				readback, val);
7ecbd4d70   Simon Glass   Fix mtest indenting
884
  			errs++;
c44d4386e   Simon Glass   Bring mtest putc(...
885
  			if (ctrlc())
7ecbd4d70   Simon Glass   Fix mtest indenting
886
  				return -1;
3863585bb   wdenk   Initial revision
887
  		}
7ecbd4d70   Simon Glass   Fix mtest indenting
888
889
  		val += incr;
  	}
3863585bb   wdenk   Initial revision
890

51209b1f4   Simon Glass   Use common mtest ...
891
  	return 0;
c9638f50f   Simon Glass   Split out the mem...
892
893
894
895
896
897
898
899
900
901
  }
  
  /*
   * Perform a memory test. A more complete alternative test can be
   * configured using CONFIG_SYS_ALT_MEMTEST. The complete test loops until
   * interrupted by ctrl-c or by a failure of one of the sub-tests.
   */
  static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,
  			char * const argv[])
  {
8c86bbe00   Simon Glass   Reduce casting in...
902
  	ulong start, end;
5512d5b03   Simon Glass   sandbox: Update m...
903
  	vu_long *buf, *dummy;
c9638f50f   Simon Glass   Split out the mem...
904
905
  	int iteration_limit;
  	int ret;
51209b1f4   Simon Glass   Use common mtest ...
906
  	ulong errs = 0;	/* number of errors, or -1 if interrupted */
c9638f50f   Simon Glass   Split out the mem...
907
  	ulong pattern;
51209b1f4   Simon Glass   Use common mtest ...
908
  	int iteration;
c9638f50f   Simon Glass   Split out the mem...
909
910
911
912
  #if defined(CONFIG_SYS_ALT_MEMTEST)
  	const int alt_test = 1;
  #else
  	const int alt_test = 0;
3863585bb   wdenk   Initial revision
913
  #endif
c9638f50f   Simon Glass   Split out the mem...
914
915
  
  	if (argc > 1)
8c86bbe00   Simon Glass   Reduce casting in...
916
  		start = simple_strtoul(argv[1], NULL, 16);
c9638f50f   Simon Glass   Split out the mem...
917
  	else
8c86bbe00   Simon Glass   Reduce casting in...
918
  		start = CONFIG_SYS_MEMTEST_START;
c9638f50f   Simon Glass   Split out the mem...
919
920
  
  	if (argc > 2)
8c86bbe00   Simon Glass   Reduce casting in...
921
  		end = simple_strtoul(argv[2], NULL, 16);
c9638f50f   Simon Glass   Split out the mem...
922
  	else
8c86bbe00   Simon Glass   Reduce casting in...
923
  		end = CONFIG_SYS_MEMTEST_END;
c9638f50f   Simon Glass   Split out the mem...
924
925
926
927
928
929
930
931
932
933
  
  	if (argc > 3)
  		pattern = (ulong)simple_strtoul(argv[3], NULL, 16);
  	else
  		pattern = 0;
  
  	if (argc > 4)
  		iteration_limit = (ulong)simple_strtoul(argv[4], NULL, 16);
  	else
  		iteration_limit = 0;
8c86bbe00   Simon Glass   Reduce casting in...
934
935
936
937
938
  	printf("Testing %08x ... %08x:
  ", (uint)start, (uint)end);
  	debug("%s:%d: start %#08lx end %#08lx
  ", __func__, __LINE__,
  	      start, end);
51209b1f4   Simon Glass   Use common mtest ...
939

5512d5b03   Simon Glass   sandbox: Update m...
940
941
  	buf = map_sysmem(start, end - start);
  	dummy = map_sysmem(CONFIG_SYS_MEMTEST_SCRATCH, sizeof(vu_long));
51209b1f4   Simon Glass   Use common mtest ...
942
943
944
945
  	for (iteration = 0;
  			!iteration_limit || iteration < iteration_limit;
  			iteration++) {
  		if (ctrlc()) {
51209b1f4   Simon Glass   Use common mtest ...
946
947
948
949
950
951
952
  			errs = -1UL;
  			break;
  		}
  
  		printf("Iteration: %6d\r", iteration + 1);
  		debug("
  ");
5512d5b03   Simon Glass   sandbox: Update m...
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
  		if (alt_test) {
  			errs = mem_test_alt(buf, start, end, dummy);
  		} else {
  			errs = mem_test_quick(buf, start, end, pattern,
  					      iteration);
  		}
  		if (errs == -1UL)
  			break;
  	}
  
  	/*
  	 * Work-around for eldk-4.2 which gives this warning if we try to
  	 * case in the unmap_sysmem() call:
  	 * warning: initialization discards qualifiers from pointer target type
  	 */
  	{
  		void *vbuf = (void *)buf;
  		void *vdummy = (void *)dummy;
  
  		unmap_sysmem(vbuf);
  		unmap_sysmem(vdummy);
51209b1f4   Simon Glass   Use common mtest ...
974
975
976
  	}
  
  	if (errs == -1UL) {
c44d4386e   Simon Glass   Bring mtest putc(...
977
978
979
  		/* Memory test was aborted - write a newline to finish off */
  		putc('
  ');
51209b1f4   Simon Glass   Use common mtest ...
980
981
982
983
984
985
986
  		ret = 1;
  	} else {
  		printf("Tested %d iteration(s) with %lu errors.
  ",
  			iteration, errs);
  		ret = errs != 0;
  	}
c9638f50f   Simon Glass   Split out the mem...
987
988
  
  	return ret;	/* not reached */
3863585bb   wdenk   Initial revision
989
  }
a2681707b   Wolfgang Denk   Feature Removal: ...
990
  #endif	/* CONFIG_CMD_MEMTEST */
3863585bb   wdenk   Initial revision
991
992
993
994
995
996
997
998
  
  /* Modify memory.
   *
   * Syntax:
   *	mm{.b, .w, .l} {addr}
   *	nm{.b, .w, .l} {addr}
   */
  static int
54841ab50   Wolfgang Denk   Make sure that ar...
999
  mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
3863585bb   wdenk   Initial revision
1000
  {
27b207fd0   wdenk   * Implement new m...
1001
1002
  	ulong	addr, i;
  	int	nbytes, size;
0628ab8ec   Simon Glass   sandbox: Change m...
1003
  	void *ptr = NULL;
3863585bb   wdenk   Initial revision
1004

47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
1005
  	if (argc != 2)
4c12eeb8b   Simon Glass   Convert cmd_usage...
1006
  		return CMD_RET_USAGE;
3863585bb   wdenk   Initial revision
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
  
  #ifdef CONFIG_BOOT_RETRY_TIME
  	reset_cmd_timeout();	/* got a good command to get here */
  #endif
  	/* We use the last specified parameters, unless new ones are
  	 * entered.
  	 */
  	addr = mm_last_addr;
  	size = mm_last_size;
  
  	if ((flag & CMD_FLAG_REPEAT) == 0) {
  		/* New command specified.  Check for a size specification.
  		 * Defaults to long if no or incorrect specification.
  		 */
27b207fd0   wdenk   * Implement new m...
1021
1022
  		if ((size = cmd_get_data_size(argv[0], 4)) < 0)
  			return 1;
3863585bb   wdenk   Initial revision
1023
1024
1025
1026
1027
1028
  
  		/* Address is specified since argc > 1
  		*/
  		addr = simple_strtoul(argv[1], NULL, 16);
  		addr += base_address;
  	}
2abbe0754   wdenk   * Patch by Nicola...
1029
1030
  #ifdef CONFIG_HAS_DATAFLASH
  	if (addr_dataflash(addr)){
4b9206ed5   wdenk   * Patches by Thom...
1031
1032
  		puts ("Can't modify DataFlash in place. Use cp instead.
  \r");
2abbe0754   wdenk   * Patch by Nicola...
1033
1034
1035
  		return 0;
  	}
  #endif
4c727c77e   Mike Frysinger   add support for m...
1036
1037
1038
1039
1040
1041
1042
  #ifdef CONFIG_BLACKFIN
  	if (addr_bfin_on_chip_mem(addr)) {
  		puts ("Can't modify L1 instruction in place. Use cp instead.
  \r");
  		return 0;
  	}
  #endif
3863585bb   wdenk   Initial revision
1043
1044
1045
1046
  	/* Print the address, followed by value.  Then accept input for
  	 * the next value.  A non-converted value exits.
  	 */
  	do {
0628ab8ec   Simon Glass   sandbox: Change m...
1047
  		ptr = map_sysmem(addr, size);
3863585bb   wdenk   Initial revision
1048
1049
  		printf("%08lx:", addr);
  		if (size == 4)
76698b4e6   York Sun   Fix memory comman...
1050
  			printf(" %08x", *((u32 *)ptr));
3863585bb   wdenk   Initial revision
1051
  		else if (size == 2)
76698b4e6   York Sun   Fix memory comman...
1052
  			printf(" %04x", *((u16 *)ptr));
3863585bb   wdenk   Initial revision
1053
  		else
76698b4e6   York Sun   Fix memory comman...
1054
  			printf(" %02x", *((u8 *)ptr));
3863585bb   wdenk   Initial revision
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
  
  		nbytes = readline (" ? ");
  		if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) {
  			/* <CR> pressed as only input, don't modify current
  			 * location and move to next. "-" pressed will go back.
  			 */
  			if (incrflag)
  				addr += nbytes ? -size : size;
  			nbytes = 1;
  #ifdef CONFIG_BOOT_RETRY_TIME
  			reset_cmd_timeout(); /* good enough to not time out */
  #endif
  		}
  #ifdef CONFIG_BOOT_RETRY_TIME
  		else if (nbytes == -2) {
  			break;	/* timed out, exit the command	*/
  		}
  #endif
  		else {
  			char *endp;
  			i = simple_strtoul(console_buffer, &endp, 16);
  			nbytes = endp - console_buffer;
  			if (nbytes) {
  #ifdef CONFIG_BOOT_RETRY_TIME
  				/* good enough to not time out
  				 */
  				reset_cmd_timeout();
  #endif
  				if (size == 4)
76698b4e6   York Sun   Fix memory comman...
1084
  					*((u32 *)ptr) = i;
3863585bb   wdenk   Initial revision
1085
  				else if (size == 2)
76698b4e6   York Sun   Fix memory comman...
1086
  					*((u16 *)ptr) = i;
3863585bb   wdenk   Initial revision
1087
  				else
76698b4e6   York Sun   Fix memory comman...
1088
  					*((u8 *)ptr) = i;
3863585bb   wdenk   Initial revision
1089
1090
1091
1092
1093
  				if (incrflag)
  					addr += size;
  			}
  		}
  	} while (nbytes);
0628ab8ec   Simon Glass   sandbox: Change m...
1094
1095
  	if (ptr)
  		unmap_sysmem(ptr);
3863585bb   wdenk   Initial revision
1096
1097
1098
1099
1100
  
  	mm_last_addr = addr;
  	mm_last_size = size;
  	return 0;
  }
710b99385   Mike Frysinger   crc32: make comma...
1101
  #ifdef CONFIG_CMD_CRC32
088f1b199   Kim Phillips   common/cmd_*.c: s...
1102
  static int do_mem_crc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
3863585bb   wdenk   Initial revision
1103
  {
d20a40de9   Simon Glass   Roll crc32 into h...
1104
  	int flags = 0;
c26e454df   wdenk   Patches by Pantel...
1105
  	int ac;
54841ab50   Wolfgang Denk   Make sure that ar...
1106
  	char * const *av;
c26e454df   wdenk   Patches by Pantel...
1107

d20a40de9   Simon Glass   Roll crc32 into h...
1108
  	if (argc < 3)
4c12eeb8b   Simon Glass   Convert cmd_usage...
1109
  		return CMD_RET_USAGE;
c26e454df   wdenk   Patches by Pantel...
1110
1111
1112
  
  	av = argv + 1;
  	ac = argc - 1;
d20a40de9   Simon Glass   Roll crc32 into h...
1113
  #ifdef CONFIG_HASH_VERIFY
c26e454df   wdenk   Patches by Pantel...
1114
  	if (strcmp(*av, "-v") == 0) {
d20a40de9   Simon Glass   Roll crc32 into h...
1115
  		flags |= HASH_FLAG_VERIFY;
c26e454df   wdenk   Patches by Pantel...
1116
1117
  		av++;
  		ac--;
c26e454df   wdenk   Patches by Pantel...
1118
  	}
d20a40de9   Simon Glass   Roll crc32 into h...
1119
  #endif
c26e454df   wdenk   Patches by Pantel...
1120

d20a40de9   Simon Glass   Roll crc32 into h...
1121
  	return hash_command("crc32", flags, cmdtp, flag, ac, av);
c26e454df   wdenk   Patches by Pantel...
1122
  }
c26e454df   wdenk   Patches by Pantel...
1123

710b99385   Mike Frysinger   crc32: make comma...
1124
  #endif
8bde7f776   wdenk   * Code cleanup:
1125
  /**************************************************/
0d4983930   wdenk   Patch by Kenneth ...
1126
  U_BOOT_CMD(
53677ef18   Wolfgang Denk   Big white-space c...
1127
  	md,	3,	1,	do_mem_md,
2fb2604d5   Peter Tyser   Command usage cle...
1128
  	"memory display",
a89c33db9   Wolfgang Denk   General help mess...
1129
  	"[.b, .w, .l] address [# of objects]"
8bde7f776   wdenk   * Code cleanup:
1130
  );
0d4983930   wdenk   Patch by Kenneth ...
1131
  U_BOOT_CMD(
53677ef18   Wolfgang Denk   Big white-space c...
1132
  	mm,	2,	1,	do_mem_mm,
a89c33db9   Wolfgang Denk   General help mess...
1133
1134
  	"memory modify (auto-incrementing address)",
  	"[.b, .w, .l] address"
8bde7f776   wdenk   * Code cleanup:
1135
  );
0d4983930   wdenk   Patch by Kenneth ...
1136
  U_BOOT_CMD(
53677ef18   Wolfgang Denk   Big white-space c...
1137
  	nm,	2,	1,	do_mem_nm,
2fb2604d5   Peter Tyser   Command usage cle...
1138
  	"memory modify (constant address)",
a89c33db9   Wolfgang Denk   General help mess...
1139
  	"[.b, .w, .l] address"
8bde7f776   wdenk   * Code cleanup:
1140
  );
0d4983930   wdenk   Patch by Kenneth ...
1141
  U_BOOT_CMD(
53677ef18   Wolfgang Denk   Big white-space c...
1142
  	mw,	4,	1,	do_mem_mw,
2fb2604d5   Peter Tyser   Command usage cle...
1143
  	"memory write (fill)",
a89c33db9   Wolfgang Denk   General help mess...
1144
  	"[.b, .w, .l] address value [count]"
8bde7f776   wdenk   * Code cleanup:
1145
  );
0d4983930   wdenk   Patch by Kenneth ...
1146
  U_BOOT_CMD(
53677ef18   Wolfgang Denk   Big white-space c...
1147
  	cp,	4,	1,	do_mem_cp,
2fb2604d5   Peter Tyser   Command usage cle...
1148
  	"memory copy",
a89c33db9   Wolfgang Denk   General help mess...
1149
  	"[.b, .w, .l] source target count"
8bde7f776   wdenk   * Code cleanup:
1150
  );
0d4983930   wdenk   Patch by Kenneth ...
1151
  U_BOOT_CMD(
53677ef18   Wolfgang Denk   Big white-space c...
1152
  	cmp,	4,	1,	do_mem_cmp,
2fb2604d5   Peter Tyser   Command usage cle...
1153
  	"memory compare",
a89c33db9   Wolfgang Denk   General help mess...
1154
  	"[.b, .w, .l] addr1 addr2 count"
8bde7f776   wdenk   * Code cleanup:
1155
  );
710b99385   Mike Frysinger   crc32: make comma...
1156
  #ifdef CONFIG_CMD_CRC32
c26e454df   wdenk   Patches by Pantel...
1157
  #ifndef CONFIG_CRC32_VERIFY
0d4983930   wdenk   Patch by Kenneth ...
1158
  U_BOOT_CMD(
53677ef18   Wolfgang Denk   Big white-space c...
1159
  	crc32,	4,	1,	do_mem_crc,
2fb2604d5   Peter Tyser   Command usage cle...
1160
  	"checksum calculation",
a89c33db9   Wolfgang Denk   General help mess...
1161
1162
  	"address count [addr]
      - compute CRC32 checksum [save at addr]"
8bde7f776   wdenk   * Code cleanup:
1163
  );
c26e454df   wdenk   Patches by Pantel...
1164
1165
1166
  #else	/* CONFIG_CRC32_VERIFY */
  
  U_BOOT_CMD(
53677ef18   Wolfgang Denk   Big white-space c...
1167
  	crc32,	5,	1,	do_mem_crc,
2fb2604d5   Peter Tyser   Command usage cle...
1168
  	"checksum calculation",
c26e454df   wdenk   Patches by Pantel...
1169
1170
1171
  	"address count [addr]
      - compute CRC32 checksum [save at addr]
  "
a89c33db9   Wolfgang Denk   General help mess...
1172
1173
  	"-v address count crc
      - verify crc of memory area"
c26e454df   wdenk   Patches by Pantel...
1174
1175
1176
  );
  
  #endif	/* CONFIG_CRC32_VERIFY */
710b99385   Mike Frysinger   crc32: make comma...
1177
  #endif
15a33e49d   Simon Glass   Add option to dis...
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
  #ifdef CONFIG_CMD_MEMINFO
  __weak void board_show_dram(ulong size)
  {
  	puts("DRAM:  ");
  	print_size(size, "
  ");
  }
  
  static int do_mem_info(cmd_tbl_t *cmdtp, int flag, int argc,
  		       char * const argv[])
  {
  	board_show_dram(gd->ram_size);
  
  	return 0;
  }
  #endif
0d4983930   wdenk   Patch by Kenneth ...
1194
  U_BOOT_CMD(
53677ef18   Wolfgang Denk   Big white-space c...
1195
  	base,	2,	1,	do_mem_base,
2fb2604d5   Peter Tyser   Command usage cle...
1196
  	"print or set address offset",
8bde7f776   wdenk   * Code cleanup:
1197
1198
1199
  	"
      - print address offset for memory commands
  "
a89c33db9   Wolfgang Denk   General help mess...
1200
1201
  	"base off
      - set address offset for memory commands to 'off'"
8bde7f776   wdenk   * Code cleanup:
1202
  );
0d4983930   wdenk   Patch by Kenneth ...
1203
  U_BOOT_CMD(
53677ef18   Wolfgang Denk   Big white-space c...
1204
  	loop,	3,	1,	do_mem_loop,
2fb2604d5   Peter Tyser   Command usage cle...
1205
  	"infinite loop on address range",
a89c33db9   Wolfgang Denk   General help mess...
1206
  	"[.b, .w, .l] address number_of_objects"
8bde7f776   wdenk   * Code cleanup:
1207
  );
56523f128   wdenk   * Patch by Martin...
1208
1209
  #ifdef CONFIG_LOOPW
  U_BOOT_CMD(
53677ef18   Wolfgang Denk   Big white-space c...
1210
  	loopw,	4,	1,	do_mem_loopw,
2fb2604d5   Peter Tyser   Command usage cle...
1211
  	"infinite write loop on address range",
a89c33db9   Wolfgang Denk   General help mess...
1212
  	"[.b, .w, .l] address number_of_objects data_to_write"
56523f128   wdenk   * Patch by Martin...
1213
1214
  );
  #endif /* CONFIG_LOOPW */
a2681707b   Wolfgang Denk   Feature Removal: ...
1215
  #ifdef CONFIG_CMD_MEMTEST
0d4983930   wdenk   Patch by Kenneth ...
1216
  U_BOOT_CMD(
b6fc6fd49   Dirk Eibach   common: Iteration...
1217
  	mtest,	5,	1,	do_mem_mtest,
a89c33db9   Wolfgang Denk   General help mess...
1218
1219
  	"simple RAM read/write test",
  	"[start [end [pattern [iterations]]]]"
8bde7f776   wdenk   * Code cleanup:
1220
  );
a2681707b   Wolfgang Denk   Feature Removal: ...
1221
  #endif	/* CONFIG_CMD_MEMTEST */
8bde7f776   wdenk   * Code cleanup:
1222

4aaf29b2f   stroese   memory commands "...
1223
1224
  #ifdef CONFIG_MX_CYCLIC
  U_BOOT_CMD(
53677ef18   Wolfgang Denk   Big white-space c...
1225
  	mdc,	4,	1,	do_mem_mdc,
2fb2604d5   Peter Tyser   Command usage cle...
1226
  	"memory display cyclic",
a89c33db9   Wolfgang Denk   General help mess...
1227
  	"[.b, .w, .l] address count delay(ms)"
4aaf29b2f   stroese   memory commands "...
1228
1229
1230
  );
  
  U_BOOT_CMD(
53677ef18   Wolfgang Denk   Big white-space c...
1231
  	mwc,	4,	1,	do_mem_mwc,
2fb2604d5   Peter Tyser   Command usage cle...
1232
  	"memory write cyclic",
a89c33db9   Wolfgang Denk   General help mess...
1233
  	"[.b, .w, .l] address value delay(ms)"
4aaf29b2f   stroese   memory commands "...
1234
1235
  );
  #endif /* CONFIG_MX_CYCLIC */
15a33e49d   Simon Glass   Add option to dis...
1236
1237
1238
1239
1240
1241
1242
1243
  
  #ifdef CONFIG_CMD_MEMINFO
  U_BOOT_CMD(
  	meminfo,	3,	1,	do_mem_info,
  	"display memory information",
  	""
  );
  #endif