1 /* $Id: r10kcache.h,v 1.1 2000/01/16 01:27:14 ralf Exp $
2 *
3 * This file is subject to the terms and conditions of the GNU General Public
4 * License. See the file "COPYING" in the main directory of this archive
5 * for more details.
6 *
7 * Inline assembly cache operations.
8 *
9 * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
10 * Copyright (C) 1999 Ralf Baechle
11 * Copyright (C) 1999 Silicon Graphics, Inc.
12 *
13 * FIXME: Handle split L2 caches.
14 */
15 #ifndef _ASM_R10KCACHE_H
16 #define _ASM_R10KCACHE_H
17
18 #include <asm/asm.h>
19 #include <asm/r10kcacheops.h>
20
21 /* These are fixed for the current R10000. */
22 #define icache_size 0x8000
23 #define dcache_size 0x8000
24 #define icache_way_size 0x4000
25 #define dcache_way_size 0x4000
26 #define ic_lsize 64
27 #define dc_lsize 32
28
29 /* These are configuration dependant. */
30 #define scache_size() ({ \
31 unsigned long __res; \
32 __res = (read_32bit_cp0_register(CP0_CONFIG) >> 16) & 3; \
33 __res = 1 << (__res + 19); \
34 __res; \
35 })
36
37 #define sc_lsize() ({ \
38 unsigned long __res; \
39 __res = (read_32bit_cp0_register(CP0_CONFIG) >> 13) & 1; \
40 __res = 1 << (__res + 6); \
41 __res; \
42 })
43
44 extern inline void flush_icache_line_indexed(unsigned long addr)
45 {
46 __asm__ __volatile__(
47 ".set noreorder\n\t"
48 "cache %1, (%0)\n\t"
49 ".set reorder"
50 :
51 : "r" (addr), "i" (Index_Invalidate_I));
52 }
53
54 extern inline void flush_dcache_line_indexed(unsigned long addr)
55 {
56 __asm__ __volatile__(
57 ".set noreorder\n\t"
58 "cache %1, (%0)\n\t"
59 ".set reorder"
60 :
61 : "r" (addr), "i" (Index_Writeback_Inv_D));
62 }
63
64 extern inline void flush_scache_line_indexed(unsigned long addr)
65 {
66 __asm__ __volatile__(
67 ".set noreorder\n\t"
68 "cache %1, (%0)\n\t"
69 ".set reorder"
70 :
71 : "r" (addr), "i" (Index_Writeback_Inv_S));
72 }
73
74 extern inline void flush_icache_line(unsigned long addr)
75 {
76 __asm__ __volatile__(
77 ".set noreorder\n\t"
78 "cache %1, (%0)\n\t"
79 ".set reorder"
80 :
81 : "r" (addr), "i" (Hit_Invalidate_I));
82 }
83
84 extern inline void flush_dcache_line(unsigned long addr)
85 {
86 __asm__ __volatile__(
87 ".set noreorder\n\t"
88 "cache %1, (%0)\n\t"
89 ".set reorder"
90 :
91 : "r" (addr), "i" (Hit_Writeback_Inv_D));
92 }
93
94 extern inline void invalidate_dcache_line(unsigned long addr)
95 {
96 __asm__ __volatile__(
97 ".set noreorder\n\t"
98 "cache %1, (%0)\n\t"
99 ".set reorder"
100 :
101 : "r" (addr), "i" (Hit_Invalidate_D));
102 }
103
104 extern inline void invalidate_scache_line(unsigned long addr)
105 {
106 __asm__ __volatile__(
107 ".set noreorder\n\t"
108 "cache %1, (%0)\n\t"
109 ".set reorder"
110 :
111 : "r" (addr), "i" (Hit_Invalidate_S));
112 }
113
114 extern inline void flush_scache_line(unsigned long addr)
115 {
116 __asm__ __volatile__(
117 ".set noreorder\n\t"
118 "cache %1, (%0)\n\t"
119 ".set reorder"
120 :
121 : "r" (addr), "i" (Hit_Writeback_Inv_S));
122 }
123
124 /*
125 * The next two are for badland addresses like signal trampolines.
126 */
127 extern inline void protected_flush_icache_line(unsigned long addr)
128 {
129 __asm__ __volatile__(
130 ".set noreorder\n\t"
131 "1:\tcache %1,(%0)\n"
132 "2:\t.set reorder\n\t"
133 ".section\t__ex_table,\"a\"\n\t"
134 ".dword\t1b,2b\n\t"
135 ".previous"
136 :
137 : "r" (addr), "i" (Hit_Invalidate_I));
138 }
139
140 extern inline void protected_writeback_dcache_line(unsigned long addr)
141 {
142 __asm__ __volatile__(
143 ".set noreorder\n\t"
144 "1:\tcache %1,(%0)\n"
145 "2:\t.set reorder\n\t"
146 ".section\t__ex_table,\"a\"\n\t"
147 ".dword\t1b,2b\n\t"
148 ".previous"
149 :
150 : "r" (addr), "i" (Hit_Writeback_Inv_D));
151 }
152
153 #define cache32_unroll16(base,op) \
154 __asm__ __volatile__(" \
155 .set noreorder; \
156 cache %1, 0x000(%0); cache %1, 0x020(%0); \
157 cache %1, 0x040(%0); cache %1, 0x060(%0); \
158 cache %1, 0x080(%0); cache %1, 0x0a0(%0); \
159 cache %1, 0x0c0(%0); cache %1, 0x0e0(%0); \
160 cache %1, 0x100(%0); cache %1, 0x120(%0); \
161 cache %1, 0x140(%0); cache %1, 0x160(%0); \
162 cache %1, 0x180(%0); cache %1, 0x1a0(%0); \
163 cache %1, 0x1c0(%0); cache %1, 0x1e0(%0); \
164 .set reorder" \
165 : \
166 : "r" (base), \
167 "i" (op));
168
169 #define cache32_unroll32(base,op) \
170 __asm__ __volatile__(" \
171 .set noreorder; \
172 cache %1, 0x000(%0); cache %1, 0x020(%0); \
173 cache %1, 0x040(%0); cache %1, 0x060(%0); \
174 cache %1, 0x080(%0); cache %1, 0x0a0(%0); \
175 cache %1, 0x0c0(%0); cache %1, 0x0e0(%0); \
176 cache %1, 0x100(%0); cache %1, 0x120(%0); \
177 cache %1, 0x140(%0); cache %1, 0x160(%0); \
178 cache %1, 0x180(%0); cache %1, 0x1a0(%0); \
179 cache %1, 0x1c0(%0); cache %1, 0x1e0(%0); \
180 cache %1, 0x200(%0); cache %1, 0x220(%0); \
181 cache %1, 0x240(%0); cache %1, 0x260(%0); \
182 cache %1, 0x280(%0); cache %1, 0x2a0(%0); \
183 cache %1, 0x2c0(%0); cache %1, 0x2e0(%0); \
184 cache %1, 0x300(%0); cache %1, 0x320(%0); \
185 cache %1, 0x340(%0); cache %1, 0x360(%0); \
186 cache %1, 0x380(%0); cache %1, 0x3a0(%0); \
187 cache %1, 0x3c0(%0); cache %1, 0x3e0(%0); \
188 .set reorder" \
189 : \
190 : "r" (base), \
191 "i" (op));
192
193 extern inline void blast_dcache32(void)
194 {
195 unsigned long way0 = KSEG0;
196 unsigned long way1 = way0 ^ 1;
197 unsigned long end = (way0 + dcache_way_size);
198
199 while (way0 < end) {
200 cache32_unroll16(way0, Index_Writeback_Inv_D);
201 cache32_unroll16(way1, Index_Writeback_Inv_D);
202 way0 += 0x200;
203 way1 += 0x200;
204 }
205 }
206
207 extern inline void blast_dcache32_page(unsigned long page)
208 {
209 unsigned long start = page;
210 unsigned long end = page + PAGE_SIZE;
211
212 while (start < end) {
213 cache32_unroll32(start, Hit_Writeback_Inv_D);
214 start += 0x400;
215 }
216 }
217
218 extern inline void blast_dcache32_page_indexed(unsigned long page)
219 {
220 unsigned long way0 = page;
221 unsigned long way1 = page ^ 1;
222 unsigned long end = page + PAGE_SIZE;
223
224 while (way0 < end) {
225 cache32_unroll16(way0, Index_Writeback_Inv_D);
226 cache32_unroll16(way1, Index_Writeback_Inv_D);
227 way0 += 0x200;
228 way1 += 0x200;
229 }
230 }
231
232 #define cache64_unroll16(base,op) \
233 __asm__ __volatile__(" \
234 .set noreorder; \
235 cache %1, 0x000(%0); cache %1, 0x040(%0); \
236 cache %1, 0x080(%0); cache %1, 0x0c0(%0); \
237 cache %1, 0x100(%0); cache %1, 0x140(%0); \
238 cache %1, 0x180(%0); cache %1, 0x1c0(%0); \
239 cache %1, 0x200(%0); cache %1, 0x240(%0); \
240 cache %1, 0x280(%0); cache %1, 0x2c0(%0); \
241 cache %1, 0x300(%0); cache %1, 0x340(%0); \
242 cache %1, 0x380(%0); cache %1, 0x3c0(%0); \
243 .set reorder" \
244 : \
245 : "r" (base), \
246 "i" (op));
247
248 #define cache64_unroll32(base,op) \
249 __asm__ __volatile__(" \
250 .set noreorder; \
251 cache %1, 0x000(%0); cache %1, 0x040(%0); \
252 cache %1, 0x080(%0); cache %1, 0x0c0(%0); \
253 cache %1, 0x100(%0); cache %1, 0x140(%0); \
254 cache %1, 0x180(%0); cache %1, 0x1c0(%0); \
255 cache %1, 0x200(%0); cache %1, 0x240(%0); \
256 cache %1, 0x280(%0); cache %1, 0x2c0(%0); \
257 cache %1, 0x300(%0); cache %1, 0x340(%0); \
258 cache %1, 0x380(%0); cache %1, 0x3c0(%0); \
259 cache %1, 0x400(%0); cache %1, 0x440(%0); \
260 cache %1, 0x480(%0); cache %1, 0x4c0(%0); \
261 cache %1, 0x500(%0); cache %1, 0x540(%0); \
262 cache %1, 0x580(%0); cache %1, 0x5c0(%0); \
263 cache %1, 0x600(%0); cache %1, 0x640(%0); \
264 cache %1, 0x680(%0); cache %1, 0x6c0(%0); \
265 cache %1, 0x700(%0); cache %1, 0x740(%0); \
266 cache %1, 0x780(%0); cache %1, 0x7c0(%0); \
267 .set reorder" \
268 : \
269 : "r" (base), \
270 "i" (op));
271
272 extern inline void blast_icache64(void)
273 {
274 unsigned long way0 = KSEG0;
275 unsigned long way1 = way0 ^ 1;
276 unsigned long end = way0 + icache_way_size;
277
278 while (way0 < end) {
279 cache64_unroll16(way0,Index_Invalidate_I);
280 cache64_unroll16(way1,Index_Invalidate_I);
281 way0 += 0x400;
282 way1 += 0x400;
283 }
284 }
285
286 extern inline void blast_icache64_page(unsigned long page)
287 {
288 unsigned long start = page;
289 unsigned long end = page + PAGE_SIZE;
290
291 while (start < end) {
292 cache64_unroll32(start,Hit_Invalidate_I);
293 start += 0x800;
294 }
295 }
296
297 extern inline void blast_icache64_page_indexed(unsigned long page)
298 {
299 unsigned long way0 = page;
300 unsigned long way1 = page ^ 1;
301 unsigned long end = page + PAGE_SIZE;
302
303 while (way0 < end) {
304 cache64_unroll16(way0,Index_Invalidate_I);
305 cache64_unroll16(way1,Index_Invalidate_I);
306 way0 += 0x400;
307 way1 += 0x400;
308 }
309 }
310
311 extern inline void blast_scache64(void)
312 {
313 unsigned long way0 = KSEG0;
314 unsigned long way1 = way0 ^ 1;
315 unsigned long end = KSEG0 + scache_size();
316
317 while (way0 < end) {
318 cache64_unroll16(way0,Index_Writeback_Inv_S);
319 cache64_unroll16(way1,Index_Writeback_Inv_S);
320 way0 += 0x400;
321 way1 += 0x400;
322 }
323 }
324
325 extern inline void blast_scache64_page(unsigned long page)
326 {
327 unsigned long start = page;
328 unsigned long end = page + PAGE_SIZE;
329
330 while (start < end) {
331 cache64_unroll32(start,Hit_Writeback_Inv_S);
332 start += 0x800;
333 }
334 }
335
336 extern inline void blast_scache64_page_indexed(unsigned long page)
337 {
338 unsigned long way0 = page;
339 unsigned long way1 = page ^ 1;
340 unsigned long end = page + PAGE_SIZE;
341
342 while (way0 < end) {
343 cache64_unroll16(way0,Index_Writeback_Inv_S);
344 cache64_unroll16(way1,Index_Writeback_Inv_S);
345 way0 += 0x400;
346 way1 += 0x400;
347 }
348 }
349
350 #define cache128_unroll16(base,op) \
351 __asm__ __volatile__(" \
352 .set noreorder; \
353 cache %1, 0x000(%0); cache %1, 0x080(%0); \
354 cache %1, 0x100(%0); cache %1, 0x180(%0); \
355 cache %1, 0x200(%0); cache %1, 0x280(%0); \
356 cache %1, 0x300(%0); cache %1, 0x380(%0); \
357 cache %1, 0x400(%0); cache %1, 0x480(%0); \
358 cache %1, 0x500(%0); cache %1, 0x580(%0); \
359 cache %1, 0x600(%0); cache %1, 0x680(%0); \
360 cache %1, 0x700(%0); cache %1, 0x780(%0); \
361 .set reorder" \
362 : \
363 : "r" (base), \
364 "i" (op));
365
366 #define cache128_unroll32(base,op) \
367 __asm__ __volatile__(" \
368 .set noreorder; \
369 cache %1, 0x000(%0); cache %1, 0x080(%0); \
370 cache %1, 0x100(%0); cache %1, 0x180(%0); \
371 cache %1, 0x200(%0); cache %1, 0x280(%0); \
372 cache %1, 0x300(%0); cache %1, 0x380(%0); \
373 cache %1, 0x400(%0); cache %1, 0x480(%0); \
374 cache %1, 0x500(%0); cache %1, 0x580(%0); \
375 cache %1, 0x600(%0); cache %1, 0x680(%0); \
376 cache %1, 0x700(%0); cache %1, 0x780(%0); \
377 cache %1, 0x800(%0); cache %1, 0x880(%0); \
378 cache %1, 0x900(%0); cache %1, 0x980(%0); \
379 cache %1, 0xa00(%0); cache %1, 0xa80(%0); \
380 cache %1, 0xb00(%0); cache %1, 0xb80(%0); \
381 cache %1, 0xc00(%0); cache %1, 0xc80(%0); \
382 cache %1, 0xd00(%0); cache %1, 0xd80(%0); \
383 cache %1, 0xe00(%0); cache %1, 0xe80(%0); \
384 cache %1, 0xf00(%0); cache %1, 0xf80(%0); \
385 .set reorder" \
386 : \
387 : "r" (base), \
388 "i" (op));
389
390 extern inline void blast_scache128(void)
391 {
392 unsigned long way0 = KSEG0;
393 unsigned long way1 = way0 ^ 1;
394 unsigned long end = way0 + scache_size();
395
396 while (way0 < end) {
397 cache128_unroll16(way0, Index_Writeback_Inv_S);
398 cache128_unroll16(way1, Index_Writeback_Inv_S);
399 way0 += 0x800;
400 way1 += 0x800;
401 }
402 }
403
404 extern inline void blast_scache128_page(unsigned long page)
405 {
406 cache128_unroll32(page, Hit_Writeback_Inv_S);
407 }
408
409 extern inline void blast_scache128_page_indexed(unsigned long page)
410 {
411 cache128_unroll32(page , Index_Writeback_Inv_S);
412 cache128_unroll32(page ^ 1, Index_Writeback_Inv_S);
413 }
414
415 #endif /* _ASM_R10KCACHE_H */
416
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.