www.pudn.com > vxworks0108.rar > sysL2BackCache.s


/* sysL2BackCache.s - L2 cache functions */

/* Copyright 1984-2000 Wind River Systems, Inc. */
/* Copyright 1996-1998 Motorola, Inc. */

/*
modification history
--------------------
01a,31jan01,BeM   written (from 01d sp755/sysL2BackCache.s)
*/

/* includes */

#define _ASMLANGUAGE
#include "type.h"
#include "reg.h"
#include "ppc750.h"
#include "sysL2BackCache.h"


    /* globals */

    .globl  sysL2BackGlobalInv
    .globl  sysL2BackFlush
    .globl  sysL2BackDisable
    .globl  sysL2BackEnable
    .globl  sysL2BackAutoSize
    .globl  sysL1DcacheEnable
    .globl  sysPVRReadBoot
    .globl  sysL1DcacheDisable
    .globl  sysL2CRWrite
    .globl  sysL2BackInit
    .globl  sysL2CRRead
    .globl  sysHID0Write
    .globl  sysHID0Read
#if defined(INCLUDE_L2PM) && defined(SP755)
    .globl  sysL2PMEnable
#endif /* INCLUDE_L2PM && SP755 */

#define DSSALL   .long 0x7e000c6c


/*********************************************************************
* sysL2BackGlobalInv - Globally invalidate L2 backside cache
*
* This function reads the value of the l2cr register, disables
* the cache, before setting the global invalidate bit.  It waits
* for the L2CR[L2IP] bit is clear before returning to the caller.
*
* RETURNS: N/A

* void sysL2BackGlobalInv
*     (
*     void
*     )

*/

sysL2BackGlobalInv:

    isync

    sync
    mfspr   r3, L2CR_REG
    andis.  r3, r3, L2CR_DISABLE_MASK_U  /* disable L2 cache*/
    mtspr   L2CR_REG, r3
    sync

    oris    r3, r3, L2CR_GBL_INV_U      /* set global invalidate command */
    mtspr   L2CR_REG, r3
    sync

/*
* Monitoring the L2CR[L2IP] bit to determine when the global
* invalidation operation is completed.
*/

invalidate_in_progress:
    mfspr   r3, L2CR_REG
    andi.   r3, r3, L2CR_IP
    bne     invalidate_in_progress


    sync
    mfspr   r3, L2CR_REG
    rlwinm  r3, r3, 0, 11, 9         /* zero out the invalidate bit*/
    mtspr   L2CR_REG, r3
    sync

    blr

/*********************************************************************
* sysL2BackFlush - Flush L2 backside cache
*
* This function reads the value of the l2cr register and sets the
* hardware flush bit (L2HWF).  It waits for the L2CR[L2HWF] bit is clear
* before returning to the caller.
*
* NOTE: The L2HWF bit is not implemented in 750 and 755 PPC processors,
*       but in the 7400.
*
* RETURNS: N/A

* void sysL2BackFlush
*     (
*     void
*     )

*/

sysL2BackFlush:

    sync
    mfspr   r3, L2CR_REG
    sync
    ori     r3, r3, L2CR_HWF      /* set flush bit*/
    mtspr   L2CR_REG, r3
    sync

/*
* Monitoring the L2CR[L2HWF] bit to determine when the flush
* operation is completed.
*/

flush_in_progress:
    mfspr   r3, L2CR_REG
    andi.   r3, r3, L2CR_HWF
    bne     flush_in_progress

    sync

    blr

/*********************************************************************
*  sysL2BackEnable - Set and enable L2 backside cache
*
* RETURNS: N/A

* void sysL2BackEnable
*     (
*     ULONG value                 /@ the value to be set is passed in r3 @/
*     )

*/

sysL2BackEnable:
    sync
    eieio
    isync
    mfspr   r3, L2CR_REG
    oris    r3, r3, L2CR_EN_U
    mtspr   L2CR_REG, r3
    eieio
    isync
    blr                 /* return to caller */

/*********************************************************************
* sysL2BackDisable - Disable the L2 backside cache
*
* The value of the l2cr register is read, the enable bit is
* disabled and written back to the l2cr register.
*
* RETURNS: N/A

* void sysL2BackDisable
*     (
*     void
*     )

*/

sysL2BackDisable:

#if TRUE
    mfspr   r5, PVR
    rlwinm  r5, r28, 16, 16, 31
    cmpli   0, 0, r28, CPU_TYPE_7400
    bne     cache_disable

cache_flush:
    sync
    eieio
    mfspr   r3, L2CR_REG
    ori     r3, r3, L2CR_HWF      /* set flush bit*/
    mtspr   L2CR_REG, r3
    sync
    eieio

flush_hwf:
    mfspr   r3, L2CR_REG
    andi.   r3, r3, L2CR_HWF
    bne     flush_hwf
    sync
    eieio
#endif

cache_disable:
    sync
    mfspr   r3, L2CR_REG
    andis.  r3, r3, L2CR_DISABLE_MASK_U     /* Disable L2 backside */
    mtspr   L2CR_REG, r3
    sync
    blr                 /* return to caller */

