From d1348c4fdefd48ed6d24c15832c567e333266ae6 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Mon, 21 Jun 2010 15:10:07 +0100 Subject: [PATCH] --- yaml --- r: 200792 b: refs/heads/master c: ad642d9f58f1af6e96efccb5f84e52c6d01db5c4 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/arm/mm/Kconfig | 19 +++++++++++++++++++ trunk/arch/arm/mm/cache-v6.S | 15 ++++++++++++--- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index 10ff43abc309..ce7cb0f3a895 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ca57926d53580f7c950496cb7ef6d7930610e1dd +refs/heads/master: ad642d9f58f1af6e96efccb5f84e52c6d01db5c4 diff --git a/trunk/arch/arm/mm/Kconfig b/trunk/arch/arm/mm/Kconfig index 346ae14824a5..fc1b2fa59429 100644 --- a/trunk/arch/arm/mm/Kconfig +++ b/trunk/arch/arm/mm/Kconfig @@ -735,6 +735,25 @@ config NEEDS_SYSCALL_FOR_CMPXCHG Forget about fast user space cmpxchg support. It is just not possible. +config DMA_CACHE_RWFO + bool "Enable read/write for ownership DMA cache maintenance" + depends on CPU_V6 && SMP + default y + help + The Snoop Control Unit on ARM11MPCore does not detect the + cache maintenance operations and the dma_{map,unmap}_area() + functions may leave stale cache entries on other CPUs. By + enabling this option, Read or Write For Ownership in the ARMv6 + DMA cache maintenance functions is performed. These LDR/STR + instructions change the cache line state to shared or modified + so that the cache operation has the desired effect. + + Note that the workaround is only valid on processors that do + not perform speculative loads into the D-cache. For such + processors, if cache maintenance operations are not broadcast + in hardware, other workarounds are needed (e.g. cache + maintenance broadcasting in software via FIQ). + config OUTER_CACHE bool diff --git a/trunk/arch/arm/mm/cache-v6.S b/trunk/arch/arm/mm/cache-v6.S index 332b48c6d4ff..86aa689ef1aa 100644 --- a/trunk/arch/arm/mm/cache-v6.S +++ b/trunk/arch/arm/mm/cache-v6.S @@ -211,7 +211,7 @@ v6_dma_inv_range: mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line #endif 1: -#ifdef CONFIG_SMP +#ifdef CONFIG_DMA_CACHE_RWFO ldr r2, [r0] @ read for ownership str r2, [r0] @ write for ownership #endif @@ -235,7 +235,7 @@ v6_dma_inv_range: v6_dma_clean_range: bic r0, r0, #D_CACHE_LINE_SIZE - 1 1: -#ifdef CONFIG_SMP +#ifdef CONFIG_DMA_CACHE_RWFO ldr r2, [r0] @ read for ownership #endif #ifdef HARVARD_CACHE @@ -258,7 +258,7 @@ v6_dma_clean_range: ENTRY(v6_dma_flush_range) bic r0, r0, #D_CACHE_LINE_SIZE - 1 1: -#ifdef CONFIG_SMP +#ifdef CONFIG_DMA_CACHE_RWFO ldr r2, [r0] @ read for ownership str r2, [r0] @ write for ownership #endif @@ -284,9 +284,13 @@ ENTRY(v6_dma_map_area) add r1, r1, r0 teq r2, #DMA_FROM_DEVICE beq v6_dma_inv_range +#ifndef CONFIG_DMA_CACHE_RWFO + b v6_dma_clean_range +#else teq r2, #DMA_TO_DEVICE beq v6_dma_clean_range b v6_dma_flush_range +#endif ENDPROC(v6_dma_map_area) /* @@ -296,6 +300,11 @@ ENDPROC(v6_dma_map_area) * - dir - DMA direction */ ENTRY(v6_dma_unmap_area) +#ifndef CONFIG_DMA_CACHE_RWFO + add r1, r1, r0 + teq r2, #DMA_TO_DEVICE + bne v6_dma_inv_range +#endif mov pc, lr ENDPROC(v6_dma_unmap_area)