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

📄 syscache.c

📁 VxWorks下 Spruce的BSP源代码
💻 C
字号:
/* sysCache.c - secondary (L2) cache library for PowerPC 750 *//*******************************************************************************   This source and object code has been made available to you by IBM on an   AS-IS basis.   IT IS PROVIDED WITHOUT WARRANTY OF ANY KIND, INCLUDING THE WARRANTIES OF   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE OR OF   NONINFRINGEMENT OF THIRD PARTY RIGHTS.  IN NO EVENT SHALL IBM OR ITS   LICENSORS BE LIABLE FOR INCIDENTAL, CONSEQUENTIAL OR PUNITIVE DAMAGES.   IBM'S OR ITS LICENSOR'S DAMAGES FOR ANY CAUSE OF ACTION, WHETHER IN   CONTRACT OR IN TORT, AT LAW OR AT EQUITY, SHALL BE LIMITED TO A MAXIMUM   OF $1,000 PER LICENSE.  Anyone receiving this source or object code is   licensed under IBM copyrights to use it in any way he or she deems fit,   including copying it, modifying it, compiling it, and redistributing it   either with or without modifications.  No license under IBM patents or   patent applications is to be implied by the copyright license.   Any user of this software should understand that neither IBM nor its   licensors will be responsible for any consequences resulting from the   use of this software.   Any person who transfers this object code or any derivative work must   include the IBM copyright notice in the transferred software.   COPYRIGHT   I B M   CORPORATION 1999   LICENSED MATERIAL  -  PROGRAM PROPERTY OF  I B M"*******************************************************************************//* Copyright 1984-2002 Wind River Systems, Inc. *//*modification history--------------------01e,23jan03,jtp  SPR 84493 recognize 750FX PVR values 700xxxxx01d,12sep02,pch  SPR 80542: recognize 750FX PVR values		 SPR 81221: add L2 flush & invalidate functions		 SPR 81212: test entire L2 cache on 750FX01c,27mar01,kab  Removed IBM support info per request01b,03nov00,mcg  updated for 750CX01a,12apr99,mcg  written (from template)*//*DESCRIPTIONThis library provides L2 cache support for the PowerPC 750 processor.The 750 processor has a dedicated L2 cache interface.*/#if defined(INCLUDE_CACHE_SUPPORT) && defined(INCLUDE_CACHE_L2)#ifdef	DEBUG_L2_HANDLERint		l2_size = 0;	/* size of L2 cache */int		sysL2flushCount = 0;char	*	sysL2initStatus = NULL;#elseLOCAL	int	l2_size = 0;	/* size of L2 cache */#endifLOCAL	void	sysL2CacheEnable (void);LOCAL	void	sysL2CacheDisable (void);LOCAL	void	sysL2CacheFlush (void);LOCAL	void	sysL2CacheInvFunc (void);IMPORT ULONG sysReadL2CR(void);                        /* assembler function */IMPORT void  sysWriteL2CR(ULONG);                      /* assembler function */IMPORT void  sysSync(void);                            /* assembler function */IMPORT void  sysDcbz(void *);                          /* assembler function */IMPORT void  sysDcbf(void *);                          /* assembler function */IMPORT VOIDFUNCPTR _pSysL2CacheInvFunc;IMPORT VOIDFUNCPTR _pSysL2CacheEnable;IMPORT VOIDFUNCPTR _pSysL2CacheFlush;IMPORT VOIDFUNCPTR _pSysL2CacheDisable;/******************************************************************************** sysL2CacheFlush - flush the L2 cache(s)** This routine flushes the L2 cache(s) if either or both were* previously initialized using sysL2CacheInit().** RETURNS: N/A** SEE ALSO: sysL2CacheInit(), sysL2CacheEnable(), sysL2CacheDisable()*/LOCAL void sysL2CacheFlush    (    void    )    {    int lockKey;    register int i;    register ULONG tmp;    if (l2_size != 0 && (vxHid0Get() & _PPC_HID0_DCE))        {	lockKey=intLock();#ifdef	DEBUG_L2_HANDLER	++sysL2flushCount;#endif	sysSync();	/*	 * Flush the inline L2 cache, using loads rather than dcbf per	 * 750CX User's Manual sec. 9.1.1 & 750FX User's Manual sec. 5.2	 */        for (i = 2 * l2_size - 32 ; i >= 0 ; i -= 32 )            tmp = *(ULONG *)(RAM_LOW_ADRS + i);	sysSync();	intUnlock(lockKey);        }    }/******************************************************************************** sysL2CacheInvFunc - Invalidate the L2 cache(s)** This routine invalidates 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()*/LOCAL void sysL2CacheInvFunc (void)    {    int lockKey;    lockKey=intLock();    sysSync();    /* Invalidate the L2 */    sysWriteL2CR (sysReadL2CR() | _PPC_L2CR_INVALIDATE);    /* spin until L2CR IP bit is cleared */    while (sysReadL2CR() & _PPC_L2CR_INPROGRESS)  	;    sysSync();    sysWriteL2CR(sysReadL2CR() & ~_PPC_L2CR_INVALIDATE);    intUnlock(lockKey);    }/******************************************************************************** sysL2CacheDisable - disable the L2 cache** This routine disables the L2 cache if it was previously initialized using* sysL2CacheInit().  Calling this routine invalidates the L2 tag bits.** RETURNS: N/A** SEE ALSO: sysL2CacheInit()*/LOCAL void sysL2CacheDisable    (    void    )    {    sysSync();    sysWriteL2CR (sysReadL2CR() & ~(_PPC_L2CR_ENABLE));    sysSync();    }/******************************************************************************** sysL2CacheEnable - enable the L2 cache** This routine invalidates and enables the L2 cache** RETURNS: N/A** SEE ALSO: sysL2CacheInit(), sysL2CacheDisable()*/LOCAL void sysL2CacheEnable    (    void    )    {    int l2cr;    sysSync();    /* Invalidate the L2 */    sysWriteL2CR (sysReadL2CR() | _PPC_L2CR_INVALIDATE);    /* spin until L2CR IP bit is cleared */    while (sysReadL2CR() & _PPC_L2CR_INPROGRESS)  	;    l2cr = sysReadL2CR();    /*     * If specified in config.h, use the L2 for data only and not for     * instructions.     */#ifdef USER_L2_CACHE_DATA_ONLY    l2cr |= _PPC_L2CR_DATA_ONLY;#endif    sysWriteL2CR((l2cr | _PPC_L2CR_ENABLE) & ~_PPC_L2CR_INVALIDATE);    }/******************************************************************************** sysL2CacheInit - initialize the L2 cache** This routine initializes and enables L2 cache support.** RETURNS: OK, or ERROR if cache is not present or not supported.** SEE ALSO: sysL2CacheDisable()**/STATUS sysL2CacheInit    (    void    )    {    int cpu;    int family;    register int j;    register unsigned int * testArea;    register unsigned int * testWord;    register unsigned int testValue;    register unsigned int rvalue;    cpu = CPU_TYPE;    family = cpu >> 16;    l2_size = 0;    /*     * Continue only if the processor is from the 7xx family     * Note 750FX can register a range of values     */    if (family == CPU_FAMILY_7XX || (family & 0xfff0) == CPU_FAMILY_750FX)        {        sysL2CacheDisable ();        /*         * Is this a 750 or 750L where the L2 is off-chip?         */        if ((cpu == CPU_TYPE_740_750)       ||            (cpu == CPU_TYPE_740L_750L)     ||            (cpu == CPU_TYPE_740L_750L_2)   ||            (cpu == CPU_TYPE_740L_750L_3))            {            l2_size = L2_CACHE_750_750L_SIZE;            /*             * The L2 Cache that is available on the 750 and 750L processor             * daughter cards has 512KB of L2 cache on board.  Set up the L2             * cache control register for 512KB, 2:1 clock ratio, pipelined             * burst SRAM.             */            /* Note: 2:1 processor to L2 bus interface ratio is not always             * correct depending on the processor core speed and the access             * parameters of the external SRAMs.             */            sysWriteL2CR(_PPC_L2CR_SIZE_512K  | _PPC_L2CR_CLKDIV_21  |                         _PPC_L2CR_RAM_PB );            }        else            {	    if (cpu == CPU_TYPE_750FX || ((cpu >> 16) & 0xfff0) ==		    CPU_FAMILY_750FX)        	l2_size = L2_CACHE_750FX_SIZE;	    else        	l2_size = L2_CACHE_750CX_SIZE;            }        /*         * If the L1 Data cache is enabled, don't go any further, just return.         */        if (vxHid0Get() & _PPC_HID0_DCE)            {	    _pSysL2CacheEnable  = sysL2CacheEnable;	    _pSysL2CacheFlush   = sysL2CacheFlush;	    _pSysL2CacheDisable = sysL2CacheDisable;	    _pSysL2CacheInvFunc = sysL2CacheInvFunc;#ifdef	DEBUG_L2_HANDLER	    sysL2initStatus = "_PPC_HID0_DCE was set\n";#endif            return(0);            }        /*         * Invalidate L2, turn on test support bit, and turn on data-only bit         * for testing the L2.         */        sysWriteL2CR(sysReadL2CR() | _PPC_L2CR_INVALIDATE |                                     _PPC_L2CR_TEST_SPRT  |                                     _PPC_L2CR_DATA_ONLY);        /*         * Check L2CR IP bit - it should take 32K core clock cycles to         * finish invalidating the L2, upon which the L2CR IP bit is cleared.         */	/* spin until L2CR IP bit is cleared */	while (sysReadL2CR() & _PPC_L2CR_INPROGRESS)  	    ;	testArea = memalign(32, l2_size);     /* Cache line boundary aligned */        if (testArea == NULL)	{#ifdef	DEBUG_L2_HANDLER	    sysL2initStatus = "memalign() failed\n";#endif            return(ERROR);	}        /*         * Enable L2 and turn off the L2 invalidate bit.         */        sysWriteL2CR((sysReadL2CR()                      | _PPC_L2CR_ENABLE) & ~_PPC_L2CR_INVALIDATE);        /* Turn on L1 data cache via the HID0 register for testing the L2. */        sysSync();        vxHid0Set(vxHid0Get() | _PPC_HID0_DCE);        /* Zero out testArea (same size as the L2) */        testWord = testArea;        while ((unsigned int)testWord < ((unsigned int)testArea + l2_size))            {            sysDcbz((void *)testWord);       /* Establish a cache line of 0   */            *testWord = 0;                   /* make the line dirty           */            sysDcbf((void *)testWord);       /* Flush the line                */            testWord += 8;                   /* the next 8 word L1 cache line */            }        /*         * Disable the L1 data cache.  Then invalidate it.         */        sysSync();        vxHid0Set(vxHid0Get() & ~_PPC_HID0_DCE);        vxHid0Set(vxHid0Get() | _PPC_HID0_DCFI);        /*         * Do a simple test to see if the L2 cache is present.  With L1 now         * disabled and the test support bit set in the L2CR, writes to         * testArea should wind up in the L2 if it exists.  Note that when the         * test support bit is set in L2CR, L2 cache misses are not forwarded         * to the 6xx bus interface.  This test helps to determine the         * difference between a 740 and a 750 at runtime.         */        testWord = testArea;        *testWord = 0x01234567;        *(testWord+1) = 0x89ABCDEF;        *(testWord+2) = ~(0x01234567);        /* change the data bus */        *(testWord+3) = ~(0x89ABCDEF);        /* change the data bus */        if ( ((rvalue = *testWord) != 0x1234567) |             ((rvalue = *(testWord+1)) != 0x89ABCDEF))            {            sysWriteL2CR(sysReadL2CR() & ~(_PPC_L2CR_ENABLE |                                           _PPC_L2CR_DATA_ONLY |                                           _PPC_L2CR_TEST_SPRT));            free(testArea);#ifdef	DEBUG_L2_HANDLER	    sysL2initStatus = "no L2 found\n";#endif            return(0);            }        /*         * We can now assume an L2 cache exists.  Now test the L2 SRAM for         * for stuck faults by writing "A"s then "5"s then "A"s again.         */        testWord = testArea;        while ((unsigned int)testWord < ((unsigned int)testArea + l2_size))            {            testValue = 0xAAAAAAAA;            for (j=0; j<3; j++)                {                *testWord = testValue;                *(testWord+2) = 0x01234567;   /* change the data bus */                *(testWord+3) = 0x89ABCDEF;   /* change the data bus */                if ( ((rvalue = *testWord) != testValue))                    {                    /* Failure occurred.  Disable and invalidate L2 */                    sysSync();                    sysWriteL2CR((sysReadL2CR() | _PPC_L2CR_INVALIDATE)                                               & ~(_PPC_L2CR_ENABLE |                                                   _PPC_L2CR_DATA_ONLY |                                                   _PPC_L2CR_TEST_SPRT));                    sysSync();		    /* spin until L2CR IP bit is cleared */		    while (sysReadL2CR() & _PPC_L2CR_INPROGRESS)  			;                    sysWriteL2CR(sysReadL2CR() & ~_PPC_L2CR_INVALIDATE);                    free(testArea);#ifdef	DEBUG_L2_HANDLER		    sysL2initStatus = "L2 test failed\n";#endif                    return(ERROR);                    }                testValue = ~testValue;                }            testWord++;            }        /*         * L2 tests passed. Disable, turn off data only and test support         * bits.  Turn on the Invalidate bit.         */        sysSync();        sysWriteL2CR((sysReadL2CR() | _PPC_L2CR_INVALIDATE)                                  & ~(_PPC_L2CR_ENABLE |                                      _PPC_L2CR_DATA_ONLY |                                      _PPC_L2CR_TEST_SPRT));        /* Wait for the invalidate to complete */        sysSync();	while (sysReadL2CR() & _PPC_L2CR_INPROGRESS)  	    ;        /*         * Turn off the invalidate bit.  L2 cache is ready to be used.         */        sysWriteL2CR(sysReadL2CR() & ~_PPC_L2CR_INVALIDATE);        free(testArea);	_pSysL2CacheEnable  = sysL2CacheEnable;	_pSysL2CacheFlush   = sysL2CacheFlush;	_pSysL2CacheDisable = sysL2CacheDisable;	_pSysL2CacheInvFunc = sysL2CacheInvFunc;#ifdef	DEBUG_L2_HANDLER	sysL2initStatus = "finished OK\n";	}    else	{	sysL2initStatus = "not a 750\n";#endif        }    return (OK);    }#endif  /* INCLUDE_CACHE_SUPPORT */

⌨️ 快捷键说明

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