Annotation of sys/arch/mips64/mips64/cache_r10k.S, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: cache_r10k.S,v 1.5 2007/06/18 20:25:55 miod Exp $ */
2:
3: /*
4: * Copyright (c) 2004 Opsycon AB (www.opsycon.se)
5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: * 1. Redistributions of source code must retain the above copyright
10: * notice, this list of conditions and the following disclaimer.
11: * 2. Redistributions in binary form must reproduce the above copyright
12: * notice, this list of conditions and the following disclaimer in the
13: * documentation and/or other materials provided with the distribution.
14: *
15: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
16: * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25: * SUCH DAMAGE.
26: *
27: */
28:
29: /*
30: * Processors supported:
31: * R10000
32: * R12000
33: * R14000 (needs to be tested)
34: */
35:
36: #include <sys/errno.h>
37: #include <sys/syscall.h>
38:
39: #include <machine/param.h>
40: #include <machine/psl.h>
41: #include <machine/asm.h>
42: #include <machine/cpu.h>
43: #include <machine/regnum.h>
44: #include <machine/pte.h>
45:
46: #include "assym.h"
47:
48: .set mips3
49:
50: #define LOAD_XKPHYS(reg, cca) \
51: li reg, cca | 0x10; \
52: dsll reg, reg, 59
53:
54: /*
55: * Skip the .h file. Noone else need to know!
56: */
57:
58: #define IndexInvalidate_I 0x00
59: #define IndexWBInvalidate_D 0x01
60: #define IndexFlashInvalidate_T 0x02
61: #define IndexWBInvalidate_S 0x03
62:
63: #define IndexLoadTag_I 0x04
64: #define IndexLoadTag_D 0x05
65: #define IndexLoadTag_S 0x07
66:
67: #define IndexStoreTag_I 0x08
68: #define IndexStoreTag_D 0x09
69: #define IndexStoreTag_S 0x0b
70:
71: #define CreateDirtyExclusive 0x09
72:
73: #define HitInvalidate_I 0x10
74: #define HitInvalidate_D 0x11
75: #define HitInvalidate_S 0x13
76:
77: #define Fill_I 0x14
78: #define HitWBInvalidate_D 0x15
79: #define HitWBInvalidate_S 0x17
80:
81: #define HitWB_I 0x18
82: #define HitWB_D 0x19
83: #define HitWB_S 0x1b
84:
85: /*
86: * Define cache type definition bits. NOTE! the 3 lsb may NOT change!
87: */
88: #define CTYPE_DIR 0x0001 /* Cache is direct mapped */
89: #define CTYPE_2WAY 0x0002 /* Cache is TWO way */
90: #define CTYPE_4WAY 0x0004 /* Cache is FOUR way */
91: #define CTYPE_WAYMASK 0x0007
92:
93: #define CTYPE_HAS_IL2 0x0100 /* Internal L2 Cache present */
94: #define CTYPE_HAS_XL2 0x0200 /* External L2 Cache present */
95: #define CTYPE_HAS_XL3 0x0400 /* External L3 Cache present */
96:
97: .set noreorder # Noreorder is default style!
98:
99: /*----------------------------------------------------------------------------
100: *
101: * Mips10k_ConfigCache --
102: *
103: * Size and configure the caches.
104: * NOTE: should only be called from mips_init().
105: *
106: * Results:
107: * Returns the value of the cpu configuration register.
108: *
109: * Side effects:
110: * The size of the data cache is stored into CpuPrimaryDataCacheSize.
111: * The size of instruction cache is stored into CpuPrimaryInstCacheSize.
112: * Alignment mask for cache aliasing test is stored in CpuCacheAliasMask.
113: * CpuSecondaryCacheSize is set to the size of the secondary cache.
114: * CpuTertiaryCacheSize is set to the size of the tertiary cache.
115: * CpuNWayCache is set to 0 for direct mapped caches, 2 for two way
116: * caches and 4 for four way caches. This primarily indicates the
117: * primary cache associativity.
118: *
119: * Allocation:
120: * ta0, ta1 ta2 used to hold I and D set size and Alias mask.
121: *
122: *----------------------------------------------------------------------------
123: */
124: LEAF(Mips10k_ConfigCache, 0)
125: .set noreorder
126: mfc0 v0, COP_0_CONFIG # Get configuration register
127:
128: srl t1, v0, 29 # Get I cache size.
129: and t1, 7
130: li t2, 4096
131: sllv ta0, t2, t1 # ta0 = Initial I set size.
132:
133: li t2, 64
134: sw t2, CpuPrimaryInstCacheLSize
135:
136: srl t1, v0, 26 # Get D cache size.
137: and t1, 7
138: li t2, 4096 # Fixed page size.
139: sllv ta1, t2, t1
140:
141: li t2, 32 # Get D cache line size.
142: sw t2, CpuPrimaryDataCacheLSize
143:
144: li t2, CTYPE_2WAY # Assume two way cache
145: li ta2, 0 # Secondary size 0.
146: li ta3, 0 # Tertiary size 0.
147:
148: or t2, CTYPE_HAS_XL2 # External L2 present.
149: srl t1, v0, 16 # Get I cache size.
150: and t1, 7
151: li ta2, 512*1024 # 512k per 'click'.
152: sll ta2, t1
153:
154: /*
155: * Get here with t2 = Cache type, ta0 = L1 I size, ta1 = L1 D size.
156: * ta2 = secondary size, ta3 = tertiary size.
157: */
158: ConfResult:
159: sw v0, CpuConfigRegister
160: mfc0 t3, COP_0_STATUS_REG
161: sw t2, CpuCacheType # Save cache attributes
162: sw t3, CpuStatusRegister
163: and t2, CTYPE_WAYMASK # isolate number of sets.
164: sw t2, CpuNWayCache
165: srl t2, 1 # get div shift for set size.
166:
167: sw ta2, CpuSecondaryCacheSize
168: sw ta3, CpuTertiaryCacheSize
169:
170: addu t1, ta0, -1 # Use icache for alias mask
171: srl t1, t2
172: and t1, ~(NBPG - 1)
173: sw t1, CpuCacheAliasMask
174:
175: sw ta0, CpuPrimaryInstCacheSize # store cache size.
176: srl ta0, t2 # calculate set size.
177: sw ta0, CpuPrimaryInstSetSize
178:
179: sw ta1, CpuPrimaryDataCacheSize # store cache size.
180: srl ta1, t2 # calculate set size.
181: sw ta1, CpuPrimaryDataSetSize
182:
183: #if 0
184: and v0, 0xfffffff8
185: or v0, 0x00000003 # set cachable writeback kseg0
186: mtc0 v0, COP_0_CONFIG # establish any new config
187: #endif
188: j ra
189: nop
190: END(Mips10k_ConfigCache)
191:
192: /*----------------------------------------------------------------------------
193: *
194: * Mips10k_SyncCache --
195: *
196: * Sync ALL caches.
197: * No need to look at number of sets since we are cleaning out
198: * the entire cache and thus will address all sets anyway.
199: *
200: * Results:
201: * None.
202: *
203: * Side effects:
204: * The contents of ALL caches are Invalidated or Synched.
205: *
206: *----------------------------------------------------------------------------
207: */
208: LEAF(Mips10k_SyncCache, 0)
209: .set noreorder
210: lw t1, CpuPrimaryInstSetSize
211: lw t2, CpuPrimaryDataSetSize
212:
213: /*
214: * Sync the instruction cache.
215: */
216:
217: LOAD_XKPHYS(t0, CCA_NONCOHERENT)
218: PTR_ADDU t1, t0, t1 # Compute end address
219: PTR_SUBU t1, 128
220:
221: 1:
222: cache IndexInvalidate_I, 0(t0)
223: cache IndexInvalidate_I, 64(t0)
224:
225: cache IndexInvalidate_I, 1(t0)
226: cache IndexInvalidate_I, 65(t0)
227:
228: bne t0, t1, 1b
229: PTR_ADDU t0, t0, 128
230:
231: /*
232: * Sync the data cache. Do L1 first. Indexed only operate on
233: * the selected cache and differs from Hit in that sense.
234: */
235:
236: LOAD_XKPHYS(t0, CCA_NONCOHERENT)
237: PTR_ADDU t1, t0, t2 # End address
238: PTR_SUBU t1, t1, 128
239: 1:
240: cache IndexWBInvalidate_D, 0(t0)
241: cache IndexWBInvalidate_D, 32(t0)
242: cache IndexWBInvalidate_D, 64(t0)
243: cache IndexWBInvalidate_D, 96(t0)
244:
245: cache IndexWBInvalidate_D, 1(t0)
246: cache IndexWBInvalidate_D, 33(t0)
247: cache IndexWBInvalidate_D, 65(t0)
248: cache IndexWBInvalidate_D, 97(t0)
249:
250: bne t0, t1, 1b
251: PTR_ADDU t0, t0, 128
252:
253: /* Do L2 */
254: LOAD_XKPHYS(t3, CCA_NONCOHERENT)
255: lw ta0, CpuSecondaryCacheSize # XXX Need set size here.
256: 10:
257: cache IndexWBInvalidate_S, 0(t3)
258: cache IndexWBInvalidate_S, 1(t3)
259: PTR_SUBU ta0, 32 # Fixed cache line size.
260: bgtz ta0, 10b
261: PTR_ADDU t3, 32
262:
263: j ra
264: nop
265: END(Mips10k_SyncCache)
266:
267: /*----------------------------------------------------------------------------
268: *
269: * Mips10k_InvalidateICachePage --
270: *
271: * void Mips10k_InvalidateICachePage(addr)
272: * vaddr_t addr;
273: *
274: * Invalidate the L1 instruction cache page given by addr.
275: *
276: * Results:
277: * Void.
278: *
279: * Side effects:
280: * The contents of the L1 Instruction cache is flushed.
281: *
282: *----------------------------------------------------------------------------
283: */
284: LEAF(Mips10k_InvalidateICachePage, 0)
285: lw v0, CpuNWayCache # Cache properties
286: and a0, ~PAGE_MASK # Page align start address
287: PTR_ADDU a1, a0, PAGE_SIZE-128 # End address.
288: addiu v0, -2 # <0 1way, 0 = two, >0 four
289: 1:
290: cache HitInvalidate_I, 0(a0)
291: cache HitInvalidate_I, 64(a0)
292:
293: bne a0, a1, 1b
294: PTR_ADDU a0, 128
295:
296: j ra
297: move v0, zero
298: END(Mips10k_InvalidateICachePage)
299:
300: /*----------------------------------------------------------------------------
301: *
302: * Mips10k_InvalidateICache --
303: *
304: * void Mips10k_SyncICache(addr, len)
305: * vaddr_t addr, len;
306: *
307: * Invalidate the L1 instruction cache for at least range
308: * of addr to addr + len - 1.
309: * The address is reduced to a XKPHYS index to avoid TLB faults.
310: *
311: * Results:
312: * None.
313: *
314: * Side effects:
315: * The contents of the L1 Instruction cache is flushed.
316: * Must not touch v0.
317: *
318: *----------------------------------------------------------------------------
319: */
320: LEAF(Mips10k_InvalidateICache, 0)
321: LOAD_XKPHYS(a2, CCA_NONCOHERENT)
322: and a0, 0x00ffffff # Reduce addr to cache index
323: PTR_ADDU a1, 63 # Round up size
324: PTR_ADDU a1, a0 # Add extra from address
325: and a0, -64 # Align start address
326: PTR_SUBU a1, a1, a0
327: PTR_ADDU a0, a2 # a0 now new XKPHYS address
328: srl a1, a1, 6 # Number of unrolled loops
329: 1:
330: addu a1, -1
331:
332: cache IndexInvalidate_I, 0(a0) # do set A
333: cache IndexInvalidate_I, 1(a0) # do set B
334:
335: bne a1, zero, 1b
336: PTR_ADDU a0, 64
337:
338: j ra
339: move v0, zero
340: END(Mips10k_InvalidateICache)
341:
342: /*----------------------------------------------------------------------------
343: *
344: * Mips10k_SyncDCachePage --
345: *
346: * void Mips10k_SyncDCachePage(addr)
347: * vaddr_t addr;
348: *
349: * Sync the L1 data cache page for address addr.
350: * The address is reduced to a XKPHYS index to avoid TLB faults.
351: *
352: * Results:
353: * None.
354: *
355: * Side effects:
356: * The contents of the cache is written back to primary memory.
357: * The cache line is invalidated.
358: *
359: *----------------------------------------------------------------------------
360: */
361: LEAF(Mips10k_SyncDCachePage, 0)
362: LOAD_XKPHYS(a2, CCA_NONCOHERENT)
363: dsll a0, 34
364: dsrl a0, 34
365: PTR_ADDU a0, a2 # a0 now new XKPHYS address
366: and a0, ~PAGE_MASK # Page align start address
367: PTR_ADDU a1, a0, PAGE_SIZE-128
368:
369: 1:
370: cache IndexWBInvalidate_D, 0(a0) # do set A
371: cache IndexWBInvalidate_D, 32(a0)
372: cache IndexWBInvalidate_D, 64(a0)
373: cache IndexWBInvalidate_D, 96(a0)
374:
375: cache IndexWBInvalidate_D, 1(a0) # do set B
376: cache IndexWBInvalidate_D, 33(a0)
377: cache IndexWBInvalidate_D, 65(a0)
378: cache IndexWBInvalidate_D, 97(a0)
379:
380: bne a1, a0, 1b
381: PTR_ADDU a0, 128
382:
383: j ra
384: nop
385: END(Mips10k_SyncDCachePage)
386:
387: /*----------------------------------------------------------------------------
388: *
389: * Mips10k_HitSyncDCache --
390: *
391: * void Mips10k_HitSyncDCache(addr, len)
392: * vaddr_t addr, len;
393: *
394: * Sync data cache for range of addr to addr + len - 1.
395: * The address can be any valid virtual address as long
396: * as no TLB invalid traps occur. Only lines with matching
397: * addr are flushed.
398: *
399: * Note: Use the CpuNWayCache flag to select 16 or 32 byte linesize.
400: * All Nway cpu's now available have a fixed 32byte linesize.
401: *
402: * Results:
403: * None.
404: *
405: * Side effects:
406: * The contents of the L1 cache is written back to primary memory.
407: * The cache line is invalidated.
408: *
409: *----------------------------------------------------------------------------
410: */
411: LEAF(Mips10k_HitSyncDCache, 0)
412: beq a1, zero, 3f # size is zero!
413: PTR_ADDU a1, 31 # Round up
414: PTR_ADDU a1, a1, a0 # Add extra from address
415: and a0, a0, -32 # align address
416: PTR_SUBU a1, a1, a0
417: srl a1, a1, 5 # Compute number of cache lines
418:
419: 1:
420: PTR_ADDU a1, -1
421: cache HitWBInvalidate_D, 0(a0)
422: bne a1, zero, 1b
423: PTR_ADDU a0, 32
424:
425: 3:
426: j ra
427: nop
428: END(Mips10k_HitSyncDCache)
429:
430:
431: /*----------------------------------------------------------------------------
432: *
433: * Mips10k_HitSyncSCache --
434: *
435: * void Mips10k_HitSyncSCache(addr, len)
436: * vaddr_t addr, len;
437: *
438: * Sync secondary cache for range of addr to addr + len - 1.
439: * The address can be any valid virtual address as long
440: * as no TLB invalid traps occur. Only lines with matching
441: * addr are flushed.
442: *
443: * Results:
444: * None.
445: *
446: * Side effects:
447: * The contents of the L2 cache is written back to primary memory.
448: * The cache line is invalidated.
449: *
450: *----------------------------------------------------------------------------
451: */
452: LEAF(Mips10k_HitSyncSCache, 0)
453: beq a1, zero, 3f # size is zero!
454: PTR_ADDU a1, a1, a0 # Add in extra from align
455: and a0, a0, -32 # Align address
456: PTR_SUBU a1, a1, a0
457: 1:
458: PTR_ADDU a1, -32
459:
460: cache HitWBInvalidate_S, 0(a0)
461:
462: bgtz a1, 1b
463: PTR_ADDU a0, 32
464:
465: 3:
466: j ra
467: nop
468: END(Mips10k_HitSyncSCache)
469:
470: /*----------------------------------------------------------------------------
471: *
472: * Mips10k_HitInvalidateDCache --
473: *
474: * void Mips10k_HitInvalidateDCache(addr, len)
475: * vaddr_t addr, len;
476: *
477: * Invalidate data cache for range of addr to addr + len - 1.
478: * The address can be any valid address as long as no TLB misses occur.
479: * (Be sure to use cached K0SEG kernel addresses or mapped addresses)
480: * Only lines with matching addresses are invalidated.
481: *
482: * Results:
483: * None.
484: *
485: * Side effects:
486: * The L1 cache line is invalidated.
487: *
488: *----------------------------------------------------------------------------
489: */
490: LEAF(Mips10k_HitInvalidateDCache, 0)
491: beq a1, zero, 3f # size is zero!
492: PTR_ADDU a1, a1, a0 # Add in extra from align
493: and a0, a0, -32 # Align address
494: PTR_SUBU a1, a1, a0
495:
496: 1:
497: PTR_ADDU a1, -32
498:
499: cache HitInvalidate_D, 0(a0)
500:
501: bgtz a1, 1b
502: PTR_ADDU a0, 32
503:
504: 3:
505: j ra
506: nop
507: END(Mips10k_HitInvalidateDCache)
508:
509:
510: /*----------------------------------------------------------------------------
511: *
512: * Mips10k_HitInvalidateSCache --
513: *
514: * void Mips10k_HitInvalidateSCache(addr, len)
515: * vaddr_t addr, len;
516: *
517: * Invalidate secondary cache for range of addr to addr + len - 1.
518: * The address can be any valid address as long as no TLB misses occur.
519: * (Be sure to use cached K0SEG kernel addresses or mapped addresses)
520: * Only lines with matching addresses are invalidated.
521: *
522: * Results:
523: * None.
524: *
525: * Side effects:
526: * The L2 cache line is invalidated.
527: *
528: *----------------------------------------------------------------------------
529: */
530: LEAF(Mips10k_HitInvalidateSCache, 0)
531: beq a1, zero, 3f # size is zero!
532: PTR_ADDU a1, a1, a0 # Add in extra from align
533: and a0, a0, -32 # Align address
534: PTR_SUBU a1, a1, a0
535: 1:
536: PTR_ADDU a1, -32
537:
538: cache HitInvalidate_S, 0(a0)
539:
540: bgtz a1, 1b
541: PTR_ADDU a0, 32
542:
543: 3:
544: j ra
545: nop
546: END(Mips10k_HitInvalidateSCache)
547:
548: /*----------------------------------------------------------------------------
549: *
550: * Mips10k_IOSyncDCache --
551: *
552: * void Mips10k_IOSyncDCache(addr, len, rw)
553: * vaddr_t addr;
554: * int len, rw;
555: *
556: * Invalidate or flush data cache for range of addr to addr + len - 1.
557: * The address can be any valid address as long as no TLB misses occur.
558: * (Be sure to use cached K0SEG kernel addresses or mapped addresses)
559: *
560: * Results:
561: * None.
562: *
563: * Side effects:
564: * If rw == 0 (read), L1 and L2 caches are invalidated or
565: * flushed if the area does not match the alignment
566: * requirements.
567: * If rw == 1 (write), L1 and L2 caches are written back
568: * to memory and invalidated.
569: * If rw == 2 (write-read), L1 and L2 caches are written back
570: * to memory and invalidated.
571: *
572: *----------------------------------------------------------------------------
573: */
574: NON_LEAF(Mips10k_IOSyncDCache, FRAMESZ(CF_SZ+2*REGSZ), ra)
575:
576: PTR_SUBU sp, FRAMESZ(CF_SZ+2*REGSZ)
577: PTR_S ra, CF_RA_OFFS+2*REGSZ(sp)
578: REG_S a0, CF_ARGSZ(sp) # save args
579: beqz a2, SyncRD # Sync PREREAD
580: REG_S a1, CF_ARGSZ+REGSZ(sp)
581: addiu a2, -1
582: bnez a2, SyncRDWB # Sync PREWRITE+PREREAD
583: nop
584:
585: SyncWR:
586: jal Mips10k_HitSyncSCache # Do L2 cache
587: nop # L1 done in parallel
588: b SyncDone
589: PTR_L ra, CF_RA_OFFS+2*REGSZ(sp)
590:
591: SyncRD:
592: and t0, a0, 63 # check if invalidate possible
593: bnez t0, SyncRDWB # both address and size must
594: and t0, a1, 63 # be aligned at the cache size
595: bnez t0, SyncRDWB
596: nop
597:
598: /*
599: * Sync for aligned read, no writeback required.
600: */
601: jal Mips10k_HitInvalidateSCache # L2 cache
602: nop # L1 done in parallel
603:
604: b SyncDone
605: PTR_L ra, CF_RA_OFFS+2*REGSZ(sp)
606:
607: /*
608: * Sync for unaligned read or write-read.
609: */
610: SyncRDWB:
611: jal Mips10k_HitSyncSCache # L2 cache
612: nop # L1 done in parallel
613:
614: PTR_L ra, CF_RA_OFFS+2*REGSZ(sp)
615:
616: SyncDone:
617: j ra
618: PTR_ADDU sp, FRAMESZ(CF_SZ+2*REGSZ)
619: END(Mips10k_IOSyncDCache)
CVSweb