Hi,

In U-Boot I found some generic memory tests commands like mtest and POST tests. But I need to do complete DDR4 memory test with below algorithms:
* Checkerboard Test
* March C- Test
* Neighborhood Pattern Sensitive Fault

Can I get any reference code for these algorithms in U-Boot ?
Implementation for these algorithms available in any of U-Boot version ?

For Checkerboard algorithm, based on the explanation from below link (got by web search) I tried to implement
https://www.design-reuse.com/articles/45915/memory-testing-self-repair-mechanism.html
Attached the file: cmd_checkerboard.c
Is the implementation I did is proper ? Can you verify once?


Similarly for March C- test based on explanation from these docs (got by web search) I tried to implement March C- test
https://eecs.ceas.uc.edu/~jonewb/Memory.pdf
http://www.ee.ncu.edu.tw/~jfli/memtest/lecture/ch03.pdf
Attached the file: cmd_marchc_min.c
Please can you verify once?

For Active Neighborhood Pattern Sensitive Fault test, still I didn't get the proper algorithms.
Can you refer me the any link or source codes for this test?

Thanks and Regards,
Devendra
#include <common.h>
#include <bootretry.h>
#include <cli.h>
#include <command.h>
#include <hash.h>
#include <watchdog.h>
#include <asm/io.h>
#include <linux/compiler.h>

void find_bit_position (int n, int val)
{
        int count = 0, i =0;

        if(val == 0)
        n = ~n;
	printf("Error in %d's bits :", val);
        for (i = 0; i < 8; i++)
        {
                if ( (n >> i) & 1)
                {
                        count++;
                        printf(" %d", i);
                }
        }
        
        printf("\nTotal bit count : %d\n", count);
}


ulong checkerboard_test ( u8 *buf, ulong count, u8 pattern, u8 anti_pattern )
{
	u8 *addr, readback;
	ulong i = 0;
	ulong errs = 0;
	
	addr = buf;
	for (i = 0; i<= count; i++)
	  {
		if(( i % 2) == 0)
			*((u8 *)addr) = pattern;
		else
			*((u8 *)addr) = anti_pattern;
		addr++;
	}

	addr = buf;
	for (i = 0; i<= count; i++)
	  {
		readback = *((u8 *)addr);

		if(( i % 2) == 0)
		{
			if (readback != pattern) {
				printf("\nMem error @ 0x%08X: found 0x%02X, expected 0x%02X\n",addr, readback, pattern);
				find_bit_position(readback, 1);
				errs++;

                                if (ctrlc())
                                        return -1;
			}
		}
		else
		{
			if (readback != anti_pattern) {
				printf("\nMem error @ 0x%08X: found 0x%02X, expected 0x%02X\n",addr, readback, anti_pattern);
				find_bit_position(readback, 1);
				errs++;

                                if (ctrlc())
                                        return -1;
			}
		}

		addr++;
	}

	return errs;
}

static int do_checkerboard_test(cmd_tbl_t *cmdtp, int flag, int argc,
		char * const argv[])
{
        ulong   start, end, count;
        int     size = 1;
        void *buf;
        ulong bytes;
	ulong errs = 0;
	int ret;

	if (argc < 3){
		printf("--help\r\n CheckerBoardTest start end\r\nEx: CheckerBoardTest 0x10000000 0x10000010\r\n\n");
		return 1;
	}

	start = simple_strtoul(argv[1], NULL, 16);

	end = simple_strtoul(argv[2], NULL, 16);

	if (start > end)
	{
		printf("\nend address need to be higher than start address\r\n\n");
		return 1;
	}

	count = end - start;
	bytes = size * count; 

	printf("Testing 0x%08x ... 0x%08x:\n", (uint)start, (uint)end);
	debug("%s:%d: start %#08lx end %#08lx\n\n", __func__, __LINE__,
			start, end);

	buf = map_sysmem(start, bytes);

	errs = checkerboard_test(buf, count, (u8) 0xaa, (u8) 0x55);
	errs = errs + checkerboard_test(buf, count, (u8) 0x55, (u8) 0xaa);
	unmap_sysmem(buf);

	if (errs == -1UL) {
		/* Memory test was aborted - write a newline to finish off */
		putc('\n');
		ret = 1;
	} else {
		printf("Test is done with %lu errors.\n", errs);
		ret = errs != 0;
	}

	return ret;     /* not reached */
}

