1
0
Files
irix-657m-src/stand/arcs/IP32prom/lib/caches/r5000_cache.s
2022-09-29 17:59:04 +03:00

275 lines
15 KiB
ArmAsm

/**************************************************************************
* *
* Copyright (C) 1996, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
#include <sys/asm.h>
#include <sys/cpu.h>
#include <sys/regdef.h>
#include <sys/sbd.h>
#include <caches.h>
#undef SIM
/* #define SIM 1 */
/********************
* r5000_cache_config
* ------------------
* Initialize cache data structures
*/
NESTED(r5000_cache_config,framesize,ra)
subu sp, framesize /* create current stack frame. */
.set noat /* disable AT macro replacement. */
sd AT, regsave-0x00(sp) /* save AT register. */
.set at /* enable AT macro replacement. */
sd ra, regsave-0x08(sp) /* save return address. */
sd a0, regsave-0x10(sp) /* save a0 */
sd t0, regsave-0x18(sp) /* save t0 */
sd t1, regsave-0x20(sp) /* save t1 */
sd t2, regsave-0x28(sp) /* save t2 */
/*
* Configure the primary cache.
*/
.set noreorder /* turn off assembler reordering */
mfc0 a0, C0_CONFIG /* read the config register. */
nop /* one nop just in case. */
.set reorder /* turn on assembler reordering */
jal cm_r4400_pcache_config /* configure the pdcache. */
/*
* Configure the 2 set primary cache.
*/
lw t2, _dcache_size /* read the cache line size. */
srl t2, 1 /* one set is half of the cache */
sw t2, _two_set_pcaches /* reported in configuration reg. */
lw t1, _icache_size /* it also applied to icache. */
srl t1, 1 /* cut the size in half. */
sw t1, _two_set_icaches /* and save it. */
/*
* Configure the secondary cache.
* The SS field (11/25/95) = 0 - 512K byte,
* 1 - 1M byte,
* 2 - 2M byte,
* 3 - Error, currently reserved
* NOTE:::
* For triton implementation the Config register bit 17 will
* set to '1' if there is 'NO' secondary cache presented, and
* set to '0' otherwise.
* Config[17] = 1 <---> No secondary cache.
* Config[17] = 0 <---> with secondary cache.
*/
and t0, a0, CONFIG_TR_SC /* check 2nd cache. */
#if defined(SIM)
beqz t0, 10f /* skip the 2nd cache configuration */
#else
bnez t0, 10f /* skip the 2nd cache configuration */
#endif
and t1, a0, CONFIG_TR_SS /* extract sidcache size. */
srl t1, CONFIG_TR_SS_SHFT /* move to bit 0 */
li t2, 2 /* Check for error boundary. */
bgt t1, t2, 10f /* Error case configure as no 2cache*/
lui t2, (0x80000 >> 16) /* With 512K increment base. */
sllv t2, t1 /* This is scache size. */
sw t2, _sidcache_size /* Reports size in Triton Scache. */
sw t2, _r4600sc_sidcache_size /* Reports size in 4600 size, */
li t1, R4600_SCACHE_LINESIZE /* Same linesize as cm_4600 */
sw t1, _scache_linesize /* save the cache line size. */
subu t1, 1 /* Line mask is linesize -1 */
sw t1, _scache_linemask /* save cache line mask. */
sw t1, dmabuf_linemask /* and dma buffer line mask. */
/*
* Configure the logical cache op table.
*/
10: li a0, PIlcops+PDlcops /* ignore 2nd cache ops for now. */
jal cm_r4400_config_lcoptab /* setup logical cache op table. */
la t0, lcoptab /* now initialize the 2nd cache ops */
la t1, unsupported_cacheop /* with unsupported cache op - nop */
addiu t0, (PIlcops+PDlcops)<<2 /* the entry point of the 2nd */
li t2, SIDlcops /* loadup the sid lcops counter. */
12: sw t1, 0(t0) /* initialize the table entries. */
sub t2, 1 /* decrement the lcop counter. */
addiu t0, 4 /* point to next entries. */
bgtz t2, 12b /* loop for SIDlcops entries. */
/*
* Initialize the flush all pointer
*/
la t2, cm_r5000_flush_all /* initialize the flush all pointer */
sw t2, _flushAllCache /* initialize the variable. */
la t1, cm_r5000_cache_valid /* load the validate check func */
sw t1, _validCacheAddr /* and initialize the func pointer */
li t2, FAKE2ND /* r5k has a faked 2nd cache. */
sw t2, _scache_type /* initialize the cache type. */
/*
* Done!!
*/
.set noat /* disable AT macro replacement. */
ld AT, regsave-0x00(sp) /* save AT register. */
.set at /* enable AT macro replacement. */
ld ra, regsave-0x08(sp) /* save return address. */
ld a0, regsave-0x10(sp) /* save a0 */
ld t0, regsave-0x18(sp) /* save t0 */
ld t1, regsave-0x20(sp) /* save t1 */
ld t2, regsave-0x28(sp) /* save t2 */
addiu sp, framesize /* create current stack frame. */
jr ra
END(r5000_cache_config)
/********************
* cm_r5000_flush_all
* ------------------
* Initialize cache variables for primary caches.
*/
LEAF(cm_r5000_flush_all)
sub sp, framesize /* create current stack frame. */
sd t0, regsave-0x08(sp) /* save t0 */
sd t1, regsave-0x10(sp) /* save t1 */
sd t2, regsave-0x18(sp) /* save t2 */
sd t3, regsave-0x20(sp) /* save t3 */
sd t4, regsave-0x28(sp) /* save t4 */
/*
* jump to kseg1 base
*/
la t0, 20f /* load target address. */
lui t1, K1BASE>>16 /* load the Kseg Base address */
or t0, t1 /* form the uncache address. */
jr t0 /* branch to uncached addr sequence */
/*
* Flush icache
*/
20: lw t0, _icache_size /* load the icache size. */
lw t1, _icache_linesize /* load the icache line size. */
25: sub t0, t1 /* point to previous line. */
bltz t0, 30f /* are we done yet ?? */
lui t2, K0BASE>>16 /* load the KSEG0 base address */
or t2, t0 /* this is the cache line index */
.set noreorder /* disable assembler reordering */
b 25b /* go back for next line. */
cache CACH_PI|C_IINV, 0(t2) /* use index writeback invalidate */
.set reorder /* enable assembler reordering */
/*
* Flush dcache
*/
30: lw t0, _dcache_size /* load the dcache size. */
lw t1, _dcache_linesize /* load the dcache line size */
lw t3, _sidcache_size /* load the 2nd cache size */
lw t4, _scache_linesize /* and 2nd cache line size. */
35: sub t0, t1 /* point to last line in dcache. */
bltz t0, 40f /* are we done yet?? */
lui t2, K0BASE>>16 /* load the KSEG0 base address */
or t2, t0 /* this is the cache line index */
.set noreorder /* disable assembler reordering */
b 35b /* go back for next line. */
cache CACH_PD|C_IWBINV, 0(t2) /* use index writeback invalidate */
.set reorder /* enable assembler reordering */
/*
* Dcone!!
*/
40: ld t0, regsave-0x08(sp) /* load t0 */
ld t1, regsave-0x10(sp) /* load t1 */
ld t2, regsave-0x18(sp) /* load t2 */
ld t3, regsave-0x20(sp) /* load t3 */
ld t4, regsave-0x28(sp) /* load t4 */
addiu sp, framesize /* restore previous jstack frame */
jr ra /* return */
END(cm_r5000_flush_all)
/***********************
* cm_r5000_cache_valid
* ---------------------
* Return 1 if there is a valid cache line match the given VA
* 0 if there is no match in all 4 caches.
* Note: We don't care about the secondary cache in R5000 because
* its a write back cache, there is no conflict between memory/2nd
* cache.
*/
NESTED(cm_r5000_cache_valid,framesize,ra)
subu sp, framesize /* create current stack frame. */
.set noat /* disable AT macro replacement. */
sd AT, regsave-0x00(sp) /* save AT register. */
.set at /* enable AT macro replacement. */
sd ra, regsave-0x08(sp) /* save return address. */
sd t0, regsave-0x10(sp) /* save t0 */
sd t1, regsave-0x18(sp) /* save t1 */
sd t2, regsave-0x20(sp) /* save t2 */
sd a0, regsave-0x28(sp) /* save a0 */
/*
* Check primary cache set 0
*/
lw t0, _dcache_linemask /* read the line size. */
not t0 /* create the line address mask */
and t1, a0, t0 /* create line address. */
.set noreorder /* disable assembler reordering */
cache CACH_PD|C_ILT, 0(t1) /* read the set0 Tags. */
nop /* 1 nop */
nop /* 2 nop */
mfc0 t0, C0_TAGLO /* read the taglo register. */
nop /* 1 nop */
nop /* 2 nop */
.set reorder /* enable assembler reordering */
srl t0, 6 /* check the PState */
andi t2, t0, 3 /* isolate the State bits. */
beqz t2, 10f /* check set 1 if invalid */
srl t0, 2 /* Physical addr<35:12> */
sll t2, a0 3 /* remove upper 3 bits of the VA */
srl t2, 15 /* and extract ADDR<35:12> */
bne t0, t2, 10f /* does not match check set 1 */
li v0, 1 /* there is a match in set 0 */
b 30f /* done, return to caller. */
/*
* Check primary cache set 1
*/
10: lw t0, _two_set_pcaches /* get ther set size */
or t1, t0 /* create 2nd set index. */
.set noreorder /* disable assembler reordering */
cache CACH_PD|C_ILT, 0(t1) /* read the set1 Tags. */
nop /* 1 nop */
nop /* 2 nop */
mfc0 t0, C0_TAGLO /* read the taglo register. */
nop /* 1 nop */
nop /* 2 nop */
.set reorder /* enable assembler reordering */
srl t0, 6 /* check the PState */
andi t2, t0, 3 /* isolate the State bits. */
beqz t2, 20f /* check 2nd set 0 if invalid */
srl t0, 2 /* Physical addr<35:12> */
sll t2, a0 3 /* remove upper 3 bits of the VA */
srl t2, 15 /* and extract ADDR<35:12> */
bne t0, t2, 20f /* does not match check set 1 */
li v0, 1 /* there is a match in set 0 */
b 30f /* done, return to caller. */
/* There is no matched valid cache */
20: move v0, zero /* line in neither cahce. */
/* return 0 */
/*
* We are done, v0 should have the return value
*/
.set noat /* disable AT macro replacement. */
30: ld AT, regsave-0x00(sp) /* save AT register. */
.set at /* enable AT macro replacement. */
ld ra, regsave-0x08(sp) /* save return address. */
ld t0, regsave-0x10(sp) /* save t0 */
ld t1, regsave-0x18(sp) /* save t1 */
ld t2, regsave-0x20(sp) /* save t2 */
ld a0, regsave-0x28(sp) /* save a0 */
addiu sp, framesize /* create current stack frame. */
jr ra /* return */
END(cm_r5000_cache_valid)
/********************************************************************\
|* LOW LEVEL CACHE OPS *|
\********************************************************************/
/* END OF FILE */
/* SECONDART DATA/INSTRUCTION CACHE */
/* PROM NEVER TURN ON R5000 2ND CACHE ANYWAY - */
/* LATER */
/* END OF FILE */