[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