/*********************************************************************
*  sysL2BackAutoSize - Autosize L2 Backside cache
*
*     L2 backside cache is available in MPC750 only.  The L2 cache size
*     could be 1M, 512K, or 256K.  The size is programmed in the L2CR
*     register.  To detect the correct size, this function assumes that
*     the L2 cache size is 1M, the cache is put in test mode so that a
*     cache flush operation (dcbf) will write from L1 cache to L2. 1M
*     of data is written to memory, then read back.  If the cache size
*     is truely 1M, all data read back will be correct as expected.  If
*     the cache size is 512 KB, half of the data will be correct, and
*     the other half is not, and so on.  Once the size is determined,
*     the value that must be set in L2CR when the L2 backside cache is
*     enabled is stored in r3.
*
*     There is no real way to distinguish MPC740 and MPC750; they both
*     have the same PRV number.  After writing to L2 backside cache, if
*     the result is neither 1M, 512 KB, or 256 KB, it must be MPC740
*     (no L2 backside cache, r3 is set to 0).
*
* RETURNS: the value of L2CR is returned in r3

* ULONG sysL2BackAutoSize
*     (
*     void
*     )

*/

sysL2BackAutoSize:

    andi.   r3, r3, 0x0
    andi.   r0, r0, 0x0
    andi.   r5, r5, 0x0             /* Make r5 to be 0 */
    andi.   r30, r30, 0x0       /* Make r30 0 */

    addis   r4, r0, 0x0     /* Count index reg. */
    addis   r6, r0, WRITE_ADDR_U    /* Address to start writing */
    addis   r5, r0, L2_SIZE_1M_U    /* Memory chunk to write to */

l2SzWriteLoop:
    dcbz    r4, r6          /* zero out the cache line */
    stwx    r4, r4, r6      /* write index to a cache line */
    dcbf    r4, r6          /* flush cache to L2 */
    addi    r4, r4, L2_ADR_INCR /* Increase the address index */
    cmp     0, 0, r4, r5
    blt     l2SzWriteLoop

    addis   r4, r0, 0x0     /* Count index  reg. - reset to 0 */

l2SzReadLoop:
    lwzx    r7, r4, r6      /* Load a word from the cache line */
    cmp 0, 0, r4, r7        /* Same as indexing value ? */
    bne l2SkipCount
    addi    r30, r30, 0x1       /* Count cache line read correctly */

l2SkipCount:

    dcbi    r4, r6          /* Invalidate the cache line */
    addi    r4, r4, L2_ADR_INCR /* increase the address index */
    cmp 0, 0, r4, r5        /* Any memory space to read ? */
    blt l2SzReadLoop

    addis   r7, r0, L2CR_SIZE_1MB   /* Load 1M l2cr value */
    cmpi    0, 0, r30, L2_SIZE_1M   /* 1M l2 backside cache ? */
    beq l2AutoSizeDone
    addis   r7, r0, L2CR_SIZE_512KB /* Load 512 KB l2cr value */
    cmpi    0, 0, r30, L2_SIZE_HM
    beq l2AutoSizeDone
    addis   r7, r0, L2CR_SIZE_256KB /* Load 256K l2cr reg. value */
    cmpi    0, 0, r30, L2_SIZE_QM
    beq l2AutoSizeDone
    addis   r7, r0, 0x0     /* No L2 cache */

l2AutoSizeDone:
    addis   r30, r0, 0x0        /* Save the value of l2cr in r30 */
    addi    r30, r7, 0x0
    addi    r3, r7, 0x0
    blr

/**********************************************************************
* sysPVRReadBoot - Read the content of the PVR register
*
* Once the PVR is read, the 16 least significant bits are shifted off
*
* RETURNS: the upper 16 bits of the PVR is returned in r3

* ULONG sysPVRReadBoot
*     (
*     void
*     )

*/

sysPVRReadBoot:
    mfspr r4, PVR_REG       /* read PVR  */
    srawi r3, r4, 16        /* shift off the least 16 bits */
    blr


/**********************************************************************
*  sysL2CRWrite - Write a value to the L2CR register
*
* RETURNS: N/A

* void sysL2CRWrite
*     (
*     ulong value    /@ value to write to the L2CR register is passed in r3 @/
*     )

*/

sysL2CRWrite:
    sync
    mtspr   L2CR_REG, r3
    sync
    blr


/**********************************************************************
*  sysL2CRRead - Read a value from the L2CR register
*
* RETURNS: the contents of L2CR register

* ulong sysL2CRRead
*     (
*     void
*     )
*/

sysL2CRRead:
    sync
    mfspr  r3,  L2CR_REG
    sync
    blr




/**********************************************************************
*  sysHID0Write - Write a value to the HID0 register
*
* RETURNS: N/A

* void sysHID0Write
*     (
*     ulong value    /@ value to write to the HID0 register is passed in r3 @/
*     )

*/

sysHID0Write:

    sync
    mtspr  HID0_REG , r3
    sync
    blr


