Commit 4d1fd7f1ae6cf4e6e4e1cad975f1dcdea62b6d83
Committed by
Tom Rini
1 parent
f9aa6a1086
Exists in
v2017.01-smarct4x
and in
48 other branches
Add 64-bit data support for memory commands
Add 64-bit data for memory commands, such as md, mw, mm, cmp. The new size ".q " is introduced. For 64-bit architecture, 64-bit data is enabled by default, by detecting compiler __LP64__. It is optional for other architectures. Signed-off-by: York Sun <yorksun@freescale.com>
Showing 5 changed files with 174 additions and 11 deletions Side-by-side Diff
README
... | ... | @@ -3470,6 +3470,9 @@ |
3470 | 3470 | Configuration Settings: |
3471 | 3471 | ----------------------- |
3472 | 3472 | |
3473 | +- CONFIG_SYS_SUPPORT_64BIT_DATA: Defined automatically if compiled as 64-bit. | |
3474 | + Optionally it can be defined to support 64-bit memory commands. | |
3475 | + | |
3473 | 3476 | - CONFIG_SYS_LONGHELP: Defined when you want long help messages included; |
3474 | 3477 | undefine this when you're short of memory. |
3475 | 3478 |
common/cmd_mem.c
... | ... | @@ -41,7 +41,7 @@ |
41 | 41 | /* Memory Display |
42 | 42 | * |
43 | 43 | * Syntax: |
44 | - * md{.b, .w, .l} {addr} {len} | |
44 | + * md{.b, .w, .l, .q} {addr} {len} | |
45 | 45 | */ |
46 | 46 | #define DISP_LINE_LEN 16 |
47 | 47 | static int do_mem_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
... | ... | @@ -155,7 +155,12 @@ |
155 | 155 | |
156 | 156 | static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
157 | 157 | { |
158 | - ulong addr, writeval, count; | |
158 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
159 | + u64 writeval; | |
160 | +#else | |
161 | + ulong writeval; | |
162 | +#endif | |
163 | + ulong addr, count; | |
159 | 164 | int size; |
160 | 165 | void *buf; |
161 | 166 | ulong bytes; |
162 | 167 | |
... | ... | @@ -175,7 +180,11 @@ |
175 | 180 | |
176 | 181 | /* Get the value to write. |
177 | 182 | */ |
183 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
184 | + writeval = simple_strtoull(argv[2], NULL, 16); | |
185 | +#else | |
178 | 186 | writeval = simple_strtoul(argv[2], NULL, 16); |
187 | +#endif | |
179 | 188 | |
180 | 189 | /* Count ? */ |
181 | 190 | if (argc == 4) { |
... | ... | @@ -189,6 +198,10 @@ |
189 | 198 | while (count-- > 0) { |
190 | 199 | if (size == 4) |
191 | 200 | *((u32 *)buf) = (u32)writeval; |
201 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
202 | + else if (size == 8) | |
203 | + *((u64 *)buf) = (u64)writeval; | |
204 | +#endif | |
192 | 205 | else if (size == 2) |
193 | 206 | *((u16 *)buf) = (u16)writeval; |
194 | 207 | else |
... | ... | @@ -262,6 +275,11 @@ |
262 | 275 | int rcode = 0; |
263 | 276 | const char *type; |
264 | 277 | const void *buf1, *buf2, *base; |
278 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
279 | + u64 word1, word2; | |
280 | +#else | |
281 | + ulong word1, word2; | |
282 | +#endif | |
265 | 283 | |
266 | 284 | if (argc != 4) |
267 | 285 | return CMD_RET_USAGE; |
... | ... | @@ -270,7 +288,9 @@ |
270 | 288 | */ |
271 | 289 | if ((size = cmd_get_data_size(argv[0], 4)) < 0) |
272 | 290 | return 1; |
273 | - type = size == 4 ? "word" : size == 2 ? "halfword" : "byte"; | |
291 | + type = size == 8 ? "double word" : | |
292 | + size == 4 ? "word" : | |
293 | + size == 2 ? "halfword" : "byte"; | |
274 | 294 | |
275 | 295 | addr1 = simple_strtoul(argv[1], NULL, 16); |
276 | 296 | addr1 += base_address; |
277 | 297 | |
... | ... | @@ -298,10 +318,14 @@ |
298 | 318 | base = buf1 = map_sysmem(addr1, bytes); |
299 | 319 | buf2 = map_sysmem(addr2, bytes); |
300 | 320 | for (ngood = 0; ngood < count; ++ngood) { |
301 | - ulong word1, word2; | |
302 | 321 | if (size == 4) { |
303 | 322 | word1 = *(u32 *)buf1; |
304 | 323 | word2 = *(u32 *)buf2; |
324 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
325 | + } else if (size == 8) { | |
326 | + word1 = *(u64 *)buf1; | |
327 | + word2 = *(u64 *)buf2; | |
328 | +#endif | |
305 | 329 | } else if (size == 2) { |
306 | 330 | word1 = *(u16 *)buf1; |
307 | 331 | word2 = *(u16 *)buf2; |
308 | 332 | |
... | ... | @@ -311,10 +335,15 @@ |
311 | 335 | } |
312 | 336 | if (word1 != word2) { |
313 | 337 | ulong offset = buf1 - base; |
314 | - | |
338 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
339 | + printf("%s at 0x%p (%#0*llx) != %s at 0x%p (%#0*llx)\n", | |
340 | + type, (void *)(addr1 + offset), size, word1, | |
341 | + type, (void *)(addr2 + offset), size, word2); | |
342 | +#else | |
315 | 343 | printf("%s at 0x%08lx (%#0*lx) != %s at 0x%08lx (%#0*lx)\n", |
316 | 344 | type, (ulong)(addr1 + offset), size, word1, |
317 | 345 | type, (ulong)(addr2 + offset), size, word2); |
346 | +#endif | |
318 | 347 | rcode = 1; |
319 | 348 | break; |
320 | 349 | } |
... | ... | @@ -434,6 +463,10 @@ |
434 | 463 | while (count-- > 0) { |
435 | 464 | if (size == 4) |
436 | 465 | *((u32 *)buf) = *((u32 *)src); |
466 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
467 | + else if (size == 8) | |
468 | + *((u64 *)buf) = *((u64 *)src); | |
469 | +#endif | |
437 | 470 | else if (size == 2) |
438 | 471 | *((u16 *)buf) = *((u16 *)src); |
439 | 472 | else |
... | ... | @@ -467,6 +500,9 @@ |
467 | 500 | { |
468 | 501 | ulong addr, length, i, bytes; |
469 | 502 | int size; |
503 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
504 | + volatile u64 *llp; | |
505 | +#endif | |
470 | 506 | volatile u32 *longp; |
471 | 507 | volatile u16 *shortp; |
472 | 508 | volatile u8 *cp; |
... | ... | @@ -497,6 +533,13 @@ |
497 | 533 | * If we have only one object, just run infinite loops. |
498 | 534 | */ |
499 | 535 | if (length == 1) { |
536 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
537 | + if (size == 8) { | |
538 | + llp = (u64 *)buf; | |
539 | + for (;;) | |
540 | + i = *llp; | |
541 | + } | |
542 | +#endif | |
500 | 543 | if (size == 4) { |
501 | 544 | longp = (u32 *)buf; |
502 | 545 | for (;;) |
... | ... | @@ -512,6 +555,16 @@ |
512 | 555 | i = *cp; |
513 | 556 | } |
514 | 557 | |
558 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
559 | + if (size == 8) { | |
560 | + for (;;) { | |
561 | + llp = (u64 *)buf; | |
562 | + i = length; | |
563 | + while (i-- > 0) | |
564 | + *llp++; | |
565 | + } | |
566 | + } | |
567 | +#endif | |
515 | 568 | if (size == 4) { |
516 | 569 | for (;;) { |
517 | 570 | longp = (u32 *)buf; |
518 | 571 | |
... | ... | @@ -542,8 +595,14 @@ |
542 | 595 | #ifdef CONFIG_LOOPW |
543 | 596 | int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
544 | 597 | { |
545 | - ulong addr, length, i, data, bytes; | |
598 | + ulong addr, length, i, bytes; | |
546 | 599 | int size; |
600 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
601 | + volatile u64 *llp; | |
602 | + u64 data; | |
603 | +#else | |
604 | + ulong data; | |
605 | +#endif | |
547 | 606 | volatile u32 *longp; |
548 | 607 | volatile u16 *shortp; |
549 | 608 | volatile u8 *cp; |
550 | 609 | |
... | ... | @@ -568,7 +627,11 @@ |
568 | 627 | length = simple_strtoul(argv[2], NULL, 16); |
569 | 628 | |
570 | 629 | /* data to write */ |
630 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
631 | + data = simple_strtoull(argv[3], NULL, 16); | |
632 | +#else | |
571 | 633 | data = simple_strtoul(argv[3], NULL, 16); |
634 | +#endif | |
572 | 635 | |
573 | 636 | bytes = size * length; |
574 | 637 | buf = map_sysmem(addr, bytes); |
575 | 638 | |
... | ... | @@ -577,11 +640,18 @@ |
577 | 640 | * If we have only one object, just run infinite loops. |
578 | 641 | */ |
579 | 642 | if (length == 1) { |
643 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
644 | + if (size == 8) { | |
645 | + llp = (u64 *)buf; | |
646 | + for (;;) | |
647 | + *llp = data; | |
648 | + } | |
649 | +#endif | |
580 | 650 | if (size == 4) { |
581 | 651 | longp = (u32 *)buf; |
582 | 652 | for (;;) |
583 | 653 | *longp = data; |
584 | - } | |
654 | + } | |
585 | 655 | if (size == 2) { |
586 | 656 | shortp = (u16 *)buf; |
587 | 657 | for (;;) |
... | ... | @@ -592,6 +662,16 @@ |
592 | 662 | *cp = data; |
593 | 663 | } |
594 | 664 | |
665 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
666 | + if (size == 8) { | |
667 | + for (;;) { | |
668 | + llp = (u64 *)buf; | |
669 | + i = length; | |
670 | + while (i-- > 0) | |
671 | + *llp++ = data; | |
672 | + } | |
673 | + } | |
674 | +#endif | |
595 | 675 | if (size == 4) { |
596 | 676 | for (;;) { |
597 | 677 | longp = (u32 *)buf; |
598 | 678 | |
... | ... | @@ -998,13 +1078,18 @@ |
998 | 1078 | /* Modify memory. |
999 | 1079 | * |
1000 | 1080 | * Syntax: |
1001 | - * mm{.b, .w, .l} {addr} | |
1002 | - * nm{.b, .w, .l} {addr} | |
1081 | + * mm{.b, .w, .l, .q} {addr} | |
1082 | + * nm{.b, .w, .l, .q} {addr} | |
1003 | 1083 | */ |
1004 | 1084 | static int |
1005 | 1085 | mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[]) |
1006 | 1086 | { |
1007 | - ulong addr, i; | |
1087 | + ulong addr; | |
1088 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
1089 | + u64 i; | |
1090 | +#else | |
1091 | + ulong i; | |
1092 | +#endif | |
1008 | 1093 | int nbytes, size; |
1009 | 1094 | void *ptr = NULL; |
1010 | 1095 | |
... | ... | @@ -1055,6 +1140,10 @@ |
1055 | 1140 | printf("%08lx:", addr); |
1056 | 1141 | if (size == 4) |
1057 | 1142 | printf(" %08x", *((u32 *)ptr)); |
1143 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
1144 | + else if (size == 8) | |
1145 | + printf(" %016llx", *((u64 *)ptr)); | |
1146 | +#endif | |
1058 | 1147 | else if (size == 2) |
1059 | 1148 | printf(" %04x", *((u16 *)ptr)); |
1060 | 1149 | else |
1061 | 1150 | |
... | ... | @@ -1079,7 +1168,11 @@ |
1079 | 1168 | #endif |
1080 | 1169 | else { |
1081 | 1170 | char *endp; |
1171 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
1172 | + i = simple_strtoull(console_buffer, &endp, 16); | |
1173 | +#else | |
1082 | 1174 | i = simple_strtoul(console_buffer, &endp, 16); |
1175 | +#endif | |
1083 | 1176 | nbytes = endp - console_buffer; |
1084 | 1177 | if (nbytes) { |
1085 | 1178 | #ifdef CONFIG_BOOT_RETRY_TIME |
... | ... | @@ -1089,6 +1182,10 @@ |
1089 | 1182 | #endif |
1090 | 1183 | if (size == 4) |
1091 | 1184 | *((u32 *)ptr) = i; |
1185 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
1186 | + else if (size == 8) | |
1187 | + *((u64 *)ptr) = i; | |
1188 | +#endif | |
1092 | 1189 | else if (size == 2) |
1093 | 1190 | *((u16 *)ptr) = i; |
1094 | 1191 | else |
1095 | 1192 | |
1096 | 1193 | |
1097 | 1194 | |
1098 | 1195 | |
1099 | 1196 | |
1100 | 1197 | |
1101 | 1198 | |
1102 | 1199 | |
1103 | 1200 | |
1104 | 1201 | |
1105 | 1202 | |
... | ... | @@ -1136,39 +1233,63 @@ |
1136 | 1233 | U_BOOT_CMD( |
1137 | 1234 | md, 3, 1, do_mem_md, |
1138 | 1235 | "memory display", |
1236 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
1237 | + "[.b, .w, .l, .q] address [# of objects]" | |
1238 | +#else | |
1139 | 1239 | "[.b, .w, .l] address [# of objects]" |
1240 | +#endif | |
1140 | 1241 | ); |
1141 | 1242 | |
1142 | 1243 | |
1143 | 1244 | U_BOOT_CMD( |
1144 | 1245 | mm, 2, 1, do_mem_mm, |
1145 | 1246 | "memory modify (auto-incrementing address)", |
1247 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
1248 | + "[.b, .w, .l, .q] address" | |
1249 | +#else | |
1146 | 1250 | "[.b, .w, .l] address" |
1251 | +#endif | |
1147 | 1252 | ); |
1148 | 1253 | |
1149 | 1254 | |
1150 | 1255 | U_BOOT_CMD( |
1151 | 1256 | nm, 2, 1, do_mem_nm, |
1152 | 1257 | "memory modify (constant address)", |
1258 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
1259 | + "[.b, .w, .l, .q] address" | |
1260 | +#else | |
1153 | 1261 | "[.b, .w, .l] address" |
1262 | +#endif | |
1154 | 1263 | ); |
1155 | 1264 | |
1156 | 1265 | U_BOOT_CMD( |
1157 | 1266 | mw, 4, 1, do_mem_mw, |
1158 | 1267 | "memory write (fill)", |
1268 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
1269 | + "[.b, .w, .l, .q] address value [count]" | |
1270 | +#else | |
1159 | 1271 | "[.b, .w, .l] address value [count]" |
1272 | +#endif | |
1160 | 1273 | ); |
1161 | 1274 | |
1162 | 1275 | U_BOOT_CMD( |
1163 | 1276 | cp, 4, 1, do_mem_cp, |
1164 | 1277 | "memory copy", |
1278 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
1279 | + "[.b, .w, .l, .q] source target count" | |
1280 | +#else | |
1165 | 1281 | "[.b, .w, .l] source target count" |
1282 | +#endif | |
1166 | 1283 | ); |
1167 | 1284 | |
1168 | 1285 | U_BOOT_CMD( |
1169 | 1286 | cmp, 4, 1, do_mem_cmp, |
1170 | 1287 | "memory compare", |
1288 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
1289 | + "[.b, .w, .l, .q] addr1 addr2 count" | |
1290 | +#else | |
1171 | 1291 | "[.b, .w, .l] addr1 addr2 count" |
1292 | +#endif | |
1172 | 1293 | ); |
1173 | 1294 | |
1174 | 1295 | #ifdef CONFIG_CMD_CRC32 |
1175 | 1296 | |
1176 | 1297 | |
1177 | 1298 | |
... | ... | @@ -1220,14 +1341,22 @@ |
1220 | 1341 | U_BOOT_CMD( |
1221 | 1342 | loop, 3, 1, do_mem_loop, |
1222 | 1343 | "infinite loop on address range", |
1344 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
1345 | + "[.b, .w, .l, .q] address number_of_objects" | |
1346 | +#else | |
1223 | 1347 | "[.b, .w, .l] address number_of_objects" |
1348 | +#endif | |
1224 | 1349 | ); |
1225 | 1350 | |
1226 | 1351 | #ifdef CONFIG_LOOPW |
1227 | 1352 | U_BOOT_CMD( |
1228 | 1353 | loopw, 4, 1, do_mem_loopw, |
1229 | 1354 | "infinite write loop on address range", |
1355 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
1356 | + "[.b, .w, .l, .q] address number_of_objects data_to_write" | |
1357 | +#else | |
1230 | 1358 | "[.b, .w, .l] address number_of_objects data_to_write" |
1359 | +#endif | |
1231 | 1360 | ); |
1232 | 1361 | #endif /* CONFIG_LOOPW */ |
1233 | 1362 | |
1234 | 1363 | |
1235 | 1364 | |
1236 | 1365 | |
... | ... | @@ -1243,13 +1372,21 @@ |
1243 | 1372 | U_BOOT_CMD( |
1244 | 1373 | mdc, 4, 1, do_mem_mdc, |
1245 | 1374 | "memory display cyclic", |
1375 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
1376 | + "[.b, .w, .l, .q] address count delay(ms)" | |
1377 | +#else | |
1246 | 1378 | "[.b, .w, .l] address count delay(ms)" |
1379 | +#endif | |
1247 | 1380 | ); |
1248 | 1381 | |
1249 | 1382 | U_BOOT_CMD( |
1250 | 1383 | mwc, 4, 1, do_mem_mwc, |
1251 | 1384 | "memory write cyclic", |
1385 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
1386 | + "[.b, .w, .l, .q] address value delay(ms)" | |
1387 | +#else | |
1252 | 1388 | "[.b, .w, .l] address value delay(ms)" |
1389 | +#endif | |
1253 | 1390 | ); |
1254 | 1391 | #endif /* CONFIG_MX_CYCLIC */ |
1255 | 1392 |
common/command.c
include/common.h
lib/display_options.c
... | ... | @@ -87,11 +87,19 @@ |
87 | 87 | { |
88 | 88 | /* linebuf as a union causes proper alignment */ |
89 | 89 | union linebuf { |
90 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
91 | + uint64_t uq[MAX_LINE_LENGTH_BYTES/sizeof(uint64_t) + 1]; | |
92 | +#endif | |
90 | 93 | uint32_t ui[MAX_LINE_LENGTH_BYTES/sizeof(uint32_t) + 1]; |
91 | 94 | uint16_t us[MAX_LINE_LENGTH_BYTES/sizeof(uint16_t) + 1]; |
92 | 95 | uint8_t uc[MAX_LINE_LENGTH_BYTES/sizeof(uint8_t) + 1]; |
93 | 96 | } lb; |
94 | 97 | int i; |
98 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
99 | + uint64_t x; | |
100 | +#else | |
101 | + uint32_t x; | |
102 | +#endif | |
95 | 103 | |
96 | 104 | if (linelen*width > MAX_LINE_LENGTH_BYTES) |
97 | 105 | linelen = MAX_LINE_LENGTH_BYTES / width; |
98 | 106 | |
99 | 107 | |
100 | 108 | |
... | ... | @@ -108,14 +116,21 @@ |
108 | 116 | |
109 | 117 | /* Copy from memory into linebuf and print hex values */ |
110 | 118 | for (i = 0; i < thislinelen; i++) { |
111 | - uint32_t x; | |
112 | 119 | if (width == 4) |
113 | 120 | x = lb.ui[i] = *(volatile uint32_t *)data; |
121 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
122 | + else if (width == 8) | |
123 | + x = lb.uq[i] = *(volatile uint64_t *)data; | |
124 | +#endif | |
114 | 125 | else if (width == 2) |
115 | 126 | x = lb.us[i] = *(volatile uint16_t *)data; |
116 | 127 | else |
117 | 128 | x = lb.uc[i] = *(volatile uint8_t *)data; |
129 | +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA | |
130 | + printf(" %0*llx", width * 2, x); | |
131 | +#else | |
118 | 132 | printf(" %0*x", width * 2, x); |
133 | +#endif | |
119 | 134 | data += width; |
120 | 135 | } |
121 | 136 |