Commit f4d6477f authored by Catalin Marinas's avatar Catalin Marinas Committed by Russell King

ARM: 6111/1: Implement read/write for ownership in the ARMv6 DMA cache ops

The Snoop Control Unit on the ARM11MPCore hardware does not detect the
cache operations and the dma_cache_maint*() functions may leave stale
cache entries on other CPUs. The solution implemented in this patch
performs a Read or Write For Ownership in the ARMv6 DMA cache
maintenance functions. These LDR/STR instructions change the cache line
state to shared or exclusive so that the cache maintenance operation has
the desired effect.
Tested-by: default avatarGeorge G. Davis <gdavis@mvista.com>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent b5a07faa
...@@ -211,6 +211,9 @@ v6_dma_inv_range: ...@@ -211,6 +211,9 @@ v6_dma_inv_range:
mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line
#endif #endif
1: 1:
#ifdef CONFIG_SMP
str r0, [r0] @ write for ownership
#endif
#ifdef HARVARD_CACHE #ifdef HARVARD_CACHE
mcr p15, 0, r0, c7, c6, 1 @ invalidate D line mcr p15, 0, r0, c7, c6, 1 @ invalidate D line
#else #else
...@@ -231,6 +234,9 @@ v6_dma_inv_range: ...@@ -231,6 +234,9 @@ v6_dma_inv_range:
v6_dma_clean_range: v6_dma_clean_range:
bic r0, r0, #D_CACHE_LINE_SIZE - 1 bic r0, r0, #D_CACHE_LINE_SIZE - 1
1: 1:
#ifdef CONFIG_SMP
ldr r2, [r0] @ read for ownership
#endif
#ifdef HARVARD_CACHE #ifdef HARVARD_CACHE
mcr p15, 0, r0, c7, c10, 1 @ clean D line mcr p15, 0, r0, c7, c10, 1 @ clean D line
#else #else
...@@ -251,6 +257,10 @@ v6_dma_clean_range: ...@@ -251,6 +257,10 @@ v6_dma_clean_range:
ENTRY(v6_dma_flush_range) ENTRY(v6_dma_flush_range)
bic r0, r0, #D_CACHE_LINE_SIZE - 1 bic r0, r0, #D_CACHE_LINE_SIZE - 1
1: 1:
#ifdef CONFIG_SMP
ldr r2, [r0] @ read for ownership
str r2, [r0] @ write for ownership
#endif
#ifdef HARVARD_CACHE #ifdef HARVARD_CACHE
mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line
#else #else
...@@ -273,7 +283,9 @@ ENTRY(v6_dma_map_area) ...@@ -273,7 +283,9 @@ ENTRY(v6_dma_map_area)
add r1, r1, r0 add r1, r1, r0
teq r2, #DMA_FROM_DEVICE teq r2, #DMA_FROM_DEVICE
beq v6_dma_inv_range beq v6_dma_inv_range
b v6_dma_clean_range teq r2, #DMA_TO_DEVICE
beq v6_dma_clean_range
b v6_dma_flush_range
ENDPROC(v6_dma_map_area) ENDPROC(v6_dma_map_area)
/* /*
...@@ -283,9 +295,6 @@ ENDPROC(v6_dma_map_area) ...@@ -283,9 +295,6 @@ ENDPROC(v6_dma_map_area)
* - dir - DMA direction * - dir - DMA direction
*/ */
ENTRY(v6_dma_unmap_area) ENTRY(v6_dma_unmap_area)
add r1, r1, r0
teq r2, #DMA_TO_DEVICE
bne v6_dma_inv_range
mov pc, lr mov pc, lr
ENDPROC(v6_dma_unmap_area) ENDPROC(v6_dma_unmap_area)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment