diff options
author | Valentine Barshak <vbarshak@mvista.com> | 2010-12-13 18:03:16 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-12-14 17:23:34 -0500 |
commit | 85b093bcc5322baa811a03ec73de0909c157f181 (patch) | |
tree | a403ad0cfc2c8d6dbeebc85d5332922410d2347c /arch/arm | |
parent | 593c252a731389ffdd00d4cb2d20192c47aa18c1 (diff) |
ARM: 6535/1: V6 MPCore v6_dma_inv_range and v6_dma_flush_range RWFO fix
Cache ownership must be acquired by reading/writing data from the
cache line to make cache operation have the desired effect on the
SMP MPCore CPU. However, the ownership is never acquired in the
v6_dma_inv_range function when cleaning the first line and
flushing the last one, in case the address is not aligned
to D_CACHE_LINE_SIZE boundary.
Fix this by reading/writing data if needed, before performing
cache operations.
While at it, fix v6_dma_flush_range to prevent RWFO outside
the buffer.
Cc: stable@kernel.org
Signed-off-by: Valentine Barshak <vbarshak@mvista.com>
Signed-off-by: George G. Davis <gdavis@mvista.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mm/cache-v6.S | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S index 99fa688dfadd..c96fa1b3f49f 100644 --- a/arch/arm/mm/cache-v6.S +++ b/arch/arm/mm/cache-v6.S | |||
@@ -203,6 +203,10 @@ ENTRY(v6_flush_kern_dcache_area) | |||
203 | * - end - virtual end address of region | 203 | * - end - virtual end address of region |
204 | */ | 204 | */ |
205 | v6_dma_inv_range: | 205 | v6_dma_inv_range: |
206 | #ifdef CONFIG_DMA_CACHE_RWFO | ||
207 | ldrb r2, [r0] @ read for ownership | ||
208 | strb r2, [r0] @ write for ownership | ||
209 | #endif | ||
206 | tst r0, #D_CACHE_LINE_SIZE - 1 | 210 | tst r0, #D_CACHE_LINE_SIZE - 1 |
207 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 | 211 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 |
208 | #ifdef HARVARD_CACHE | 212 | #ifdef HARVARD_CACHE |
@@ -211,6 +215,10 @@ v6_dma_inv_range: | |||
211 | mcrne p15, 0, r0, c7, c11, 1 @ clean unified line | 215 | mcrne p15, 0, r0, c7, c11, 1 @ clean unified line |
212 | #endif | 216 | #endif |
213 | tst r1, #D_CACHE_LINE_SIZE - 1 | 217 | tst r1, #D_CACHE_LINE_SIZE - 1 |
218 | #ifdef CONFIG_DMA_CACHE_RWFO | ||
219 | ldrneb r2, [r1, #-1] @ read for ownership | ||
220 | strneb r2, [r1, #-1] @ write for ownership | ||
221 | #endif | ||
214 | bic r1, r1, #D_CACHE_LINE_SIZE - 1 | 222 | bic r1, r1, #D_CACHE_LINE_SIZE - 1 |
215 | #ifdef HARVARD_CACHE | 223 | #ifdef HARVARD_CACHE |
216 | mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D line | 224 | mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D line |
@@ -218,10 +226,6 @@ v6_dma_inv_range: | |||
218 | mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line | 226 | mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line |
219 | #endif | 227 | #endif |
220 | 1: | 228 | 1: |
221 | #ifdef CONFIG_DMA_CACHE_RWFO | ||
222 | ldr r2, [r0] @ read for ownership | ||
223 | str r2, [r0] @ write for ownership | ||
224 | #endif | ||
225 | #ifdef HARVARD_CACHE | 229 | #ifdef HARVARD_CACHE |
226 | mcr p15, 0, r0, c7, c6, 1 @ invalidate D line | 230 | mcr p15, 0, r0, c7, c6, 1 @ invalidate D line |
227 | #else | 231 | #else |
@@ -229,6 +233,10 @@ v6_dma_inv_range: | |||
229 | #endif | 233 | #endif |
230 | add r0, r0, #D_CACHE_LINE_SIZE | 234 | add r0, r0, #D_CACHE_LINE_SIZE |
231 | cmp r0, r1 | 235 | cmp r0, r1 |
236 | #ifdef CONFIG_DMA_CACHE_RWFO | ||
237 | ldrlo r2, [r0] @ read for ownership | ||
238 | strlo r2, [r0] @ write for ownership | ||
239 | #endif | ||
232 | blo 1b | 240 | blo 1b |
233 | mov r0, #0 | 241 | mov r0, #0 |
234 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer | 242 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer |
@@ -263,12 +271,12 @@ v6_dma_clean_range: | |||
263 | * - end - virtual end address of region | 271 | * - end - virtual end address of region |
264 | */ | 272 | */ |
265 | ENTRY(v6_dma_flush_range) | 273 | ENTRY(v6_dma_flush_range) |
266 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 | ||
267 | 1: | ||
268 | #ifdef CONFIG_DMA_CACHE_RWFO | 274 | #ifdef CONFIG_DMA_CACHE_RWFO |
269 | ldr r2, [r0] @ read for ownership | 275 | ldrb r2, [r0] @ read for ownership |
270 | str r2, [r0] @ write for ownership | 276 | strb r2, [r0] @ write for ownership |
271 | #endif | 277 | #endif |
278 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 | ||
279 | 1: | ||
272 | #ifdef HARVARD_CACHE | 280 | #ifdef HARVARD_CACHE |
273 | mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line | 281 | mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line |
274 | #else | 282 | #else |
@@ -276,6 +284,10 @@ ENTRY(v6_dma_flush_range) | |||
276 | #endif | 284 | #endif |
277 | add r0, r0, #D_CACHE_LINE_SIZE | 285 | add r0, r0, #D_CACHE_LINE_SIZE |
278 | cmp r0, r1 | 286 | cmp r0, r1 |
287 | #ifdef CONFIG_DMA_CACHE_RWFO | ||
288 | ldrlob r2, [r0] @ read for ownership | ||
289 | strlob r2, [r0] @ write for ownership | ||
290 | #endif | ||
279 | blo 1b | 291 | blo 1b |
280 | mov r0, #0 | 292 | mov r0, #0 |
281 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer | 293 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer |