commands: import memtester 4.3.0 from Debian GNU/Linux
PATCH v2 1/1 commands: import memtester 4.3.0 from Debian GNU/Linux
Memtester is an utility for testing the memory subsystem for faults. For hardware developers, memtester can be told to test memory starting at a particular physical address.
This port is based on the sources from Debian GNU/Linux. Debian package meta data is as follows:
Package: memtester Version: 4.3.0-5 Homepage: http://pyropus.ca/software/memtester/ APT-Sources: http://ftp.ru.debian.org/debian testing/main amd64 Packages
Dissected version of this patch can be found at
https://github.com/pmamonov/barebox/commits/memtester
Changes since v1:
1acbafe7a2 init global vars on start 7664692fd4 use proper return value a10eba5b49 use strtoull_suffix() to parse memory size 001b623c16 add option to set TESTMASK 3acfe07d56 make tests[] static
528360ebd7 fix license
--- commands/Kconfig | 8 + commands/Makefile | 1 + commands/memtester/Makefile | 1 + commands/memtester/memtester.c | 295 ++++++++++++++++++ commands/memtester/memtester.h | 21 ++ commands/memtester/sizes.h | 37 +++ commands/memtester/tests.c | 537 +++++++++++++++++++++++++++++++++ commands/memtester/tests.h | 36 +++ commands/memtester/types.h | 35 +++ 9 files changed, 971 insertions(+) create mode 100644 commands/memtester/Makefile create mode 100644 commands/memtester/memtester.c create mode 100644 commands/memtester/memtester.h create mode 100644 commands/memtester/sizes.h create mode 100644 commands/memtester/tests.c create mode 100644 commands/memtester/tests.h create mode 100644 commands/memtester/types.h
commands/Kconfig +8 -0
@@ -1611,6 +1611,14 @@ config CMD_MEMTEST -i ITERATIONS perform number of iterations (default 1, 0 is endless) -b perform only a test on bus lines +config CMD_MEMTESTER + tristate + prompt "memtester" + help + Utility for testing the memory subsystem. + + Homepage: http://pyropus.ca/software/memtester/ + config CMD_MM tristate select DEV_MEM
commands/Makefile +1 -0
@@ -49,6 +49,7 @@ obj-$(CONFIG_CMD_LOADENV) += loadenv.o obj-$(CONFIG_CMD_NAND) += nand.o obj-$(CONFIG_CMD_NANDTEST) += nandtest.o obj-$(CONFIG_CMD_MEMTEST) += memtest.o +obj-$(CONFIG_CMD_MEMTESTER) += memtester/ obj-$(CONFIG_CMD_TRUE) += true.o obj-$(CONFIG_CMD_FALSE) += false.o obj-$(CONFIG_CMD_VERSION) += version.o
commands/memtester/Makefile new file +1 -0
@@ -0,0 +1 @@ +obj-y += tests.o memtester.o
commands/memtester/memtester.c new file +295 -0
295 lines not on this page · raw message
commands/memtester/memtester.h new file +21 -0
@@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +* Very simple (yet, for some reason, very effective) memory tester. +* Originally by Simon Kirby <[email protected]> <[email protected]> +* Version 2 by Charles Cazabon <[email protected]> +* Version 3 not publicly released. +* Version 4 rewrite: +* Copyright (C) 2004-2012 Charles Cazabon <[email protected]> +* +* This file contains the declarations for external variables from the main file. +* See other comments in that file. +* +*/ + +#include <types.h> + +/* extern declarations. */ + +extern int use_phys; +extern off_t physaddrbase; +
commands/memtester/sizes.h new file +37 -0
@@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +* Very simple but very effective user-space memory tester. +* Originally by Simon Kirby <[email protected]> <[email protected]> +* Version 2 by Charles Cazabon <[email protected]> +* Version 3 not publicly released. +* Version 4 rewrite: +* Copyright (C) 2004-2012 Charles Cazabon <[email protected]> +* +* This file contains some macro definitions for handling 32/64 bit platforms. +* +*/ + +#include <linux/limits.h> + +#define rand32 () ((unsigned int) rand() | ( (unsigned int) rand() << 16)) + +#if defined(CONFIG_32BIT ) +#define rand_ul () rand32() +#define UL_ONEBITS 0xffffffff +#define UL_LEN 32 +#define CHECKERBOARD1 0x55555555 +#define CHECKERBOARD2 0xaaaaaaaa +#define UL_BYTE (x) ((x | x << 8 | x << 16 | x << 24)) +#elif defined(CONFIG_64BIT ) +#define rand64 () (((ul) rand32()) << 32 | ((ul) rand32())) +#define rand_ul () rand64() +#define UL_ONEBITS 0xffffffffffffffffUL +#define UL_LEN 64 +#define CHECKERBOARD1 0x5555555555555555 +#define CHECKERBOARD2 0xaaaaaaaaaaaaaaaa +#define UL_BYTE (x) (((ul)x | (ul)x<<8 | (ul)x<<16 | (ul)x<<24 | (ul)x<<32 | (ul)x<<40 | (ul)x<<48 | (ul)x<<56)) +#else +#error long on this platform is not 32 or 64 bits +#endif + +
commands/memtester/tests.c new file +537 -0
537 lines not on this page · raw message
commands/memtester/tests.h new file +36 -0
@@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +* Very simple yet very effective memory tester. +* Originally by Simon Kirby <[email protected]> <[email protected]> +* Version 2 by Charles Cazabon <[email protected]> +* Version 3 not publicly released. +* Version 4 rewrite: +* Copyright (C) 2004-2012 Charles Cazabon <[email protected]> +* +* This file contains the declarations for the functions for the actual tests, +* called from the main routine in memtester.c. See other comments in that +* file. +* +*/ + +/* Function declaration. */ + +int test_stuck_address (unsigned long volatile *bufa,size_t count); +int test_random_value (unsigned long volatile *bufa,unsigned long volatile *bufb,size_t count); +int test_xor_comparison (unsigned long volatile *bufa,unsigned long volatile *bufb,size_t count); +int test_sub_comparison (unsigned long volatile *bufa,unsigned long volatile *bufb,size_t count); +int test_mul_comparison (unsigned long volatile *bufa,unsigned long volatile *bufb,size_t count); +int test_div_comparison (unsigned long volatile *bufa,unsigned long volatile *bufb,size_t count); +int test_or_comparison (unsigned long volatile *bufa,unsigned long volatile *bufb,size_t count); +int test_and_comparison (unsigned long volatile *bufa,unsigned long volatile *bufb,size_t count); +int test_seqinc_comparison (unsigned long volatile *bufa,unsigned long volatile *bufb,size_t count); +int test_solidbits_comparison (unsigned long volatile *bufa,unsigned long volatile *bufb,size_t count); +int test_checkerboard_comparison (unsigned long volatile *bufa,unsigned long volatile *bufb,size_t count); +int test_blockseq_comparison (unsigned long volatile *bufa,unsigned long volatile *bufb,size_t count); +int test_walkbits0_comparison (unsigned long volatile *bufa,unsigned long volatile *bufb,size_t count); +int test_walkbits1_comparison (unsigned long volatile *bufa,unsigned long volatile *bufb,size_t count); +int test_bitspread_comparison (unsigned long volatile *bufa,unsigned long volatile *bufb,size_t count); +int test_bitflip_comparison (unsigned long volatile *bufa,unsigned long volatile *bufb,size_t count); +int test_8bit_wide_random (unsigned long volatile *bufa,unsigned long volatile *bufb,size_t count); +int test_16bit_wide_random (unsigned long volatile *bufa,unsigned long volatile *bufb,size_t count); +
commands/memtester/types.h new file +35 -0
@@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +* Very simple but very effective user-space memory tester. +* Originally by Simon Kirby <[email protected]> <[email protected]> +* Version 2 by Charles Cazabon <[email protected]> +* Version 3 not publicly released. +* Version 4 rewrite: +* Copyright (C) 2004-2010 Charles Cazabon <[email protected]> +* +* This file contains typedefs, structure, and union definitions. +* +*/ + +#include "sizes.h" + +typedef unsigned long ul ; +typedef unsigned long long ull ; +typedef unsigned long volatile ulv ; +typedef unsigned char volatile u8v ; +typedef unsigned short volatile u16v ; + +struct test { +char *name; +int (*fp)(ulv *,ulv *,size_t ); +}; + +typedef union { +unsigned char bytes[UL_LEN /8 ]; +ul val; +}mword8_t ; + +typedef union { +unsigned short u16s[UL_LEN /16 ]; +ul val; +}mword16_t ;
Signature · 7 lines
2.20.1 _______________________________________________ barebox mailing list [email protected] http://lists.infradead.org/mailman/listinfo/barebox
Hi Peter,
There are a few more things to fix. I just saw I never answered to your last mail.
Quoted 1 line
Do you prefer this two step version to be submitted?
No, it's ok as a singe patch.
Quoted 141 lines · Peter Mamonov
Memtester is an utility for testing the memory subsystem for faults. For hardware developers, memtester can be told to test memory starting at a particular physical address.
This port is based on the sources from Debian GNU/Linux. Debian package meta data is as follows:
Package: memtester Version: 4.3.0-5 Homepage: http://pyropus.ca/software/memtester/ APT-Sources: http://ftp.ru.debian.org/debian testing/main amd64 PackagesDissected version of this patch can be found at
https://github.com/pmamonov/barebox/commits/memtesterChanges since v1:
1acbafe7a2init global vars on start7664692fd4use proper return valuea10eba5b49usestrtoull_suffix()to parse memory size001b623c16add option to set TESTMASK3acfe07d56make tests[] static
528360ebd7fix licenseSigned-off-by Peter Mamonov <[email protected]>--- commands/Kconfig | 8 + commands/Makefile | 1 + commands/memtester/Makefile | 1 + commands/memtester/memtester.c | 295 ++++++++++++++++++ commands/memtester/memtester.h | 21 ++ commands/memtester/sizes.h | 37 +++ commands/memtester/tests.c | 537 +++++++++++++++++++++++++++++++++ commands/memtester/tests.h | 36 +++ commands/memtester/types.h | 35 +++ 9 files changed, 971 insertions(+) create mode 100644 commands/memtester/Makefile create mode 100644 commands/memtester/memtester.c create mode 100644 commands/memtester/memtester.h create mode 100644 commands/memtester/sizes.h create mode 100644 commands/memtester/tests.c create mode 100644 commands/memtester/tests.h create mode 100644 commands/memtester/types.hcommands/Kconfig +8
-0@@ -1611,6 +1611,14 @@ config CMD_MEMTEST -i ITERATIONS perform number of iterations (default 1, 0 is endless) -b perform only a test on bus lines +config CMD_MEMTESTER + tristate + prompt "memtester" + help + Utility for testing the memory subsystem. + + Homepage: http://pyropus.ca/software/memtester/ + config CMD_MM tristate select DEV_MEMcommands/Makefile +1
-0@@ -49,6 +49,7 @@ obj-$(CONFIG_CMD_LOADENV) += loadenv.o obj-$(CONFIG_CMD_NAND) += nand.o obj-$(CONFIG_CMD_NANDTEST) += nandtest.o obj-$(CONFIG_CMD_MEMTEST) += memtest.o +obj-$(CONFIG_CMD_MEMTESTER) += memtester/ obj-$(CONFIG_CMD_TRUE) += true.o obj-$(CONFIG_CMD_FALSE) += false.o obj-$(CONFIG_CMD_VERSION) += version.ocommands/memtester/Makefile new file +1
-0@@ -0,0 +1 @@ +obj-y += tests.o memtester.ocommands/memtester/memtester.c new file +53
-0@@ -0,0 +1,295 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +* memtester version 4 +* +* Very simple but very effective user-space memory tester. +* Originally by Simon Kirby <[email protected]> <[email protected]> +* Version 2 by Charles Cazabon <[email protected]> +* Version 3 not publicly released. +* Version 4 rewrite: +* Copyright (C) 2004-2012 Charles Cazabon <[email protected]> +* +*/ + +#define __version__ "4.3.0" + +#include <stdlib.h> +#include <stdio.h> +#include <types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <errno.h> +#include <getopt.h> +#include <common.h> +#include <command.h> +#include <environment.h> +#include <fs.h> + +#include "types.h" +#include "sizes.h" +#include "tests.h" + +#define EXIT_FAIL_NONSTARTER COMMAND_ERROR +#define EXIT_FAIL_ADDRESSLINES 0x02 +#define EXIT_FAIL_OTHERTEST 0x04 + +static struct test tests[] = { + {"Random Value" , test_random_value }, + {"Compare XOR" , test_xor_comparison }, + {"Compare SUB" , test_sub_comparison }, + {"Compare MUL" , test_mul_comparison }, + {"Compare DIV" ,test_div_comparison }, + {"Compare OR" , test_or_comparison }, + {"Compare AND" , test_and_comparison }, + {"Sequential Increment" , test_seqinc_comparison }, + {"Solid Bits" , test_solidbits_comparison }, + {"Block Sequential" , test_blockseq_comparison }, + {"Checkerboard" , test_checkerboard_comparison }, + {"Bit Spread" , test_bitspread_comparison }, + {"Bit Flip" , test_bitflip_comparison }, + {"Walking Ones" , test_walkbits1_comparison }, + {"Walking Zeroes" , test_walkbits0_comparison },
commands/memtester/memtester.c line 63
Quoted 10 lines
commands/memtester/memtester.c new file +10
-0+ { "8-bit Writes", test_8bit_wide_random }, + { "16-bit Writes", test_16bit_wide_random }, + { NULL, NULL } +}; + +/* Function declarations */ + +/* Global vars - so tests have access to this information */ +int use_phys; +off_t physaddrbase;
These names are too generic for global variables. Please add a memtester_ prefix.
commands/memtester/memtester.c line 70
Quoted 7 lines
commands/memtester/memtester.c new file +7
-0+ +static int do_memtester (int argc,char **argv) { +ul loops, loop, i; +size_t wantmb, wantbytes, bufsize, + halflen, count; +char *addrsuffix, *loopsuffix; +void volatile *buf, *aligned;
You can drop this 'volatile' here - it's the functions you call with this buf that need it. Also you can drop the casts when using this buf.
Quoted 74 lines
commands/memtester/memtester.c new file +74
-0+ulv *bufa, *bufb; +int exit_code =0 , ret; +int memfd =0 , opt; +size_t maxbytes =-1 ;/* addressable memory, in bytes */ +size_t maxmb = (maxbytes >>20 ) +1 ;/* addressable memory, in MB */ +/* Device to mmap memory from with -p, default is normal core */ +char *device_name ="/dev/mem" ; +struct stat statbuf; +int device_specified =0 ; +ul testmask =0 ; + + use_phys =0 ; + physaddrbase =0 ; + +printf ("memtester version " __version__" (%d-bit)\n" ,UL_LEN ); +printf ("Copyright (C) 2001-2012 Charles Cazabon.\n" ); +printf ("Licensed under the GNU General Public License version 2 (only).\n" ); +printf ("\n" ); + +while ((opt =getopt (argc, argv,"p:d:m:" )) !=-1 ) { +switch (opt) { +case 'm' : + errno =0 ; + testmask =simple_strtoul (optarg,0 ,0 ); +if (errno) { +printf ("error parsing MEMTESTER_TEST_MASK %s: %s\n" , + optarg,strerror (errno)); +return COMMAND_ERROR_USAGE ; + } +printf ("using testmask 0x%lx\n" , testmask); +break ; +case 'p' : + errno =0 ; + physaddrbase = (off_t )simple_strtoull (optarg, &addrsuffix,16 ); +if (errno !=0 ) { +printf ("failed to parse physaddrbase arg; should be hex " +"address (0x123...)\n" ); +return COMMAND_ERROR_USAGE ; + } +if (*addrsuffix !='\0' ) { +/* got an invalid character in the address */ +printf ("failed to parse physaddrbase arg; should be hex " +"address (0x123...)\n" ); +return COMMAND_ERROR_USAGE ; + } +/* okay, got address */ + use_phys =1 ; +break ; +case 'd' : +if (stat (optarg,&statbuf)) { +printf ("can not use %s as device: %s\n" , optarg, +strerror (errno)); +return COMMAND_ERROR_USAGE ; + }else { +if (!S_ISCHR (statbuf.st_mode)) { +printf ("can not mmap non-char device %s\n" , + optarg); +return COMMAND_ERROR_USAGE ; + }else { + device_name = optarg; + device_specified =1 ; + } + } +break ; +default :/* '?' */ +return COMMAND_ERROR_USAGE ; + } + } +if (device_specified && !use_phys) { +printf ("for mem device, physaddrbase (-p) must be specified\n" ); +return COMMAND_ERROR_USAGE ; + } + +if (optind >= argc) {
commands/memtester/memtester.c line 154
Quoted 10 lines
commands/memtester/memtester.c new file +10
-0+printf ("need memory argument, in MB\n" ); +return COMMAND_ERROR_USAGE ; + } + + errno =0 ; + wantbytes = (size_t )strtoull_suffix (argv[optind],0 ,0 ); +if (errno !=0 ) { +printf ("failed to parse memory argument" ); +return COMMAND_ERROR_USAGE ; + }
strtoull_suffix() doesn't set errno. There is currently no way to detect an error from strtoull_suffix().
Quoted 6 lines
commands/memtester/memtester.c new file +6
-0+ wantmb = (wantbytes >>20 ); + optind++; +if (wantmb > maxmb) { +printf ("This system can only address %llu MB.\n" , (ull ) maxmb); +return EXIT_FAIL_NONSTARTER ; + }
commands/memtester/memtester.c line 170
Quoted 10 lines
commands/memtester/memtester.c new file +10
-0+ +if (optind >= argc) { + loops =0 ; + }else { + errno =0 ; + loops =simple_strtoul (argv[optind], &loopsuffix,0 ); +if (errno !=0 ) { +printf ("failed to parse number of loops" ); +return COMMAND_ERROR_USAGE ; + }
same here. You can use kstrtoul instead which allows checking for errors. Another option would be to change simple_strtoul() to set errno.
Quoted 13 lines
commands/memtester/memtester.c new file +13
-0+if (*loopsuffix !='\0' ) { +printf ("loop suffix %c\n" , *loopsuffix); +return COMMAND_ERROR_USAGE ; + } + } + +printf ("want %lluMB (%llu bytes)\n" , (ull ) wantmb, (ull ) wantbytes); + buf =NULL ; + +if (use_phys) { + memfd =open (device_name,O_RDWR ); +if (memfd ==-1 ) { + printf("failed to open %s for physical memory: %s\n",
commands/memtester/memtester.c line 193
Quoted 10 lines
commands/memtester/memtester.c new file +10
-0+ device_name, strerror(errno)); +return EXIT_FAIL_NONSTARTER ; + } + buf = (void volatile *)memmap (memfd,PROT_READ |PROT_WRITE ) + + physaddrbase; +if (buf ==MAP_FAILED ) { +printf ("failed to mmap %s for physical memory: %s\n" , + device_name,strerror (errno)); +return EXIT_FAIL_NONSTARTER ; + }
memfd is not closed in this error path.
Quoted 19 lines
commands/memtester/memtester.c new file +19
-0+ + bufsize = wantbytes;/* accept no less */ + }else { + buf = (void volatile *)malloc (wantbytes); +if (!buf) { +printf ("malloc failed\n" ); +return ENOMEM ; + } +printf ("got %lluMB (%llu bytes)\n" , (ull ) wantbytes >>20 , + (ull ) wantbytes); + } + bufsize = wantbytes; + aligned = buf; + +printf ("buffer @ 0x%p\n" , buf); + + halflen = bufsize /2 ; + count = halflen /sizeof (ul); + bufa = (ulv *) aligned;
commands/memtester/memtester.c line 222
Quoted 10 lines
commands/memtester/memtester.c new file +10
-0+ bufb = (ulv *) ((size_t ) aligned + halflen); + +for (loop=1 ; ((!loops) || loop <= loops); loop++) { +printf ("Loop %lu" , loop); +if (loops) { +printf ("/%lu" , loops); + } +printf (":\n" ); +printf (" %-20s: " ,"Stuck Address" ); +console_flush ();
Why did you add all these console_flush() throughout the code?
Quoted 112 lines
commands/memtester/memtester.c new file +73
-0+ ret =test_stuck_address (aligned, bufsize /sizeof (ul)); +if (!ret) { +printf ("ok\n" ); + }else if (ret == -EINTR ) { + goto out; + }else { + exit_code |=EXIT_FAIL_ADDRESSLINES ; + } +for (i=0 ;;i++) { +if (!tests[i].name)break ; +/* If using a custom testmask, only run this test if the +bit corresponding to this test was set by the user. +*/ +if (testmask && (!((1 << i) & testmask))) { +continue ; + } +printf (" %-20s: " , tests[i].name); + ret = tests[i].fp (bufa, bufb, count); +if (!ret) { +printf ("ok\n" ); + }else if (ret == -EINTR ) { + goto out; + }else { + exit_code |=EXIT_FAIL_OTHERTEST ; + } +console_flush (); + } +printf ("\n" ); +console_flush (); + } +out: +if (use_phys) +close (memfd); +else +free ((void *)buf); +printf ("Done.\n" ); +console_flush (); +if (!exit_code) +return 0 ; +printf ("%s FAILED: 0x%x\n" , argv[0 ], exit_code); +return COMMAND_ERROR ; +} + +BAREBOX_CMD_HELP_START(memtester) +BAREBOX_CMD_HELP_TEXT("Options:") +BAREBOX_CMD_HELP_TEXT("-p PHYSADDR") +BAREBOX_CMD_HELP_TEXT(" tells memtester to test a specific region of memory starting at physical") +BAREBOX_CMD_HELP_TEXT(" address PHYSADDR (given in hex), by mmaping a device specified by the -d") +BAREBOX_CMD_HELP_TEXT(" option (below, or /dev/mem by default).") +BAREBOX_CMD_HELP_TEXT("") +BAREBOX_CMD_HELP_TEXT("-d DEVICE") +BAREBOX_CMD_HELP_TEXT(" a device to mmap") +BAREBOX_CMD_HELP_TEXT("") +BAREBOX_CMD_HELP_TEXT("") +BAREBOX_CMD_HELP_TEXT("-m TESTMASK") +BAREBOX_CMD_HELP_TEXT(" bitmask to select desired tests") +BAREBOX_CMD_HELP_TEXT("") +BAREBOX_CMD_HELP_TEXT("MEMORY ") +BAREBOX_CMD_HELP_TEXT(" the amount of memory to allocate and test in bytes. You") +BAREBOX_CMD_HELP_TEXT(" can include a suffix of K, M, or G to indicate kilobytes, ") +BAREBOX_CMD_HELP_TEXT(" megabytes, or gigabytes respectively.") +BAREBOX_CMD_HELP_TEXT("") +BAREBOX_CMD_HELP_TEXT("ITERATIONS") +BAREBOX_CMD_HELP_TEXT(" (optional) number of loops to iterate through. Default is infinite.") +BAREBOX_CMD_HELP_END + +BAREBOX_CMD_START(memtester) + .cmd = do_memtester, + BAREBOX_CMD_DESC("memory stress-testing") + BAREBOX_CMD_OPTS("[-p PHYSADDR [-d DEVICE]] [-m TESTMASK] <MEMORY>[k|M|G] [ITERATIONS]") + BAREBOX_CMD_GROUP(CMD_GRP_MEM) + BAREBOX_CMD_HELP(cmd_memtester_help) +BAREBOX_CMD_ENDcommands/memtester/memtester.h new file +21
-0@@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +* Very simple (yet, for some reason, very effective) memory tester. +* Originally by Simon Kirby <[email protected]> <[email protected]> +* Version 2 by Charles Cazabon <[email protected]> +* Version 3 not publicly released. +* Version 4 rewrite: +* Copyright (C) 2004-2012 Charles Cazabon <[email protected]> +* +* This file contains the declarations for external variables from the main file. +* See other comments in that file. +* +*/ + +#include <types.h> + +/* extern declarations. */ + +extern int use_phys; +extern off_t physaddrbase; +commands/memtester/sizes.h new file +6
-0@@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +* Very simple but very effective user-space memory tester. +* Originally by Simon Kirby <[email protected]> <[email protected]> +* Version 2 by Charles Cazabon <[email protected]> +* Version 3 not publicly released.
commands/memtester/sizes.h line 16
Quoted 10 lines
commands/memtester/sizes.h new file +10
-0+* Version 4 rewrite: +* Copyright (C) 2004-2012 Charles Cazabon <[email protected]> +* +* This file contains some macro definitions for handling 32/64 bit platforms. +* +*/ + +#include <linux/limits.h> + +#define rand32 () ((unsigned int) rand() | ( (unsigned int) rand() << 16))
For some historic reason RAND_MAX in barebox is defined as 32768, so rand() returns only 15bit. While I am sure that this can and should be changed we also have random32() which does what you want here.
Quoted 49 lines
commands/memtester/sizes.h new file +21
-0+ +#if defined(CONFIG_32BIT ) +#define rand_ul () rand32() +#define UL_ONEBITS 0xffffffff +#define UL_LEN 32 +#define CHECKERBOARD1 0x55555555 +#define CHECKERBOARD2 0xaaaaaaaa +#define UL_BYTE (x) ((x | x << 8 | x << 16 | x << 24)) +#elif defined(CONFIG_64BIT ) +#define rand64 () (((ul) rand32()) << 32 | ((ul) rand32())) +#define rand_ul () rand64() +#define UL_ONEBITS 0xffffffffffffffffUL +#define UL_LEN 64 +#define CHECKERBOARD1 0x5555555555555555 +#define CHECKERBOARD2 0xaaaaaaaaaaaaaaaa +#define UL_BYTE (x) (((ul)x | (ul)x<<8 | (ul)x<<16 | (ul)x<<24 | (ul)x<<32 | (ul)x<<40 | (ul)x<<48 | (ul)x<<56)) +#else +#error long on this platform is not 32 or 64 bits +#endif + +commands/memtester/tests.c new file +22
-0@@ -0,0 +1,537 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +* Very simple but very effective user-space memory tester. +* Originally by Simon Kirby <[email protected]> <[email protected]> +* Version 2 by Charles Cazabon <[email protected]> +* Version 3 not publicly released. +* Version 4 rewrite: +* Copyright (C) 2004-2012 Charles Cazabon <[email protected]> +* +* This file contains the functions for the actual tests, called from the +* main routine in memtester.c. See other comments in that file. +* +*/ + +#include <common.h> +#include <types.h> +#include <stdio.h> +#include <stdlib.h> +#include <linux/limits.h> + +#include "types.h" +#include "sizes.h"
commands/memtester/tests.c line 32
Quoted 10 lines
commands/memtester/tests.c new file +10
-0+#include "memtester.h" +#include "tests.h" + +char progress[] ="-\\|/" ; +#define PROGRESSLEN 4 +#define PROGRESSOFTEN 2500 +#define ONE 0x00000001L + +mword8_t mword8; +mword16_t mword16;
These should be static.
Sascha
Signature · 9 lines
Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list [email protected] http://lists.infradead.org/mailman/listinfo/barebox
Hi, Sascha,
Quoted 14 lines · Sascha Hauer
Hi Peter,
There are a few more things to fix. I just saw I never answered to your last mail.
[...]
commands/memtester/memtester.c line 154
Quoted 6 lines
commands/memtester/memtester.c new file +6
-0+ errno =0 ; + wantbytes = (size_t )strtoull_suffix (argv[optind],0 ,0 ); +if (errno !=0 ) { +printf ("failed to parse memory argument" ); +return COMMAND_ERROR_USAGE ; + }
Quoted 2 lines
strtoull_suffix()doesn't set errno. There is currently no way to detect an error fromstrtoull_suffix().
errno is checked throughout the original code, including this slightly modified piece. Should I remove those checks or keep them for the sake of future errno support?
Quoted 6 lines
[...]
Review
Quoted 2 lines
(quoted diff) +2
-0+ printf(" %-20s: ", "Stuck Address"); + console_flush();Why did you add all these
console_flush()throughout the code?
I've merely replaced fflush(stdout) with console_flush() (see the original:
https://github.com/pmamonov/barebox/blob/31fd9d18f37ed58e5e559fe2ad6686066966f86e/commands/memtester/memtester.c#L374).
I choosed to keep all those (excessive) flushes as is, since most of the output is a progress indicator which should be displayed immediately and I wasn't sure that some type of barebox console won't cache the output.
PS Will address other comments in the next patch.
Peter
_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
Quoted 17 lines · Peter Mamonov
Hi, Sascha,
Quoted 14 lines · Sascha Hauer
Hi Peter,
There are a few more things to fix. I just saw I never answered to your last mail.
[...]
Quoted 6 lines
commands/memtester/memtester.c new file +6
-0+ errno =0 ; + wantbytes = (size_t )strtoull_suffix (argv[optind],0 ,0 ); +if (errno !=0 ) { +printf ("failed to parse memory argument" ); +return COMMAND_ERROR_USAGE ; + }
Quoted 6 lines
Quoted 2 lines
strtoull_suffix()doesn't set errno. There is currently no way to detect an error fromstrtoull_suffix().errno is checked throughout the original code, including this slightly modified piece. Should I remove those checks or keep them for the sake of future errno support?
I'd say it's not worth it to keep compatibility to the original code in this file. There are many small things that could/should be done differently, so just drop errno from the code, use kstrtoul where appropriate (unlike simple_strtoul kstrto* return an error).
Quoted 6 lines
Quoted 6 lines
[...]
Quoted 2 lines
(quoted diff) +2
-0+ printf(" %-20s: ", "Stuck Address"); + console_flush();
Quoted 8 lines
Quoted 1 line
Why did you add all these
console_flush()throughout the code?I've merely replaced
fflush(stdout)withconsole_flush()(see the original:
https://github.com/pmamonov/barebox/blob/31fd9d18f37ed58e5e559fe2ad6686066966f86e/commands/memtester/memtester.c#L374).
I choosed to keep all those (excessive) flushes as is, since most of the output is a progress indicator which should be displayed immediately and I wasn't sure that some type of barebox console won't cache the output.
barebox doesn't cache anything in the console layer. Only the UART drivers do in their FIFOs, so console_flush() merely waits until the hardware FIFOs are drained. Normally there is no reason to use console_flush(), it's mainly useful to call it right before resetting the board, before booting Linux, or before switching the baudrate.
Sascha
Signature · 9 lines
Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list [email protected] http://lists.infradead.org/mailman/listinfo/barebox