📄 cache.s
字号:
/*
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
// Cache control
// Platform independent
*/
#include <asm.h>
#include <mipsreg.h>
#include <cpureg.h>
#include <cache.h>
#define jalfix(func) \
jal func; \
nop;
#define KSEG0_BASE 0x80000000
#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:
--*/
.globl CacheInit
.ent CacheInit
.set noreorder
CacheInit:
move s0,ra /* save ra.*/
nop
/*
// Invalidate the caches
*/
jalfix(InvalidateICache)
jalfix(InvalidateDCache)
#if 1
/*
# Initialize the data cache(s)
*/
jalfix(InitDataCache)
/*
# Fill the Icache, all icache lines
*/
mfc0 t5, CP0_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*/
ICacheStart:
li t1,KSEG0_BASE+(1<<20) /*get virtual address to index cache*/
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*/
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*/
nop
j ra /* return from routine*/
nop
.end CacheInit
/*++
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(InvalidateICache)
.set noreorder
/*
// invalid state
*/
mfc0 t5,CP0_CONFIG /* read config register*/
li t0,(PRIMARY_CACHE_INVALID << TAGLO_PSTATE)
mtc0 t0,CP0_TAGLO /* set tag registers to invalid*/
mtc0 zero,CP0_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*/
/*
//store tag to all icache lines
*/
li t1,KSEG0_BASE+(1<<20) /* get virtual address to index cache*/
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*/
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(InvalidateDCache)
.set noreorder
/*
// invalid state
*/
mfc0 t5, CP0_CONFIG /*read config register for cache size*/
li t0, (PRIMARY_CACHE_INVALID << TAGLO_PSTATE) | 0x02
mtc0 t0, CP0_TAGLO /*set tag to invalid*/
mtc0 zero, CP0_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*/
/*
# store tag to all Dcache
*/
li t1, KSEG0_BASE+(1<<20) /* get virtual address to index cache*/
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*/
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(InitDataCache)
.set noreorder
mfc0 t5, CP0_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*/
/*
# create dirty exclusive to all Dcache
*/
li t1, KSEG0_BASE+(1<<20) /*# get virtual address to index cache*/
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*/
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
/*
R4Kcache.s: R4000 cache support functions for SDE-MIPS
(C) 1997 Algorithmics Ltd
*/
/*
* 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); \
nop; \
bne addr, maxaddr, 10b; \
addu addr, linesize;
/*++
Routine Description:
Flush and invalidate DCache
Syntax:
void
FlushDCache(
void
);
Arguments:
-- none --
Return Value:
-- none --
--*/
LEAF(FlushDCache)
.set noreorder
mfc0 t0, CP0_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*/
li a0, KSEG0_BASE
cacheop(a0, a1, a2, INDEX_WRITEBACK_INVALIDATE_D)
j ra
nop
.end
/*++
Routine Description:
Flush and invalidate ICache
Syntax:
void
FlushICache(
void
);
Arguments:
-- none --
Return Value:
-- none --
--*/
LEAF(FlushICache)
.set noreorder
mfc0 t0, CP0_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*/
li a0, KSEG0_BASE
cacheop(a0, a1, a2,INDEX_INVALIDATE_I)
j ra
nop
.end
/*
# Cache error exception handler
*/
LEAF(CacheErrorHandler)
.set noreorder
.set noat
nop
nop
break 1
eret
.globl CacheErrorHandler_End
CacheErrorHandler_End:
.set reorder
.set at
.end CacheErrorHandler
LEAF(DelayDisplay1)
.set noreorder
/* li a0,0x01000*/
li a0,0x06000
testloop:
subu a0,0x1
nop
beqz a0,testend
nop
b testloop
nop
testend:
j ra
nop
.end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -