📄 cach4101.mip
字号:
bal restore_and_enable // restore settings from t8 and t9
nop // does not enable cache since we changed t9
// does not modify v0
move $ra, $t7 // restore return address
jr $ra // return
nop
ENDFRAME SysDisableCache
//************************************************************************
// Function: SysInvalidateICache
//
// Inputs: address - start address of area to be cleared from i-cache.
// length - size of area to be cleared from i-cache.
//
// Ouputs: None.
//
// Returns: Nothing.
//
// Description: Invaildate (clear) range of memory from instruction cache.
// - Both instruction caches are cleared, even if not enabled.
// - Actual range cleared is rounded to cache line boundaries.
// - Locked lines are not cleared !
//
//************************************************************************
FRAME SysInvalidateICache,$sp,2,$ra
move $t7, $ra // save return address,
// t7 will be preserved across calls
bal disable_and_save // disable and save settings in t8 and t9
nop // t8 and t9 will be preserved across calls
// args a0 and a1 were not modified by the
// above call, and are passed in on the
// following call as the first two args
li $a2, 0 // third arg, do not clear locked lines
bal clear_icache // invalidate range of instruction cache
nop
bal restore_and_enable // restore settings from t8 and t9
nop
move $ra, $t7 // restore return address
jr $ra // return
nop
ENDFRAME SysInvalidateICache
//************************************************************************
// Function: SysInvalidateDCache
//
// Inputs: address - start address of area to be cleared from d-cache.
// length - size of area to be cleared from d-cache.
//
// Ouputs: None.
//
// Returns: Nothing.
//
// Description: Invaildate (clear) range of memory from data cache.
// - Actual range cleared is rounded to cache line boundaries.
//
//************************************************************************
FRAME SysInvalidateDCache,$sp,2,$ra
move $t7, $ra // save return address,
// t7 will be preserved across calls
bal disable_and_save // disable and save settings in t8 and t9
nop // t8 and t9 will be preserved across calls
// args a0 and a1 were not modified by the
// above call, and are passed in on the
// following call as the args
bal clear_dcache // invalidate range of data cache
nop
bal restore_and_enable // restore settings from t8 and t9
nop
move $ra, $t7 // restore return address
jr $ra // return
nop
ENDFRAME SysInvalidateDCache
//************************************************************************
// Function: SysLockCache
//
// Inputs: address - start address of area to be locked in i-cache.
// length - size of area to be locked in i-cache.
//
// Ouputs: None.
//
// Returns: SUCCESS (0) or FAILURE (-1).
//
// Description: Lock range of instructions into i-cache set 0.
// - Size is limited to size of i-cache set 0 (8192 bytes).
// - Size must be integral number of cache lines (16 bytes each).
// - Range is also cleared from i-cache set 1 to insure coherency.
//
//************************************************************************
FRAME SysLockCache,$sp,2,$ra
move $t7, $ra // save return address,
// t7 will be preserved across calls
bal disable_and_save // disable and save settings in t8 and t9
nop // t8 and t9 will be preserved across calls
// args a0 and a1 were not modified by the
// above call, and are passed in on the
// following call as the first two args
li $a2, 1 // third arg, clear locked lines
bal clear_icache // clear range before locking
nop // this is mainly to be sure set 1 does not
// contain tags that might match the locked code
bal lock_icache // lock code into i-cache set 0
nop // return code is placed in v0
bal restore_and_enable // restore settings from t8 and t9
nop // call does not modify v0
move $ra, $t7 // restore return address
jr $ra // return
nop
ENDFRAME SysLockCache
//************************************************************************
// Function: SysUnlockCache
//
// Inputs: address - start address of area to be unlocked from i-cache.
// length - size of area to be unlocked from i-cache.
//
// Ouputs: None.
//
// Returns: Nothings.
//
// Description: Unlock range of instructions in i-cache set 0.
// - Actual range unlocked is rounded to cache line boundaries.
// - Instructions remain as valid cache lines.
//
//************************************************************************
FRAME SysUnlockCache,$sp,2,$ra
move $t7, $ra // save return address,
// t7 will be preserved across calls
bal disable_and_save // disable and save settings in t8 and t9
nop // t8 and t9 will be preserved across calls
// args a0 and a1 were not modified by the
// above call, and are passed in on the
// following call as the args
bal unlock_icache // unlock code in i-cache set 0
nop
bal restore_and_enable // restore settings from t8 and t9
nop
move $ra, $t7 // restore return address
jr $ra // return
nop
ENDFRAME SysUnlockCache
//*****************************************************************************
//*****************************************************************************
//****
//**** Start of service functions.
//****
//**** These routines should not be called directly from outside this file.
//**** They are intended to be called from the above API functions only.
//**** They expect interrupts to be disabled and all caches are also disabled.
//**** They do not modify registers t7, t8, t9.
//****
//*****************************************************************************
//*****************************************************************************
//************************************************************************
// Function: disable_and_save
//
// Inputs: None.
//
// Ouputs: None.
//
// Returns: Nothing.
//
// Description: Disable and save settings in registers
// - Disable interrupts and both caches.
// - Save current settings in t8 and t9.
// - Return running in uncached space.
//
// Register Usage:
// ---------------
// t0 - temp
//
// t8 - saved C0_STATUS register
// t9 - saved CBSYS register
//
//************************************************************************
disable_and_save:
mfc0 $t8, COPROC_ZERO_SR // Save STATUS register value in t8
nop
nop
and $t0, $t8, ~SR_IE // Disable all interrupts
mtc0 $t0, COPROC_ZERO_SR
nop
nop
la $t0, CBSYS_ADDR // Save CBSYS register value in t9
lw $t9, 0($t0)
sw $zero, 0($t0) // Disable Caches, MMU, Write Buffer, Read Priority
lw $zero, 0($t0) // Flush the write buffer
or $ra, KSEG1_BASE // Modify return address to kseg1 (uncached)
jr $ra // return
nop
//************************************************************************
// Function: restore_and_enable
//
// Inputs: None.
//
// Ouputs: None.
//
// Returns: Nothing.
//
// Description: Restore cache mode and interrupts from saved settings
// - Settings were saved in t8 and t9.
//
// Register Usage:
// ---------------
// t0 - temp
//
// t8 - saved C0_STATUS register
// t9 - saved CBSYS register
//
//************************************************************************
restore_and_enable:
la $t0, CBSYS_ADDR // Restore CBSYS from saved value in t9
sw $t9, 0($t0)
mtc0 $t8, COPROC_ZERO_SR // Re-enable interrupts
nop
nop
jr $ra // return
nop
//************************************************************************
// Function: clear_icache
//
// Inputs: start_address - start address of area to be cleared
// length - size of area to be cleared
// clear_all - if non-zero, clear lines even if locked in set 0
//
// Ouputs: None.
//
// Returns: Nothing.
//
// Description:
//
// Clear (invalidate) all lines in the instruction cache that correspond
// to the range of addresses given.
//
// Locked lines are not cleared unless the clear_all flag is specified.
//
// The range actually cleared is rounded to whole cache line bounaries.
//
// The tag entries are not checked before clearing the data,
// thus valid cache lines in the specified range will still
// be cleared even if the tags refer to an entirely different
// page.
//
// This is a local function and it is expected that the CBSYS register
// has been saved and cleared (cache disabled) before calling.
//
// This function does not modify registers t7, t8, t9.
// For registers used see below.
//
//---------------------------------------------------------------------
// Register Usage:
// ---------------
// a0 - start address
// a1 - length
// a3 - clear all (clear locked lines)
//
// t0 - end address
// t1 - current address ptr
// t2 - tag
//
//************************************************************************
clear_icache:
beqz $a0, 8f // Just return if length = 0
nop
bltu $a1, I_CACHE_SIZE, 1f // Make sure length is less than cache size
nop
li $a1, I_CACHE_SIZE // else force length = cache size
1:
add $t0, $a0, $a1 // End address = start address + length
and $a0, ~(CACHE_LINE_SIZE - 1) // Round start address to begining of line
add $t0, (CACHE_LINE_SIZE - 1) // Rounded end address to end of line
and $t0, ~(CACHE_LINE_SIZE - 1)
sub $t0, CACHE_LINE_SIZE // adjust end pointer back one to allow
// the increment instruction to be placed
// in the branch delay slot below
//-----------------------------------
// Clear I-Cache Set 0
la $t1, CBSYS_ADDR // Set cache mode to i-cache set 0, tag access
li $t2, CBSYS_I0_TAG_MODE
sw $t2, 0($t1)
//-----------------------------------
bnez $a2, clear_all // test if 'clear all' option set
nop
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -