2 * arch/v850/kernel/v850e2_cache.c -- Cache control for V850E2 cache
5 * Copyright (C) 2003 NEC Electronics Corporation
6 * Copyright (C) 2003 Miles Bader <miles@gnu.org>
8 * This file is subject to the terms and conditions of the GNU General
9 * Public License. See the file COPYING in the main directory of this
10 * archive for more details.
12 * Written by Miles Bader <miles@gnu.org>
17 #include <asm/v850e2_cache.h>
19 /* Cache operations we can do. The encoding corresponds directly to the
20 value we need to write into the COPR register. */
22 OP_SYNC_IF_DIRTY
= V850E2_CACHE_COPR_CFC(0), /* 000 */
23 OP_SYNC_IF_VALID
= V850E2_CACHE_COPR_CFC(1), /* 001 */
24 OP_SYNC_IF_VALID_AND_CLEAR
= V850E2_CACHE_COPR_CFC(3), /* 011 */
25 OP_WAY_CLEAR
= V850E2_CACHE_COPR_CFC(4), /* 100 */
26 OP_FILL
= V850E2_CACHE_COPR_CFC(5), /* 101 */
27 OP_CLEAR
= V850E2_CACHE_COPR_CFC(6), /* 110 */
28 OP_CREATE_DIRTY
= V850E2_CACHE_COPR_CFC(7) /* 111 */
31 /* Which cache to use. This encoding also corresponds directly to the
32 value we need to write into the COPR register. */
35 DCACHE
= V850E2_CACHE_COPR_LBSL
38 /* Returns ADDR rounded down to the beginning of its cache-line. */
39 #define CACHE_LINE_ADDR(addr) \
40 ((addr) & ~(V850E2_CACHE_LINE_SIZE - 1))
41 /* Returns END_ADDR rounded up to the `limit' of its cache-line. */
42 #define CACHE_LINE_END_ADDR(end_addr) \
43 CACHE_LINE_ADDR(end_addr + (V850E2_CACHE_LINE_SIZE - 1))
46 /* Low-level cache ops. */
48 /* Apply cache-op OP to all entries in CACHE. */
49 static inline void cache_op_all (enum cache_op op
, enum cache cache
)
51 int cmd
= op
| cache
| V850E2_CACHE_COPR_WSLE
| V850E2_CACHE_COPR_STRT
;
53 if (op
!= OP_WAY_CLEAR
) {
54 /* The WAY_CLEAR operation does the whole way, but other
55 ops take begin-index and count params; we just indicate
57 V850E2_CACHE_CADL
= 0;
58 V850E2_CACHE_CADH
= 0;
59 V850E2_CACHE_CCNT
= V850E2_CACHE_WAY_SIZE
- 1;
62 V850E2_CACHE_COPR
= cmd
| V850E2_CACHE_COPR_WSL(0); /* way 0 */
63 V850E2_CACHE_COPR
= cmd
| V850E2_CACHE_COPR_WSL(1); /* way 1 */
64 V850E2_CACHE_COPR
= cmd
| V850E2_CACHE_COPR_WSL(2); /* way 2 */
65 V850E2_CACHE_COPR
= cmd
| V850E2_CACHE_COPR_WSL(3); /* way 3 */
68 /* Apply cache-op OP to all entries in CACHE covering addresses ADDR
70 static inline void cache_op_range (enum cache_op op
, u32 addr
, u32 len
,
73 u32 start
= CACHE_LINE_ADDR (addr
);
74 u32 end
= CACHE_LINE_END_ADDR (addr
+ len
);
75 u32 num_lines
= (end
- start
) >> V850E2_CACHE_LINE_SIZE_BITS
;
77 V850E2_CACHE_CADL
= start
& 0xFFFF;
78 V850E2_CACHE_CADH
= start
>> 16;
79 V850E2_CACHE_CCNT
= num_lines
- 1;
81 V850E2_CACHE_COPR
= op
| cache
| V850E2_CACHE_COPR_STRT
;
87 static void cache_exec_after_store_all (void)
89 cache_op_all (OP_SYNC_IF_DIRTY
, DCACHE
);
90 cache_op_all (OP_WAY_CLEAR
, ICACHE
);
93 static void cache_exec_after_store_range (u32 start
, u32 len
)
95 cache_op_range (OP_SYNC_IF_DIRTY
, start
, len
, DCACHE
);
96 cache_op_range (OP_CLEAR
, start
, len
, ICACHE
);
100 /* Exported functions. */
102 void flush_icache (void)
104 cache_exec_after_store_all ();
107 void flush_icache_range (unsigned long start
, unsigned long end
)
109 cache_exec_after_store_range (start
, end
- start
);
112 void flush_icache_page (struct vm_area_struct
*vma
, struct page
*page
)
114 cache_exec_after_store_range (page_to_virt (page
), PAGE_SIZE
);
117 void flush_icache_user_range (struct vm_area_struct
*vma
, struct page
*page
,
118 unsigned long addr
, int len
)
120 cache_exec_after_store_range (addr
, len
);
123 void flush_cache_sigtramp (unsigned long addr
)
125 /* For the exact size, see signal.c, but 16 bytes should be enough. */
126 cache_exec_after_store_range (addr
, 16);