Commit e39cd81c44740d7355d277ed3d38536cbe1e003d
Committed by
Wolfgang Denk
1 parent
63240ba88c
Exists in
master
and in
54 other branches
lib_ppc: rework the flush_cache
- It is possible to miss flush/invalidate the last cache line, we fix it at here. - add the volatile and memory clobber. They are pointed by Scott Wood. Signed-off-by: Dave Liu <daveliu@freescale.com>
Showing 1 changed file with 17 additions and 19 deletions Side-by-side Diff
lib_ppc/cache.c
... | ... | @@ -25,30 +25,28 @@ |
25 | 25 | #include <asm/cache.h> |
26 | 26 | #include <watchdog.h> |
27 | 27 | |
28 | -void flush_cache (ulong start_addr, ulong size) | |
28 | +void flush_cache(ulong start_addr, ulong size) | |
29 | 29 | { |
30 | 30 | #ifndef CONFIG_5xx |
31 | - ulong addr, end_addr = start_addr + size; | |
31 | + ulong addr, start, end; | |
32 | 32 | |
33 | - if (CONFIG_SYS_CACHELINE_SIZE) { | |
34 | - addr = start_addr & (CONFIG_SYS_CACHELINE_SIZE - 1); | |
35 | - for (addr = start_addr; | |
36 | - addr < end_addr; | |
37 | - addr += CONFIG_SYS_CACHELINE_SIZE) { | |
38 | - asm ("dcbst 0,%0": :"r" (addr)); | |
39 | - WATCHDOG_RESET(); | |
40 | - } | |
41 | - asm ("sync"); /* Wait for all dcbst to complete on bus */ | |
33 | + start = start_addr & ~(CONFIG_SYS_CACHELINE_SIZE - 1); | |
34 | + end = start_addr + size - 1; | |
42 | 35 | |
43 | - for (addr = start_addr; | |
44 | - addr < end_addr; | |
45 | - addr += CONFIG_SYS_CACHELINE_SIZE) { | |
46 | - asm ("icbi 0,%0": :"r" (addr)); | |
47 | - WATCHDOG_RESET(); | |
48 | - } | |
36 | + for (addr = start; addr <= end; addr += CONFIG_SYS_CACHELINE_SIZE) { | |
37 | + asm volatile("dcbst 0,%0" : : "r" (addr) : "memory"); | |
38 | + WATCHDOG_RESET(); | |
49 | 39 | } |
50 | - asm ("sync"); /* Always flush prefetch queue in any case */ | |
51 | - asm ("isync"); | |
40 | + /* wait for all dcbst to complete on bus */ | |
41 | + asm volatile("sync" : : : "memory"); | |
42 | + | |
43 | + for (addr = start; addr <= end; addr += CONFIG_SYS_CACHELINE_SIZE) { | |
44 | + asm volatile("icbi 0,%0" : : "r" (addr) : "memory"); | |
45 | + WATCHDOG_RESET(); | |
46 | + } | |
47 | + asm volatile("sync" : : : "memory"); | |
48 | + /* flush prefetch queue */ | |
49 | + asm volatile("isync" : : : "memory"); | |
52 | 50 | #endif |
53 | 51 | } |