source: rtems/c/src/lib/libbsp/mips/rbtx4938/startup/idtmem.S @ 4ba5ac6

4.104.114.84.95
Last change on this file since 4ba5ac6 was 4ba5ac6, checked in by Ralf Corsepius <ralf.corsepius@…>, on 03/16/06 at 17:41:28

New (Submission by Bruce Robinson <brucer@…>).

  • Property mode set to 100644
File size: 19.2 KB
Line 
1/*
2
3Based upon IDT provided code with the following release:
4
5This source code has been made available to you by IDT on an AS-IS
6basis. Anyone receiving this source is licensed under IDT copyrights
7to use it in any way he or she deems fit, including copying it,
8modifying it, compiling it, and redistributing it either with or
9without modifications.  No license under IDT patents or patent
10applications is to be implied by the copyright license.
11
12Any user of this software should understand that IDT cannot provide
13technical support for this software and will not be responsible for
14any consequences resulting from the use of this software.
15
16Any person who transfers this source code or any derivative work must
17include the IDT copyright notice, this paragraph, and the preceeding
18two paragraphs in the transferred software.
19
20COPYRIGHT IDT CORPORATION 1996
21LICENSED MATERIAL - PROGRAM PROPERTY OF IDT
22
23  $Id$
24
25*/
26
27/************************************************************************
28**
29**      idtmem.s - memory and cache functions
30**
31**      Copyright 1991 Integrated Device Technology, Inc.
32**      All Rights Reserved
33**
34**************************************************************************/
35
36/*
37 * 950313: Ketan fixed bugs in mfc0/mtc0 hazards, and removed hack
38 * to set mem_size.
39 */
40
41#include <rtems/mips/iregdef.h>
42#include <rtems/mips/idtcpu.h>
43#include <rtems/asm.h>
44
45        .data
46mem_size:
47        .word   0
48dcache_size:
49        .word   0
50icache_size:
51#if __mips == 1
52        .word   MINCACHE
53#endif
54#if __mips == 3
55        .word   0
56#endif
57
58#if __mips == 3
59        .data
60scache_size:
61        .word   0
62icache_linesize:
63        .word   0
64dcache_linesize:
65        .word   0
66scache_linesize:
67        .word   0
68#endif
69
70                .text
71
72#if __mips == 1
73#define CONFIGFRM ((2*4)+4)
74
75/*************************************************************************
76**
77** Config_Dcache() -- determine size of Data cache
78**
79**************************************************************************/
80
81FRAME(config_Dcache,sp, CONFIGFRM, ra)
82        .set    noreorder
83        subu    sp,CONFIGFRM
84        sw      ra,CONFIGFRM-4(sp)      /* save return address */
85        sw      s0,4*4(sp)              /* save s0 in first regsave slot */
86        mfc0    s0,C0_SR                /* save SR */
87        nop
88        mtc0    zero,C0_SR              /* disable interrupts */
89        .set    reorder
90        jal     _size_cache             /* returns Data cache size in v0 */
91        sw      v0, dcache_size         /* save it */
92        and     s0, ~SR_PE              /* do not clear PE */
93        .set    noreorder
94        mtc0    s0,C0_SR                /* restore SR */
95        nop
96        .set    reorder
97        lw      s0, 4*4(sp)             /* restore s0 */
98        lw      ra,CONFIGFRM-4(sp)      /* restore ra */
99        addu    sp,CONFIGFRM            /* pop stack */
100        j       ra
101ENDFRAME(config_Dcache)
102
103/*************************************************************************
104**
105** Config_Icache() -- determine size of Instruction cache
106**                    MUST be run in uncached mode/handled in idt_csu.s
107**
108**************************************************************************/
109
110FRAME(config_Icache,sp, CONFIGFRM, ra)
111        .set    noreorder
112        subu    sp,CONFIGFRM
113        sw      ra,CONFIGFRM-4(sp)      /* save return address */
114        sw      s0,4*4(sp)              /* save s0 in first regsave slot */
115        mfc0    s0,C0_SR                /* save SR */
116        nop
117        mtc0    zero, C0_SR             /* disable interrupts */
118        li      v0,SR_SWC               /* swap caches/disable ints  */
119        mtc0    v0,C0_SR
120        nop
121        .set    reorder
122        jal     _size_cache             /* returns instruction cache size */
123        .set    noreorder
124        mtc0    zero,C0_SR              /* swap back caches */
125        nop
126        and     s0,~SR_PE               /* do not inadvertantly clear PE */
127        mtc0    s0,C0_SR                /* restore SR */
128        nop
129        .set    reorder
130        sw      v0, icache_size         /* save it AFTER caches back */
131        lw      s0,4*4(sp)              /* restore s0 */
132        lw      ra,CONFIGFRM-4(sp)      /* restore ra */
133        addu    sp,CONFIGFRM            /* pop stack */
134        j       ra
135ENDFRAME(config_Icache)
136
137/************************************************************************
138**
139** _size_cache()
140** returns cache size in v0
141**
142************************************************************************/
143
144FRAME(_size_cache,sp,0,ra)
145        .set    noreorder
146        mfc0    t0,C0_SR                /* save current sr */
147        nop
148        and     t0,~SR_PE               /* do not inadvertently clear PE */
149        or      v0,t0,SR_ISC            /* isolate cache */
150        mtc0    v0,C0_SR
151        /*
152         * First check if there is a cache there at all
153         */
154        move    v0,zero
155        li      v1,0xa5a5a5a5           /* distinctive pattern */
156        sw      v1,K0BASE               /* try to write into cache */
157        lw      t1,K0BASE               /* try to read from cache */
158        nop
159        mfc0    t2,C0_SR
160        nop
161        .set    reorder
162        and     t2,SR_CM
163        bne     t2,zero,3f              /* cache miss, must be no cache */
164        bne     v1,t1,3f                /* data not equal -> no cache */
165        /*
166         * Clear cache size boundries to known state.
167         */
168        li      v0,MINCACHE
1691:
170        sw      zero,K0BASE(v0)
171        sll     v0,1
172        ble     v0,MAXCACHE,1b
173
174        li      v0,-1
175        sw      v0,K0BASE(zero)         /* store marker in cache */
176        li      v0,MINCACHE             /* MIN cache size */
177
1782:      lw      v1,K0BASE(v0)           /* Look for marker */
179        bne     v1,zero,3f              /* found marker */
180        sll     v0,1                    /* cache size * 2 */
181        ble     v0,MAXCACHE,2b          /* keep looking */
182        move    v0,zero                 /* must be no cache */
183        .set    noreorder
1843:      mtc0    t0,C0_SR                /* restore sr */
185        j       ra
186        nop
187ENDFRAME(_size_cache)
188        .set    reorder
189
190#define FLUSHFRM (2*4)
191
192/***************************************************************************
193**
194** flush_Dcache() -  flush entire Data cache
195**
196****************************************************************************/
197FRAME(flush_Dcache,sp,FLUSHFRM,ra)
198        lw      t2, dcache_size
199        .set    noreorder
200        mfc0    t3,C0_SR                /* save SR */
201        nop
202        and     t3,~SR_PE               /* dont inadvertently clear PE */
203        beq     t2,zero,_Dflush_done    /* no D cache, get out! */
204        nop
205        li      v0, SR_ISC              /* isolate cache */
206        mtc0    v0, C0_SR
207        nop
208        .set    reorder
209        li      t0,K0BASE               /* set loop registers  */
210        or      t1,t0,t2
211
2122:      sb      zero,0(t0)
213        sb      zero,4(t0)
214        sb      zero,8(t0)
215        sb      zero,12(t0)
216        sb      zero,16(t0)
217        sb      zero,20(t0)
218        sb      zero,24(t0)
219        addu    t0,32
220        sb      zero,-4(t0)
221        bne     t0,t1,2b
222
223        .set    noreorder
224_Dflush_done:
225        mtc0    t3,C0_SR                /* restore Status Register */
226        .set    reorder
227        j       ra
228ENDFRAME(flush_Dcache)
229
230/***************************************************************************
231**
232** flush_Icache() -  flush entire Instruction cache
233**
234**      NOTE: Icache can only be flushed/cleared when uncached
235**            Code forces into uncached memory regardless of calling mode
236**
237****************************************************************************/
238FRAME(flush_Icache,sp,FLUSHFRM,ra)
239        lw      t1,icache_size
240        .set    noreorder
241        mfc0    t3,C0_SR                /* save SR */
242        nop
243        la      v0,1f
244        li      v1,K1BASE
245        or      v0,v1
246        j       v0                      /* force into non-cached space */
247        nop
2481:
249        and     t3,~SR_PE               /* dont inadvertently clear PE */
250        beq     t1,zero,_Iflush_done    /* no i-cache get out */
251        nop
252        li      v0,SR_ISC|SR_SWC        /* disable intr, isolate and swap */
253        mtc0    v0,C0_SR
254        li      t0,K0BASE
255        .set    reorder
256        or      t1,t0,t1
257
2581:      sb      zero,0(t0)
259        sb      zero,4(t0)
260        sb      zero,8(t0)
261        sb      zero,12(t0)
262        sb      zero,16(t0)
263        sb      zero,20(t0)
264        sb      zero,24(t0)
265        addu    t0,32
266        sb      zero,-4(t0)
267        bne     t0,t1,1b
268        .set    noreorder
269_Iflush_done:
270        mtc0    t3,C0_SR                /* un-isolate, enable interrupts */
271        .set    reorder
272        j       ra
273ENDFRAME(flush_Icache)
274
275/**************************************************************************
276**
277** clear_Dcache(base_addr, byte_count) - flush portion of Data cache
278**
279**      a0 = base address of portion to be cleared
280**      a1 = byte count of length
281**
282***************************************************************************/
283FRAME(clear_Dcache,sp,0,ra)
284
285        lw      t2, dcache_size         /* Data cache size */
286        .set    noreorder
287        mfc0    t3,C0_SR                /* save SR */
288        nop
289        and     t3,~SR_PE               /* dont inadvertently clear PE */
290        nop
291        nop
292        .set    reorder
293        /*
294         * flush data cache
295         */
296
297        .set    noreorder
298        nop
299        li      v0,SR_ISC               /* isolate data cache */
300        mtc0    v0,C0_SR
301        .set    reorder
302        bltu    t2,a1,1f                /* cache is smaller than region */
303        move    t2,a1
3041:      addu    t2,a0                   /* ending address + 1 */
305        move    t0,a0
306
3071:      sb      zero,0(t0)
308        sb      zero,4(t0)
309        sb      zero,8(t0)
310        sb      zero,12(t0)
311        sb      zero,16(t0)
312        sb      zero,20(t0)
313        sb      zero,24(t0)
314        addu    t0,32
315        sb      zero,-4(t0)
316        bltu    t0,t2,1b
317
318        .set    noreorder
319        mtc0    t3,C0_SR                /* un-isolate, enable interrupts */
320        nop
321        .set    reorder
322        j       ra
323ENDFRAME(clear_Dcache)
324
325/**************************************************************************
326**
327** clear_Icache(base_addr, byte_count) - flush portion of Instruction cache
328**
329**      a0 = base address of portion to be cleared
330**      a1 = byte count of length
331**
332**      NOTE: Icache can only be flushed/cleared when uncached
333**            Code forces into uncached memory regardless of calling mode
334**
335***************************************************************************/
336FRAME(clear_Icache,sp,0,ra)
337
338        lw      t1, icache_size         /* Instruction cache size */
339        /*
340         * flush text cache
341         */
342        .set    noreorder
343        mfc0    t3,C0_SR                /* save SR */
344        nop
345        la      v0,1f
346        li      v1,K1BASE
347        or      v0,v1
348        j       v0                      /* force into non-cached space */
349        nop
3501:
351        and     t3,~SR_PE               /* dont inadvertently clear PE */
352        nop
353        nop
354        li      v0,SR_ISC|SR_SWC        /* disable intr, isolate and swap */
355        mtc0    v0,C0_SR
356        .set    reorder
357        bltu    t1,a1,1f                /* cache is smaller than region */
358        move    t1,a1
3591:      addu    t1,a0                   /* ending address + 1 */
360        move    t0,a0
361
362        sb      zero,0(t0)
363        sb      zero,4(t0)
364        sb      zero,8(t0)
365        sb      zero,12(t0)
366        sb      zero,16(t0)
367        sb      zero,20(t0)
368        sb      zero,24(t0)
369        addu    t0,32
370        sb      zero,-4(t0)
371        bltu    t0,t1,1b
372        .set    noreorder
373        mtc0    t3,C0_SR                /* un-isolate, enable interrupts */
374        nop
375        nop
376        nop                             /* allow time for caches to swap */
377        .set    reorder
378        j       ra
379ENDFRAME(clear_Icache)
380
381/**************************************************************************
382**
383**  get_mem_conf - get memory configuration
384**
385***************************************************************************/
386
387FRAME(get_mem_conf,sp,0,ra)
388
389        lw      t6, mem_size
390        sw      t6, 0(a0)
391        lw      t7, icache_size
392        sw      t7, 4(a0)
393        lw      t8, dcache_size
394        sw      t8, 8(a0)
395        j       ra
396
397ENDFRAME(get_mem_conf)
398#endif /* __mips == 1 */
399
400#if __mips == 3
401#define LEAF(label)     FRAME(label,sp,0,ra)
402#define XLEAF(label) \
403        .globl label ; \
404label:
405
406/*
407 * cacheop macro to automate cache operations
408 * first some helpers...
409 */
410#define _mincache(size, maxsize) \
411        bltu    size,maxsize,8f ;       \
412        move    size,maxsize ;          \
4138:
414
415#define _align(tmp, minaddr, maxaddr, linesize) \
416        subu    tmp,linesize,1 ;        \
417        not     tmp ;                   \
418        and     minaddr,tmp ;           \
419        addu    maxaddr,-1 ;            \
420        and     maxaddr,tmp
421
422/* This is a bit of a hack really because it relies on minaddr=a0 */
423#define _doop1(op1) \
424        cache   op1,0(a0)
425
426#define _doop2(op1, op2) \
427        cache   op1,0(a0) ;             \
428        cache   op2,0(a0)
429
430/* specials for cache initialisation */
431#define _doop1lw1(op1) \
432        cache   op1,0(a0) ;             \
433        lw      zero,0(a0) ;            \
434        cache   op1,0(a0)
435
436#define _doop121(op1,op2) \
437        cache   op1,0(a0) ;             \
438        nop;                            \
439        cache   op2,0(a0) ;             \
440        nop;                            \
441        cache   op1,0(a0)
442
443#define _oploopn(minaddr, maxaddr, linesize, tag, ops) \
444        .set    noreorder ;             \
4457:      _doop##tag##ops ;               \
446        bne     minaddr,maxaddr,7b ;    \
447        addu    minaddr,linesize ;      \
448        .set    reorder
449
450/* finally the cache operation macros */
451#define icacheopn(kva, n, cache_size, cache_linesize, tag, ops) \
452        _mincache(n, cache_size);       \
453        blez    n,9f ;                  \
454        addu    n,kva ;                 \
455        _align(t1, kva, n, cache_linesize) ; \
456        _oploopn(kva, n, cache_linesize, tag, ops) ; \
4579:
458
459#define vcacheopn(kva, n, cache_size, cache_linesize, tag, ops) \
460        blez    n,9f ;                  \
461        addu    n,kva ;                 \
462        _align(t1, kva, n, cache_linesize) ; \
463        _oploopn(kva, n, cache_linesize, tag, ops) ; \
4649:
465
466#define icacheop(kva, n, cache_size, cache_linesize, op) \
467        icacheopn(kva, n, cache_size, cache_linesize, 1, (op))
468
469#define vcacheop(kva, n, cache_size, cache_linesize, op) \
470        vcacheopn(kva, n, cache_size, cache_linesize, 1, (op))
471
472        .text
473
474/*
475 * static void _size_cache()    R4000
476 *
477 * Internal routine to determine cache sizes by looking at R4000 config
478 * register.  Sizes are returned in registers, as follows:
479 *      t2      icache size
480 *      t3      dcache size
481 *      t6      scache size
482 *      t4      icache line size
483 *      t5      dcache line size
484 *      t7      scache line size
485 */
486LEAF(_size_cache)
487        mfc0    t0,C0_CONFIG
488
489        and     t1,t0,CFG_ICMASK
490        srl     t1,CFG_ICSHIFT
491        li      t2,0x1000
492        sll     t2,t1
493
494        and     t1,t0,CFG_DCMASK
495        srl     t1,CFG_DCSHIFT
496        li      t3,0x1000
497        sll     t3,t1
498
499        li      t4,32
500        and     t1,t0,CFG_IB
501        bnez    t1,1f
502        li      t4,16
5031:
504
505        li      t5,32
506        and     t1,t0,CFG_DB
507        bnez    t1,1f
508        li      t5,16
5091:
510
511        move    t6,zero                 # default to no scache
512        move    t7,zero                 #
513
514        and     t1,t0,CFG_C_UNCACHED    # test config register
515        bnez    t1,1f                   # no scache if uncached/non-coherent
516
517        li      t6,0x100000             # assume 1Mb scache <<-NOTE
518        and     t1,t0,CFG_SBMASK
519        srl     t1,CFG_SBSHIFT
520        li      t7,16
521        sll     t7,t1
5221:      j       ra
523ENDFRAME(_size_cache)
524
525/*
526 * void config_cache()   R4000
527 *
528 * Work out size of I, D & S caches, assuming they are already initialised.
529 */
530LEAF(config_cache)
531        lw      t0,icache_size
532        bgtz    t0,8f                   # already known?
533        move    v0,ra
534        bal     _size_cache
535        move    ra,v0
536
537        sw      t2,icache_size
538        sw      t3,dcache_size
539        sw      t6,scache_size
540        sw      t4,icache_linesize
541        sw      t5,dcache_linesize
542        sw      t7,scache_linesize
5438:      j       ra
544ENDFRAME(config_cache)
545
546/*
547 * void _init_cache()   R4000
548 */
549LEAF(_init_cache)
550        /*
551         * First work out the sizes
552         */
553        move    v0,ra
554        bal     _size_cache
555        move    ra,v0
556
557        /*
558         * The caches may be in an indeterminate state,
559         * so we force good parity into them by doing an
560         * invalidate, load/fill, invalidate for each line.
561         */
562
563        /* disable all i/u and cache exceptions */
564        mfc0    v0,C0_SR
565        and     v1,v0,~SR_IE
566        or      v1,SR_DE
567        mtc0    v1,C0_SR
568
569        mtc0    zero,C0_TAGLO
570        mtc0    zero,C0_TAGHI
571
572        /* assume bottom of RAM will generate good parity for the cache */
573        li      a0,PHYS_TO_K0(0)
574        move    a2,t2           # icache_size
575        move    a3,t4           # icache_linesize
576        move    a1,a2
577        icacheopn(a0,a1,a2,a3,121,(Index_Store_Tag_I,Fill_I))
578
579        li      a0,PHYS_TO_K0(0)
580        move    a2,t3           # dcache_size
581        move    a3,t5           # dcache_linesize
582        move    a1,a2
583        icacheopn(a0,a1,a2,a3,1lw1,(Index_Store_Tag_D))
584
585        /* assume unified I & D in scache <<-NOTE */
586        blez    t6,1f
587        li      a0,PHYS_TO_K0(0)
588        move    a2,t6
589        move    a3,t7
590        move    a1,a2
591        icacheopn(a0,a1,a2,a3,1lw1,(Index_Store_Tag_SD))
592
5931:      mtc0    v0,C0_SR
594        j       ra
595ENDFRAME(_init_cache)
596
597/*
598 * void flush_cache (void)   R4000
599 *
600 * Flush and invalidate all caches
601 */
602LEAF(flush_cache)
603        /* secondary cacheops do all the work if present */
604        lw      a2,scache_size
605        blez    a2,1f
606        lw      a3,scache_linesize
607        li      a0,PHYS_TO_K0(0)
608        move    a1,a2
609        icacheop(a0,a1,a2,a3,Index_Writeback_Inv_SD)
610        b       2f
611
6121:
613        lw      a2,icache_size
614        blez    a2,2f
615        lw      a3,icache_linesize
616        li      a0,PHYS_TO_K0(0)
617        move    a1,a2
618        icacheop(a0,a1,a2,a3,Index_Invalidate_I)
619
620        lw      a2,dcache_size
621        lw      a3,dcache_linesize
622        li      a0,PHYS_TO_K0(0)
623        move    a1,a2
624        icacheop(a0,a1,a2,a3,Index_Writeback_Inv_D)
625
6262:      j       ra
627ENDFRAME(flush_cache)
628
629/*
630 * void flush_cache_nowrite (void)   R4000
631 *
632 * Invalidate all caches
633 */
634LEAF(flush_cache_nowrite)
635        mfc0    v0,C0_SR
636        and     v1,v0,~SR_IE
637        mtc0    v1,C0_SR
638
639        mtc0    zero,C0_TAGLO
640        mtc0    zero,C0_TAGHI
641
642        lw      a2,icache_size
643        blez    a2,2f
644        lw      a3,icache_linesize
645        li      a0,PHYS_TO_K0(0)
646        move    a1,a2
647        icacheop(a0,a1,a2,a3,Index_Invalidate_I)
648
649        lw      a2,dcache_size
650        lw      a3,dcache_linesize
651        li      a0,PHYS_TO_K0(0)
652        move    a1,a2
653        icacheop(a0,a1,a2,a3,Index_Store_Tag_D)
654
655        lw      a2,scache_size
656        blez    a2,2f
657        lw      a3,scache_linesize
658        li      a0,PHYS_TO_K0(0)
659        move    a1,a2
660        icacheop(a0,a1,a2,a3,Index_Store_Tag_SD)
661
6622:      mtc0    v0,C0_SR
663        j       ra
664ENDFRAME(flush_cache_nowrite)
665
666/*
667 * void clean_cache (unsigned kva, size_t n)   R4000
668 *
669 * Writeback and invalidate address range in all caches
670 */
671LEAF(clean_cache)
672XLEAF(clear_cache)
673
674        /* secondary cacheops do all the work (if fitted) */
675        lw      a2,scache_size
676        blez    a2,1f
677        lw      a3,scache_linesize
678        vcacheop(a0,a1,a2,a3,Hit_Writeback_Inv_SD)
679        b       2f
680
6811:      lw      a2,icache_size
682        blez    a2,2f
683        lw      a3,icache_linesize
684        /* save kva & n for subsequent loop */
685        move    t8,a0
686        move    t9,a1
687        vcacheop(a0,a1,a2,a3,Hit_Invalidate_I)
688
689        lw      a2,dcache_size
690        lw      a3,dcache_linesize
691        /* restore kva & n */
692        move    a0,t8
693        move    a1,t9
694        vcacheop(a0,a1,a2,a3,Hit_Writeback_Inv_D)
695
6962:      j       ra
697ENDFRAME(clean_cache)
698
699/*
700 * void clean_dcache (unsigned kva, size_t n)   R4000
701 *
702 * Writeback and invalidate address range in primary data cache
703 */
704LEAF(clean_dcache)
705        lw      a2,dcache_size
706        blez    a2,2f
707        lw      a3,dcache_linesize
708
709        vcacheop(a0,a1,a2,a3,Hit_Writeback_Inv_D)
710
7112:      j       ra
712ENDFRAME(clean_dcache)
713
714/*
715 * void clean_dcache_indexed (unsigned kva, size_t n)   R4000
716 *
717 * Writeback and invalidate indexed range in primary data cache
718 */
719LEAF(clean_dcache_indexed)
720        lw      a2,dcache_size
721        blez    a2,2f
722        lw      a3,dcache_linesize
723
724#ifdef CPU_ORION
725        srl     a2,1                    # do one set (half cache) at a time
726        move    t8,a0                   # save kva & n
727        move    t9,a1
728        icacheop(a0,a1,a2,a3,Index_Writeback_Inv_D)
729
730        addu    a0,t8,a2                # do next set
731        move    a1,t9                   # restore n
732#endif
733        icacheop(a0,a1,a2,a3,Index_Writeback_Inv_D)
734
7352:      j       ra
736ENDFRAME(clean_dcache_indexed)
737
738/*
739 * void clean_dcache_nowrite (unsigned kva, size_t n)   R4000
740 *
741 * Invalidate an address range in primary data cache
742 */
743LEAF(clean_dcache_nowrite)
744        lw      a2,dcache_size
745        blez    a2,2f
746        lw      a3,dcache_linesize
747
748        vcacheop(a0,a1,a2,a3,Hit_Invalidate_D)
749
7502:      j       ra
751ENDFRAME(clean_dcache_nowrite)
752
753/*
754 * void clean_dcache_nowrite_indexed (unsigned kva, size_t n)   R4000
755 *
756 * Invalidate indexed range in primary data cache
757 */
758LEAF(clean_dcache_nowrite_indexed)
759        mfc0    v0,C0_SR
760        and     v1,v0,~SR_IE
761        mtc0    v1,C0_SR
762
763        mtc0    zero,C0_TAGLO
764        mtc0    zero,C0_TAGHI
765
766        lw      a2,dcache_size
767        blez    a2,2f
768        lw      a3,dcache_linesize
769
770#ifdef CPU_ORION
771        srl     a2,1                    # do one set (half cache) at a time
772        move    t8,a0                   # save kva & n
773        move    t9,a1
774        icacheop(a0,a1,a2,a3,Index_Store_Tag_D)
775
776        addu    a0,t8,a2                # do next set
777        move    a1,t9                   # restore n
778#endif
779        icacheop(a0,a1,a2,a3,Index_Store_Tag_D)
780
7812:      mtc0    v0,C0_SR
782        j       ra
783ENDFRAME(clean_dcache_nowrite_indexed)
784
785/*
786 * void clean_icache (unsigned kva, size_t n)   R4000
787 *
788 * Invalidate address range in primary instruction cache
789 */
790LEAF(clean_icache)
791        lw      a2,icache_size
792        blez    a2,2f
793        lw      a3,icache_linesize
794
795        vcacheop(a0,a1,a2,a3,Hit_Invalidate_I)
796
7972:      j       ra
798ENDFRAME(clean_icache)
799
800/*
801 * void clean_icache_indexed (unsigned kva, size_t n)   R4000
802 *
803 * Invalidate indexed range in primary instruction cache
804 */
805LEAF(clean_icache_indexed)
806        lw      a2,icache_size
807        blez    a2,2f
808        lw      a3,icache_linesize
809
810#ifdef CPU_ORION
811        srl     a2,1                    # do one set (half cache) at a time
812        move    t8,a0                   # save kva & n
813        move    t9,a1
814        icacheop(a0,a1,a2,a3,Index_Invalidate_I)
815
816        addu    a0,t8,a2                # do next set
817        move    a1,t9                   # restore n
818#endif
819        icacheop(a0,a1,a2,a3,Index_Invalidate_I)
820
8212:      j       ra
822ENDFRAME(clean_icache_indexed)
823
824/*
825 * void clean_scache (unsigned kva, size_t n)   R4000
826 *
827 * Writeback and invalidate address range in secondary cache
828 */
829LEAF(clean_scache)
830        lw      a2,scache_size
831        blez    a2,2f
832        lw      a3,scache_linesize
833        vcacheop(a0,a1,a2,a3,Hit_Writeback_Inv_SD)
834
8352:      j       ra
836ENDFRAME(clean_scache)
837
838/*
839 * void clean_scache_indexed (unsigned kva, size_t n)   R4000
840 *
841 * Writeback and invalidate indexed range in secondary cache
842 */
843LEAF(clean_scache_indexed)
844        lw      a2,scache_size
845        blez    a2,2f
846        lw      a3,scache_linesize
847
848        icacheop(a0,a1,a2,a3,Index_Writeback_Inv_SD)
849
8502:      j       ra
851ENDFRAME(clean_scache_indexed)
852
853/*
854 * void clean_scache_nowrite (unsigned kva, size_t n)   R4000
855 *
856 * Invalidate an address range in secondary cache
857 */
858LEAF(clean_scache_nowrite)
859        lw      a2,scache_size
860        blez    a2,2f
861        lw      a3,scache_linesize
862
863        vcacheop(a0,a1,a2,a3,Hit_Invalidate_SD)
864
8652:      j       ra
866ENDFRAME(clean_scache_nowrite)
867
868/*
869 * void clean_scache_nowrite_indexed (unsigned kva, size_t n)   R4000
870 *
871 * Invalidate indexed range in secondary cache
872 */
873LEAF(clean_scache_nowrite_indexed)
874        mfc0    v0,C0_SR
875        and     v1,v0,~SR_IE
876        mtc0    v1,C0_SR
877
878        mtc0    zero,C0_TAGLO
879        mtc0    zero,C0_TAGHI
880
881        lw      a2,scache_size
882        blez    a2,2f
883        lw      a3,scache_linesize
884
885        icacheop(a0,a1,a2,a3,Index_Store_Tag_SD)
886
8872:      mtc0    v0,C0_SR
888        j       ra
889ENDFRAME(clean_scache_nowrite_indexed)
890
891/**************************************************************************
892**
893**  get_mem_conf - get memory configuration  R4000
894**
895***************************************************************************/
896
897FRAME(get_mem_conf,sp,0,ra)
898
899        lw      t6, mem_size
900        sw      t6, 0(a0)
901        lw      t7, icache_size
902        sw      t7, 4(a0)
903        lw      t8, dcache_size
904        sw      t8, 8(a0)
905        lw      t7, scache_size
906        sw      t7, 12(a0)
907        j       ra
908
909ENDFRAME(get_mem_conf)
910
911#endif /* __mips == 3 */
912
913/*
914 * void set_mem_size (mem_size)
915 *
916 * config_memory()'s memory size gets written into mem_size here.
917 * Now we don't need to call config_cache() with memory size - New to IDTC6.0
918 */
919FRAME(set_memory_size,sp,0,ra)
920        sw      a0, mem_size
921        j       ra
922ENDFRAME(set_memory_size)
Note: See TracBrowser for help on using the repository browser.