cmd_mem.c 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400
  1. /*
  2. * (C) Copyright 2000
  3. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. /*
  8. * Memory Functions
  9. *
  10. * Copied from FADS ROM, Dan Malek (dmalek@jlc.net)
  11. */
  12. #include <common.h>
  13. #include <bootretry.h>
  14. #include <cli.h>
  15. #include <command.h>
  16. #ifdef CONFIG_HAS_DATAFLASH
  17. #include <dataflash.h>
  18. #endif
  19. #include <hash.h>
  20. #include <watchdog.h>
  21. #include <asm/io.h>
  22. #include <linux/compiler.h>
  23. DECLARE_GLOBAL_DATA_PTR;
  24. #ifndef CONFIG_SYS_MEMTEST_SCRATCH
  25. #define CONFIG_SYS_MEMTEST_SCRATCH 0
  26. #endif
  27. static int mod_mem(cmd_tbl_t *, int, int, int, char * const []);
  28. /* Display values from last command.
  29. * Memory modify remembered values are different from display memory.
  30. */
  31. static uint dp_last_addr, dp_last_size;
  32. static uint dp_last_length = 0x40;
  33. static uint mm_last_addr, mm_last_size;
  34. static ulong base_address = 0;
  35. /* Memory Display
  36. *
  37. * Syntax:
  38. * md{.b, .w, .l, .q} {addr} {len}
  39. */
  40. #define DISP_LINE_LEN 16
  41. static int do_mem_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  42. {
  43. ulong addr, length;
  44. #if defined(CONFIG_HAS_DATAFLASH)
  45. ulong nbytes, linebytes;
  46. #endif
  47. int size;
  48. int rc = 0;
  49. /* We use the last specified parameters, unless new ones are
  50. * entered.
  51. */
  52. addr = dp_last_addr;
  53. size = dp_last_size;
  54. length = dp_last_length;
  55. if (argc < 2)
  56. return CMD_RET_USAGE;
  57. if ((flag & CMD_FLAG_REPEAT) == 0) {
  58. /* New command specified. Check for a size specification.
  59. * Defaults to long if no or incorrect specification.
  60. */
  61. if ((size = cmd_get_data_size(argv[0], 4)) < 0)
  62. return 1;
  63. /* Address is specified since argc > 1
  64. */
  65. addr = simple_strtoul(argv[1], NULL, 16);
  66. addr += base_address;
  67. /* If another parameter, it is the length to display.
  68. * Length is the number of objects, not number of bytes.
  69. */
  70. if (argc > 2)
  71. length = simple_strtoul(argv[2], NULL, 16);
  72. }
  73. #if defined(CONFIG_HAS_DATAFLASH)
  74. /* Print the lines.
  75. *
  76. * We buffer all read data, so we can make sure data is read only
  77. * once, and all accesses are with the specified bus width.
  78. */
  79. nbytes = length * size;
  80. do {
  81. char linebuf[DISP_LINE_LEN];
  82. void* p;
  83. linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes;
  84. rc = read_dataflash(addr, (linebytes/size)*size, linebuf);
  85. p = (rc == DATAFLASH_OK) ? linebuf : (void*)addr;
  86. print_buffer(addr, p, size, linebytes/size, DISP_LINE_LEN/size);
  87. nbytes -= linebytes;
  88. addr += linebytes;
  89. if (ctrlc()) {
  90. rc = 1;
  91. break;
  92. }
  93. } while (nbytes > 0);
  94. #else
  95. # if defined(CONFIG_BLACKFIN)
  96. /* See if we're trying to display L1 inst */
  97. if (addr_bfin_on_chip_mem(addr)) {
  98. char linebuf[DISP_LINE_LEN];
  99. ulong linebytes, nbytes = length * size;
  100. do {
  101. linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes;
  102. memcpy(linebuf, (void *)addr, linebytes);
  103. print_buffer(addr, linebuf, size, linebytes/size, DISP_LINE_LEN/size);
  104. nbytes -= linebytes;
  105. addr += linebytes;
  106. if (ctrlc()) {
  107. rc = 1;
  108. break;
  109. }
  110. } while (nbytes > 0);
  111. } else
  112. # endif
  113. {
  114. ulong bytes = size * length;
  115. const void *buf = map_sysmem(addr, bytes);
  116. /* Print the lines. */
  117. print_buffer(addr, buf, size, length, DISP_LINE_LEN / size);
  118. addr += bytes;
  119. unmap_sysmem(buf);
  120. }
  121. #endif
  122. dp_last_addr = addr;
  123. dp_last_length = length;
  124. dp_last_size = size;
  125. return (rc);
  126. }
  127. static int do_mem_mm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  128. {
  129. return mod_mem (cmdtp, 1, flag, argc, argv);
  130. }
  131. static int do_mem_nm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  132. {
  133. return mod_mem (cmdtp, 0, flag, argc, argv);
  134. }
  135. static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  136. {
  137. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  138. u64 writeval;
  139. #else
  140. ulong writeval;
  141. #endif
  142. ulong addr, count;
  143. int size;
  144. void *buf;
  145. ulong bytes;
  146. if ((argc < 3) || (argc > 4))
  147. return CMD_RET_USAGE;
  148. /* Check for size specification.
  149. */
  150. if ((size = cmd_get_data_size(argv[0], 4)) < 1)
  151. return 1;
  152. /* Address is specified since argc > 1
  153. */
  154. addr = simple_strtoul(argv[1], NULL, 16);
  155. addr += base_address;
  156. /* Get the value to write.
  157. */
  158. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  159. writeval = simple_strtoull(argv[2], NULL, 16);
  160. #else
  161. writeval = simple_strtoul(argv[2], NULL, 16);
  162. #endif
  163. /* Count ? */
  164. if (argc == 4) {
  165. count = simple_strtoul(argv[3], NULL, 16);
  166. } else {
  167. count = 1;
  168. }
  169. bytes = size * count;
  170. buf = map_sysmem(addr, bytes);
  171. while (count-- > 0) {
  172. if (size == 4)
  173. *((u32 *)buf) = (u32)writeval;
  174. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  175. else if (size == 8)
  176. *((u64 *)buf) = (u64)writeval;
  177. #endif
  178. else if (size == 2)
  179. *((u16 *)buf) = (u16)writeval;
  180. else
  181. *((u8 *)buf) = (u8)writeval;
  182. buf += size;
  183. }
  184. unmap_sysmem(buf);
  185. return 0;
  186. }
  187. #ifdef CONFIG_MX_CYCLIC
  188. static int do_mem_mdc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  189. {
  190. int i;
  191. ulong count;
  192. if (argc < 4)
  193. return CMD_RET_USAGE;
  194. count = simple_strtoul(argv[3], NULL, 10);
  195. for (;;) {
  196. do_mem_md (NULL, 0, 3, argv);
  197. /* delay for <count> ms... */
  198. for (i=0; i<count; i++)
  199. udelay (1000);
  200. /* check for ctrl-c to abort... */
  201. if (ctrlc()) {
  202. puts("Abort\n");
  203. return 0;
  204. }
  205. }
  206. return 0;
  207. }
  208. static int do_mem_mwc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  209. {
  210. int i;
  211. ulong count;
  212. if (argc < 4)
  213. return CMD_RET_USAGE;
  214. count = simple_strtoul(argv[3], NULL, 10);
  215. for (;;) {
  216. do_mem_mw (NULL, 0, 3, argv);
  217. /* delay for <count> ms... */
  218. for (i=0; i<count; i++)
  219. udelay (1000);
  220. /* check for ctrl-c to abort... */
  221. if (ctrlc()) {
  222. puts("Abort\n");
  223. return 0;
  224. }
  225. }
  226. return 0;
  227. }
  228. #endif /* CONFIG_MX_CYCLIC */
  229. static int do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  230. {
  231. ulong addr1, addr2, count, ngood, bytes;
  232. int size;
  233. int rcode = 0;
  234. const char *type;
  235. const void *buf1, *buf2, *base;
  236. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  237. u64 word1, word2;
  238. #else
  239. ulong word1, word2;
  240. #endif
  241. if (argc != 4)
  242. return CMD_RET_USAGE;
  243. /* Check for size specification.
  244. */
  245. if ((size = cmd_get_data_size(argv[0], 4)) < 0)
  246. return 1;
  247. type = size == 8 ? "double word" :
  248. size == 4 ? "word" :
  249. size == 2 ? "halfword" : "byte";
  250. addr1 = simple_strtoul(argv[1], NULL, 16);
  251. addr1 += base_address;
  252. addr2 = simple_strtoul(argv[2], NULL, 16);
  253. addr2 += base_address;
  254. count = simple_strtoul(argv[3], NULL, 16);
  255. #ifdef CONFIG_HAS_DATAFLASH
  256. if (addr_dataflash(addr1) | addr_dataflash(addr2)){
  257. puts ("Comparison with DataFlash space not supported.\n\r");
  258. return 0;
  259. }
  260. #endif
  261. #ifdef CONFIG_BLACKFIN
  262. if (addr_bfin_on_chip_mem(addr1) || addr_bfin_on_chip_mem(addr2)) {
  263. puts ("Comparison with L1 instruction memory not supported.\n\r");
  264. return 0;
  265. }
  266. #endif
  267. bytes = size * count;
  268. base = buf1 = map_sysmem(addr1, bytes);
  269. buf2 = map_sysmem(addr2, bytes);
  270. for (ngood = 0; ngood < count; ++ngood) {
  271. if (size == 4) {
  272. word1 = *(u32 *)buf1;
  273. word2 = *(u32 *)buf2;
  274. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  275. } else if (size == 8) {
  276. word1 = *(u64 *)buf1;
  277. word2 = *(u64 *)buf2;
  278. #endif
  279. } else if (size == 2) {
  280. word1 = *(u16 *)buf1;
  281. word2 = *(u16 *)buf2;
  282. } else {
  283. word1 = *(u8 *)buf1;
  284. word2 = *(u8 *)buf2;
  285. }
  286. if (word1 != word2) {
  287. ulong offset = buf1 - base;
  288. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  289. printf("%s at 0x%p (%#0*llx) != %s at 0x%p (%#0*llx)\n",
  290. type, (void *)(addr1 + offset), size, word1,
  291. type, (void *)(addr2 + offset), size, word2);
  292. #else
  293. printf("%s at 0x%08lx (%#0*lx) != %s at 0x%08lx (%#0*lx)\n",
  294. type, (ulong)(addr1 + offset), size, word1,
  295. type, (ulong)(addr2 + offset), size, word2);
  296. #endif
  297. rcode = 1;
  298. break;
  299. }
  300. buf1 += size;
  301. buf2 += size;
  302. /* reset watchdog from time to time */
  303. if ((ngood % (64 << 10)) == 0)
  304. WATCHDOG_RESET();
  305. }
  306. unmap_sysmem(buf1);
  307. unmap_sysmem(buf2);
  308. printf("Total of %ld %s(s) were the same\n", ngood, type);
  309. return rcode;
  310. }
  311. static int do_mem_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  312. {
  313. ulong addr, dest, count, bytes;
  314. int size;
  315. const void *src;
  316. void *buf;
  317. if (argc != 4)
  318. return CMD_RET_USAGE;
  319. /* Check for size specification.
  320. */
  321. if ((size = cmd_get_data_size(argv[0], 4)) < 0)
  322. return 1;
  323. addr = simple_strtoul(argv[1], NULL, 16);
  324. addr += base_address;
  325. dest = simple_strtoul(argv[2], NULL, 16);
  326. dest += base_address;
  327. count = simple_strtoul(argv[3], NULL, 16);
  328. if (count == 0) {
  329. puts ("Zero length ???\n");
  330. return 1;
  331. }
  332. #ifndef CONFIG_SYS_NO_FLASH
  333. /* check if we are copying to Flash */
  334. if ( (addr2info(dest) != NULL)
  335. #ifdef CONFIG_HAS_DATAFLASH
  336. && (!addr_dataflash(dest))
  337. #endif
  338. ) {
  339. int rc;
  340. puts ("Copy to Flash... ");
  341. rc = flash_write ((char *)addr, dest, count*size);
  342. if (rc != 0) {
  343. flash_perror (rc);
  344. return (1);
  345. }
  346. puts ("done\n");
  347. return 0;
  348. }
  349. #endif
  350. #ifdef CONFIG_HAS_DATAFLASH
  351. /* Check if we are copying from RAM or Flash to DataFlash */
  352. if (addr_dataflash(dest) && !addr_dataflash(addr)){
  353. int rc;
  354. puts ("Copy to DataFlash... ");
  355. rc = write_dataflash (dest, addr, count*size);
  356. if (rc != 1) {
  357. dataflash_perror (rc);
  358. return (1);
  359. }
  360. puts ("done\n");
  361. return 0;
  362. }
  363. /* Check if we are copying from DataFlash to RAM */
  364. if (addr_dataflash(addr) && !addr_dataflash(dest)
  365. #ifndef CONFIG_SYS_NO_FLASH
  366. && (addr2info(dest) == NULL)
  367. #endif
  368. ){
  369. int rc;
  370. rc = read_dataflash(addr, count * size, (char *) dest);
  371. if (rc != 1) {
  372. dataflash_perror (rc);
  373. return (1);
  374. }
  375. return 0;
  376. }
  377. if (addr_dataflash(addr) && addr_dataflash(dest)){
  378. puts ("Unsupported combination of source/destination.\n\r");
  379. return 1;
  380. }
  381. #endif
  382. #ifdef CONFIG_BLACKFIN
  383. /* See if we're copying to/from L1 inst */
  384. if (addr_bfin_on_chip_mem(dest) || addr_bfin_on_chip_mem(addr)) {
  385. memcpy((void *)dest, (void *)addr, count * size);
  386. return 0;
  387. }
  388. #endif
  389. bytes = size * count;
  390. buf = map_sysmem(dest, bytes);
  391. src = map_sysmem(addr, bytes);
  392. while (count-- > 0) {
  393. if (size == 4)
  394. *((u32 *)buf) = *((u32 *)src);
  395. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  396. else if (size == 8)
  397. *((u64 *)buf) = *((u64 *)src);
  398. #endif
  399. else if (size == 2)
  400. *((u16 *)buf) = *((u16 *)src);
  401. else
  402. *((u8 *)buf) = *((u8 *)src);
  403. src += size;
  404. buf += size;
  405. /* reset watchdog from time to time */
  406. if ((count % (64 << 10)) == 0)
  407. WATCHDOG_RESET();
  408. }
  409. unmap_sysmem(buf);
  410. unmap_sysmem(src);
  411. return 0;
  412. }
  413. static int do_mem_base(cmd_tbl_t *cmdtp, int flag, int argc,
  414. char * const argv[])
  415. {
  416. if (argc > 1) {
  417. /* Set new base address.
  418. */
  419. base_address = simple_strtoul(argv[1], NULL, 16);
  420. }
  421. /* Print the current base address.
  422. */
  423. printf("Base Address: 0x%08lx\n", base_address);
  424. return 0;
  425. }
  426. static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc,
  427. char * const argv[])
  428. {
  429. ulong addr, length, i, bytes;
  430. int size;
  431. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  432. volatile u64 *llp;
  433. #endif
  434. volatile u32 *longp;
  435. volatile u16 *shortp;
  436. volatile u8 *cp;
  437. const void *buf;
  438. if (argc < 3)
  439. return CMD_RET_USAGE;
  440. /*
  441. * Check for a size specification.
  442. * Defaults to long if no or incorrect specification.
  443. */
  444. if ((size = cmd_get_data_size(argv[0], 4)) < 0)
  445. return 1;
  446. /* Address is always specified.
  447. */
  448. addr = simple_strtoul(argv[1], NULL, 16);
  449. /* Length is the number of objects, not number of bytes.
  450. */
  451. length = simple_strtoul(argv[2], NULL, 16);
  452. bytes = size * length;
  453. buf = map_sysmem(addr, bytes);
  454. /* We want to optimize the loops to run as fast as possible.
  455. * If we have only one object, just run infinite loops.
  456. */
  457. if (length == 1) {
  458. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  459. if (size == 8) {
  460. llp = (u64 *)buf;
  461. for (;;)
  462. i = *llp;
  463. }
  464. #endif
  465. if (size == 4) {
  466. longp = (u32 *)buf;
  467. for (;;)
  468. i = *longp;
  469. }
  470. if (size == 2) {
  471. shortp = (u16 *)buf;
  472. for (;;)
  473. i = *shortp;
  474. }
  475. cp = (u8 *)buf;
  476. for (;;)
  477. i = *cp;
  478. }
  479. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  480. if (size == 8) {
  481. for (;;) {
  482. llp = (u64 *)buf;
  483. i = length;
  484. while (i-- > 0)
  485. *llp++;
  486. }
  487. }
  488. #endif
  489. if (size == 4) {
  490. for (;;) {
  491. longp = (u32 *)buf;
  492. i = length;
  493. while (i-- > 0)
  494. *longp++;
  495. }
  496. }
  497. if (size == 2) {
  498. for (;;) {
  499. shortp = (u16 *)buf;
  500. i = length;
  501. while (i-- > 0)
  502. *shortp++;
  503. }
  504. }
  505. for (;;) {
  506. cp = (u8 *)buf;
  507. i = length;
  508. while (i-- > 0)
  509. *cp++;
  510. }
  511. unmap_sysmem(buf);
  512. return 0;
  513. }
  514. #ifdef CONFIG_LOOPW
  515. static int do_mem_loopw(cmd_tbl_t *cmdtp, int flag, int argc,
  516. char * const argv[])
  517. {
  518. ulong addr, length, i, bytes;
  519. int size;
  520. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  521. volatile u64 *llp;
  522. u64 data;
  523. #else
  524. ulong data;
  525. #endif
  526. volatile u32 *longp;
  527. volatile u16 *shortp;
  528. volatile u8 *cp;
  529. void *buf;
  530. if (argc < 4)
  531. return CMD_RET_USAGE;
  532. /*
  533. * Check for a size specification.
  534. * Defaults to long if no or incorrect specification.
  535. */
  536. if ((size = cmd_get_data_size(argv[0], 4)) < 0)
  537. return 1;
  538. /* Address is always specified.
  539. */
  540. addr = simple_strtoul(argv[1], NULL, 16);
  541. /* Length is the number of objects, not number of bytes.
  542. */
  543. length = simple_strtoul(argv[2], NULL, 16);
  544. /* data to write */
  545. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  546. data = simple_strtoull(argv[3], NULL, 16);
  547. #else
  548. data = simple_strtoul(argv[3], NULL, 16);
  549. #endif
  550. bytes = size * length;
  551. buf = map_sysmem(addr, bytes);
  552. /* We want to optimize the loops to run as fast as possible.
  553. * If we have only one object, just run infinite loops.
  554. */
  555. if (length == 1) {
  556. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  557. if (size == 8) {
  558. llp = (u64 *)buf;
  559. for (;;)
  560. *llp = data;
  561. }
  562. #endif
  563. if (size == 4) {
  564. longp = (u32 *)buf;
  565. for (;;)
  566. *longp = data;
  567. }
  568. if (size == 2) {
  569. shortp = (u16 *)buf;
  570. for (;;)
  571. *shortp = data;
  572. }
  573. cp = (u8 *)buf;
  574. for (;;)
  575. *cp = data;
  576. }
  577. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  578. if (size == 8) {
  579. for (;;) {
  580. llp = (u64 *)buf;
  581. i = length;
  582. while (i-- > 0)
  583. *llp++ = data;
  584. }
  585. }
  586. #endif
  587. if (size == 4) {
  588. for (;;) {
  589. longp = (u32 *)buf;
  590. i = length;
  591. while (i-- > 0)
  592. *longp++ = data;
  593. }
  594. }
  595. if (size == 2) {
  596. for (;;) {
  597. shortp = (u16 *)buf;
  598. i = length;
  599. while (i-- > 0)
  600. *shortp++ = data;
  601. }
  602. }
  603. for (;;) {
  604. cp = (u8 *)buf;
  605. i = length;
  606. while (i-- > 0)
  607. *cp++ = data;
  608. }
  609. }
  610. #endif /* CONFIG_LOOPW */
  611. #ifdef CONFIG_CMD_MEMTEST
  612. static ulong mem_test_alt(vu_long *buf, ulong start_addr, ulong end_addr,
  613. vu_long *dummy)
  614. {
  615. vu_long *addr;
  616. ulong errs = 0;
  617. ulong val, readback;
  618. int j;
  619. vu_long offset;
  620. vu_long test_offset;
  621. vu_long pattern;
  622. vu_long temp;
  623. vu_long anti_pattern;
  624. vu_long num_words;
  625. static const ulong bitpattern[] = {
  626. 0x00000001, /* single bit */
  627. 0x00000003, /* two adjacent bits */
  628. 0x00000007, /* three adjacent bits */
  629. 0x0000000F, /* four adjacent bits */
  630. 0x00000005, /* two non-adjacent bits */
  631. 0x00000015, /* three non-adjacent bits */
  632. 0x00000055, /* four non-adjacent bits */
  633. 0xaaaaaaaa, /* alternating 1/0 */
  634. };
  635. num_words = (end_addr - start_addr) / sizeof(vu_long);
  636. /*
  637. * Data line test: write a pattern to the first
  638. * location, write the 1's complement to a 'parking'
  639. * address (changes the state of the data bus so a
  640. * floating bus doesn't give a false OK), and then
  641. * read the value back. Note that we read it back
  642. * into a variable because the next time we read it,
  643. * it might be right (been there, tough to explain to
  644. * the quality guys why it prints a failure when the
  645. * "is" and "should be" are obviously the same in the
  646. * error message).
  647. *
  648. * Rather than exhaustively testing, we test some
  649. * patterns by shifting '1' bits through a field of
  650. * '0's and '0' bits through a field of '1's (i.e.
  651. * pattern and ~pattern).
  652. */
  653. addr = buf;
  654. for (j = 0; j < sizeof(bitpattern) / sizeof(bitpattern[0]); j++) {
  655. val = bitpattern[j];
  656. for (; val != 0; val <<= 1) {
  657. *addr = val;
  658. *dummy = ~val; /* clear the test data off the bus */
  659. readback = *addr;
  660. if (readback != val) {
  661. printf("FAILURE (data line): "
  662. "expected %08lx, actual %08lx\n",
  663. val, readback);
  664. errs++;
  665. if (ctrlc())
  666. return -1;
  667. }
  668. *addr = ~val;
  669. *dummy = val;
  670. readback = *addr;
  671. if (readback != ~val) {
  672. printf("FAILURE (data line): "
  673. "Is %08lx, should be %08lx\n",
  674. readback, ~val);
  675. errs++;
  676. if (ctrlc())
  677. return -1;
  678. }
  679. }
  680. }
  681. /*
  682. * Based on code whose Original Author and Copyright
  683. * information follows: Copyright (c) 1998 by Michael
  684. * Barr. This software is placed into the public
  685. * domain and may be used for any purpose. However,
  686. * this notice must not be changed or removed and no
  687. * warranty is either expressed or implied by its
  688. * publication or distribution.
  689. */
  690. /*
  691. * Address line test
  692. * Description: Test the address bus wiring in a
  693. * memory region by performing a walking
  694. * 1's test on the relevant bits of the
  695. * address and checking for aliasing.
  696. * This test will find single-bit
  697. * address failures such as stuck-high,
  698. * stuck-low, and shorted pins. The base
  699. * address and size of the region are
  700. * selected by the caller.
  701. * Notes: For best results, the selected base
  702. * address should have enough LSB 0's to
  703. * guarantee single address bit changes.
  704. * For example, to test a 64-Kbyte
  705. * region, select a base address on a
  706. * 64-Kbyte boundary. Also, select the
  707. * region size as a power-of-two if at
  708. * all possible.
  709. *
  710. * Returns: 0 if the test succeeds, 1 if the test fails.
  711. */
  712. pattern = (vu_long) 0xaaaaaaaa;
  713. anti_pattern = (vu_long) 0x55555555;
  714. debug("%s:%d: length = 0x%.8lx\n", __func__, __LINE__, num_words);
  715. /*
  716. * Write the default pattern at each of the
  717. * power-of-two offsets.
  718. */
  719. for (offset = 1; offset < num_words; offset <<= 1)
  720. addr[offset] = pattern;
  721. /*
  722. * Check for address bits stuck high.
  723. */
  724. test_offset = 0;
  725. addr[test_offset] = anti_pattern;
  726. for (offset = 1; offset < num_words; offset <<= 1) {
  727. temp = addr[offset];
  728. if (temp != pattern) {
  729. printf("\nFAILURE: Address bit stuck high @ 0x%.8lx:"
  730. " expected 0x%.8lx, actual 0x%.8lx\n",
  731. start_addr + offset*sizeof(vu_long),
  732. pattern, temp);
  733. errs++;
  734. if (ctrlc())
  735. return -1;
  736. }
  737. }
  738. addr[test_offset] = pattern;
  739. WATCHDOG_RESET();
  740. /*
  741. * Check for addr bits stuck low or shorted.
  742. */
  743. for (test_offset = 1; test_offset < num_words; test_offset <<= 1) {
  744. addr[test_offset] = anti_pattern;
  745. for (offset = 1; offset < num_words; offset <<= 1) {
  746. temp = addr[offset];
  747. if ((temp != pattern) && (offset != test_offset)) {
  748. printf("\nFAILURE: Address bit stuck low or"
  749. " shorted @ 0x%.8lx: expected 0x%.8lx,"
  750. " actual 0x%.8lx\n",
  751. start_addr + offset*sizeof(vu_long),
  752. pattern, temp);
  753. errs++;
  754. if (ctrlc())
  755. return -1;
  756. }
  757. }
  758. addr[test_offset] = pattern;
  759. }
  760. /*
  761. * Description: Test the integrity of a physical
  762. * memory device by performing an
  763. * increment/decrement test over the
  764. * entire region. In the process every
  765. * storage bit in the device is tested
  766. * as a zero and a one. The base address
  767. * and the size of the region are
  768. * selected by the caller.
  769. *
  770. * Returns: 0 if the test succeeds, 1 if the test fails.
  771. */
  772. num_words++;
  773. /*
  774. * Fill memory with a known pattern.
  775. */
  776. for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
  777. WATCHDOG_RESET();
  778. addr[offset] = pattern;
  779. }
  780. /*
  781. * Check each location and invert it for the second pass.
  782. */
  783. for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
  784. WATCHDOG_RESET();
  785. temp = addr[offset];
  786. if (temp != pattern) {
  787. printf("\nFAILURE (read/write) @ 0x%.8lx:"
  788. " expected 0x%.8lx, actual 0x%.8lx)\n",
  789. start_addr + offset*sizeof(vu_long),
  790. pattern, temp);
  791. errs++;
  792. if (ctrlc())
  793. return -1;
  794. }
  795. anti_pattern = ~pattern;
  796. addr[offset] = anti_pattern;
  797. }
  798. /*
  799. * Check each location for the inverted pattern and zero it.
  800. */
  801. for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
  802. WATCHDOG_RESET();
  803. anti_pattern = ~pattern;
  804. temp = addr[offset];
  805. if (temp != anti_pattern) {
  806. printf("\nFAILURE (read/write): @ 0x%.8lx:"
  807. " expected 0x%.8lx, actual 0x%.8lx)\n",
  808. start_addr + offset*sizeof(vu_long),
  809. anti_pattern, temp);
  810. errs++;
  811. if (ctrlc())
  812. return -1;
  813. }
  814. addr[offset] = 0;
  815. }
  816. return 0;
  817. }
  818. static ulong mem_test_quick(vu_long *buf, ulong start_addr, ulong end_addr,
  819. vu_long pattern, int iteration)
  820. {
  821. vu_long *end;
  822. vu_long *addr;
  823. ulong errs = 0;
  824. ulong incr, length;
  825. ulong val, readback;
  826. /* Alternate the pattern */
  827. incr = 1;
  828. if (iteration & 1) {
  829. incr = -incr;
  830. /*
  831. * Flip the pattern each time to make lots of zeros and
  832. * then, the next time, lots of ones. We decrement
  833. * the "negative" patterns and increment the "positive"
  834. * patterns to preserve this feature.
  835. */
  836. if (pattern & 0x80000000)
  837. pattern = -pattern; /* complement & increment */
  838. else
  839. pattern = ~pattern;
  840. }
  841. length = (end_addr - start_addr) / sizeof(ulong);
  842. end = buf + length;
  843. printf("\rPattern %08lX Writing..."
  844. "%12s"
  845. "\b\b\b\b\b\b\b\b\b\b",
  846. pattern, "");
  847. for (addr = buf, val = pattern; addr < end; addr++) {
  848. WATCHDOG_RESET();
  849. *addr = val;
  850. val += incr;
  851. }
  852. puts("Reading...");
  853. for (addr = buf, val = pattern; addr < end; addr++) {
  854. WATCHDOG_RESET();
  855. readback = *addr;
  856. if (readback != val) {
  857. ulong offset = addr - buf;
  858. printf("\nMem error @ 0x%08X: "
  859. "found %08lX, expected %08lX\n",
  860. (uint)(uintptr_t)(start_addr + offset*sizeof(vu_long)),
  861. readback, val);
  862. errs++;
  863. if (ctrlc())
  864. return -1;
  865. }
  866. val += incr;
  867. }
  868. return 0;
  869. }
  870. /*
  871. * Perform a memory test. A more complete alternative test can be
  872. * configured using CONFIG_SYS_ALT_MEMTEST. The complete test loops until
  873. * interrupted by ctrl-c or by a failure of one of the sub-tests.
  874. */
  875. static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,
  876. char * const argv[])
  877. {
  878. ulong start, end;
  879. vu_long *buf, *dummy;
  880. int iteration_limit;
  881. int ret;
  882. ulong errs = 0; /* number of errors, or -1 if interrupted */
  883. ulong pattern;
  884. int iteration;
  885. #if defined(CONFIG_SYS_ALT_MEMTEST)
  886. const int alt_test = 1;
  887. #else
  888. const int alt_test = 0;
  889. #endif
  890. if (argc > 1)
  891. start = simple_strtoul(argv[1], NULL, 16);
  892. else
  893. start = CONFIG_SYS_MEMTEST_START;
  894. if (argc > 2)
  895. end = simple_strtoul(argv[2], NULL, 16);
  896. else
  897. end = CONFIG_SYS_MEMTEST_END;
  898. if (argc > 3)
  899. pattern = (ulong)simple_strtoul(argv[3], NULL, 16);
  900. else
  901. pattern = 0;
  902. if (argc > 4)
  903. iteration_limit = (ulong)simple_strtoul(argv[4], NULL, 16);
  904. else
  905. iteration_limit = 0;
  906. printf("Testing %08x ... %08x:\n", (uint)start, (uint)end);
  907. debug("%s:%d: start %#08lx end %#08lx\n", __func__, __LINE__,
  908. start, end);
  909. buf = map_sysmem(start, end - start);
  910. dummy = map_sysmem(CONFIG_SYS_MEMTEST_SCRATCH, sizeof(vu_long));
  911. for (iteration = 0;
  912. !iteration_limit || iteration < iteration_limit;
  913. iteration++) {
  914. if (ctrlc()) {
  915. errs = -1UL;
  916. break;
  917. }
  918. printf("Iteration: %6d\r", iteration + 1);
  919. debug("\n");
  920. if (alt_test) {
  921. errs = mem_test_alt(buf, start, end, dummy);
  922. } else {
  923. errs = mem_test_quick(buf, start, end, pattern,
  924. iteration);
  925. }
  926. if (errs == -1UL)
  927. break;
  928. }
  929. /*
  930. * Work-around for eldk-4.2 which gives this warning if we try to
  931. * case in the unmap_sysmem() call:
  932. * warning: initialization discards qualifiers from pointer target type
  933. */
  934. {
  935. void *vbuf = (void *)buf;
  936. void *vdummy = (void *)dummy;
  937. unmap_sysmem(vbuf);
  938. unmap_sysmem(vdummy);
  939. }
  940. if (errs == -1UL) {
  941. /* Memory test was aborted - write a newline to finish off */
  942. putc('\n');
  943. ret = 1;
  944. } else {
  945. printf("Tested %d iteration(s) with %lu errors.\n",
  946. iteration, errs);
  947. ret = errs != 0;
  948. }
  949. return ret; /* not reached */
  950. }
  951. #endif /* CONFIG_CMD_MEMTEST */
  952. /* Modify memory.
  953. *
  954. * Syntax:
  955. * mm{.b, .w, .l, .q} {addr}
  956. * nm{.b, .w, .l, .q} {addr}
  957. */
  958. static int
  959. mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
  960. {
  961. ulong addr;
  962. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  963. u64 i;
  964. #else
  965. ulong i;
  966. #endif
  967. int nbytes, size;
  968. void *ptr = NULL;
  969. if (argc != 2)
  970. return CMD_RET_USAGE;
  971. bootretry_reset_cmd_timeout(); /* got a good command to get here */
  972. /* We use the last specified parameters, unless new ones are
  973. * entered.
  974. */
  975. addr = mm_last_addr;
  976. size = mm_last_size;
  977. if ((flag & CMD_FLAG_REPEAT) == 0) {
  978. /* New command specified. Check for a size specification.
  979. * Defaults to long if no or incorrect specification.
  980. */
  981. if ((size = cmd_get_data_size(argv[0], 4)) < 0)
  982. return 1;
  983. /* Address is specified since argc > 1
  984. */
  985. addr = simple_strtoul(argv[1], NULL, 16);
  986. addr += base_address;
  987. }
  988. #ifdef CONFIG_HAS_DATAFLASH
  989. if (addr_dataflash(addr)){
  990. puts ("Can't modify DataFlash in place. Use cp instead.\n\r");
  991. return 0;
  992. }
  993. #endif
  994. #ifdef CONFIG_BLACKFIN
  995. if (addr_bfin_on_chip_mem(addr)) {
  996. puts ("Can't modify L1 instruction in place. Use cp instead.\n\r");
  997. return 0;
  998. }
  999. #endif
  1000. /* Print the address, followed by value. Then accept input for
  1001. * the next value. A non-converted value exits.
  1002. */
  1003. do {
  1004. ptr = map_sysmem(addr, size);
  1005. printf("%08lx:", addr);
  1006. if (size == 4)
  1007. printf(" %08x", *((u32 *)ptr));
  1008. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  1009. else if (size == 8)
  1010. printf(" %016llx", *((u64 *)ptr));
  1011. #endif
  1012. else if (size == 2)
  1013. printf(" %04x", *((u16 *)ptr));
  1014. else
  1015. printf(" %02x", *((u8 *)ptr));
  1016. nbytes = cli_readline(" ? ");
  1017. if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) {
  1018. /* <CR> pressed as only input, don't modify current
  1019. * location and move to next. "-" pressed will go back.
  1020. */
  1021. if (incrflag)
  1022. addr += nbytes ? -size : size;
  1023. nbytes = 1;
  1024. /* good enough to not time out */
  1025. bootretry_reset_cmd_timeout();
  1026. }
  1027. #ifdef CONFIG_BOOT_RETRY_TIME
  1028. else if (nbytes == -2) {
  1029. break; /* timed out, exit the command */
  1030. }
  1031. #endif
  1032. else {
  1033. char *endp;
  1034. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  1035. i = simple_strtoull(console_buffer, &endp, 16);
  1036. #else
  1037. i = simple_strtoul(console_buffer, &endp, 16);
  1038. #endif
  1039. nbytes = endp - console_buffer;
  1040. if (nbytes) {
  1041. /* good enough to not time out
  1042. */
  1043. bootretry_reset_cmd_timeout();
  1044. if (size == 4)
  1045. *((u32 *)ptr) = i;
  1046. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  1047. else if (size == 8)
  1048. *((u64 *)ptr) = i;
  1049. #endif
  1050. else if (size == 2)
  1051. *((u16 *)ptr) = i;
  1052. else
  1053. *((u8 *)ptr) = i;
  1054. if (incrflag)
  1055. addr += size;
  1056. }
  1057. }
  1058. } while (nbytes);
  1059. if (ptr)
  1060. unmap_sysmem(ptr);
  1061. mm_last_addr = addr;
  1062. mm_last_size = size;
  1063. return 0;
  1064. }
  1065. #ifdef CONFIG_CMD_CRC32
  1066. static int do_mem_crc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  1067. {
  1068. int flags = 0;
  1069. int ac;
  1070. char * const *av;
  1071. if (argc < 3)
  1072. return CMD_RET_USAGE;
  1073. av = argv + 1;
  1074. ac = argc - 1;
  1075. #ifdef CONFIG_HASH_VERIFY
  1076. if (strcmp(*av, "-v") == 0) {
  1077. flags |= HASH_FLAG_VERIFY;
  1078. av++;
  1079. ac--;
  1080. }
  1081. #endif
  1082. return hash_command("crc32", flags, cmdtp, flag, ac, av);
  1083. }
  1084. #endif
  1085. /**************************************************/
  1086. U_BOOT_CMD(
  1087. md, 3, 1, do_mem_md,
  1088. "memory display",
  1089. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  1090. "[.b, .w, .l, .q] address [# of objects]"
  1091. #else
  1092. "[.b, .w, .l] address [# of objects]"
  1093. #endif
  1094. );
  1095. U_BOOT_CMD(
  1096. mm, 2, 1, do_mem_mm,
  1097. "memory modify (auto-incrementing address)",
  1098. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  1099. "[.b, .w, .l, .q] address"
  1100. #else
  1101. "[.b, .w, .l] address"
  1102. #endif
  1103. );
  1104. U_BOOT_CMD(
  1105. nm, 2, 1, do_mem_nm,
  1106. "memory modify (constant address)",
  1107. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  1108. "[.b, .w, .l, .q] address"
  1109. #else
  1110. "[.b, .w, .l] address"
  1111. #endif
  1112. );
  1113. U_BOOT_CMD(
  1114. mw, 4, 1, do_mem_mw,
  1115. "memory write (fill)",
  1116. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  1117. "[.b, .w, .l, .q] address value [count]"
  1118. #else
  1119. "[.b, .w, .l] address value [count]"
  1120. #endif
  1121. );
  1122. U_BOOT_CMD(
  1123. cp, 4, 1, do_mem_cp,
  1124. "memory copy",
  1125. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  1126. "[.b, .w, .l, .q] source target count"
  1127. #else
  1128. "[.b, .w, .l] source target count"
  1129. #endif
  1130. );
  1131. U_BOOT_CMD(
  1132. cmp, 4, 1, do_mem_cmp,
  1133. "memory compare",
  1134. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  1135. "[.b, .w, .l, .q] addr1 addr2 count"
  1136. #else
  1137. "[.b, .w, .l] addr1 addr2 count"
  1138. #endif
  1139. );
  1140. #ifdef CONFIG_CMD_CRC32
  1141. #ifndef CONFIG_CRC32_VERIFY
  1142. U_BOOT_CMD(
  1143. crc32, 4, 1, do_mem_crc,
  1144. "checksum calculation",
  1145. "address count [addr]\n - compute CRC32 checksum [save at addr]"
  1146. );
  1147. #else /* CONFIG_CRC32_VERIFY */
  1148. U_BOOT_CMD(
  1149. crc32, 5, 1, do_mem_crc,
  1150. "checksum calculation",
  1151. "address count [addr]\n - compute CRC32 checksum [save at addr]\n"
  1152. "-v address count crc\n - verify crc of memory area"
  1153. );
  1154. #endif /* CONFIG_CRC32_VERIFY */
  1155. #endif
  1156. #ifdef CONFIG_CMD_MEMINFO
  1157. __weak void board_show_dram(ulong size)
  1158. {
  1159. puts("DRAM: ");
  1160. print_size(size, "\n");
  1161. }
  1162. static int do_mem_info(cmd_tbl_t *cmdtp, int flag, int argc,
  1163. char * const argv[])
  1164. {
  1165. board_show_dram(gd->ram_size);
  1166. return 0;
  1167. }
  1168. #endif
  1169. U_BOOT_CMD(
  1170. base, 2, 1, do_mem_base,
  1171. "print or set address offset",
  1172. "\n - print address offset for memory commands\n"
  1173. "base off\n - set address offset for memory commands to 'off'"
  1174. );
  1175. U_BOOT_CMD(
  1176. loop, 3, 1, do_mem_loop,
  1177. "infinite loop on address range",
  1178. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  1179. "[.b, .w, .l, .q] address number_of_objects"
  1180. #else
  1181. "[.b, .w, .l] address number_of_objects"
  1182. #endif
  1183. );
  1184. #ifdef CONFIG_LOOPW
  1185. U_BOOT_CMD(
  1186. loopw, 4, 1, do_mem_loopw,
  1187. "infinite write loop on address range",
  1188. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  1189. "[.b, .w, .l, .q] address number_of_objects data_to_write"
  1190. #else
  1191. "[.b, .w, .l] address number_of_objects data_to_write"
  1192. #endif
  1193. );
  1194. #endif /* CONFIG_LOOPW */
  1195. #ifdef CONFIG_CMD_MEMTEST
  1196. U_BOOT_CMD(
  1197. mtest, 5, 1, do_mem_mtest,
  1198. "simple RAM read/write test",
  1199. "[start [end [pattern [iterations]]]]"
  1200. );
  1201. #endif /* CONFIG_CMD_MEMTEST */
  1202. #ifdef CONFIG_MX_CYCLIC
  1203. U_BOOT_CMD(
  1204. mdc, 4, 1, do_mem_mdc,
  1205. "memory display cyclic",
  1206. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  1207. "[.b, .w, .l, .q] address count delay(ms)"
  1208. #else
  1209. "[.b, .w, .l] address count delay(ms)"
  1210. #endif
  1211. );
  1212. U_BOOT_CMD(
  1213. mwc, 4, 1, do_mem_mwc,
  1214. "memory write cyclic",
  1215. #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
  1216. "[.b, .w, .l, .q] address value delay(ms)"
  1217. #else
  1218. "[.b, .w, .l] address value delay(ms)"
  1219. #endif
  1220. );
  1221. #endif /* CONFIG_MX_CYCLIC */
  1222. #ifdef CONFIG_CMD_MEMINFO
  1223. U_BOOT_CMD(
  1224. meminfo, 3, 1, do_mem_info,
  1225. "display memory information",
  1226. ""
  1227. );
  1228. #endif