Hi Lukasz,

On Tuesday 09 August 2011 08:11 PM, Lukasz Majewski wrote:
> Dear all,
> 
> As we know dcache is now enabled in u-boot.
> 
> I'm trying to make the S5P Goni target working with d-cache enabled.
> There are some patches and ideas appearing on the list (e.g.
> http://patchwork.ozlabs.org/patch/109199/ made by Aneesh V)
> 
> 
> I'm currently using the u-boot/master branch,
> SHA1: d26a82023af5771462f7223241ed18cfb7965f71 
> 
> After some research I can say that flush_dcache_all() and
> invalidate_dcache_all() are working(at least on my target).
> 
> However I'm planning to use the "range" versions:
>       flush_dcache_range((unsigned long) (buf), sizeof(buf));
>       invalidate_dcache_range((unsigned long) (buf), sizeof(buf));
> 
> Those versions are not working on the Cortex-A8 (armv7) GONI target.
> I'd like to ask if anybody was trying to use those functions
> (defined at cache_v7.c) on other armv7 targets? 

I have tested cache on OMAP3(Cortex-A8) and OMAP4(Cortex-A9). Why do you
think it's not working for you. Did you run some tests? If so, what was
the result? Are you enabling only L1 or both L1 & L2? Can you try the
attached crude patch for testing caches. You might have to change the
addresses according to your platform. If you could run it, let me know
the results.

best regards,
Aneesh
>From 0d0d3d195583c85b2bb2a69efa25f35b62c2db9e Mon Sep 17 00:00:00 2001
From: Aneesh V <ane...@ti.com>
Date: Fri, 17 Jun 2011 14:35:38 +0530
Subject: [PATCH] u-boot: cache-test

Signed-off-by: Aneesh V <ane...@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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to