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

📄 syscache.c

📁 LoPEC Early Access VxWorks BSP
💻 C
字号:
/* sysCache.c - secondary (L2) cache library for MPC75x, MCP74x0 *//* Copyright 1984-1999 Wind River Systems, Inc. *//* Copyright 1996-2000 Motorola, Inc., All Rights Reserved. *//*modification history--------------------01b,02feb01,scb  Removed INCLUDE_CACHE_SUPPORT, INCLUDE_CACHE_L2 conditionals01a,16nov00,scb  Copied from mv5100 version (prev 2.4)*//*DESCRIPTIONThis library provides L2 cache support, and is derived fromcode supplied by Motorola.Support is included for initializing/enabling the L2 Cache on boot andenabling/disabling the L2 Cache with system calls.  Only Inline caches aresupported since there are no VPD-based boards with a look-aside cache.Parameters used to configured the L2 controller are gathered from the L2Cache Record in the VPD.*//* includes */#include "vxWorks.h"#include "sysCache.h"/* defines */#define BOARD_CONV_SHIFT  25/* forward declarations */STATUS           sysL2CacheInit (void);LOCAL STATUS     sysL2InlineCacheInit (void);void             sysL2CacheEnable (void);LOCAL void       sysL2InlineCacheEnable (void);void             sysL2CacheDisable (void);LOCAL void       sysL2InlineCacheDisable (void);LOCAL STATUS     sysL2CacheInfoGet(UCHAR, UCHAR *);LOCAL UINT       sysL2InlineCacheSize (void);LOCAL UINT       sysL2InlineCacheSpd (void);/* externals */IMPORT UINT sysL2crGet (void);IMPORT void sysL2crPut (UINT regVal);IMPORT UINT sysGetMpuSpd (void);IMPORT void sysMaxL2Disable(void);/* Cache backside ratio */LOCAL UINT boardConvTable[] =    {    0x0, 0x1, 0x2, 0x4, 0x5, 0x6, 0x0, 0x0, 0x0,    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0    };LOCAL UINT boardFreqTable[] =    {    10, 10, 15, 20, 25, 30, 10, 10,    10, 10, 10, 10, 10, 10, 10, 10    };LOCAL VPD_PACKET * pVpdL2CachePacket = NULL;/******************************************************************************** sysL2CacheInfoGet - Get L2 Cache Info from the VPD.** This routine parses the VPD data structure for a L2 cache record and returns* field information in the record based on the L2CachePacketField that is* passed to it. ** RETURNS: OK, or ERROR if VPD L2 cache record missing or corrupt.** SEE ALSO: sysL2InlineCacheInit(), sysL2GetCacheSize()*/ LOCAL STATUS sysL2CacheInfoGet    (    UCHAR L2CachePacketFieldId,  /* Id for L2 cache record */    UCHAR * pL2CachePacketField  /* pointer to field information */    )    {    UINT i;     UINT fieldSize = 0;    BOOL fieldError = FALSE;    if (pVpdL2CachePacket == NULL)        {        /* Extract a VPD L2 Cache Packet */        if (sysVpdPktGet(VPD_PID_L2, 0, &sysVpdPkts[0], &pVpdL2CachePacket)            == ERROR)            return (ERROR);        }    /* Determine field length and if the field has a valid parameter */    switch (L2CachePacketFieldId)        {        case L2C_MID:        case L2C_DID:           fieldSize = 2;           break;        case L2C_DDW:        case L2C_NOD:        case L2C_NOC:        case L2C_CW:        case L2C_ASSOCIATE:            fieldSize = 1;            break;        case L2C_TYPE:            if (pVpdL2CachePacket->data[L2CachePacketFieldId] > L2C_TYPE_INLINE)                fieldError = TRUE;            else                fieldSize = 1;            break;        case L2C_OPERATIONMODE:            if (pVpdL2CachePacket->data[L2CachePacketFieldId] > L2C_OM_WB)                fieldError = TRUE;            else                fieldSize = 1;            break;        case L2C_ERROR_DETECT:            if (pVpdL2CachePacket->data[L2CachePacketFieldId] > L2C_ED_ECC)                fieldError = TRUE;            else                fieldSize = 1;            break;        case L2C_SIZE:            if (pVpdL2CachePacket->data[L2CachePacketFieldId] > L2C_SIZE_4M)                fieldError = TRUE;            else                fieldSize = 1;            break;        case L2C_TYPE_BACKSIDE:            if (pVpdL2CachePacket->data[L2CachePacketFieldId] > L2C_TYPE_BS_BNP)                fieldError = TRUE;            else                fieldSize = 1;            break;        case L2C_RATIO_BACKSIDE:            if (pVpdL2CachePacket->data[L2CachePacketFieldId] > L2C_RATIO_3_1)                fieldError = TRUE;            else                fieldSize = 1;                break;        default:            fieldError= TRUE;        break;        }    if (!fieldError)       {       if (fieldSize == 1)           pL2CachePacketField[0] =               pVpdL2CachePacket->data[L2CachePacketFieldId];        else           for (i=0; i<fieldSize; i++)               pL2CachePacketField[i] =                   pVpdL2CachePacket->data[L2CachePacketFieldId+i];       return OK;       }    else       return ERROR;    }/******************************************************************************** sysL2CacheInit - initialize the L2 cache ** This routine initializes and enables L2 cache(s) support. ** RETURNS: OK, or ERROR if cache is not present or not supported.** SEE ALSO: sysL2CacheInit(), sysL2CacheEnable(), sysL2CacheDisable()*/ STATUS sysL2CacheInit (void)    {    STATUS status = OK;    /* check for presence of L2 cache */    if (sysL2InlineCacheSize() != 0)        status |= sysL2InlineCacheInit();    return (status);    }/******************************************************************************** sysL2InlineCacheInit - initialize the L2 in-line cache.** This routine initializes and enables L2 in-line cache support.** RETURNS: OK, or ERROR if cache is not present or not supported.*/ LOCAL STATUS sysL2InlineCacheInit(void)    {    UINT l2CacheSize;    UINT l2crVal;    UCHAR l2CacheType, l2CacheRatio;    /* check for presence of L2 cache */    if ((l2CacheSize = sysL2InlineCacheSize()) == 0)        return(ERROR);        /* No L2 cache to init */    /* Initialize RAM type, output hold, differential clock */    if (sysL2CacheInfoGet(L2C_TYPE_BACKSIDE, &l2CacheType) == ERROR)        {        sysDebugMsg ("L2 cache record missing or corrupt.  L2 Cache Disabled.",                     CONTINUE_EXECUTION);        return(ERROR);        /* VPD Error */        }    switch ( l2CacheType )        {        case L2C_TYPE_BS_LWP:          /* Late Write, with Parity */        case L2C_TYPE_BS_LWNP:        /* Late Write, without Parity */        /*         * L2PE  = No parity enable         * L2RAM = Pipe reg-reg sync late-write         * L2OH  = 1.0ns         * L2DF  = Diff clock         */              l2crVal = MPC750_L2CR_RAM_PLTWR |              MPC750_L2CR_OH_1NS |              MPC750_L2CR_DF;        break;    case L2C_TYPE_BS_BP:          /* Burst with parity */    case L2C_TYPE_BS_BNP:         /* Burst, without Parity */        /*         * L2PE  = No parity enable         * L2RAM = Pipe reg-reg sync burst         * L2OH  = 0.5ns         * L2DF  = Nondiff clock         */        l2crVal = MPC750_L2CR_RAM_PBRST;              break;    default:        l2crVal = 0;        break;    }    /* Initialize the L2 clock ratio */        if (sysL2CacheInfoGet(L2C_RATIO_BACKSIDE, &l2CacheRatio) == ERROR)        {        sysDebugMsg("L2 cache record missing or corrupt.  L2 cache disabled.",                    CONTINUE_EXECUTION);        return (ERROR);        }    l2crVal |= boardConvTable[l2CacheRatio] << BOARD_CONV_SHIFT;    /*     * if L2 speed is below normal L2 speed threshold, set slow bit in L2     * cache control register.     */    if (sysL2InlineCacheSpd() < MPC750_L2_CACHE_SPEED_THRESHOLD)        l2crVal |= MPC750_L2CR_SL;    /* Set the Cache size */    switch (l2CacheSize)        {        case L2C_MEM_256K:            l2crVal |= MPC750_L2CR_256K;            break;        case L2C_MEM_512K:            l2crVal |= MPC750_L2CR_512K;            break;        case L2C_MEM_1M:            l2crVal |= MPC750_L2CR_1024K;            break;        case L2C_MEM_2M:            l2crVal |= MPC750_L2CR_2048K;            break;        }    /* Write out the L2 cache control register */    sysL2crPut(l2crVal);    /* Invalidate the L2 cache */    l2crVal |= MPC750_L2CR_I;    sysL2crPut(l2crVal);    __asm__("sync");    /* wait for all memory transactions to finish */    while (sysL2crGet() & MPC750_L2CR_IP)        ;    l2crVal &= ~MPC750_L2CR_I;    sysL2crPut(l2crVal);    /* Enable the L2 cache */    sysL2InlineCacheEnable();    return (OK);    }/******************************************************************************** sysL2InlineCacheEnable - enable the L2 in-line cache* * RETURNS: N/A*/ LOCAL void sysL2InlineCacheEnable (void)    {    UINT l2crVal;     if (sysL2InlineCacheSize() == 0)        return;                   /* Return if no L2 Inline cache present */    /* make sure L2 is already disabled */    if ( ((l2crVal = sysL2crGet()) & MPC750_L2CR_E) == 0)        {        l2crVal |= MPC750_L2CR_E;        sysL2crPut(l2crVal);        }    }/******************************************************************************** sysL2CacheDisable - disable the L2 cache(s)* * This routine disables the L2 cache(s) if either or both were* previously initialized using sysL2CacheInit().  Calling this * routine invalidates the L2 tag bits.** RETURNS: N/A** SEE ALSO: sysL2CacheInit(), sysL2CacheEnable(), sysL2CacheDisable()*/ void sysL2CacheDisable (void)    {    UINT cacheSize;    if ((cacheSize = sysL2InlineCacheSize()) != 0)        sysL2InlineCacheDisable();    }/******************************************************************************** sysL2InlineCacheDisable - disable the L2 in-line cache** If the in-line cache is enabled, this routine disables it via the following* steps:** .IP "1."* Flush by reading one word from each cache line within a cache* enabled buffer.  Note that this buffer should be twice the size of* the L2 cache to override the pseudo-LRU replacement algorithm.* .IP "2."* Turn off the cache enable bit in the L2CR.* .IP "3."* Invalidate the L2 cache contents.** RETURNS: N/A*/ LOCAL void sysL2InlineCacheDisable (void)    {    register ULONG tmp;    register ULONG l2crVal;    register int i;    int  lockKey;          /* interrupt lock key */    lockKey = intLock();   /* disable interrupts */    if ((l2crVal = sysL2crGet()) & MPC750_L2CR_E)        {        if (CPU_TYPE == CPU_TYPE_750)            {            if (vxHid0Get() & _PPC_HID0_DCE)                {                /* flush the inline L2 cache */                for (i = 2*sysL2InlineCacheSize() - 32; i >= 0; i -= 32 )                tmp = *(ULONG *)(RAM_LOW_ADRS + i);                }            /* disable the inline L2 cache */            __asm__("sync");            l2crVal &= ~MPC750_L2CR_E;            sysL2crPut(l2crVal);            __asm__("sync");            /* invalidate the inline L2 cache */            sysL2crPut(l2crVal | MPC750_L2CR_I);            __asm__("sync");    /* wait for all memory transactions to finish */            while (sysL2crGet() & MPC750_L2CR_IP)                 ;            sysL2crPut(l2crVal);            }        else                                            {            sysMaxL2Disable();            l2crVal &= ~MPC750_L2CR_E;            /* invalidate the inline L2 cache */            sysL2crPut(l2crVal | MPC750_L2CR_I);            __asm__("sync");    /* wait for all memory transactions to finish */            }        }        intUnlock(lockKey);             /* re-enable interrupts */    }/******************************************************************************** sysL2InlineCacheSize() - Determine size of the L2 in-line cache.** This function returns the size of the L2 in-line cache.  If no L2* in-line cache is present, the size returned is zero so this function's* return value can be used like a boolean to determine if the L2 in-line* cache is actually present.** RETURNS: Size of L2 in-line cache or zero if in-line cache not present.** NOTE: Don't confuse the L2 in-line cache with the other possible type* of cache, referred to as the "glance" or "lookaside" cache.*/ LOCAL UINT sysL2InlineCacheSize()    {    STATUS size;    UCHAR l2CacheSize;    if (CPU_TYPE != CPU_TYPE_750 && CPU_TYPE != CPU_TYPE_MAX)        return(0);    /* Not an Arthur/Max chip so no in-line L2 cache */    if (sysL2CacheInfoGet(L2C_SIZE, &l2CacheSize) == ERROR)        {        sysDebugMsg ("L2 cache record missing or corrupt.  L2 cache disabled.",                     CONTINUE_EXECUTION);        return (0);        }    switch ( l2CacheSize )        {        case L2C_SIZE_256K:            size = L2C_MEM_256K;            break;        case L2C_SIZE_512K:            size = L2C_MEM_512K;            break;        case L2C_SIZE_1M:            size = L2C_MEM_1M;            break;        case L2C_SIZE_2M:            size = L2C_MEM_2M;            break;        case L2C_SIZE_4M:            size = L2C_MEM_4M;            break;        default:            size = L2C_MEM_NONE;            break;        }    return(size);    }/******************************************************************************** sysL2InlineCacheSpd() - Determine speed of the L2 in-line cache.** This function returns the speed of the L2 in-line cache.  If no L2* in-line cache is present, the speed returned is zero so this function's* return value can be used like a boolean to determine if the L2 in-line* cache is actually present.** RETURNS: Speed of L2 in-line cache or zero if in-line cache not present.** NOTE: Don't confuse the L2 in-line cache with the other possible type* of cache, referred to as the "glance" or "lookaside" cache.*/ LOCAL UINT sysL2InlineCacheSpd(void)    {    UINT l2Spd;    UCHAR l2CacheRatio;    if (sysL2InlineCacheSize() == 0)        return(0);       if (sysL2CacheInfoGet(L2C_RATIO_BACKSIDE, &l2CacheRatio) == ERROR)        {        sysDebugMsg ("L2 cache record missing or corrupt.  L2 Cache Disabled.",                     CONTINUE_EXECUTION);        return(ERROR);          /* VPD Error */        }    l2Spd = (sysGetMpuSpd() / boardFreqTable[l2CacheRatio]) * 10;    return(l2Spd);    }   /******************************************************************************** sysL2CacheEnable - enable the L2 cache(s)* * This routine enables the L2 cache(s).* It checks for the presence of either L2 cache * and ensures that the cache(s) is(are) disabled.** RETURNS: N/A** SEE ALSO: sysL2CacheInit(), sysL2CacheEnable(), sysL2CacheDisable()*/ void sysL2CacheEnable (void)    {    UINT cacheSize;    if ((cacheSize = sysL2InlineCacheSize()) != 0)        sysL2InlineCacheEnable();    }

⌨️ 快捷键说明

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