U_BOOT_CMD(
		CheckerBoardTest,  3,      0,      do_checkerboard_test,
		"Checker Board test for HPS DDR",
		""
	  );
#include <common.h>
#include <bootretry.h>
#include <cli.h>
#include <command.h>
#include <hash.h>
#include <watchdog.h>
#include <asm/io.h>
#include <linux/compiler.h>


static ulong marchcells ( u8 *buf, ulong count, ulong end)
{
	u8 *addr, readback;
	ulong i = 0;
	ulong errs = 0;
	u8 ones = 0xFF;
	u8 zeros = 0x00;
	
	addr = buf;
	for (i = 0; i<= count; i++)
	{
		*addr = zeros;
		addr++;
	}

	addr = buf;
	for (i = 0; i<= count; i++)
	  {
		readback = *((u8 *)addr);

			if (readback != zeros) {
				printf("\nMem error @ 0x%08X: found 0x%02X, expected 0x%02X\n",addr, readback, zeros);
				find_bit_position(readback, 1);
				errs++;

	                        if (ctrlc())
					return -1;
			}
		*addr = ones;
		addr++;
	}

	addr = buf;

	for (i = 0; i<= count; i++)
	  {
		readback = *((u8 *)addr);

			if (readback != ones) {
				printf("\nMem error @ 0x%08X: found 0x%02X, expected 0x%02X\n",addr, readback, ones);
				find_bit_position(readback, 1);
				errs++;

	                        if (ctrlc())
					return -1;
			}
		*addr = zeros;
		addr++;
	}

	addr = end;

	for (i = 0; i<= count; i++)
	  {
		readback = *((u8 *)addr);

			if (readback != zeros) {
				printf("\nMem error @ 0x%08X: found 0x%02X, expected 0x%02X\n",addr, readback, zeros);
				find_bit_position(readback, 1);
				errs++;

	                        if (ctrlc())
					return -1;
			}
		*addr = ones;
		addr--;
	}

	addr = end;
	for (i = 0; i<= count; i++)
	  {
		readback = *((u8 *)addr);

			if (readback != ones) {
				printf("\nMem error @ 0x%08X: found 0x%02X, expected 0x%02X\n",addr, readback, ones);
				find_bit_position(readback, 1);
				errs++;

	                        if (ctrlc())
					return -1;
			}
		*addr = zeros;
		addr--;
	}

	addr = buf;
	for (i = 0; i<= count; i++)
	  {
		readback = *((u8 *)addr);

			if (readback != zeros) {
				printf("\nMem error @ 0x%08X: found 0x%02X, expected 0x%02X\n",addr, readback, zeros);
				find_bit_position(readback, 1);
				errs++;

	                        if (ctrlc())
					return -1;
			}
		addr++;
	}

	return errs;
}

static int do_march_c_min_test (cmd_tbl_t *cmdtp, int flag, int argc,
		char * const argv[])
{
        ulong   start, end, count;
        int     size = 1;
        void *buf;
        ulong bytes;
	ulong errs = 0;
	int ret;

        if (argc < 3){
                printf("--help\r\nMarchCMinusTest start end \r\nEx: MarchCMinusTest 0x10000000 0x10000010\r\n\n");
                return 1;
        }

	start = simple_strtoul(argv[1], NULL, 16);

	end = simple_strtoul(argv[2], NULL, 16);

	if (start > end)
	{
		printf("\nend address need to be higher than start address\r\n\n");
		return 1;
	}

	count = end - start;
	bytes = size * count; 

	printf("Testing 0x%08x ... 0x%08x:\n", (uint)start, (uint)end);
	debug("%s:%d: start %#08lx end %#08lx\n\n", __func__, __LINE__,
			start, end);

	buf = map_sysmem(start, bytes);

	errs = marchcells(buf, count, end);
	unmap_sysmem(buf);

	if (errs == -1UL) {
		/* Memory test was aborted - write a newline to finish off */
		putc('\n');
		ret = 1;
	} else {
		printf("Test is done with %lu errors.\n", errs);
		ret = errs != 0;
	}

	return ret;     /* not reached */
}


U_BOOT_CMD(
                MarchCMinusTest,  3,      0,      do_march_c_min_test,
                "March C- test for HPS DDR",
                ""
          );
_______________________________________________
U-Boot mailing list
[email protected]
https://lists.denx.de/listinfo/u-boot

Reply via email to