📄 cach4101.mip
字号:
//-----------------------------------
// clear_all not set - check lock bit before clearing
move $t1, $a0 // Let t1 hold current address
1:
lw $t2, 0($t1) // Load current tag
nop
and $t2, TAG_LOCK_BIT // test if lock bit set
bnez $t2, 2f // skip clear if lock bit is set
nop
sw $zero, 0($t1) // Clear out tag for this line
2:
bne $t1, $t0, 1b // loop till end ptr reached
add $t1, CACHE_LINE_SIZE // move ahead to next line (BD slot)
b clear_set1 // set 0 dene, now clear set 1
nop
//-----------------------------------
// clear_all is set - clear all lines
clear_all:
la $t1, CBSYS_ADDR // Set cache mode to i-cache set 0, tag access
li $t2, CBSYS_I0_TAG_MODE
sw $t2, 0($t1)
move $t1, $a0 // Let t1 hold current address
1:
sw $zero, 0($t1) // Clear out tag for this line
bne $t1, $t0, 1b // loop till end ptr reached
add $t1, CACHE_LINE_SIZE // move ahead to next line (BD slot)
//-----------------------------------
// Clear I-Cache Set 1
clear_set1:
la $t1, CBSYS_ADDR // Set cache mode to i-cache set 1, tag access
li $t2, CBSYS_I1_TAG_MODE
sw $t2, 0($t1)
move $t1, $a0 // Let t1 hold current address
1:
sw $zero, 0($t1) // Clear out tag for this line
bne $t1, $t0, 1b // loop till end ptr reached
add $t1, CACHE_LINE_SIZE // move ahead to next line (BD slot)
//-----------------------------------
// Return
8:
jr $ra
nop
//************************************************************************
// Function: clear_dcache
//
// Inputs: start_address - start address of area to be cleared
// length - size of area to be cleared
//
// Ouputs: None.
//
// Returns: Nothing.
//
// Description:
//
// Clear (invalidate) all lines in the data cache that correspond to
// the range of addresses given.
//
// 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
//
// t0 - end address
// t1 - current address ptr
// t2 - temp
//
//************************************************************************
clear_dcache:
beqz $a0, 8f // Just return if length = 0
nop
bltu $a1, D_CACHE_SIZE, 1f // Make sure length is less than cache size
nop
li $a1, D_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 D-Cache
la $t1, CBSYS_ADDR // Set cache mode to d-cache, tag access
li $t2, CBSYS_D_TAG_MODE
sw $t2, 0($t1)
move $t1, $a0 // Let t1 hold current address
1:
sw $zero, 0($t1) // Clear out tag for this line
bne $t1, $t0, 1b // loop till end ptr reached
add $t1, CACHE_LINE_SIZE // move ahead to next line (BD slot)
//-----------------------------------
// Return
8:
jr $ra
nop
//************************************************************************
// Function: lock_icache
//
// Inputs: start_address - start address of instructions to be locked
// length - range of instructions to be locked
//
// Ouputs: None.
//
// Returns: SUCCESS (0) or FAILURE (-1).
//
// Description:
//
// Load and lock range of instructions into I-Cache set 0, overwriting
// any existing locked instructions in the same range, if any.
//
// Size of instructions to be locked must fit entirely into i-cache
// set 0 (8192 bytes).
//
// Size of instructions to be locked must be an integral number of
// cache lines (16 bytes each).
//
// 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
//
// t0 - end address
// t1 - current address ptr
// t2 - uncached ptr / tag
//
// t3 - instruction word 1
// t4 - instruction word 2
// t5 - instruction word 3
// t6 - instruction word 4
//
// v0 - return code
//
//************************************************************************
lock_icache:
//-----------------------------------
// Check input parameters
beqz $a0, 8f // Length must be greater than 0
nop // else return success
and $v0, $a0, (CACHE_LINE_SIZE - 1) // Must start on line size boundary
bnez $v0, 9f // else return error
nop
bgtu $a1, I_CACHE_SIZE, 9f // Must fit in cache
nop // else return error
and $v0, $a1, (CACHE_LINE_SIZE - 1) // Length must be multiple of line size
bnez $v0, 9f // else return error
nop
//-----------------------------------
add $t0, $a0, $a1 // Set up end pointer for both loops
sub $t0, CACHE_LINE_SIZE // adjust end pointer back one to allow
// the increment instruction to be placed
// in the branch delay slot below
//-----------------------------------
// Load instructions
la $t1, CBSYS_ADDR // Set cache mode to i-cache set 0, data access
li $t2, CBSYS_I0_DATA_MODE
sw $t2, 0($t1)
move $t1, $a0 // ptr to instructions in cache
or $t2, $a0, KSEG1_BASE // ptr to instructions in uncached space
1:
lw $t3, 0($t2) // load instructions from uncached space
lw $t4, 4($t2) // entire line (4 words) are loaded
lw $t5, 8($t2)
lw $t6, 12($t2)
sw $t3, 0($t1) // store instructions in cache
sw $t4, 4($t1) // entire line (4 words) are stored
sw $t5, 8($t1)
sw $t6, 12($t1)
add $t2, CACHE_LINE_SIZE
bne $t1, $t0, 1b // loop till end ptr reached
add $t1, CACHE_LINE_SIZE // move ahead to next line (BD slot)
//-----------------------------------
// Load tags with lock and valid bits set
la $t1, CBSYS_ADDR // Set cache mode to i-cache set 0, tag access
li $t2, CBSYS_I0_TAG_MODE
sw $t2, 0($t1)
move $t1, $a0 // Let t1 hold current address
1:
and $t2, $t1, TAG_ADDR_BITS // get tag addr bits from current address
or $t2, TAG_VALID_LOCKED // set lock bit and 4 valid bits
sw $t2, 0($t1) // store tag
bne $t1, $t0, 1b // loop till end ptr reached
add $t1, CACHE_LINE_SIZE // move ahead to next line (BD slot)
//-----------------------------------
// Return Success
8:
move $v0, $zero // succes return (v0 = 0)
jr $ra
nop
//-----------------------------------
// Return Error
9:
sub $v0, $zero, 1 // eror return (v0 = -1)
jr $ra
nop
//************************************************************************
// Function: unlock_icache
//
// Inputs: start_address - start address of instructions to be unlocked
// length - range of instructions to be unlocked
//
// Ouputs: None.
//
// Returns: Nothing.
//
// Description:
//
// Unlock range of instructions in I-Cache set 0.
//
// Instructions are left in cache and still valid, but not locked.
//
// The range actually cleared is rounded to whole cache line bounaries.
//
// 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
//
// t0 - end address
// t1 - current address ptr
// t2 - tag
//
//************************************************************************
unlock_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 lock bit in tags - leave valid bits alone
la $t1, CBSYS_ADDR // Set cache mode to i-cache set 0, tag access
li $t2, CBSYS_I0_TAG_MODE
sw $t2, 0($t1)
move $t1, $a0 // Let t1 hold current address
1:
lw $t2, 0($t1) // load tag for this line
nop
and $t2, ~TAG_LOCK_BIT // clear lock bit only
sw $t2, 0($t1) // store tag
bne $t1, $t0, 1b // loop till end ptr reached
add $t1, CACHE_LINE_SIZE // move ahead to next line (BD slot)
//-----------------------------------
// Return
8:
jr $ra
nop
//************************************************************************
// End Of File
//************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -