⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cach4101.mip

📁 psos for mips bsp
💻 MIP
📖 第 1 页 / 共 3 页
字号:

 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 + -