source: rtems/c/src/lib/libbsp/mips/p4000/startup/idtmem.S @ 8445e57

4.104.114.84.95
Last change on this file since 8445e57 was f198c63, checked in by Joel Sherrill <joel.sherrill@…>, on 09/06/96 at 18:11:41

new file for MIPS port by Craig Lebakken (lebakken@…) and
Derrick Ostertag (ostertag@…).

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