cache.s

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· S 代码 · 共 493 行

S
493
字号
#include "kxmips.h"
#include "nkintr.h"

#define jalfix(func)     \
     jal  func;     \
     nop;

#define KSEG0_BASE 0x80000000

#if R4000

#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:

    Copy from NT mips firmware -- paulsh, 03/22/95

--*/
    LEAF_ENTRY(CacheInit)

    .set noreorder
        move    s0,ra                   // save ra.

    //
    // Invalidate the caches
    //
    jalfix(InvalidateICache)
    jalfix(InvalidateDCache)

#if 1
    //
    // Initialize the data cache(s)
    //
    //jalfix(InitDataCache)

    //
    // Fill the Icache,  all icache lines
    //

#if R4100
    mfc0    s1, config          // read config register
     andi s2, s1, 0x1000      // mask off 12th bit, the "small cache flag"
     beq       zero, s2, CI_On_R4101
     li        s2, 16                   // s2 = I cache line size [delay slot]
     srl       s1, s1, CONFIG_IC
     andi s1, s1, 0x7
     addi s1, s1, 10
     li        t0, 1
     j         CI_On_R410x
     sllv s1, t0, s1               // s1 = I cache size [delay slot]
CI_On_R4101:    
     li        s1, 2048            // s1 = I cache size
CI_On_R410x:
#else
    mfc0    t5, 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
#endif

ICacheStart:
#if R4100
    li      t1,KSEG0_BASE+(1<<20)       // get virtual address to index cache
#else
    li      t1,KSEG0_BASE+(1<<20)       // get virtual address to index cache
#endif    
    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
    cache   INDEX_FILL_I,1(t1)          //sudhakar
#if R4100
     nop
#endif    
    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
    j       ra                      // return from routine
    nop

    .end

