~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/include/asm-mips/r4kcache.h

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * r4kcache.h: Inline assembly cache operations.
  3  *
  4  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  5  *
  6  * $Id: r4kcache.h,v 1.7 1997/12/18 13:00:45 ralf Exp $
  7  *
  8  * FIXME: Handle split L2 caches.
  9  */
 10 #ifndef _MIPS_R4KCACHE_H
 11 #define _MIPS_R4KCACHE_H
 12 
 13 #include <asm/asm.h>
 14 #include <asm/cacheops.h>
 15 
 16 extern inline void flush_icache_line_indexed(unsigned long addr)
 17 {
 18         __asm__ __volatile__(
 19                 ".set noreorder\n\t"
 20                 ".set mips3\n\t"
 21                 "cache %1, (%0)\n\t"
 22                 ".set mips0\n\t"
 23                 ".set reorder"
 24                 :
 25                 : "r" (addr),
 26                   "i" (Index_Invalidate_I));
 27 }
 28 
 29 extern inline void flush_dcache_line_indexed(unsigned long addr)
 30 {
 31         __asm__ __volatile__(
 32                 ".set noreorder\n\t"
 33                 ".set mips3\n\t"
 34                 "cache %1, (%0)\n\t"
 35                 ".set mips0\n\t"
 36                 ".set reorder"
 37                 :
 38                 : "r" (addr),
 39                   "i" (Index_Writeback_Inv_D));
 40 }
 41 
 42 extern inline void flush_scache_line_indexed(unsigned long addr)
 43 {
 44         __asm__ __volatile__(
 45                 ".set noreorder\n\t"
 46                 ".set mips3\n\t"
 47                 "cache %1, (%0)\n\t"
 48                 ".set mips0\n\t"
 49                 ".set reorder"
 50                 :
 51                 : "r" (addr),
 52                   "i" (Index_Writeback_Inv_SD));
 53 }
 54 
 55 extern inline void flush_icache_line(unsigned long addr)
 56 {
 57         __asm__ __volatile__(
 58                 ".set noreorder\n\t"
 59                 ".set mips3\n\t"
 60                 "cache %1, (%0)\n\t"
 61                 ".set mips0\n\t"
 62                 ".set reorder"
 63                 :
 64                 : "r" (addr),
 65                   "i" (Hit_Invalidate_I));
 66 }
 67 
 68 extern inline void flush_dcache_line(unsigned long addr)
 69 {
 70         __asm__ __volatile__(
 71                 ".set noreorder\n\t"
 72                 ".set mips3\n\t"
 73                 "cache %1, (%0)\n\t"
 74                 ".set mips0\n\t"
 75                 ".set reorder"
 76                 :
 77                 : "r" (addr),
 78                   "i" (Hit_Writeback_Inv_D));
 79 }
 80 
 81 extern inline void invalidate_dcache_line(unsigned long addr)
 82 {
 83         __asm__ __volatile__(
 84                 ".set noreorder\n\t"
 85                 ".set mips3\n\t"
 86                 "cache %1, (%0)\n\t"
 87                 ".set mips0\n\t"
 88                 ".set reorder"
 89                 :
 90                 : "r" (addr),
 91                   "i" (Hit_Invalidate_D));
 92 }
 93 
 94 extern inline void invalidate_scache_line(unsigned long addr)
 95 {
 96         __asm__ __volatile__(
 97                 ".set noreorder\n\t"
 98                 ".set mips3\n\t"
 99                 "cache %1, (%0)\n\t"
100                 ".set mips0\n\t"
101                 ".set reorder"
102                 :
103                 : "r" (addr),
104                   "i" (Hit_Invalidate_SD));
105 }
106 
107 extern inline void flush_scache_line(unsigned long addr)
108 {
109         __asm__ __volatile__(
110                 ".set noreorder\n\t"
111                 ".set mips3\n\t"
112                 "cache %1, (%0)\n\t"
113                 ".set mips0\n\t"
114                 ".set reorder"
115                 :
116                 : "r" (addr),
117                   "i" (Hit_Writeback_Inv_SD));
118 }
119 
120 /*
121  * The next two are for badland addresses like signal trampolines.
122  */
123 extern inline void protected_flush_icache_line(unsigned long addr)
124 {
125         __asm__ __volatile__(
126                 ".set noreorder\n\t"
127                 ".set mips3\n"
128                 "1:\tcache %1,(%0)\n"
129                 "2:\t.set mips0\n\t"
130                 ".set reorder\n\t"
131                 ".section\t__ex_table,\"a\"\n\t"
132                 STR(PTR)"\t1b,2b\n\t"
133                 ".previous"
134                 :
135                 : "r" (addr),
136                   "i" (Hit_Invalidate_I));
137 }
138 
139 extern inline void protected_writeback_dcache_line(unsigned long addr)
140 {
141         __asm__ __volatile__(
142                 ".set noreorder\n\t"
143                 ".set mips3\n"
144                 "1:\tcache %1,(%0)\n"
145                 "2:\t.set mips0\n\t"
146                 ".set reorder\n\t"
147                 ".section\t__ex_table,\"a\"\n\t"
148                 STR(PTR)"\t1b,2b\n\t"
149                 ".previous"
150                 :
151                 : "r" (addr),
152                   "i" (Hit_Writeback_D));
153 }
154 
155 #define cache16_unroll32(base,op)                               \
156         __asm__ __volatile__("                                  \
157                 .set noreorder;                                 \
158                 .set mips3;                                     \
159                 cache %1, 0x000(%0); cache %1, 0x010(%0);       \
160                 cache %1, 0x020(%0); cache %1, 0x030(%0);       \
161                 cache %1, 0x040(%0); cache %1, 0x050(%0);       \
162                 cache %1, 0x060(%0); cache %1, 0x070(%0);       \
163                 cache %1, 0x080(%0); cache %1, 0x090(%0);       \
164                 cache %1, 0x0a0(%0); cache %1, 0x0b0(%0);       \
165                 cache %1, 0x0c0(%0); cache %1, 0x0d0(%0);       \
166                 cache %1, 0x0e0(%0); cache %1, 0x0f0(%0);       \
167                 cache %1, 0x100(%0); cache %1, 0x110(%0);       \
168                 cache %1, 0x120(%0); cache %1, 0x130(%0);       \
169                 cache %1, 0x140(%0); cache %1, 0x150(%0);       \
170                 cache %1, 0x160(%0); cache %1, 0x170(%0);       \
171                 cache %1, 0x180(%0); cache %1, 0x190(%0);       \
172                 cache %1, 0x1a0(%0); cache %1, 0x1b0(%0);       \
173                 cache %1, 0x1c0(%0); cache %1, 0x1d0(%0);       \
174                 cache %1, 0x1e0(%0); cache %1, 0x1f0(%0);       \
175                 .set mips0;                                     \
176                 .set reorder"                                   \
177                 :                                               \
178                 : "r" (base),                                   \
179                   "i" (op));
180 
181 extern inline void blast_dcache16(void)
182 {
183         unsigned long start = KSEG0;
184         unsigned long end = (start + dcache_size);
185 
186         while(start < end) {
187                 cache16_unroll32(start,Index_Writeback_Inv_D);
188                 start += 0x200;
189         }
190 }
191 
192 extern inline void blast_dcache16_page(unsigned long page)
193 {
194         unsigned long start = page;
195         unsigned long end = (start + PAGE_SIZE);
196 
197         while(start < end) {
198                 cache16_unroll32(start,Hit_Writeback_Inv_D);
199                 start += 0x200;
200         }
201 }
202 
203 extern inline void blast_dcache16_page_indexed(unsigned long page)
204 {
205         unsigned long start = page;
206         unsigned long end = (start + PAGE_SIZE);
207 
208         while(start < end) {
209                 cache16_unroll32(start,Index_Writeback_Inv_D);
210                 start += 0x200;
211         }
212 }
213 
214 extern inline void blast_icache16(void)
215 {
216         unsigned long start = KSEG0;
217         unsigned long end = (start + icache_size);
218 
219         while(start < end) {
220                 cache16_unroll32(start,Index_Invalidate_I);
221                 start += 0x200;
222         }
223 }
224 
225 extern inline void blast_icache16_page(unsigned long page)
226 {
227         unsigned long start = page;
228         unsigned long end = (start + PAGE_SIZE);
229 
230         while(start < end) {
231                 cache16_unroll32(start,Hit_Invalidate_I);
232                 start += 0x200;
233         }
234 }
235 
236 extern inline void blast_icache16_page_indexed(unsigned long page)
237 {
238         unsigned long start = page;
239         unsigned long end = (start + PAGE_SIZE);
240 
241         while(start < end) {
242                 cache16_unroll32(start,Index_Invalidate_I);
243                 start += 0x200;
244         }
245 }
246 
247 extern inline void blast_scache16(void)
248 {
249         unsigned long start = KSEG0;
250         unsigned long end = KSEG0 + scache_size;
251 
252         while(start < end) {
253                 cache16_unroll32(start,Index_Writeback_Inv_SD);
254                 start += 0x200;
255         }
256 }
257 
258 extern inline void blast_scache16_page(unsigned long page)
259 {
260         unsigned long start = page;
261         unsigned long end = page + PAGE_SIZE;
262 
263         while(start < end) {
264                 cache16_unroll32(start,Hit_Writeback_Inv_SD);
265                 start += 0x200;
266         }
267 }
268 
269 extern inline void blast_scache16_page_indexed(unsigned long page)
270 {
271         unsigned long start = page;
272         unsigned long end = page + PAGE_SIZE;
273 
274         while(start < end) {
275                 cache16_unroll32(start,Index_Writeback_Inv_SD);
276                 start += 0x200;
277         }
278 }
279 
280 #define cache32_unroll32(base,op)                               \
281         __asm__ __volatile__("                                  \
282                 .set noreorder;                                 \
283                 .set mips3;                                     \
284                 cache %1, 0x000(%0); cache %1, 0x020(%0);       \
285                 cache %1, 0x040(%0); cache %1, 0x060(%0);       \
286                 cache %1, 0x080(%0); cache %1, 0x0a0(%0);       \
287                 cache %1, 0x0c0(%0); cache %1, 0x0e0(%0);       \
288                 cache %1, 0x100(%0); cache %1, 0x120(%0);       \
289                 cache %1, 0x140(%0); cache %1, 0x160(%0);       \
290                 cache %1, 0x180(%0); cache %1, 0x1a0(%0);       \
291                 cache %1, 0x1c0(%0); cache %1, 0x1e0(%0);       \
292                 cache %1, 0x200(%0); cache %1, 0x220(%0);       \
293                 cache %1, 0x240(%0); cache %1, 0x260(%0);       \
294                 cache %1, 0x280(%0); cache %1, 0x2a0(%0);       \
295                 cache %1, 0x2c0(%0); cache %1, 0x2e0(%0);       \
296                 cache %1, 0x300(%0); cache %1, 0x320(%0);       \
297                 cache %1, 0x340(%0); cache %1, 0x360(%0);       \
298                 cache %1, 0x380(%0); cache %1, 0x3a0(%0);       \
299                 cache %1, 0x3c0(%0); cache %1, 0x3e0(%0);       \
300                 .set mips0;                                     \
301                 .set reorder"                                   \
302                 :                                               \
303                 : "r" (base),                                   \
304                   "i" (op));
305 
306 extern inline void blast_dcache32(void)
307 {
308         unsigned long start = KSEG0;
309         unsigned long end = (start + dcache_size);
310 
311         while(start < end) {
312                 cache32_unroll32(start,Index_Writeback_Inv_D);
313                 start += 0x400;
314         }
315 }
316 
317 /*
318  * Call this function only with interrupts disabled or R4600 V2.0 may blow
319  * up on you.
320  *
321  * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Inv_D,
322  * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Excl_D will only
323  * operate correctly if the internal data cache refill buffer is empty.  These
324  * CACHE instructions should be separated from any potential data cache miss
325  * by a load instruction to an uncached address to empty the response buffer."
326  * (Revision 2.0 device errata from IDT available on http://www.idt.com/
327  * in .pdf format.)
328  */
329 extern inline void blast_dcache32_page(unsigned long page)
330 {
331         unsigned long start = page;
332         unsigned long end = (start + PAGE_SIZE);
333 
334         /*
335          * Sigh ... workaround for R4600 v1.7 bug.  Explanation see above.
336          */
337         *(volatile unsigned long *)KSEG1;
338 
339         __asm__ __volatile__("nop;nop;nop;nop");
340         while(start < end) {
341                 cache32_unroll32(start,Hit_Writeback_Inv_D);
342                 start += 0x400;
343         }
344 }
345 
346 extern inline void blast_dcache32_page_indexed(unsigned long page)
347 {
348         unsigned long start = page;
349         unsigned long end = (start + PAGE_SIZE);
350 
351         while(start < end) {
352                 cache32_unroll32(start,Index_Writeback_Inv_D);
353                 start += 0x400;
354         }
355 }
356 
357 extern inline void blast_icache32(void)
358 {
359         unsigned long start = KSEG0;
360         unsigned long end = (start + icache_size);
361 
362         while(start < end) {
363                 cache32_unroll32(start,Index_Invalidate_I);
364                 start += 0x400;
365         }
366 }
367 
368 extern inline void blast_icache32_page(unsigned long page)
369 {
370         unsigned long start = page;
371         unsigned long end = (start + PAGE_SIZE);
372 
373         while(start < end) {
374                 cache32_unroll32(start,Hit_Invalidate_I);
375                 start += 0x400;
376         }
377 }
378 
379 extern inline void blast_icache32_page_indexed(unsigned long page)
380 {
381         unsigned long start = page;
382         unsigned long end = (start + PAGE_SIZE);
383 
384         while(start < end) {
385                 cache32_unroll32(start,Index_Invalidate_I);
386                 start += 0x400;
387         }
388 }
389 
390 extern inline void blast_scache32(void)
391 {
392         unsigned long start = KSEG0;
393         unsigned long end = KSEG0 + scache_size;
394 
395         while(start < end) {
396                 cache32_unroll32(start,Index_Writeback_Inv_SD);
397                 start += 0x400;
398         }
399 }
400 
401 extern inline void blast_scache32_page(unsigned long page)
402 {
403         unsigned long start = page;
404         unsigned long end = page + PAGE_SIZE;
405 
406         while(start < end) {
407                 cache32_unroll32(start,Hit_Writeback_Inv_SD);
408                 start += 0x400;
409         }
410 }
411 
412 extern inline void blast_scache32_page_indexed(unsigned long page)
413 {
414         unsigned long start = page;
415         unsigned long end = page + PAGE_SIZE;
416 
417         while(start < end) {
418                 cache32_unroll32(start,Index_Writeback_Inv_SD);
419                 start += 0x400;
420         }
421 }
422 
423 #define cache64_unroll32(base,op)                               \
424         __asm__ __volatile__("                                  \
425                 .set noreorder;                                 \
426                 .set mips3;                                     \
427                 cache %1, 0x000(%0); cache %1, 0x040(%0);       \
428                 cache %1, 0x080(%0); cache %1, 0x0c0(%0);       \
429                 cache %1, 0x100(%0); cache %1, 0x140(%0);       \
430                 cache %1, 0x180(%0); cache %1, 0x1c0(%0);       \
431                 cache %1, 0x200(%0); cache %1, 0x240(%0);       \
432                 cache %1, 0x280(%0); cache %1, 0x2c0(%0);       \
433                 cache %1, 0x300(%0); cache %1, 0x340(%0);       \
434                 cache %1, 0x380(%0); cache %1, 0x3c0(%0);       \
435                 cache %1, 0x400(%0); cache %1, 0x440(%0);       \
436                 cache %1, 0x480(%0); cache %1, 0x4c0(%0);       \
437                 cache %1, 0x500(%0); cache %1, 0x540(%0);       \
438                 cache %1, 0x580(%0); cache %1, 0x5c0(%0);       \
439                 cache %1, 0x600(%0); cache %1, 0x640(%0);       \
440                 cache %1, 0x680(%0); cache %1, 0x6c0(%0);       \
441                 cache %1, 0x700(%0); cache %1, 0x740(%0);       \
442                 cache %1, 0x780(%0); cache %1, 0x7c0(%0);       \
443                 .set mips0;                                     \
444                 .set reorder"                                   \
445                 :                                               \
446                 : "r" (base),                                   \
447                   "i" (op));
448 
449 extern inline void blast_scache64(void)
450 {
451         unsigned long start = KSEG0;
452         unsigned long end = KSEG0 + scache_size;
453 
454         while(start < end) {
455                 cache64_unroll32(start,Index_Writeback_Inv_SD);
456                 start += 0x800;
457         }
458 }
459 
460 extern inline void blast_scache64_page(unsigned long page)
461 {
462         unsigned long start = page;
463         unsigned long end = page + PAGE_SIZE;
464 
465         while(start < end) {
466                 cache64_unroll32(start,Hit_Writeback_Inv_SD);
467                 start += 0x800;
468         }
469 }
470 
471 extern inline void blast_scache64_page_indexed(unsigned long page)
472 {
473         unsigned long start = page;
474         unsigned long end = page + PAGE_SIZE;
475 
476         while(start < end) {
477                 cache64_unroll32(start,Index_Writeback_Inv_SD);
478                 start += 0x800;
479         }
480 }
481 
482 #define cache128_unroll32(base,op)                              \
483         __asm__ __volatile__("                                  \
484                 .set noreorder;                                 \
485                 .set mips3;                                     \
486                 cache %1, 0x000(%0); cache %1, 0x080(%0);       \
487                 cache %1, 0x100(%0); cache %1, 0x180(%0);       \
488                 cache %1, 0x200(%0); cache %1, 0x280(%0);       \
489                 cache %1, 0x300(%0); cache %1, 0x380(%0);       \
490                 cache %1, 0x400(%0); cache %1, 0x480(%0);       \
491                 cache %1, 0x500(%0); cache %1, 0x580(%0);       \
492                 cache %1, 0x600(%0); cache %1, 0x680(%0);       \
493                 cache %1, 0x700(%0); cache %1, 0x780(%0);       \
494                 cache %1, 0x800(%0); cache %1, 0x880(%0);       \
495                 cache %1, 0x900(%0); cache %1, 0x980(%0);       \
496                 cache %1, 0xa00(%0); cache %1, 0xa80(%0);       \
497                 cache %1, 0xb00(%0); cache %1, 0xb80(%0);       \
498                 cache %1, 0xc00(%0); cache %1, 0xc80(%0);       \
499                 cache %1, 0xd00(%0); cache %1, 0xd80(%0);       \
500                 cache %1, 0xe00(%0); cache %1, 0xe80(%0);       \
501                 cache %1, 0xf00(%0); cache %1, 0xf80(%0);       \
502                 .set mips0;                                     \
503                 .set reorder"                                   \
504                 :                                               \
505                 : "r" (base),                                   \
506                   "i" (op));
507 
508 extern inline void blast_scache128(void)
509 {
510         unsigned long start = KSEG0;
511         unsigned long end = KSEG0 + scache_size;
512 
513         while(start < end) {
514                 cache128_unroll32(start,Index_Writeback_Inv_SD);
515                 start += 0x1000;
516         }
517 }
518 
519 extern inline void blast_scache128_page(unsigned long page)
520 {
521         cache128_unroll32(page,Hit_Writeback_Inv_SD);
522 }
523 
524 extern inline void blast_scache128_page_indexed(unsigned long page)
525 {
526         cache128_unroll32(page,Index_Writeback_Inv_SD);
527 }
528 
529 #endif /* !(_MIPS_R4KCACHE_H) */
530 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.