cache.s
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· S 代码 · 共 493 行
S
493 行
#include "kxmips.h"
#include "nkintr.h"
#define jalfix(func) \
jal func; \
nop;
#define KSEG0_BASE 0x80000000
#if R4000
#define INDEX_FILL_I 0x14
/*++
CacheInit:
This routine will initialize the cache tags and data for the
primary data cache, primary instruction cache, but not secondary cache
Subroutines are called to invalidate all of the tags in the
instruction and data caches.
Arguments:
None.
Return Value:
None.
Notes:
Copy from NT mips firmware -- paulsh, 03/22/95
--*/
LEAF_ENTRY(CacheInit)
.set noreorder
move s0,ra // save ra.
//
// Invalidate the caches
//
jalfix(InvalidateICache)
jalfix(InvalidateDCache)
#if 1
//
// Initialize the data cache(s)
//
//jalfix(InitDataCache)
//
// Fill the Icache, all icache lines
//
#if R4100
mfc0 s1, config // read config register
andi s2, s1, 0x1000 // mask off 12th bit, the "small cache flag"
beq zero, s2, CI_On_R4101
li s2, 16 // s2 = I cache line size [delay slot]
srl s1, s1, CONFIG_IC
andi s1, s1, 0x7
addi s1, s1, 10
li t0, 1
j CI_On_R410x
sllv s1, t0, s1 // s1 = I cache size [delay slot]
CI_On_R4101:
li s1, 2048 // s1 = I cache size
CI_On_R410x:
#else
mfc0 t5, config // read config register
nop
srl t0, t5, CONFIG_IC // compute instruction cache size
and t0, t0, 0x7 //
addu t0, t0, 12 //
li s1, 1 //
sll s1, s1, t0 // s1 = I cache size
srl t0, t5, CONFIG_IB // compute instruction cache line size
and t0, t0, 1 //
li s2, 16 //
sll s2, s2, t0 // s2 = I cache line size
#endif
ICacheStart:
#if R4100
li t1,KSEG0_BASE+(1<<20) // get virtual address to index cache
#else
li t1,KSEG0_BASE+(1<<20) // get virtual address to index cache
#endif
addu t0,t1,s1 // add I cache size
subu t0,t0,s2 // sub line size.
FillICache:
cache INDEX_FILL_I,0(t1) // Fill I cache from memory
cache INDEX_FILL_I,1(t1) //sudhakar
#if R4100
nop
#endif
bne t1,t0,FillICache // loop
addu t1,t1,s2 // increment index
//
// Invalidate the caches again
//
jalfix(InvalidateICache)
jalfix(InvalidateDCache)
#endif
move ra,s0 // move return address back to ra
j ra // return from routine
nop
.end
/*++
InvalidateICache:
This routine invalidates the contents of the instruction cache.
The instruction cache is invalidated by writing an invalid tag to
each cache line, therefore nothing is written back to memory.
Arguments:
None.
Return Value:
None.
--*/
LEAF_ENTRY(InvalidateICache)
.set noreorder
//
// invalid state
//
#if R4100
mfc0 t6, config // read config register
andi t7, t6, 0x1000 // mask off 12th bit, the "small cache flag"
beq zero, t7, IIC_On_R4101
li t7, 16 // s2 = I cache line size [delay slot]
srl t6, t6, CONFIG_IC
andi t6, t6, 0x7
addi t6, t6, 10
li t0, 1
j IIC_On_R410x
sllv t6, t0, t6 // s1 = I cache size [delay slot]
IIC_On_R4101:
li t6, 2048 // s1 = I cache size
IIC_On_R410x:
li t0,(PRIMARY_CACHE_INVALID << TAGLO_PSTATE)
mtc0 t0,taglo // set tag registers to invalid
mtc0 zero,taghi
#else
mfc0 t5,config // read config register
li t0,(PRIMARY_CACHE_INVALID << TAGLO_PSTATE)
mtc0 t0,taglo // set tag registers to invalid
mtc0 zero,taghi
srl t0,t5,CONFIG_IC // compute instruction cache size
and t0,t0,0x7 //
addu t0,t0,12 //
li t6,1 //
sll t6,t6,t0 // t6 = I cache size
srl t0,t5,CONFIG_IB // compute instruction cache line size
and t0,t0,1 //
li t7,16 //
sll t7,t7,t0 // t7 = I cache line size
#endif
//
// store tag to all icache lines
//
#if R4100
li t1,KSEG0_BASE+(1<<20) // get virtual address to index cache
#else
li t1,KSEG0_BASE+(1<<20) // get virtual address to index cache
#endif
addu t0,t1,t6 // get last index address
subu t0,t0,t7
WriteICacheTag:
cache INDEX_STORE_TAG_I,0(t1) // store tag in Instruction cache
cache INDEX_STORE_TAG_I,1(t1) //sudhakar
#ifdef R4100
nop
#endif
bne t1,t0,WriteICacheTag // loop
addu t1,t1,t7 // increment index
j ra
nop
.end InvalidateICache
/*++
InvalidateDCache:
This routine invalidates the contents of the D cache.
Data cache is invalidated by writing an invalid tag to each cache
line, therefore nothing is written back to memory.
Arguments:
None.
Return Value:
None.
--*/
LEAF_ENTRY(InvalidateDCache)
.set noreorder
//
// invalid state
//
#if R4100
mfc0 t6, config // read config register
andi t7, t6, 0x1000 // mask off 12th bit, the "small cache flag"
beq zero, t7, IDC_On_R4101
li t7, 16 // s2 = D cache line size [delay slot]
srl t6, t6, CONFIG_DC
andi t6, t6, 0x7
addi t6, t6, 10
li t0, 1
j IDC_On_R410x
sllv t6, t0, t6 // s1 = D cache size [delay slot]
IDC_On_R4101:
li t6, 1024 // s1 = D cache size
IDC_On_R410x:
li t0, (PRIMARY_CACHE_INVALID << TAGLO_PSTATE) | 0x02
mtc0 t0, taglo // set tag to invalid
mtc0 zero, taghi
#else
mfc0 t5, config // read config register for cache size
li t0, (PRIMARY_CACHE_INVALID << TAGLO_PSTATE) | 0x02
mtc0 t0, taglo // set tag to invalid
mtc0 zero, taghi
srl t0, t5, CONFIG_DC // compute data cache size
and t0, t0, 0x7 //
addu t0, t0, 12 //
li t6, 1 //
sll t6, t6, t0 // t6 = data cache size
srl t0, t5, CONFIG_DB // compute data cache line size
and t0, t0, 1 //
li t7, 16 //
sll t7, t7, t0 // t7 = data cache line size
#endif
//
// store tag to all Dcache
//
#if R4100
li t1, KSEG0_BASE+(1<<20) // get virtual address to index cache
#else
li t1, KSEG0_BASE+(1<<20) // get virtual address to index cache
#endif
addu t2, t1, t6 // add cache size
subu t2, t2, t7 // adjust for cache line size.
WriteDCacheTag:
cache INDEX_STORE_TAG_D, 0(t1) // store tag in Data cache
cache INDEX_STORE_TAG_D, 1(t1) //sudhakar
#if R4100
nop
#endif
bne t1, t2, WriteDCacheTag // loop
addu t1, t1, t7 // increment index by cache line
j ra
nop
.end InvalidateDCache
/*++
InitDataCache:
This routine initializes the data fields of the primary and
secondary data caches.
Arguments:
None.
Return Value:
None.
--*/
LEAF_ENTRY(InitDataCache)
.set noreorder
#if R4100
mfc0 t6, config // read config register
andi t7, t6, 0x1000 // mask off 12th bit, the "small cache flag"
beq zero, t7, InitDC_On_R4101
li t7, 16 // s2 = D cache line size [delay slot]
srl t6, t6, CONFIG_DC
andi t6, t6, 0x7
addi t6, t6, 10
li t0, 1
j InitDC_On_R410x
sllv t6, t0, t6 // s1 = D cache size [delay slot]
InitDC_On_R4101:
li t6, 1024 // s1 = D cache size
InitDC_On_R410x:
#else
mfc0 t5, config // read config register
nop
srl t0, t5, CONFIG_DC // compute data cache size
and t0, t0, 0x7 //
addu t0, t0, 12 //
li t6, 1 //
sll t6, t6, t0 // t6 = data cache size
srl t0, t5, CONFIG_DB // compute data cache line size
and t0, t0, 1 //
li t7, 16 //
sll t7, t7, t0 // t7 = data cache line size
#endif
//
// create dirty exclusive to all Dcache
//
#if R4100
li t1, KSEG0_BASE+(1<<20) // get virtual address to index cache
#else
li t1, KSEG0_BASE+(1<<20) // get virtual address to index cache
#endif
addu t2, t1, t6 // add cache size
subu t2, t2, t7 // adjust for cache line size.
WriteDCacheDe:
cache CREATE_DIRTY_EXCLUSIVE_D, 0(t1) // store tag in Data cache
cache CREATE_DIRTY_EXCLUSIVE_D, 1(t1) //sudhakar
nop
sd zero, 0(t1) // write
sd zero, 8(t1) // write
bne t1, t2, WriteDCacheDe // loop
addu t1, t1, t7 // increment index by cache line
j ra // return
nop
.end InitDataCache
/*
* macros to automate cache operations
*/
#define addr t0
#define maxaddr t1
#define mask t2
#define cacheop(kva, n, linesize, op) \
addu maxaddr, kva, n; \
subu mask, linesize, 1; \
not mask; \
and addr, kva, mask; \
addu maxaddr, -1; \
and maxaddr, mask; \
10: cache op,0(addr); \
cache op,1(addr); \
nop; \
bne addr, maxaddr, 10b; \
addu addr, linesize;
/*++
Routine Description:
Flush and invalidate DCache
Syntax:
void
FlushDCache(
void
);
Arguments:
-- none --
Return Value:
-- none --
--*/
LEAF_ENTRY(FlushDCache)
.set noreorder
#if R4100
mfc0 a1, config // read config register
andi a2, a1, 0x1000 // mask off 12th bit, the "small cache flag"
beq zero, a2, FDC_On_R4101
li a2, 16 // s2 = D cache line size [delay slot]
srl a1, a1, CONFIG_DC
andi a1, a1, 0x7
addi a1, a1, 10
li t0, 1
j FDC_On_R410x
sllv a1, t0, a1 // s1 = D cache size [delay slot]
FDC_On_R4101:
li a1, 1024 // s1 = D cache size
FDC_On_R410x:
#else
mfc0 t0, config // read config register
nop
srl t1, t0, CONFIG_DC // compute data cache size
and t1, t1, 0x7 //
addu t1, t1, 12 //
li a1, 1 //
sll a1, a1, t1 // a1 = D cache size
srl t1, t0, CONFIG_DB // compute data cache line size
and t1, t1, 1 //
li a2, 16 //
sll a2, a2, t1 // a2 = D cache line size
#endif
li a0, KSEG0_BASE
cacheop(a0, a1, a2, INDEX_WRITEBACK_INVALIDATE_D)
j ra
nop
.end
#if R4100
LEAF_ENTRY(CacheErrorHandler)
nop
nop
break 1
eret
.globl CacheErrorHandler_End
CacheErrorHandler_End:
.end CacheErrorHandler
#endif
/*++
Routine Description:
Flush and invalidate ICache
Syntax:
void
FlushICache(
void
);
Arguments:
-- none --
Return Value:
-- none --
--*/
LEAF_ENTRY(FlushICache)
.set noreorder
#if R4100
mfc0 a1, config // read config register
andi a2, a1, 0x1000 // mask off 12th bit, the "small cache flag"
beq zero, a2, FIC_On_R4101
li a2, 16 // s2 = I cache line size [delay slot]
srl a1, a1, CONFIG_IC
andi a1, a1, 0x7
addi a1, a1, 10
li t0, 1
j FIC_On_R410x
sllv a1, t0, a1 // s1 = I cache size [delay slot]
FIC_On_R4101:
li a1, 2048 // s1 = I cache size
FIC_On_R410x:
#else
mfc0 t0, config // read config register
nop
srl t1, t0, CONFIG_IC // compute instruction cache size
and t1, t1, 0x7 //
addu t1, t1, 12 //
li a1, 1 //
sll a1, a1, t1 // a1 = I cache size
srl t1, t0, CONFIG_IB // compute instruction cache line size
and t1, t1, 1 //
li a2, 16 //
sll a2, a2, t1 // a2 = I cache line size
#endif
li a0, KSEG0_BASE
cacheop(a0, a1, a2,INDEX_INVALIDATE_I)
j ra
nop
.end
#endif // R4000
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?