/**********************************************************************
*  sysHID0Read - Read a value from the HID0 register
*
* RETURNS: the contents of HID0 register

* ulong sysHID0Read
*     (
*     void
*     )

*/

sysHID0Read:

    sync
    mfspr   r3, HID0_REG
    sync
    blr



/*********************************************************************
*   sysL2BackInit - Initialize L2 Back Cache.
*
*   RETURNS:    N/A
*   void sysL2BackInit
*       (
*       void
*       )
*/

sysL2BackInit:
    mfspr   r3, L2CR_REG
    andis.  r4, r3, L2CR_EN_U
    bne     l2backenable_done

    mflr    r7
    addi    r3, r0, 0x0
    mfspr   r8, 1009            /* HID1 */
    rlwinm  r8, r8, 4, 28, 31   /* get PLL configuration bits */

    cmplwi  r8, PPC750_PLL_CFG_2
    beq     sysL2BackInit_1
    cmplwi  r8, PPC750_PLL_CFG_3
    beq     sysL2BackInit_1_5
    cmplwi  r8, PPC750_PLL_CFG_4
    beq     sysL2BackInit_2
    cmplwi  r8, PPC750_PLL_CFG_5
    beq     sysL2BackInit_2_5
    cmplwi  r8, PPC750_PLL_CFG_6
    beq     sysL2BackInit_3
    cmplwi  r8, PPC750_PLL_CFG_7
    beq     sysL2BackInit_3_5
    cmplwi  r8, PPC750_PLL_CFG_8
    beq     sysL2BackInit_4
    cmplwi  r8, PPC750_PLL_CFG_10
    beq     sysL2BackInit_4
    cmplwi  r8, PPC750_PLL_CFG_3_5
    beq     sysL2BackInit_2
    cmplwi  r8, PPC750_PLL_CFG_4_5
    beq     sysL2BackInit_2_5
    cmplwi  r8, PPC750_PLL_CFG_5_5
    beq     sysL2BackInit_3
    cmplwi  r8, PPC750_PLL_CFG_6_5
    beq     sysL2BackInit_3_5
    cmplwi  r8, PPC750_PLL_CFG_7_5
    beq     sysL2BackInit_4
    b       sysL2BackInit_4


sysL2BackInit_1:
    oris    r3, r3, L2CR_CLK_1
    b   sysL2BackInitClk
sysL2BackInit_1_5:
    oris    r3, r3, L2CR_CLK_1_5
    b   sysL2BackInitClk
sysL2BackInit_2:
    oris    r3, r3, L2CR_CLK_2
    b   sysL2BackInitClk
sysL2BackInit_2_5:
    oris    r3, r3, L2CR_CLK_2_5
    b   sysL2BackInitClk
sysL2BackInit_3:
    oris    r3, r3, L2CR_CLK_3
    b   sysL2BackInitClk
sysL2BackInit_3_5:
    oris    r3, r3, L2CR_CLK_3_5
    b   sysL2BackInitClk
sysL2BackInit_4:
    oris    r3, r3, L2CR_CLK_4
    b   sysL2BackInitClk


sysL2BackInitClk:
    sync
    mtspr   L2CR_REG, r3
    sync

    bl      sysL2BackGlobalInv

    sync
    mfspr   r3, L2CR_REG
    oris    r3, r3, L2CR_CFG
    mtspr   L2CR_REG, r3
    sync

    isync

    mtlr    r7

l2backenable_done:
    blr

/**********************************************************************
*  sysL1DcacheEnable - Enable the L1 Dcache
*
* RETURNS: N/A

* void sysL1DcacheEnable
*     (
*     void
*     )

*/

sysL1DcacheEnable:

    mfspr   r5,HID0_REG             /* turn on  the D cache. */
    ori     r5,r5,L1_DCACHE_ENABLE      /* Data cache only! */
    andi.   r6,r5,L1_DCACHE_INV_MASK        /* clear the invalidate bit */
    mtspr   HID0_REG,r5
    isync
    sync
    mtspr   HID0_REG,r6
    isync
    sync
    blr

/**********************************************************************
*  sysL1DcacheDisable - Disable the L1 Dcache
*
* RETURNS: N/A

* void sysL1DcacheDisable
*     (
*     void
*     )

*/

sysL1DcacheDisable:

    mfspr   r5,HID0_REG
    andi.   r5,r5,L1_DCACHE_DISABLE
    mtspr   HID0_REG,r5
    isync
    sync
    blr


#if defined(INCLUDE_L2PM) && defined(SP755)

/**********************************************************************
*  sysL2PMEnable - Enable the Private Memory in L2 Cache Ram for MCP755
*
* RETURNS: N/A

* void sysL2PMEnable
*     (
*     void
*     )

*/

sysL2PMEnable:
    isync
    sync
    addi    r3, r0, 0x0
    oris    r3, r3, L2PMBA
    ori     r3, r3, L2PM_SIZE
    mtspr   L2PM_REG, r3
    sync
    blr
#endif /* INCLUDE_L2PM && SP755 */