From c3330e9d6a11b6ead4a2346001338ce884b5832b Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Fri, 17 Sep 2010 13:10:30 +0200 Subject: ARM (ARM926ejs): add data cache support, tested on magnesium and tx25 board Enable "cache" command on tx25 and magnesium board and test performance. Test 1: Loading 127 MB of data from NAND flash into RAM: Instr. Cache off on on Data Cache off off on -------------------------------------------------- magnesium 32,6s 22,5s 30s = x 1,09 tx25 (29MB only) 9,69s 5,05s 8,16s = x 1,19 Test 2: uncompressing a gzipped image from RAM to RAM (size compressed: 6.5 MiB, uncompressed: 35 MiB): Instr. Cache off on on Data Cache off off on -------------------------------------------------- magnesium 4,25s 2,08s 1,72s = x 2,47 tx25 4,82s 2,04s 1,84s = x 2,62 Portions of this work were supported by funding from the CE Linux Forum. Signed-off-by: Alessandro Rubini Signed-off-by: Heiko Schocher Cc: Alessandro Rubini --- arch/arm/lib/cache.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch/arm/lib/cache.c') diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c index 61ee9d3b1..b36fd2440 100644 --- a/arch/arm/lib/cache.c +++ b/arch/arm/lib/cache.c @@ -31,6 +31,12 @@ void flush_cache (unsigned long dummy1, unsigned long dummy2) void arm1136_cache_flush(void); arm1136_cache_flush(); +#endif +#ifdef CONFIG_ARM926EJS + /* test and clean, page 2-23 of arm926ejs manual */ + asm("0: mrc p15, 0, r15, c7, c10, 3\n\t" "bne 0b\n" : : : "memory"); + /* disable write buffer as well (page 2-22) */ + asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); #endif return; } -- cgit v1.2.3-70-g09d2 From 95c6f6d34d4ff23f4d005488d84682eec5fa9ec8 Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Fri, 17 Sep 2010 13:10:31 +0200 Subject: ARM V7 (OMAP): add data cache support, test on Beagle board Add data cache support for ARM V7 systems. Used cache flush functions from linux:arch/arm/mm/cache-v7.S developed from Catalin Marinas. Enable "cache" command on Beagle board and test performance. Test 1: Loading 127 MB of data from NAND flash into RAM: Instr. Cache off on on Data Cache off off on -------------------------------------------------- Beagle (Cortex A8) 116s 106s 30.3s = x 3.8 Test 2: uncompressing a gzipped image from RAM to RAM (size compressed: 6.5 MiB, uncompressed: 35 MiB): Instr. Cache off on on Data Cache off off on -------------------------------------------------- Beagle (Cortex A8) 1.84s 1.64s 0.12s = x 15.3 Portions of this work were supported by funding from the CE Linux Forum. Signed-off-by: Heiko Schocher Reviewed-by: Ben Gardiner --- arch/arm/cpu/armv7/omap3/cache.S | 80 ++++++++++++++++++++++++++++++++++++++++ arch/arm/lib/cache.c | 5 +++ include/configs/omap3_beagle.h | 1 + 3 files changed, 86 insertions(+) (limited to 'arch/arm/lib/cache.c') diff --git a/arch/arm/cpu/armv7/omap3/cache.S b/arch/arm/cpu/armv7/omap3/cache.S index fdc1666fe..cda87ba1a 100644 --- a/arch/arm/cpu/armv7/omap3/cache.S +++ b/arch/arm/cpu/armv7/omap3/cache.S @@ -181,3 +181,83 @@ setup_auxcr: orrlt r0, r0, #1 << 27 .word 0xE1600070 @ SMC bx lr + +.align 5 +.global v7_flush_dcache_all +.global v7_flush_cache_all + +/* + * v7_flush_dcache_all() + * + * Flush the whole D-cache. + * + * Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode) + * + * - mm - mm_struct describing address space + */ +v7_flush_dcache_all: +# dmb @ ensure ordering with previous memory accesses + mrc p15, 1, r0, c0, c0, 1 @ read clidr + ands r3, r0, #0x7000000 @ extract loc from clidr + mov r3, r3, lsr #23 @ left align loc bit field + beq finished @ if loc is 0, then no need to clean + mov r10, #0 @ start clean at cache level 0 +loop1: + add r2, r10, r10, lsr #1 @ work out 3x current cache level + mov r1, r0, lsr r2 @ extract cache type bits from clidr + and r1, r1, #7 @ mask of the bits for current cache only + cmp r1, #2 @ see what cache we have at this level + blt skip @ skip if no cache, or just i-cache + mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr + mcr p15, 0, r10, c7, c5, 4 @ flush prefetch buffer, + @ with armv7 this is 'isb', + @ but we compile with armv5 + mrc p15, 1, r1, c0, c0, 0 @ read the new csidr + and r2, r1, #7 @ extract the length of the cache lines + add r2, r2, #4 @ add 4 (line length offset) + ldr r4, =0x3ff + ands r4, r4, r1, lsr #3 @ find maximum number on the way size + clz r5, r4 @ find bit position of way size increment + ldr r7, =0x7fff + ands r7, r7, r1, lsr #13 @ extract max number of the index size +loop2: + mov r9, r4 @ create working copy of max way size +loop3: + orr r11, r10, r9, lsl r5 @ factor way and cache number into r11 + orr r11, r11, r7, lsl r2 @ factor index number into r11 + mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way + subs r9, r9, #1 @ decrement the way + bge loop3 + subs r7, r7, #1 @ decrement the index + bge loop2 +skip: + add r10, r10, #2 @ increment cache number + cmp r3, r10 + bgt loop1 +finished: + mov r10, #0 @ swith back to cache level 0 + mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr +# dsb + mcr p15, 0, r10, c7, c5, 4 @ flush prefetch buffer, + @ with armv7 this is 'isb', + @ but we compile with armv5 + mov pc, lr + +/* + * v7_flush_cache_all() + * + * Flush the entire cache system. + * The data cache flush is now achieved using atomic clean / invalidates + * working outwards from L1 cache. This is done using Set/Way based cache + * maintainance instructions. + * The instruction cache can still be invalidated back to the point of + * unification in a single instruction. + * + */ +v7_flush_cache_all: + stmfd sp!, {r0-r7, r9-r11, lr} + bl v7_flush_dcache_all + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate + ldmfd sp!, {r0-r7, r9-r11, lr} + mov pc, lr diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c index b36fd2440..3684cad16 100644 --- a/arch/arm/lib/cache.c +++ b/arch/arm/lib/cache.c @@ -37,6 +37,11 @@ void flush_cache (unsigned long dummy1, unsigned long dummy2) asm("0: mrc p15, 0, r15, c7, c10, 3\n\t" "bne 0b\n" : : : "memory"); /* disable write buffer as well (page 2-22) */ asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); +#endif +#ifdef CONFIG_ARMCORTEXA8 + void v7_flush_cache_all(void); + + v7_flush_cache_all(); #endif return; } diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h index 71553f9a0..3f6e803eb 100644 --- a/include/configs/omap3_beagle.h +++ b/include/configs/omap3_beagle.h @@ -120,6 +120,7 @@ /* commands to include */ #include +#define CONFIG_CMD_CACHE #define CONFIG_CMD_EXT2 /* EXT2 Support */ #define CONFIG_CMD_FAT /* FAT support */ #define CONFIG_CMD_JFFS2 /* JFFS2 Support */ -- cgit v1.2.3-70-g09d2 From 7e4a9e6dc819b2b3499659ca90e1e9c6d4ca3077 Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Fri, 17 Sep 2010 13:10:32 +0200 Subject: ARM (ARM11): add data cache support, test on Qong board Add data cache support for arm1136 systems. Enable "cache" command on Qong board and test performance. Test 1: Loading 127 MB of data from NAND flash into RAM: Instr. Cache off on on Data Cache off off on -------------------------------------------------- QONG (ARM11) 177s 95s 43s = x 4.1 Test 2: uncompressing a gzipped image from RAM to RAM (size compressed: 6.5 MiB, uncompressed: 35 MiB): Instr. Cache off on on Data Cache off off on -------------------------------------------------- QONG (ARM11) 1.54s 0.95s 0.18s = x 8.6 Portions of this work were supported by funding from the CE Linux Forum. Signed-off-by: Heiko Schocher --- arch/arm/cpu/arm1136/start.S | 5 +++++ arch/arm/lib/cache.c | 2 +- include/configs/qong.h | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) (limited to 'arch/arm/lib/cache.c') diff --git a/arch/arm/cpu/arm1136/start.S b/arch/arm/cpu/arm1136/start.S index 41eb82dae..1c58abdcd 100644 --- a/arch/arm/cpu/arm1136/start.S +++ b/arch/arm/cpu/arm1136/start.S @@ -439,6 +439,11 @@ fiq: .align 5 .global arm1136_cache_flush arm1136_cache_flush: +#if !defined(CONFIG_SYS_NO_ICACHE) mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache +#endif +#if !defined(CONFIG_SYS_NO_DCACHE) + mcr p15, 0, r1, c7, c14, 0 @ invalidate D cache +#endif mov pc, lr @ back to caller #endif /* CONFIG_PRELOADER */ diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c index 3684cad16..55b633ee0 100644 --- a/arch/arm/lib/cache.c +++ b/arch/arm/lib/cache.c @@ -27,7 +27,7 @@ void flush_cache (unsigned long dummy1, unsigned long dummy2) { -#ifdef CONFIG_OMAP2420 +#if defined(CONFIG_OMAP2420) || defined(CONFIG_ARM1136) void arm1136_cache_flush(void); arm1136_cache_flush(); diff --git a/include/configs/qong.h b/include/configs/qong.h index 100fa3f8a..4735b5eb8 100644 --- a/include/configs/qong.h +++ b/include/configs/qong.h @@ -104,6 +104,7 @@ #include +#define CONFIG_CMD_CACHE #define CONFIG_CMD_PING #define CONFIG_CMD_DHCP #define CONFIG_CMD_NET -- cgit v1.2.3-70-g09d2