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

📄 cach4101.mip

📁 psos for mips bsp
💻 MIP
📖 第 1 页 / 共 3 页
字号:
//************************************************************************
// Notice: Copyright (c) 2001 LSI Logic Corporation - All Rights Reserved 
//
// File Name: cach4101.s
//                                                  
// $Revision: /main/20010426_1.4_integration_branch/1.6_integration/1 $ 
//
// $Date: 27-Jan-2003.17:28:21 $
//
// Description: LSI 4102 Cache setup and maintainence routines.
//
//  All code contained in this file is specific to the LSI 4102 
//  processor core.
//
//  This file provides a set of API functions that can be used
//  to initialize, enable, disable, flush, or lock lines in the
//  cache.  
//
//  The high level API functions are all implemented in a similar 
//  manner, utilizing calls to the lower level service functions 
//  found at the end of the file.
//
//  The API functions are:
//
//      SysInitCache()
//      SysFlushCache()
//
//      SysEnableCache(cache_settings)
//      old_settings SysDisableCache()
//
//      SysInvalidateICache(start_addr, length)
//      SysInvalidateDCache(start_addr, length)
//
//      SysLockCache(start_addr, length)
//      SysUnlockCache(start_addr, length)
//
//  The service functions are:
//
//      disable_and_save()        - must be called first
//      restore_and_enable()
//
//      clear_icache(start_addr, length, clear_all)
//      clear_dcache(start_addr, length, clear_all)
//
//      lock_icache(start_addr, length)
//      unlock_icache(start_addr, length)
//  
//  The disable_and_save() function disables interrupts and
//  clears out the cache mode to disable all caches.  This 
//  function must be called first, before usings any of the other
//  service functions.  All of the other service functions require
//  that interrupts and caches are disabled before use.
// 
//  The disable_and_save() routine also performs a jump to uncached 
//  space on return.  The rest of the code following the disable will 
//  run in uncached space until the return from the API function.
//  The service routines also require to be run from uncached space.
//
//  Register Usage:
//  ---------------
//    Registers t8 and t9 are used by the disable_and_save() 
//    subroutine to store the original interupt and cache settings 
//    before disableing both.  Later the values are restored by the
//    restore_and_enable() from the same registers.
//
//    API functions must not modify t8 or t9 unless they are intending
//    to change the cache mode upon exit.  Service functions must not
//    modify t8 or t9 at all.
//
//    Current API functions use t7 to save the return address.
//    Service functions must not modify t7.
//       
//  Cache line locking:
//  -------------------
//    Instructions to be locked in cache must be fill a whole
//    number of lines.  It would be possible to fill only a few
//    words in a cache line, mark them valid, and lock the line,
//    but this would could still cause a line refill due to the 
//    other invalid words.  Also, there could be no benefit to
//    locking an invalid word in cache.  
//
//    For these reasons, the lock_icache() function requires that the
//    start_addr to be aligned to a cache line boundary (16 bytes),
//    and that the length be a multiple of the cache line size (16 bytes).
// 
// Warning:  Attempting to debug code locked in cache may not work.
//           Breakpoints set in memory will not be seen in cache.
//           Locked lines may be cleared out by the debugger itself 
//           if the cache is flushed by the debugger.
//
//************************************************************************

#ifdef __GNUC__
# include "gnuasm.a"
#else
# include "asmblr.a"
#endif

 CACHE_LINE_SIZE  = 16     // Cache line size in bytes (for all sets)
                           // Modifying this this requires code changes also
 
 I_CACHE_SIZE     = 8192   // i-cache size in bytes (each set, 2 sets)
 D_CACHE_SIZE     = 8192   // d-cache size in bytes (one set only)

 CBSYS_ADDR       = 0xBFFF0000  // Address of CBSYS register

 CBSYS_EN_I       = 0x00000001  // cache enable bits
 CBSYS_EN_I1      = 0x00000002
 CBSYS_EN_D       = 0x00000010

 CBSYS_IRS_MASK   = 0x0000000C
 CBSYS_IRS_1      = 0x00000000  // i-cache refill size bits
 CBSYS_IRS_2      = 0x00000004
 CBSYS_IRS_4      = 0x00000008
 CBSYS_IRS_8      = 0x0000000C

 CBSYS_DRS_MASK   = 0x00000060
 CBSYS_DRS_1      = 0x00000000  // d-cache refill size bits
 CBSYS_DRS_2      = 0x00000020  // setting > 1 requires DBE bit on, below
 CBSYS_DRS_4      = 0x00000040
 CBSYS_DRS_8      = 0x00000060

 CBSYS_DBE        = 0x00008000  // d-cache burst refill enable (DBE)

 CBSYS_CM_NORMAL  = 0x00000000  // cache mode select bits
 CBSYS_CM_I_DATA  = 0x00000100
 CBSYS_CM_I_TAG   = 0x00000200
 CBSYS_CM_D_TAG   = 0x00000300

 CBSYS_CACHE_MASK = 0x0000837F  // all bits used for cache settings
 
 // special cache modes to allow acces to the tag and data rams
 // Note: d-cache must always be enabled, even when using the i-cache modes
 CBSYS_D_TAG_MODE   = (CBSYS_CM_D_TAG  | CBSYS_EN_D)
 CBSYS_I0_TAG_MODE  = (CBSYS_CM_I_TAG  | CBSYS_EN_D | CBSYS_EN_I)
 CBSYS_I0_DATA_MODE = (CBSYS_CM_I_DATA | CBSYS_EN_D | CBSYS_EN_I)
 CBSYS_I1_TAG_MODE  = (CBSYS_CM_I_TAG  | CBSYS_EN_D | CBSYS_EN_I | CBSYS_EN_I1)

 TAG_LOCK_BIT     = 0x00000010  // tag lock bit only
 TAG_VALID_LOCKED = 0x0000001f  // tag lock bit plus 4 valid bits

 TAG_ADDR_BITS    = (~(I_CACHE_SIZE - 1))  // address bits used to match tag

 KSEG0_BASE       = 0x80000000  // start of cached space 
 KSEG1_BASE       = 0xA0000000  // start of uncached space

   
 .text
 .set noreorder 



