aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAkira Takeuchi <takeuchi.akr@jp.panasonic.com>2010-10-27 12:28:45 -0400
committerDavid Howells <dhowells@redhat.com>2010-10-27 12:28:45 -0400
commit0bd3eb6ca772775da6125ea5b044d4257473d18d (patch)
treea5aa631714910e2d9a698cd9334bbe1b49e33e2f
parent9b287bf9924cedaf1accd7293db3627bef7c46e3 (diff)
MN10300: SMP: Differentiate local cache flushing
Differentiate local cache flushing from global cache flushing so that they can be done differently on SMP systems. Rename the cache functions from: mn10300_[id]cache_*() to: mn10300_[id]_localcache_*() and on a UP system, assign the global labels to the local labels. Signed-off-by: Akira Takeuchi <takeuchi.akr@jp.panasonic.com> Signed-off-by: Kiyoshi Owada <owada.kiyoshi@jp.panasonic.com> Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r--arch/mn10300/include/asm/cacheflush.h50
-rw-r--r--arch/mn10300/mm/cache-flush-by-tag.S143
-rw-r--r--arch/mn10300/mm/cache-inv-by-tag.S199
-rw-r--r--arch/mn10300/proc-mn103e010/include/proc/cache.h9
4 files changed, 289 insertions, 112 deletions
diff --git a/arch/mn10300/include/asm/cacheflush.h b/arch/mn10300/include/asm/cacheflush.h
index a9f41688961a..748143f65418 100644
--- a/arch/mn10300/include/asm/cacheflush.h
+++ b/arch/mn10300/include/asm/cacheflush.h
@@ -20,12 +20,31 @@
20 * Primitive routines 20 * Primitive routines
21 */ 21 */
22#ifdef CONFIG_MN10300_CACHE_ENABLED 22#ifdef CONFIG_MN10300_CACHE_ENABLED
23extern void mn10300_local_icache_inv(void);
24extern void mn10300_local_icache_inv_page(unsigned long start);
25extern void mn10300_local_icache_inv_range(unsigned long start, unsigned long end);
26extern void mn10300_local_icache_inv_range2(unsigned long start, unsigned long size);
27extern void mn10300_local_dcache_inv(void);
28extern void mn10300_local_dcache_inv_page(unsigned long start);
29extern void mn10300_local_dcache_inv_range(unsigned long start, unsigned long end);
30extern void mn10300_local_dcache_inv_range2(unsigned long start, unsigned long size);
23extern void mn10300_icache_inv(void); 31extern void mn10300_icache_inv(void);
32extern void mn10300_icache_inv_page(unsigned long start);
33extern void mn10300_icache_inv_range(unsigned long start, unsigned long end);
34extern void mn10300_icache_inv_range2(unsigned long start, unsigned long size);
24extern void mn10300_dcache_inv(void); 35extern void mn10300_dcache_inv(void);
25extern void mn10300_dcache_inv_page(unsigned long start); 36extern void mn10300_dcache_inv_page(unsigned long start);
26extern void mn10300_dcache_inv_range(unsigned long start, unsigned long end); 37extern void mn10300_dcache_inv_range(unsigned long start, unsigned long end);
27extern void mn10300_dcache_inv_range2(unsigned long start, unsigned long size); 38extern void mn10300_dcache_inv_range2(unsigned long start, unsigned long size);
28#ifdef CONFIG_MN10300_CACHE_WBACK 39#ifdef CONFIG_MN10300_CACHE_WBACK
40extern void mn10300_local_dcache_flush(void);
41extern void mn10300_local_dcache_flush_page(unsigned long start);
42extern void mn10300_local_dcache_flush_range(unsigned long start, unsigned long end);
43extern void mn10300_local_dcache_flush_range2(unsigned long start, unsigned long size);
44extern void mn10300_local_dcache_flush_inv(void);
45extern void mn10300_local_dcache_flush_inv_page(unsigned long start);
46extern void mn10300_local_dcache_flush_inv_range(unsigned long start, unsigned long end);
47extern void mn10300_local_dcache_flush_inv_range2(unsigned long start, unsigned long size);
29extern void mn10300_dcache_flush(void); 48extern void mn10300_dcache_flush(void);
30extern void mn10300_dcache_flush_page(unsigned long start); 49extern void mn10300_dcache_flush_page(unsigned long start);
31extern void mn10300_dcache_flush_range(unsigned long start, unsigned long end); 50extern void mn10300_dcache_flush_range(unsigned long start, unsigned long end);
@@ -35,6 +54,18 @@ extern void mn10300_dcache_flush_inv_page(unsigned long start);
35extern void mn10300_dcache_flush_inv_range(unsigned long start, unsigned long end); 54extern void mn10300_dcache_flush_inv_range(unsigned long start, unsigned long end);
36extern void mn10300_dcache_flush_inv_range2(unsigned long start, unsigned long size); 55extern void mn10300_dcache_flush_inv_range2(unsigned long start, unsigned long size);
37#else 56#else
57#define mn10300_local_dcache_flush() do {} while (0)
58#define mn10300_local_dcache_flush_page(start) do {} while (0)
59#define mn10300_local_dcache_flush_range(start, end) do {} while (0)
60#define mn10300_local_dcache_flush_range2(start, size) do {} while (0)
61#define mn10300_local_dcache_flush_inv() \
62 mn10300_local_dcache_inv()
63#define mn10300_local_dcache_flush_inv_page(start) \
64 mn10300_local_dcache_inv_page(start)
65#define mn10300_local_dcache_flush_inv_range(start, end) \
66 mn10300_local_dcache_inv_range(start, end)
67#define mn10300_local_dcache_flush_inv_range2(start, size) \
68 mn10300_local_dcache_inv_range2(start, size)
38#define mn10300_dcache_flush() do {} while (0) 69#define mn10300_dcache_flush() do {} while (0)
39#define mn10300_dcache_flush_page(start) do {} while (0) 70#define mn10300_dcache_flush_page(start) do {} while (0)
40#define mn10300_dcache_flush_range(start, end) do {} while (0) 71#define mn10300_dcache_flush_range(start, end) do {} while (0)
@@ -48,7 +79,26 @@ extern void mn10300_dcache_flush_inv_range2(unsigned long start, unsigned long s
48 mn10300_dcache_inv_range2((start), (size)) 79 mn10300_dcache_inv_range2((start), (size))
49#endif /* CONFIG_MN10300_CACHE_WBACK */ 80#endif /* CONFIG_MN10300_CACHE_WBACK */
50#else 81#else
82#define mn10300_local_icache_inv() do {} while (0)
83#define mn10300_local_icache_inv_page(start) do {} while (0)
84#define mn10300_local_icache_inv_range(start, end) do {} while (0)
85#define mn10300_local_icache_inv_range2(start, size) do {} while (0)
86#define mn10300_local_dcache_inv() do {} while (0)
87#define mn10300_local_dcache_inv_page(start) do {} while (0)
88#define mn10300_local_dcache_inv_range(start, end) do {} while (0)
89#define mn10300_local_dcache_inv_range2(start, size) do {} while (0)
90#define mn10300_local_dcache_flush() do {} while (0)
91#define mn10300_local_dcache_flush_inv_page(start) do {} while (0)
92#define mn10300_local_dcache_flush_inv() do {} while (0)
93#define mn10300_local_dcache_flush_inv_range(start, end)do {} while (0)
94#define mn10300_local_dcache_flush_inv_range2(start, size) do {} while (0)
95#define mn10300_local_dcache_flush_page(start) do {} while (0)
96#define mn10300_local_dcache_flush_range(start, end) do {} while (0)
97#define mn10300_local_dcache_flush_range2(start, size) do {} while (0)
51#define mn10300_icache_inv() do {} while (0) 98#define mn10300_icache_inv() do {} while (0)
99#define mn10300_icache_inv_page(start) do {} while (0)
100#define mn10300_icache_inv_range(start, end) do {} while (0)
101#define mn10300_icache_inv_range2(start, size) do {} while (0)
52#define mn10300_dcache_inv() do {} while (0) 102#define mn10300_dcache_inv() do {} while (0)
53#define mn10300_dcache_inv_page(start) do {} while (0) 103#define mn10300_dcache_inv_page(start) do {} while (0)
54#define mn10300_dcache_inv_range(start, end) do {} while (0) 104#define mn10300_dcache_inv_range(start, end) do {} while (0)
diff --git a/arch/mn10300/mm/cache-flush-by-tag.S b/arch/mn10300/mm/cache-flush-by-tag.S
index 8fe90e49b96c..5cd6a27dd63e 100644
--- a/arch/mn10300/mm/cache-flush-by-tag.S
+++ b/arch/mn10300/mm/cache-flush-by-tag.S
@@ -1,4 +1,4 @@
1/* MN10300 CPU core caching routines 1/* MN10300 CPU core caching routines, using direct tag flushing
2 * 2 *
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
@@ -14,8 +14,11 @@
14#include <asm/smp.h> 14#include <asm/smp.h>
15#include <asm/page.h> 15#include <asm/page.h>
16#include <asm/cache.h> 16#include <asm/cache.h>
17#include <asm/irqflags.h>
17 18
18 .am33_2 19 .am33_2
20
21#ifndef CONFIG_SMP
19 .globl mn10300_dcache_flush 22 .globl mn10300_dcache_flush
20 .globl mn10300_dcache_flush_page 23 .globl mn10300_dcache_flush_page
21 .globl mn10300_dcache_flush_range 24 .globl mn10300_dcache_flush_range
@@ -25,17 +28,30 @@
25 .globl mn10300_dcache_flush_inv_range 28 .globl mn10300_dcache_flush_inv_range
26 .globl mn10300_dcache_flush_inv_range2 29 .globl mn10300_dcache_flush_inv_range2
27 30
31mn10300_dcache_flush = mn10300_local_dcache_flush
32mn10300_dcache_flush_page = mn10300_local_dcache_flush_page
33mn10300_dcache_flush_range = mn10300_local_dcache_flush_range
34mn10300_dcache_flush_range2 = mn10300_local_dcache_flush_range2
35mn10300_dcache_flush_inv = mn10300_local_dcache_flush_inv
36mn10300_dcache_flush_inv_page = mn10300_local_dcache_flush_inv_page
37mn10300_dcache_flush_inv_range = mn10300_local_dcache_flush_inv_range
38mn10300_dcache_flush_inv_range2 = mn10300_local_dcache_flush_inv_range2
39
40#endif /* !CONFIG_SMP */
41
28############################################################################### 42###############################################################################
29# 43#
30# void mn10300_dcache_flush(void) 44# void mn10300_local_dcache_flush(void)
31# Flush the entire data cache back to RAM 45# Flush the entire data cache back to RAM
32# 46#
33############################################################################### 47###############################################################################
34 ALIGN 48 ALIGN
35mn10300_dcache_flush: 49 .globl mn10300_local_dcache_flush
50 .type mn10300_local_dcache_flush,@function
51mn10300_local_dcache_flush:
36 movhu (CHCTR),d0 52 movhu (CHCTR),d0
37 btst CHCTR_DCEN,d0 53 btst CHCTR_DCEN,d0
38 beq mn10300_dcache_flush_end 54 beq mn10300_local_dcache_flush_end
39 55
40 # read the addresses tagged in the cache's tag RAM and attempt to flush 56 # read the addresses tagged in the cache's tag RAM and attempt to flush
41 # those addresses specifically 57 # those addresses specifically
@@ -44,41 +60,56 @@ mn10300_dcache_flush:
44 mov DCACHE_PURGE(0,0),a1 # dcache purge request address 60 mov DCACHE_PURGE(0,0),a1 # dcache purge request address
45 mov L1_CACHE_NWAYS*L1_CACHE_NENTRIES,d1 # total number of entries 61 mov L1_CACHE_NWAYS*L1_CACHE_NENTRIES,d1 # total number of entries
46 62
47mn10300_dcache_flush_loop: 63mn10300_local_dcache_flush_loop:
48 mov (a0),d0 64 mov (a0),d0
49 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 65 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0
50 or L1_CACHE_TAG_VALID,d0 # retain valid entries in the 66 or L1_CACHE_TAG_VALID,d0 # retain valid entries in the
51 # cache 67 # cache
52 mov d0,(a1) # conditional purge 68 mov d0,(a1) # conditional purge
53 69
54mn10300_dcache_flush_skip:
55 add L1_CACHE_BYTES,a0 70 add L1_CACHE_BYTES,a0
56 add L1_CACHE_BYTES,a1 71 add L1_CACHE_BYTES,a1
57 add -1,d1 72 add -1,d1
58 bne mn10300_dcache_flush_loop 73 bne mn10300_local_dcache_flush_loop
59 74
60mn10300_dcache_flush_end: 75mn10300_local_dcache_flush_end:
61 ret [],0 76 ret [],0
77 .size mn10300_local_dcache_flush,.-mn10300_local_dcache_flush
62 78
63############################################################################### 79###############################################################################
64# 80#
65# void mn10300_dcache_flush_page(unsigned long start) 81# void mn10300_local_dcache_flush_page(unsigned long start)
66# void mn10300_dcache_flush_range(unsigned long start, unsigned long end) 82# void mn10300_local_dcache_flush_range(unsigned long start, unsigned long end)
67# void mn10300_dcache_flush_range2(unsigned long start, unsigned long size) 83# void mn10300_local_dcache_flush_range2(unsigned long start, unsigned long size)
68# Flush a range of addresses on a page in the dcache 84# Flush a range of addresses on a page in the dcache
69# 85#
70############################################################################### 86###############################################################################
71 ALIGN 87 ALIGN
72mn10300_dcache_flush_page: 88 .globl mn10300_local_dcache_flush_page
89 .globl mn10300_local_dcache_flush_range
90 .globl mn10300_local_dcache_flush_range2
91 .type mn10300_local_dcache_flush_page,@function
92 .type mn10300_local_dcache_flush_range,@function
93 .type mn10300_local_dcache_flush_range2,@function
94mn10300_local_dcache_flush_page:
95 and ~(PAGE_SIZE-1),d0
73 mov PAGE_SIZE,d1 96 mov PAGE_SIZE,d1
74mn10300_dcache_flush_range2: 97mn10300_local_dcache_flush_range2:
75 add d0,d1 98 add d0,d1
76mn10300_dcache_flush_range: 99mn10300_local_dcache_flush_range:
77 movm [d2,d3],(sp) 100 movm [d2],(sp)
78 101
79 movhu (CHCTR),d2 102 movhu (CHCTR),d2
80 btst CHCTR_DCEN,d2 103 btst CHCTR_DCEN,d2
81 beq mn10300_dcache_flush_range_end 104 beq mn10300_local_dcache_flush_range_end
105
106 sub d0,d1,a0
107 cmp MN10300_DCACHE_FLUSH_BORDER,a0
108 ble 1f
109
110 movm (sp),[d2]
111 bra mn10300_local_dcache_flush
1121:
82 113
83 # round start addr down 114 # round start addr down
84 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 115 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0
@@ -101,7 +132,7 @@ mn10300_dcache_flush_range:
101 or L1_CACHE_TAG_VALID,a1 # retain valid entries in the 132 or L1_CACHE_TAG_VALID,a1 # retain valid entries in the
102 # cache 133 # cache
103 134
104mn10300_dcache_flush_range_loop: 135mn10300_local_dcache_flush_range_loop:
105 mov a1,(L1_CACHE_WAYDISP*0,a0) # conditionally purge this line 136 mov a1,(L1_CACHE_WAYDISP*0,a0) # conditionally purge this line
106 # all ways 137 # all ways
107 138
@@ -109,55 +140,80 @@ mn10300_dcache_flush_range_loop:
109 add L1_CACHE_BYTES,a1 140 add L1_CACHE_BYTES,a1
110 and ~L1_CACHE_WAYDISP,a0 # make sure way stay on way 0 141 and ~L1_CACHE_WAYDISP,a0 # make sure way stay on way 0
111 add -1,d1 142 add -1,d1
112 bne mn10300_dcache_flush_range_loop 143 bne mn10300_local_dcache_flush_range_loop
144
145mn10300_local_dcache_flush_range_end:
146 ret [d2],4
113 147
114mn10300_dcache_flush_range_end: 148 .size mn10300_local_dcache_flush_page,.-mn10300_local_dcache_flush_page
115 ret [d2,d3],8 149 .size mn10300_local_dcache_flush_range,.-mn10300_local_dcache_flush_range
150 .size mn10300_local_dcache_flush_range2,.-mn10300_local_dcache_flush_range2
116 151
117############################################################################### 152###############################################################################
118# 153#
119# void mn10300_dcache_flush_inv(void) 154# void mn10300_local_dcache_flush_inv(void)
120# Flush the entire data cache and invalidate all entries 155# Flush the entire data cache and invalidate all entries
121# 156#
122############################################################################### 157###############################################################################
123 ALIGN 158 ALIGN
124mn10300_dcache_flush_inv: 159 .globl mn10300_local_dcache_flush_inv
160 .type mn10300_local_dcache_flush_inv,@function
161mn10300_local_dcache_flush_inv:
125 movhu (CHCTR),d0 162 movhu (CHCTR),d0
126 btst CHCTR_DCEN,d0 163 btst CHCTR_DCEN,d0
127 beq mn10300_dcache_flush_inv_end 164 beq mn10300_local_dcache_flush_inv_end
128 165
129 # hit each line in the dcache with an unconditional purge 166 mov L1_CACHE_NENTRIES,d1
130 mov DCACHE_PURGE(0,0),a1 # dcache purge request address 167 clr a1
131 mov L1_CACHE_NWAYS*L1_CACHE_NENTRIES,d1 # total number of entries
132 168
133mn10300_dcache_flush_inv_loop: 169mn10300_local_dcache_flush_inv_loop:
134 mov (a1),d0 # unconditional purge 170 mov (DCACHE_PURGE_WAY0(0),a1),d0 # unconditional purge
171 mov (DCACHE_PURGE_WAY1(0),a1),d0 # unconditional purge
172 mov (DCACHE_PURGE_WAY2(0),a1),d0 # unconditional purge
173 mov (DCACHE_PURGE_WAY3(0),a1),d0 # unconditional purge
135 174
136 add L1_CACHE_BYTES,a1 175 add L1_CACHE_BYTES,a1
137 add -1,d1 176 add -1,d1
138 bne mn10300_dcache_flush_inv_loop 177 bne mn10300_local_dcache_flush_inv_loop
139 178
140mn10300_dcache_flush_inv_end: 179mn10300_local_dcache_flush_inv_end:
141 ret [],0 180 ret [],0
181 .size mn10300_local_dcache_flush_inv,.-mn10300_local_dcache_flush_inv
142 182
143############################################################################### 183###############################################################################
144# 184#
145# void mn10300_dcache_flush_inv_page(unsigned long start) 185# void mn10300_local_dcache_flush_inv_page(unsigned long start)
146# void mn10300_dcache_flush_inv_range(unsigned long start, unsigned long end) 186# void mn10300_local_dcache_flush_inv_range(unsigned long start, unsigned long end)
147# void mn10300_dcache_flush_inv_range2(unsigned long start, unsigned long size) 187# void mn10300_local_dcache_flush_inv_range2(unsigned long start, unsigned long size)
148# Flush and invalidate a range of addresses on a page in the dcache 188# Flush and invalidate a range of addresses on a page in the dcache
149# 189#
150############################################################################### 190###############################################################################
151 ALIGN 191 ALIGN
152mn10300_dcache_flush_inv_page: 192 .globl mn10300_local_dcache_flush_inv_page
193 .globl mn10300_local_dcache_flush_inv_range
194 .globl mn10300_local_dcache_flush_inv_range2
195 .type mn10300_local_dcache_flush_inv_page,@function
196 .type mn10300_local_dcache_flush_inv_range,@function
197 .type mn10300_local_dcache_flush_inv_range2,@function
198mn10300_local_dcache_flush_inv_page:
199 and ~(PAGE_SIZE-1),d0
153 mov PAGE_SIZE,d1 200 mov PAGE_SIZE,d1
154mn10300_dcache_flush_inv_range2: 201mn10300_local_dcache_flush_inv_range2:
155 add d0,d1 202 add d0,d1
156mn10300_dcache_flush_inv_range: 203mn10300_local_dcache_flush_inv_range:
157 movm [d2,d3],(sp) 204 movm [d2],(sp)
205
158 movhu (CHCTR),d2 206 movhu (CHCTR),d2
159 btst CHCTR_DCEN,d2 207 btst CHCTR_DCEN,d2
160 beq mn10300_dcache_flush_inv_range_end 208 beq mn10300_local_dcache_flush_inv_range_end
209
210 sub d0,d1,a0
211 cmp MN10300_DCACHE_FLUSH_INV_BORDER,a0
212 ble 1f
213
214 movm (sp),[d2]
215 bra mn10300_local_dcache_flush_inv
2161:
161 217
162 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 # round start 218 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 # round start
163 # addr down 219 # addr down
@@ -178,7 +234,7 @@ mn10300_dcache_flush_inv_range:
178 lsr L1_CACHE_SHIFT,d1 # total number of entries to 234 lsr L1_CACHE_SHIFT,d1 # total number of entries to
179 # examine 235 # examine
180 236
181mn10300_dcache_flush_inv_range_loop: 237mn10300_local_dcache_flush_inv_range_loop:
182 mov a1,(L1_CACHE_WAYDISP*0,a0) # conditionally purge this line 238 mov a1,(L1_CACHE_WAYDISP*0,a0) # conditionally purge this line
183 # in all ways 239 # in all ways
184 240
@@ -186,7 +242,10 @@ mn10300_dcache_flush_inv_range_loop:
186 add L1_CACHE_BYTES,a1 242 add L1_CACHE_BYTES,a1
187 and ~L1_CACHE_WAYDISP,a0 # make sure way stay on way 0 243 and ~L1_CACHE_WAYDISP,a0 # make sure way stay on way 0
188 add -1,d1 244 add -1,d1
189 bne mn10300_dcache_flush_inv_range_loop 245 bne mn10300_local_dcache_flush_inv_range_loop
190 246
191mn10300_dcache_flush_inv_range_end: 247mn10300_local_dcache_flush_inv_range_end:
192 ret [d2,d3],8 248 ret [d2],4
249 .size mn10300_local_dcache_flush_inv_page,.-mn10300_local_dcache_flush_inv_page
250 .size mn10300_local_dcache_flush_inv_range,.-mn10300_local_dcache_flush_inv_range
251 .size mn10300_local_dcache_flush_inv_range2,.-mn10300_local_dcache_flush_inv_range2
diff --git a/arch/mn10300/mm/cache-inv-by-tag.S b/arch/mn10300/mm/cache-inv-by-tag.S
index e839d0aedd69..e9713b40c0ff 100644
--- a/arch/mn10300/mm/cache-inv-by-tag.S
+++ b/arch/mn10300/mm/cache-inv-by-tag.S
@@ -13,40 +13,65 @@
13#include <asm/smp.h> 13#include <asm/smp.h>
14#include <asm/page.h> 14#include <asm/page.h>
15#include <asm/cache.h> 15#include <asm/cache.h>
16#include <asm/irqflags.h>
17#include <asm/cacheflush.h>
16 18
17#define mn10300_dcache_inv_range_intr_interval \ 19#define mn10300_local_dcache_inv_range_intr_interval \
18 +((1 << MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL) - 1) 20 +((1 << MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL) - 1)
19 21
20#if mn10300_dcache_inv_range_intr_interval > 0xff 22#if mn10300_local_dcache_inv_range_intr_interval > 0xff
21#error MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL must be 8 or less 23#error MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL must be 8 or less
22#endif 24#endif
23 25
24 .am33_2 26 .am33_2
25 27
26 .globl mn10300_icache_inv 28 .globl mn10300_local_icache_inv_page
27 .globl mn10300_dcache_inv 29 .globl mn10300_local_icache_inv_range
28 .globl mn10300_dcache_inv_range 30 .globl mn10300_local_icache_inv_range2
29 .globl mn10300_dcache_inv_range2 31
30 .globl mn10300_dcache_inv_page 32mn10300_local_icache_inv_page = mn10300_local_icache_inv
33mn10300_local_icache_inv_range = mn10300_local_icache_inv
34mn10300_local_icache_inv_range2 = mn10300_local_icache_inv
35
36#ifndef CONFIG_SMP
37 .globl mn10300_icache_inv
38 .globl mn10300_icache_inv_page
39 .globl mn10300_icache_inv_range
40 .globl mn10300_icache_inv_range2
41 .globl mn10300_dcache_inv
42 .globl mn10300_dcache_inv_page
43 .globl mn10300_dcache_inv_range
44 .globl mn10300_dcache_inv_range2
45
46mn10300_icache_inv = mn10300_local_icache_inv
47mn10300_icache_inv_page = mn10300_local_icache_inv_page
48mn10300_icache_inv_range = mn10300_local_icache_inv_range
49mn10300_icache_inv_range2 = mn10300_local_icache_inv_range2
50mn10300_dcache_inv = mn10300_local_dcache_inv
51mn10300_dcache_inv_page = mn10300_local_dcache_inv_page
52mn10300_dcache_inv_range = mn10300_local_dcache_inv_range
53mn10300_dcache_inv_range2 = mn10300_local_dcache_inv_range2
54
55#endif /* !CONFIG_SMP */
31 56
32############################################################################### 57###############################################################################
33# 58#
34# void mn10300_icache_inv(void) 59# void mn10300_local_icache_inv(void)
35# Invalidate the entire icache 60# Invalidate the entire icache
36# 61#
37############################################################################### 62###############################################################################
38 ALIGN 63 ALIGN
39mn10300_icache_inv: 64 .globl mn10300_local_icache_inv
65 .type mn10300_local_icache_inv,@function
66mn10300_local_icache_inv:
40 mov CHCTR,a0 67 mov CHCTR,a0
41 68
42 movhu (a0),d0 69 movhu (a0),d0
43 btst CHCTR_ICEN,d0 70 btst CHCTR_ICEN,d0
44 beq mn10300_icache_inv_end 71 beq mn10300_local_icache_inv_end
45 72
46 mov epsw,d1 73#if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3)
47 and ~EPSW_IE,epsw 74 LOCAL_CLI_SAVE(d1)
48 nop
49 nop
50 75
51 # disable the icache 76 # disable the icache
52 and ~CHCTR_ICEN,d0 77 and ~CHCTR_ICEN,d0
@@ -75,29 +100,36 @@ mn10300_icache_inv:
75 movhu d0,(a0) 100 movhu d0,(a0)
76 movhu (a0),d0 101 movhu (a0),d0
77 102
78 mov d1,epsw 103 LOCAL_IRQ_RESTORE(d1)
104#else /* CONFIG_AM33_2 || CONFIG_AM33_3 */
105 # invalidate
106 or CHCTR_ICINV,d0
107 movhu d0,(a0)
108 movhu (a0),d0
109#endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */
79 110
80mn10300_icache_inv_end: 111mn10300_local_icache_inv_end:
81 ret [],0 112 ret [],0
113 .size mn10300_local_icache_inv,.-mn10300_local_icache_inv
82 114
83############################################################################### 115###############################################################################
84# 116#
85# void mn10300_dcache_inv(void) 117# void mn10300_local_dcache_inv(void)
86# Invalidate the entire dcache 118# Invalidate the entire dcache
87# 119#
88############################################################################### 120###############################################################################
89 ALIGN 121 ALIGN
90mn10300_dcache_inv: 122 .globl mn10300_local_dcache_inv
123 .type mn10300_local_dcache_inv,@function
124mn10300_local_dcache_inv:
91 mov CHCTR,a0 125 mov CHCTR,a0
92 126
93 movhu (a0),d0 127 movhu (a0),d0
94 btst CHCTR_DCEN,d0 128 btst CHCTR_DCEN,d0
95 beq mn10300_dcache_inv_end 129 beq mn10300_local_dcache_inv_end
96 130
97 mov epsw,d1 131#if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3)
98 and ~EPSW_IE,epsw 132 LOCAL_CLI_SAVE(d1)
99 nop
100 nop
101 133
102 # disable the dcache 134 # disable the dcache
103 and ~CHCTR_DCEN,d0 135 and ~CHCTR_DCEN,d0
@@ -126,40 +158,69 @@ mn10300_dcache_inv:
126 movhu d0,(a0) 158 movhu d0,(a0)
127 movhu (a0),d0 159 movhu (a0),d0
128 160
129 mov d1,epsw 161 LOCAL_IRQ_RESTORE(d1)
162#else /* CONFIG_AM33_2 || CONFIG_AM33_3 */
163 # invalidate
164 or CHCTR_DCINV,d0
165 movhu d0,(a0)
166 movhu (a0),d0
167#endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */
130 168
131mn10300_dcache_inv_end: 169mn10300_local_dcache_inv_end:
132 ret [],0 170 ret [],0
171 .size mn10300_local_dcache_inv,.-mn10300_local_dcache_inv
133 172
134############################################################################### 173###############################################################################
135# 174#
136# void mn10300_dcache_inv_range(unsigned start, unsigned end) 175# void mn10300_local_dcache_inv_range(unsigned long start, unsigned long end)
137# void mn10300_dcache_inv_range2(unsigned start, unsigned size) 176# void mn10300_local_dcache_inv_range2(unsigned long start, unsigned long size)
138# void mn10300_dcache_inv_page(unsigned start) 177# void mn10300_local_dcache_inv_page(unsigned long start)
139# Invalidate a range of addresses on a page in the dcache 178# Invalidate a range of addresses on a page in the dcache
140# 179#
141############################################################################### 180###############################################################################
142 ALIGN 181 ALIGN
143mn10300_dcache_inv_page: 182 .globl mn10300_local_dcache_inv_page
183 .globl mn10300_local_dcache_inv_range
184 .globl mn10300_local_dcache_inv_range2
185 .type mn10300_local_dcache_inv_page,@function
186 .type mn10300_local_dcache_inv_range,@function
187 .type mn10300_local_dcache_inv_range2,@function
188mn10300_local_dcache_inv_page:
189 and ~(PAGE_SIZE-1),d0
144 mov PAGE_SIZE,d1 190 mov PAGE_SIZE,d1
145mn10300_dcache_inv_range2: 191mn10300_local_dcache_inv_range2:
146 add d0,d1 192 add d0,d1
147mn10300_dcache_inv_range: 193mn10300_local_dcache_inv_range:
194 # If we are in writeback mode we check the start and end alignments,
195 # and if they're not cacheline-aligned, we must flush any bits outside
196 # the range that share cachelines with stuff inside the range
197#ifdef CONFIG_MN10300_CACHE_WBACK
198 btst ~(L1_CACHE_BYTES-1),d0
199 bne 1f
200 btst ~(L1_CACHE_BYTES-1),d1
201 beq 2f
2021:
203 bra mn10300_local_dcache_flush_inv_range
2042:
205#endif /* CONFIG_MN10300_CACHE_WBACK */
206
148 movm [d2,d3,a2],(sp) 207 movm [d2,d3,a2],(sp)
149 mov CHCTR,a2
150 208
209 mov CHCTR,a2
151 movhu (a2),d2 210 movhu (a2),d2
152 btst CHCTR_DCEN,d2 211 btst CHCTR_DCEN,d2
153 beq mn10300_dcache_inv_range_end 212 beq mn10300_local_dcache_inv_range_end
154 213
214#ifndef CONFIG_MN10300_CACHE_WBACK
155 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 # round start 215 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 # round start
156 # addr down 216 # addr down
157 mov d0,a1
158 217
159 add L1_CACHE_BYTES,d1 # round end addr up 218 add L1_CACHE_BYTES,d1 # round end addr up
160 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1 219 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1
220#endif /* !CONFIG_MN10300_CACHE_WBACK */
221 mov d0,a1
161 222
162 clr d2 # we're going to clear tag ram 223 clr d2 # we're going to clear tag RAM
163 # entries 224 # entries
164 225
165 # read the tags from the tag RAM, and if they indicate a valid dirty 226 # read the tags from the tag RAM, and if they indicate a valid dirty
@@ -176,14 +237,8 @@ mn10300_dcache_inv_range:
176 237
177 and ~(L1_CACHE_DISPARITY-1),a1 # determine comparator base 238 and ~(L1_CACHE_DISPARITY-1),a1 # determine comparator base
178 239
179mn10300_dcache_inv_range_outer_loop: 240mn10300_local_dcache_inv_range_outer_loop:
180 # disable interrupts 241 LOCAL_CLI_SAVE(d3)
181 mov epsw,d3
182 and ~EPSW_IE,epsw
183 nop # note that reading CHCTR and
184 # AND'ing D0 occupy two delay
185 # slots after disabling
186 # interrupts
187 242
188 # disable the dcache 243 # disable the dcache
189 movhu (a2),d0 244 movhu (a2),d0
@@ -196,63 +251,63 @@ mn10300_dcache_inv_range_outer_loop:
196 btst CHCTR_DCBUSY,d0 251 btst CHCTR_DCBUSY,d0
197 lne 252 lne
198 253
199mn10300_dcache_inv_range_loop: 254mn10300_local_dcache_inv_range_loop:
200 255
201 # process the way 0 slot 256 # process the way 0 slot
202 mov (L1_CACHE_WAYDISP*0,a0),d0 # read the tag in the way 0 slot 257 mov (L1_CACHE_WAYDISP*0,a0),d0 # read the tag in the way 0 slot
203 btst L1_CACHE_TAG_VALID,d0 258 btst L1_CACHE_TAG_VALID,d0
204 beq mn10300_dcache_inv_range_skip_0 # jump if this cacheline is not 259 beq mn10300_local_dcache_inv_range_skip_0 # jump if this cacheline
205 # valid 260 # is not valid
206 261
207 xor a1,d0 262 xor a1,d0
208 lsr 12,d0 263 lsr 12,d0
209 bne mn10300_dcache_inv_range_skip_0 # jump if not this cacheline 264 bne mn10300_local_dcache_inv_range_skip_0 # jump if not this cacheline
210 265
211 mov d2,(a0) # kill the tag 266 mov d2,(L1_CACHE_WAYDISP*0,a0) # kill the tag
212 267
213mn10300_dcache_inv_range_skip_0: 268mn10300_local_dcache_inv_range_skip_0:
214 269
215 # process the way 1 slot 270 # process the way 1 slot
216 mov (L1_CACHE_WAYDISP*1,a0),d0 # read the tag in the way 1 slot 271 mov (L1_CACHE_WAYDISP*1,a0),d0 # read the tag in the way 1 slot
217 btst L1_CACHE_TAG_VALID,d0 272 btst L1_CACHE_TAG_VALID,d0
218 beq mn10300_dcache_inv_range_skip_1 # jump if this cacheline is not 273 beq mn10300_local_dcache_inv_range_skip_1 # jump if this cacheline
219 # valid 274 # is not valid
220 275
221 xor a1,d0 276 xor a1,d0
222 lsr 12,d0 277 lsr 12,d0
223 bne mn10300_dcache_inv_range_skip_1 # jump if not this cacheline 278 bne mn10300_local_dcache_inv_range_skip_1 # jump if not this cacheline
224 279
225 mov d2,(a0) # kill the tag 280 mov d2,(L1_CACHE_WAYDISP*1,a0) # kill the tag
226 281
227mn10300_dcache_inv_range_skip_1: 282mn10300_local_dcache_inv_range_skip_1:
228 283
229 # process the way 2 slot 284 # process the way 2 slot
230 mov (L1_CACHE_WAYDISP*2,a0),d0 # read the tag in the way 2 slot 285 mov (L1_CACHE_WAYDISP*2,a0),d0 # read the tag in the way 2 slot
231 btst L1_CACHE_TAG_VALID,d0 286 btst L1_CACHE_TAG_VALID,d0
232 beq mn10300_dcache_inv_range_skip_2 # jump if this cacheline is not 287 beq mn10300_local_dcache_inv_range_skip_2 # jump if this cacheline
233 # valid 288 # is not valid
234 289
235 xor a1,d0 290 xor a1,d0
236 lsr 12,d0 291 lsr 12,d0
237 bne mn10300_dcache_inv_range_skip_2 # jump if not this cacheline 292 bne mn10300_local_dcache_inv_range_skip_2 # jump if not this cacheline
238 293
239 mov d2,(a0) # kill the tag 294 mov d2,(L1_CACHE_WAYDISP*2,a0) # kill the tag
240 295
241mn10300_dcache_inv_range_skip_2: 296mn10300_local_dcache_inv_range_skip_2:
242 297
243 # process the way 3 slot 298 # process the way 3 slot
244 mov (L1_CACHE_WAYDISP*3,a0),d0 # read the tag in the way 3 slot 299 mov (L1_CACHE_WAYDISP*3,a0),d0 # read the tag in the way 3 slot
245 btst L1_CACHE_TAG_VALID,d0 300 btst L1_CACHE_TAG_VALID,d0
246 beq mn10300_dcache_inv_range_skip_3 # jump if this cacheline is not 301 beq mn10300_local_dcache_inv_range_skip_3 # jump if this cacheline
247 # valid 302 # is not valid
248 303
249 xor a1,d0 304 xor a1,d0
250 lsr 12,d0 305 lsr 12,d0
251 bne mn10300_dcache_inv_range_skip_3 # jump if not this cacheline 306 bne mn10300_local_dcache_inv_range_skip_3 # jump if not this cacheline
252 307
253 mov d2,(a0) # kill the tag 308 mov d2,(L1_CACHE_WAYDISP*3,a0) # kill the tag
254 309
255mn10300_dcache_inv_range_skip_3: 310mn10300_local_dcache_inv_range_skip_3:
256 311
257 # approx every N steps we re-enable the cache and see if there are any 312 # approx every N steps we re-enable the cache and see if there are any
258 # interrupts to be processed 313 # interrupts to be processed
@@ -260,9 +315,10 @@ mn10300_dcache_inv_range_skip_3:
260 # (the bottom nibble of the count is zero in both cases) 315 # (the bottom nibble of the count is zero in both cases)
261 add L1_CACHE_BYTES,a0 316 add L1_CACHE_BYTES,a0
262 add L1_CACHE_BYTES,a1 317 add L1_CACHE_BYTES,a1
318 and ~L1_CACHE_WAYDISP,a0
263 add -1,d1 319 add -1,d1
264 btst mn10300_dcache_inv_range_intr_interval,d1 320 btst mn10300_local_dcache_inv_range_intr_interval,d1
265 bne mn10300_dcache_inv_range_loop 321 bne mn10300_local_dcache_inv_range_loop
266 322
267 # wait for the cache to finish what it's doing 323 # wait for the cache to finish what it's doing
268 setlb 324 setlb
@@ -279,11 +335,14 @@ mn10300_dcache_inv_range_skip_3:
279 # - we don't bother with delay NOPs as we'll have enough instructions 335 # - we don't bother with delay NOPs as we'll have enough instructions
280 # before we disable interrupts again to give the interrupts a chance 336 # before we disable interrupts again to give the interrupts a chance
281 # to happen 337 # to happen
282 mov d3,epsw 338 LOCAL_IRQ_RESTORE(d3)
283 339
284 # go around again if the counter hasn't yet reached zero 340 # go around again if the counter hasn't yet reached zero
285 add 0,d1 341 add 0,d1
286 bne mn10300_dcache_inv_range_outer_loop 342 bne mn10300_local_dcache_inv_range_outer_loop
287 343
288mn10300_dcache_inv_range_end: 344mn10300_local_dcache_inv_range_end:
289 ret [d2,d3,a2],12 345 ret [d2,d3,a2],12
346 .size mn10300_local_dcache_inv_page,.-mn10300_local_dcache_inv_page
347 .size mn10300_local_dcache_inv_range,.-mn10300_local_dcache_inv_range
348 .size mn10300_local_dcache_inv_range2,.-mn10300_local_dcache_inv_range2
diff --git a/arch/mn10300/proc-mn103e010/include/proc/cache.h b/arch/mn10300/proc-mn103e010/include/proc/cache.h
index bdc1f9a59b4c..c1528004163c 100644
--- a/arch/mn10300/proc-mn103e010/include/proc/cache.h
+++ b/arch/mn10300/proc-mn103e010/include/proc/cache.h
@@ -30,4 +30,13 @@
30 */ 30 */
31#define MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL 4 31#define MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL 4
32 32
33/*
34 * The size of range at which it becomes more economical to just flush the
35 * whole cache rather than trying to flush the specified range.
36 */
37#define MN10300_DCACHE_FLUSH_BORDER \
38 +(L1_CACHE_NWAYS * L1_CACHE_NENTRIES * L1_CACHE_BYTES)
39#define MN10300_DCACHE_FLUSH_INV_BORDER \
40 +(L1_CACHE_NWAYS * L1_CACHE_NENTRIES * L1_CACHE_BYTES)
41
33#endif /* _ASM_PROC_CACHE_H */ 42#endif /* _ASM_PROC_CACHE_H */