/*++

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_ENTRY(InvalidateICache)

    .set noreorder
    //
    // invalid state
    //
#if R4100
    mfc0    t6, config          // read config register
     andi t7, t6, 0x1000      // mask off 12th bit, the "small cache flag"
     beq       zero, t7, IIC_On_R4101
     li        t7, 16                   // s2 = I cache line size [delay slot]
     srl       t6, t6, CONFIG_IC
     andi t6, t6, 0x7
     addi t6, t6, 10
     li        t0, 1
     j         IIC_On_R410x
     sllv t6, t0, t6               // s1 = I cache size [delay slot]
IIC_On_R4101:    
     li        t6, 2048            // s1 = I cache size
IIC_On_R410x:
    li      t0,(PRIMARY_CACHE_INVALID << TAGLO_PSTATE)
    mtc0    t0,taglo                // set tag registers to invalid
    mtc0    zero,taghi
#else
    mfc0    t5,config               // read config register
    li      t0,(PRIMARY_CACHE_INVALID << TAGLO_PSTATE)
    mtc0    t0,taglo                // set tag registers to invalid
    mtc0    zero,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
#endif    
    //
    // store tag to all icache lines
    //
#if R4100
    li      t1,KSEG0_BASE+(1<<20)   // get virtual address to index cache
#else
    li      t1,KSEG0_BASE+(1<<20)   // get virtual address to index cache
#endif    
    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
     cache   INDEX_STORE_TAG_I,1(t1) //sudhakar
#ifdef R4100
     nop
#endif         
    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_ENTRY(InvalidateDCache)

    .set noreorder
    //
    // invalid state
    //
#if R4100
    mfc0    t6, config          // read config register
     andi t7, t6, 0x1000      // mask off 12th bit, the "small cache flag"
     beq       zero, t7, IDC_On_R4101
     li        t7, 16                   // s2 = D cache line size [delay slot]
     srl       t6, t6, CONFIG_DC
     andi t6, t6, 0x7
     addi t6, t6, 10
     li        t0, 1
     j         IDC_On_R410x
     sllv t6, t0, t6               // s1 = D cache size [delay slot]
IDC_On_R4101:    
     li        t6, 1024            // s1 = D cache size
IDC_On_R410x:
    li      t0, (PRIMARY_CACHE_INVALID << TAGLO_PSTATE) | 0x02
    mtc0    t0, taglo           // set tag to invalid
    mtc0    zero, taghi
#else     
    mfc0    t5, config          // read config register for cache size
    li      t0, (PRIMARY_CACHE_INVALID << TAGLO_PSTATE) | 0x02
    mtc0    t0, taglo           // set tag to invalid
    mtc0    zero, 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
#endif

    //
    // store tag to all Dcache
    //
#if R4100
    li      t1, KSEG0_BASE+(1<<20)      // get virtual address to index cache
#else
    li      t1, KSEG0_BASE+(1<<20)      // get virtual address to index cache
#endif    
    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
    cache   INDEX_STORE_TAG_D, 1(t1)    //sudhakar
#if R4100 
     nop
#endif    
    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_ENTRY(InitDataCache)

    .set noreorder
#if R4100
    mfc0    t6, config          // read config register
     andi t7, t6, 0x1000      // mask off 12th bit, the "small cache flag"
     beq       zero, t7, InitDC_On_R4101
     li        t7, 16                   // s2 = D cache line size [delay slot]
     srl       t6, t6, CONFIG_DC
     andi t6, t6, 0x7
     addi t6, t6, 10
     li        t0, 1
     j         InitDC_On_R410x
     sllv t6, t0, t6               // s1 = D cache size [delay slot]
InitDC_On_R4101:    
     li        t6, 1024            // s1 = D cache size
InitDC_On_R410x:
#else     
    mfc0    t5, 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
#endif

    //
    // create dirty exclusive to all Dcache
    //
#if R4100
    li      t1, KSEG0_BASE+(1<<20)  // get virtual address to index cache
#else
    li      t1, KSEG0_BASE+(1<<20)  // get virtual address to index cache
#endif    
    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
    cache   CREATE_DIRTY_EXCLUSIVE_D, 1(t1) //sudhakar
    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
/*
 * 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);                 \
    cache   op,1(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_ENTRY(FlushDCache)

.set noreorder
#if R4100
    mfc0    a1, config          // read config register
     andi a2, a1, 0x1000      // mask off 12th bit, the "small cache flag"
     beq       zero, a2, FDC_On_R4101
     li        a2, 16                   // s2 = D cache line size [delay slot]
     srl       a1, a1, CONFIG_DC
     andi a1, a1, 0x7
     addi a1, a1, 10
     li        t0, 1
     j         FDC_On_R410x
     sllv a1, t0, a1               // s1 = D cache size [delay slot]
FDC_On_R4101:    
     li        a1, 1024            // s1 = D cache size
FDC_On_R410x:
#else     
    mfc0    t0, 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
#endif
    li      a0, KSEG0_BASE
    cacheop(a0, a1, a2, INDEX_WRITEBACK_INVALIDATE_D)
    j   ra
    nop
    .end

#if R4100
LEAF_ENTRY(CacheErrorHandler)
     nop
     nop
     break     1
     eret
     .globl    CacheErrorHandler_End
CacheErrorHandler_End:

     .end CacheErrorHandler
#endif

/*++

Routine Description:

    Flush and invalidate ICache

Syntax:

    void
    FlushICache(
        void
        );

Arguments:

    -- none --

Return Value:

    -- none --

--*/
    LEAF_ENTRY(FlushICache)

.set noreorder
#if R4100
    mfc0    a1, config          // read config register
     andi a2, a1, 0x1000      // mask off 12th bit, the "small cache flag"
     beq       zero, a2, FIC_On_R4101
     li        a2, 16                   // s2 = I cache line size [delay slot]
     srl       a1, a1, CONFIG_IC
     andi a1, a1, 0x7
     addi a1, a1, 10
     li        t0, 1
     j         FIC_On_R410x
     sllv a1, t0, a1               // s1 = I cache size [delay slot]
FIC_On_R4101:    
     li        a1, 2048            // s1 = I cache size
FIC_On_R410x:
#else
    mfc0    t0, 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
#endif
    li      a0, KSEG0_BASE
    cacheop(a0, a1, a2,INDEX_INVALIDATE_I)
    j   ra
    nop
    .end

#endif    // R4000

⌨️ 快捷键说明

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