//************************************************************************
// Function: SysInitCache
//
// Inputs:   None.
//
// Ouputs:   None.
//
// Returns:  Nothing.
//
// Description: Initialize the cache. 
//              - Invalidate the entire cache, clearing any locked lines.
//              - Cache is left disabled at end of the routine.
//
//************************************************************************
FRAME SysInitCache,$sp,0,$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

 li    $a0, KSEG0_BASE         // invalidate all of instruction cache
 li    $a1, I_CACHE_SIZE
 li    $a2, 1                  // clear locked lines
 bal   clear_icache
 nop

 li    $a0, KSEG0_BASE         // invalidate all of data cache
 li    $a1, D_CACHE_SIZE
 bal   clear_dcache
 nop 

 and   $t9, ~CBSYS_CACHE_MASK  // disabled all cache settings
                               // t9 is save location of original settings

 bal   restore_and_enable      // restore settings from t8 and t9
 nop                           // does not enable cache since we changed t9

 move  $ra, $t7                // restore return address

 jr    $ra                     // return
 nop

ENDFRAME SysInitCache



//************************************************************************
// Function: SysFlushCache
//
// Inputs:   None.
//
// Ouputs:   None.
//
// Returns:  Nothing.
//
// Description: Flush the cache. 
//              - Invalidate the entire cache.
//              - Lines locked in instruction cache are not cleared !
//
//************************************************************************
FRAME SysFlushCache,$sp,0,$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

 li    $a0, KSEG0_BASE         // invalidate all of instruction cache
 li    $a1, I_CACHE_SIZE
 li    $a2, 0                  // do not clear locked lines
 bal   clear_icache
 nop

 li    $a0, KSEG0_BASE         // invalidate all of data cache
 li    $a1, D_CACHE_SIZE
 bal   clear_dcache
 nop       

 bal   restore_and_enable      // restore settings from t8 and t9
 nop

 move  $ra, $t7                // restore return address

 jr    $ra                     // return
 nop

ENDFRAME SysFlushCache



//************************************************************************
// Function: SysEnableCache
//
// Inputs:   cache_mode - new cache mode.
//
// Ouputs:   None.
//
// Returns:  Nothing.
//
// Description: Enable cache with the specified mode (first argument).
//              - Cache should be flushed first before enabling if there 
//                is a chance that it may not be coherent.
//              - The following checks are performed on the requested 
//                setting:
//                o D-Cache refill disabled for SC2005-ES and older devices
//                o DBE enabled if DRS > 0
//              - Cache refills are disabled if EJTAG debug is required
//
//************************************************************************
FRAME SysEnableCache,$sp,1,$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

 and   $t9, ~CBSYS_CACHE_MASK  // clear all cache settings
                               // t9 is save location of original settings

 and   $a0, CBSYS_CACHE_MASK   // mask off input parameter
                               // only changes to cache settings are allowed

 // If EJTAG debug is required then the refill size of the caches must be 
 // set to zero, otherwise the probe may get out of sync.
#ifdef DEBUG_EJTAG
 and   $a0, ~(CBSYS_DRS_MASK | CBSYS_IRS_MASK)
#endif

 // Detect the chip revision. This is performed by attempting to write to the
 // SMCWDT2 register which is only available in SC2005-G11 and newer revisions. 
 // If the value read back is not the same as written then an ES or older part
 // is being used.
 li    $t0, 0xbe302024      // SMCWDT2 address
 li    $t1, 3737            // dummy value
 sw    $t1, 0($t0)       
 lw    $t0, 0($t0)
 nop                        // reqd by GHS to prevent a warning

 beq   $t1, $t0, SC2005_G11
 nop

SC2005_ES:
 // The ES and older revisions cannot use the D-Cache refill due to a 
 // hardware error (see the SC2000 errata.) Therefore clear the DRS field
 // prior to applying the settings.
 li    $t0, ~CBSYS_DRS_MASK
 b     apply_settings
 and   $a0, $a0, $t0
 
SC2005_G11:
 // On G11 and newer revisions DBE has to be set if DRS is greater than 0.
 // Check the value requested and enable DBE if required.
 and   $t0, $a0, CBSYS_DRS_MASK
 beqz  $t0, apply_settings
 nop
 
 ori   $a0, CBSYS_DBE

apply_settings:
 or    $t9, $a0                // apply new settings to save register

 bal   restore_and_enable      // restore settings from t8 and t9 
 nop                           // new settings are applied since we changed t9

 move  $ra, $t7                // restore return address

 jr    $ra                     // return
 nop

ENDFRAME SysEnableCache



//************************************************************************
// Function: SysDisableCache
//
// Inputs:   None.
//
// Ouputs:   None.
//
// Returns:  UINT32 - previous cache mode.
//
// Description: Disable all caches and return previous mode.
//
//************************************************************************
FRAME SysDisableCache,$sp,0,$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

 and   $v0, $t9, CBSYS_CACHE_MASK  // set return value to original settings
                                   // bits not related to cache are masked off

 and   $t9, ~CBSYS_CACHE_MASK  // disabled all cache settings
                               // t9 is save location of original settings

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -