diff options
author | Srikant Patnaik | 2015-01-11 12:28:04 +0530 |
---|---|---|
committer | Srikant Patnaik | 2015-01-11 12:28:04 +0530 |
commit | 871480933a1c28f8a9fed4c4d34d06c439a7a422 (patch) | |
tree | 8718f573808810c2a1e8cb8fb6ac469093ca2784 /arch/blackfin/mach-common/cache.S | |
parent | 9d40ac5867b9aefe0722bc1f110b965ff294d30d (diff) | |
download | FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.gz FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.bz2 FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.zip |
Moved, renamed, and deleted files
The original directory structure was scattered and unorganized.
Changes are basically to make it look like kernel structure.
Diffstat (limited to 'arch/blackfin/mach-common/cache.S')
-rw-r--r-- | arch/blackfin/mach-common/cache.S | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/arch/blackfin/mach-common/cache.S b/arch/blackfin/mach-common/cache.S new file mode 100644 index 00000000..9f4dd35b --- /dev/null +++ b/arch/blackfin/mach-common/cache.S @@ -0,0 +1,124 @@ +/* + * Blackfin cache control code + * + * Copyright 2004-2008 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include <linux/linkage.h> +#include <asm/blackfin.h> +#include <asm/cache.h> +#include <asm/page.h> + +/* 05000443 - IFLUSH cannot be last instruction in hardware loop */ +#if ANOMALY_05000443 +# define BROK_FLUSH_INST "IFLUSH" +#else +# define BROK_FLUSH_INST "no anomaly! yeah!" +#endif + +/* Since all L1 caches work the same way, we use the same method for flushing + * them. Only the actual flush instruction differs. We write this in asm as + * GCC can be hard to coax into writing nice hardware loops. + * + * Also, we assume the following register setup: + * R0 = start address + * R1 = end address + */ +.macro do_flush flushins:req label + + R2 = -L1_CACHE_BYTES; + + /* start = (start & -L1_CACHE_BYTES) */ + R0 = R0 & R2; + + /* end = ((end - 1) & -L1_CACHE_BYTES) + L1_CACHE_BYTES; */ + R1 += -1; + R1 = R1 & R2; + R1 += L1_CACHE_BYTES; + + /* count = (end - start) >> L1_CACHE_SHIFT */ + R2 = R1 - R0; + R2 >>= L1_CACHE_SHIFT; + P1 = R2; + +.ifnb \label +\label : +.endif + P0 = R0; + + LSETUP (1f, 2f) LC1 = P1; +1: +.ifeqs "\flushins", BROK_FLUSH_INST + \flushins [P0++]; + nop; + nop; +2: nop; +.else +2: \flushins [P0++]; +.endif + + RTS; +.endm + +#ifdef CONFIG_ICACHE_FLUSH_L1 +.section .l1.text +#else +.text +#endif + +/* Invalidate all instruction cache lines assocoiated with this memory area */ +#ifdef CONFIG_SMP +# define _blackfin_icache_flush_range _blackfin_icache_flush_range_l1 +#endif +ENTRY(_blackfin_icache_flush_range) + do_flush IFLUSH +ENDPROC(_blackfin_icache_flush_range) + +#ifdef CONFIG_SMP +.text +# undef _blackfin_icache_flush_range +ENTRY(_blackfin_icache_flush_range) + p0.L = LO(DSPID); + p0.H = HI(DSPID); + r3 = [p0]; + r3 = r3.b (z); + p2 = r3; + p0.L = _blackfin_iflush_l1_entry; + p0.H = _blackfin_iflush_l1_entry; + p0 = p0 + (p2 << 2); + p1 = [p0]; + jump (p1); +ENDPROC(_blackfin_icache_flush_range) +#endif + +#ifdef CONFIG_DCACHE_FLUSH_L1 +.section .l1.text +#else +.text +#endif + +/* Throw away all D-cached data in specified region without any obligation to + * write them back. Since the Blackfin ISA does not have an "invalidate" + * instruction, we use flush/invalidate. Perhaps as a speed optimization we + * could bang on the DTEST MMRs ... + */ +ENTRY(_blackfin_dcache_invalidate_range) + do_flush FLUSHINV +ENDPROC(_blackfin_dcache_invalidate_range) + +/* Flush all data cache lines assocoiated with this memory area */ +ENTRY(_blackfin_dcache_flush_range) + do_flush FLUSH, .Ldfr +ENDPROC(_blackfin_dcache_flush_range) + +/* Our headers convert the page structure to an address, so just need to flush + * its contents like normal. We know the start address is page aligned (which + * greater than our cache alignment), as is the end address. So just jump into + * the middle of the dcache flush function. + */ +ENTRY(_blackfin_dflush_page) + P1 = 1 << (PAGE_SHIFT - L1_CACHE_SHIFT); + jump .Ldfr; +ENDPROC(_blackfin_dflush_page) |