[U-Boot] [PATCH 04/26] 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
Signed-off-by: Heiko Schocher hs@denx.de Reviewed-by: Ben Gardinerbengardiner@nanometrics.ca --- - changes since v1: rebased as patch "arm cp15: setup mmu and enable dcache" changed.
- changes since v2: - changed commit message - added source from cache flush functions
- changes since v3: - changed commit message - moved cache patches before relocation patches
arch/arm/cpu/armv7/omap3/cache.S | 82 ++++++++++++++++++++++++++++++++++++++ arch/arm/lib/cache.c | 5 ++ include/configs/omap3_beagle.h | 1 + 3 files changed, 88 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap3/cache.S b/arch/arm/cpu/armv7/omap3/cache.S index 4b65ac5..b983d23 100644 --- a/arch/arm/cpu/armv7/omap3/cache.S +++ b/arch/arm/cpu/armv7/omap3/cache.S @@ -189,3 +189,85 @@ l2_cache_disable_EARLIER_THAN_ES2: str r3, [sp, #4] l2_cache_disable_END: ldmfd r13!, {r1, r2, r3, pc} + +.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 b36fd24..3684cad 100644 --- a/arch/arm/lib/cache.c +++ b/arch/arm/lib/cache.c @@ -38,5 +38,10 @@ void flush_cache (unsigned long dummy1, unsigned long dummy2) /* 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 ae5a791..b066d4d 100644 --- a/include/configs/omap3_beagle.h +++ b/include/configs/omap3_beagle.h @@ -120,6 +120,7 @@ /* commands to include */ #include <config_cmd_default.h>
+#define CONFIG_CMD_CACHE #define CONFIG_CMD_EXT2 /* EXT2 Support */ #define CONFIG_CMD_FAT /* FAT support */ #define CONFIG_CMD_JFFS2 /* JFFS2 Support */
participants (1)
-
Heiko Schocher