[PATCH] u-boot: cache-test

Aneesh V aneesh at ti.com
Fri Jun 17 11:05:38 CEST 2011


Signed-off-by: Aneesh V <aneesh at ti.com>
---
 arch/arm/lib/board.c |  140 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 138 insertions(+), 2 deletions(-)

diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index 14a56f6..bd7b5f1 100644
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -39,6 +39,7 @@
  */
 
 #include <common.h>
+#include <asm/armv7.h>
 #include <command.h>
 #include <malloc.h>
 #include <stdio_dev.h>
@@ -49,6 +50,7 @@
 #include <onenand_uboot.h>
 #include <mmc.h>
 
+
 #ifdef CONFIG_BITBANGMII
 #include <miiphy.h>
 #endif
@@ -78,6 +80,11 @@ extern void rtl8019_get_enetaddr (uchar * addr);
 #include <i2c.h>
 #endif
 
+u32 memtest_chunk_size = 1024*1024;
+u32 memtest_pattern = 0;
+u32 memtest_src_addr = 0x80000000;
+u32 memtest_addr_aligned = 0x80000000;
+u32 memtest_dst_addr = 0x84000000;
 
 /************************************************************************
  * Coloured LED functionality
@@ -128,7 +135,134 @@ static int init_baudrate(void)
 	return (0);
 }
 
-static int display_banner(void)
+#define SYNC_TIMER_32K	(*(volatile u32 *)0x4a304010)
+#define TIMER_32K_FREQUENCY  32768
+
+inline u32 timestamp_in_us(void)
+{
+    return (SYNC_TIMER_32K * (1000000/TIMER_32K_FREQUENCY));
+}
+
+
+void set_memory(u32 start, u32 size, u32 start_pattern)
+{
+	u8 *src = (u8 *)start;
+	int i;
+	for (i=0; i<size; i++)
+		src[i] = start_pattern++;
+}
+
+int validate_memory(u32 start, u32 size, u8 start_pattern)
+{
+	u8 *src = (u8 *)start;
+	int i;
+	for (i=0; i<size; i++) {
+		if(src[i] != start_pattern++) {
+			printf("memory error at %08x:%02x \n", start+i, src[i]);
+			return 1;
+		}
+	}
+	return 0;
+}
+
+void my_memcpy(u32 source, u32 dest, u32 size)
+{
+	u8 *src = (u8 *)source;
+	u8 *dst = (u8 *)dest;
+	int i;
+	for (i=0; i<size; i++)
+		dst[i] = src[i];
+}
+
+void test_basic_performance(void)
+{
+	u32 start, end, i,j;
+	for (j=0; j<12; j++) {
+		memtest_chunk_size <<= 1;
+		start = timestamp_in_us();
+		for (i = 0; i < 100; i++) {
+			my_memcpy(memtest_src_addr, memtest_dst_addr, memtest_chunk_size);
+		}
+		end = timestamp_in_us();
+		printf("performance %dKB: %d MBps\n", memtest_chunk_size/1024, memtest_chunk_size*100/(end-start));
+	}
+}
+
+void test_basic_copy(void)
+{
+	set_memory(memtest_src_addr, memtest_chunk_size, memtest_pattern);
+	my_memcpy(memtest_src_addr, memtest_dst_addr, memtest_chunk_size);
+	if(validate_memory(memtest_dst_addr, memtest_chunk_size, memtest_pattern))
+		puts("test_basic_copy failed\n");
+	else
+		puts("test_basic_copy success\n");
+}
+
+void test_inval_d_range(void)
+{
+	memtest_pattern++;
+	set_memory(memtest_src_addr, memtest_chunk_size, memtest_pattern);
+	my_memcpy(memtest_src_addr, memtest_dst_addr, memtest_chunk_size);
+	invalidate_dcache_range(memtest_dst_addr, memtest_dst_addr+memtest_chunk_size);
+	if(validate_memory(memtest_dst_addr, memtest_chunk_size, memtest_pattern))
+		puts("test_inval_d_range success\n");
+	else
+		puts("test_inval_d_range failed\n");
+}
+void test_flush_d_range(void)
+{
+	memtest_pattern++;
+	set_memory(memtest_src_addr, memtest_chunk_size, memtest_pattern);
+	my_memcpy(memtest_src_addr, memtest_dst_addr, memtest_chunk_size);
+	flush_dcache_range(memtest_dst_addr, memtest_dst_addr+memtest_chunk_size);
+	invalidate_dcache_range(memtest_dst_addr, memtest_dst_addr+memtest_chunk_size);
+	if(validate_memory(memtest_dst_addr, memtest_chunk_size, memtest_pattern))
+		puts("test_flush_d_range failed\n");
+	else
+		puts("test_flush_d_range success\n");
+}
+
+void test_flush_d_all(void)
+{
+	volatile int i=10;
+	//while(i);
+	memtest_pattern++;
+	printf("memtest_pattern %d\n", memtest_pattern);
+	flush_dcache_all();
+	set_memory(memtest_src_addr, memtest_chunk_size, memtest_pattern);
+	my_memcpy(memtest_src_addr, memtest_dst_addr, memtest_chunk_size);
+	flush_dcache_all();
+	invalidate_dcache_range(memtest_dst_addr, memtest_dst_addr+memtest_chunk_size);
+	if(validate_memory(memtest_dst_addr, memtest_chunk_size, memtest_pattern))
+		puts("test_flush_d_all failed\n");
+	else
+		puts("test_flush_d_all success\n");
+}
+
+
+void test_inval_d_all(void)
+{
+	memtest_pattern++;
+	set_memory(memtest_src_addr, memtest_chunk_size, memtest_pattern);
+	my_memcpy(memtest_src_addr, memtest_dst_addr, memtest_chunk_size);
+	puts("test_flush_d_all - destructive test - expect a crash after this. If there is a crash test is successful!");
+	invalidate_dcache_all();
+	invalidate_dcache_range(memtest_dst_addr, memtest_dst_addr+memtest_chunk_size);
+	if(validate_memory(memtest_dst_addr, memtest_chunk_size, memtest_pattern))
+		puts("test_flush_d_all failed\n");
+	else
+		puts("test_flush_d_all success\n");
+}
+
+void my_memtest(void)
+{
+	test_basic_copy();
+	test_flush_d_range();
+	test_inval_d_range();
+	test_flush_d_all();
+}
+
+static int display_banner (void)
 {
 	printf("\n\n%s\n\n", version_string);
 	debug("U-Boot code: %08lX -> %08lX  BSS: -> %08lX\n",
@@ -413,7 +547,7 @@ void board_init_f(ulong bootflag)
 	gd->relocaddr = addr;
 	gd->start_addr_sp = addr_sp;
 	gd->reloc_off = addr - _TEXT_BASE;
-	debug("relocation Offset is: %08lx\n", gd->reloc_off);
+	printf ("relocation Offset is: %08lx\n", gd->reloc_off);
 	memcpy(id, (void *)gd, sizeof(gd_t));
 
 	relocate_code(addr_sp, id, addr);
@@ -458,6 +592,8 @@ void board_init_r(gd_t *id, ulong dest_addr)
 	dcache_enable();
 
 	debug("monitor flash len: %08lX\n", monitor_flash_len);
+	my_memtest();
+
 	board_init();	/* Setup chipselects */
 
 #ifdef CONFIG_SERIAL_MULTI
-- 
1.7.0.4


--------------000800010200060709070602--


More information about the U-Boot mailing list