OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [mips64orion/] [p4000/] [startup/] [idtmem.S] - Blame information for rev 173

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
2
 
3
Based upon IDT provided code with the following release:
4
 
5
This source code has been made available to you by IDT on an AS-IS
6
basis. Anyone receiving this source is licensed under IDT copyrights
7
to use it in any way he or she deems fit, including copying it,
8
modifying it, compiling it, and redistributing it either with or
9
without modifications.  No license under IDT patents or patent
10
applications is to be implied by the copyright license.
11
 
12
Any user of this software should understand that IDT cannot provide
13
technical support for this software and will not be responsible for
14
any consequences resulting from the use of this software.
15
 
16
Any person who transfers this source code or any derivative work must
17
include the IDT copyright notice, this paragraph, and the preceeding
18
two paragraphs in the transferred software.
19
 
20
COPYRIGHT IDT CORPORATION 1996
21
LICENSED MATERIAL - PROGRAM PROPERTY OF IDT
22
 
23
  $Id: idtmem.S,v 1.2 2001-09-27 12:00:25 chris Exp $
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 
42
#include 
43
#include 
44
 
45
        .data
46
mem_size:
47
        .word   0
48
dcache_size:
49
        .word   0
50
icache_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
60
scache_size:
61
        .word   0
62
icache_linesize:
63
        .word   0
64
dcache_linesize:
65
        .word   0
66
scache_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
 
82
FRAME(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
102
ENDFRAME(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
 
112
FRAME(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
137
ENDFRAME(config_Icache)
138
 
139
/************************************************************************
140
**
141
** _size_cache()
142
** returns cache size in v0
143
**
144
************************************************************************/
145
 
146
FRAME(_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
171
1:
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
 
180
2:      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
186
3:      mtc0    t0,C0_SR                /* restore sr */
187
        j       ra
188
        nop
189
ENDFRAME(_size_cache)
190
        .set    reorder
191
 
192
 
193
#define FLUSHFRM (2*4)
194
 
195
/***************************************************************************
196
**
197
** flush_Dcache() -  flush entire Data cache
198
**
199
****************************************************************************/
200
FRAME(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
 
215
2:      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
231
ENDFRAME(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
****************************************************************************/
242
FRAME(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
252
1:
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
 
262
1:      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
277
ENDFRAME(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
***************************************************************************/
287
FRAME(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
308
1:      addu    t2,a0                   /* ending address + 1 */
309
        move    t0,a0
310
 
311
1:      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
327
ENDFRAME(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
***************************************************************************/
341
FRAME(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
355
1:
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
364
1:      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
384
ENDFRAME(clear_Icache)
385
 
386
 
387
/**************************************************************************
388
**
389
**  get_mem_conf - get memory configuration
390
**
391
***************************************************************************/
392
 
393
 
394
FRAME(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
 
404
ENDFRAME(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 ; \
411
label:
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 ;          \
421
8:
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 ;             \
453
7:      _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) ; \
465
9:
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) ; \
472
9:
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
 */
494
LEAF(_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
511
1:
512
 
513
        li      t5,32
514
        and     t1,t0,CFG_DB
515
        bnez    t1,1f
516
        li      t5,16
517
1:
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
530
1:      j       ra
531
END(_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
 */
539
LEAF(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
552
8:      j       ra
553
END(config_cache)
554
 
555
 
556
/*
557
 * void _init_cache()   R4000
558
 */
559
LEAF(_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
 
603
1:      mtc0    v0,C0_SR
604
        j       ra
605
END(_init_cache)
606
 
607
 
608
/*
609
 * void flush_cache (void)   R4000
610
 *
611
 * Flush and invalidate all caches
612
 */
613
LEAF(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
 
623
1:
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
 
637
2:      j       ra
638
END(flush_cache)
639
 
640
/*
641
 * void flush_cache_nowrite (void)   R4000
642
 *
643
 * Invalidate all caches
644
 */
645
LEAF(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
 
673
2:      mtc0    v0,C0_SR
674
        j       ra
675
END(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
 */
682
LEAF(clean_cache)
683
XLEAF(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
 
692
1:      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
 
707
2:      j       ra
708
END(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
 */
715
LEAF(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
 
722
2:      j       ra
723
END(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
 */
730
LEAF(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
 
746
2:      j       ra
747
END(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
 */
754
LEAF(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
 
761
2:      j       ra
762
END(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
 */
769
LEAF(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
 
792
2:      mtc0    v0,C0_SR
793
        j       ra
794
END(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
 */
801
LEAF(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
 
808
2:      j       ra
809
END(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
 */
816
LEAF(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
 
832
2:      j       ra
833
END(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
 */
842
LEAF(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
 
848
2:      j       ra
849
END(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
 */
856
LEAF(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
 
863
2:      j       ra
864
END(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
 */
871
LEAF(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
 
878
2:      j       ra
879
END(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
 */
886
LEAF(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
 
900
2:      mtc0    v0,C0_SR
901
        j       ra
902
END(clean_scache_nowrite_indexed)
903
 
904
/**************************************************************************
905
**
906
**  get_mem_conf - get memory configuration  R4000
907
**
908
***************************************************************************/
909
 
910
 
911
FRAME(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
 
923
ENDFRAME(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
 */
933
FRAME(set_memory_size,sp,0,ra)
934
        sw      a0, mem_size
935
        j       ra
936
ENDFRAME(set_memory_size)
937
 
938
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.