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

📄 cache.c

📁 st boot Linux 源码示范程序。 可以移植到其他平台
💻 C
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************
File Name   : cache.c

Description : CACHE setup

              This module contains functions for configuring the system
              on-board instruction and data caches.

Copyright (C) 1999-2005 STMicroelectronics

History     :

    15/08/99  First attempt.

    15/02/00  Modified to import cachereg.h for chip-specific cache
              configuration register map and region look-up table.

    16/02/01  Changed to 16-bit access; required for later cache
              subsystems that use > 8 bits per register.
              
    12/05/05  St200 specific dcache configuration.

Reference   :
*****************************************************************************/

/* Includes --------------------------------------------------------------- */

#include <stdio.h>
#include "stlite.h"                     /* STLite includes */

#include "stsys.h"                      /* STAPI includes */

#include "stbootcache.h"                /* Cache control interface */
#include "stboot.h"

#ifdef ST_OS21
#ifdef ARCHITECTURE_ST200
#include <machine/sysconf.h>
#include <machine/rtrecord.h>
#include <machine/bsp.h>
#include <sys/bitfields.h>
#include <machine/ctrlreg.h>
#endif
#endif

#ifdef ST_OS20 /*not required for "non OS20" - ST40, ST200 devices*/
#include "cachereg.h"                   /* Regs for required chip */

/* Private types/constants ------------------------------------------------ */

/* Private cache control structure */
typedef struct
{
    U32         StartAddress;
    U32         EndAddress;
    U32         CacheEnableOffset;
    U16         CacheEnableBitMask;
} CacheControlTable_t;

/* Private variables ------------------------------------------------------ */

/* See STixxxx.h for the definition of the cache control LUT.
 */
static const CacheControlTable_t CacheControlLUT[] = DCACHE_LUT;

/* Private function prototypes -------------------------------------------- */

/* System cache initialization */

/* Function definitions --------------------------------------------------- */

/*****************************************************************************
Name: stboot_InitICache()
Description:
    Initializes the instruction cache.

Parameters:
    CacheDevice_p,  pointer to device base address.
    ICacheEnable,   boolean reflecting whether to enable disable icache.

Return Value:
    None.

See Also:
    stboot_InitDCache()
*****************************************************************************/

void stboot_InitICache(CacheReg_t *CacheDevice_p,
                       BOOL ICacheEnable)
{
    /* Initialize instruction cache, if enabled */
    if (ICacheEnable)
    {
#if defined(ST_5514) || defined(ST_5516) || defined(ST_5517) || defined(ST_5528) || defined(ST_5100) || defined(ST_5101) || defined(ST_7710) || defined(ST_5105) || defined(ST_5700) || defined(ST_5188) || defined(ST_5107)
        /* Enabling instruction caching on all memory (see DDTS 14020) */
        
        /* SMI (usually used when UNIFIED_MEMORY defined) */
        STSYS_WriteRegDev16LE(CacheDevice_p+ICAC_Region1BlockEnable, 0xFFFF);
        
        #ifdef STBOOT_LMI_TOP_REGION_ICACHE_ENABLE
        STSYS_WriteRegDev16LE(CacheDevice_p+ICAC_Region1TopEnable, 0x0001);
        #endif

        /* EMI (usually used when UNIFIED_MEMORY not defined) */
        STSYS_WriteRegDev16LE(CacheDevice_p+ICAC_Region3BlockEnable, 0xFFFF);
        STSYS_WriteRegDev16LE(CacheDevice_p+ICAC_Region3BankEnable,  0x000F);
#endif

        /* Invalidate the instruction cache */
        CacheDevice_p[INVALIDATE_ICACHE] = 1;
        
        /* Enable the instruction cache */
        CacheDevice_p[ENABLE_ICACHE] = 1;
    }
            
} /* stboot_InitICache() */

/*****************************************************************************
Name: stboot_InitDCache()
Description:
    Initializes the system data cache.  This is done by reading an array
    of defined cacheable memory areas, checking the cache control look-up
    table, and setting the appropriate cache control registers.

    Assuming the cache control look-up table has been correctly defined,
    this code should be easily portable to any backend decoder.

Parameters:
    CacheDevice_p,  pointer to device base address.
    DCacheMap,      array of cacheable area definitions.

Return Value:
    TRUE,           there was a problem with the dcache map.
    FALSE,          the dcache was setup without error.

See Also:
    stboot_InitDCache()
*****************************************************************************/

BOOL stboot_InitDCache(CacheReg_t *CacheDevice_p,
                       STBOOT_DCache_Area_t *DCacheMap)
{
    const CacheControlTable_t *CacheLUT_p;
    STBOOT_DCache_Area_t *CacheMap_p;

#ifdef ST_5100
    S8 Error = 0;
    U32 CachingAddressStart, CachingAddressEnd;
#endif

    if(DCacheMap == NULL)
    {
        /* No cache map, do nothing, no error */
        return FALSE;
    }
    
    if( (DCacheMap->StartAddress == NULL) &&
        (DCacheMap->EndAddress == NULL) )
    {
        /* Empty regions specified, do nothing, no error */
        return FALSE;
    }
    
    /* Data cache initialization is done in two stages:
     * 1. The dcache map is validated against the cache control
     *    lookup table.  If all map entries are valid then
     *    stage 2 can be executed, otherwise an error is
     *    returned.
     *
     * 2. The dcache map settings are applied to the device
     *    cache control registers using the cache control
     *    lookup table.  No error checking is performed at this
     *    stage.
     */

    /* 1. Validate the dcache map against the cache control LUT.
     */
    for ( CacheMap_p = DCacheMap;
          ( CacheMap_p->StartAddress != NULL &&
            CacheMap_p->EndAddress != NULL );
          CacheMap_p++ )
    {
        BOOL RegionOk, StartAddressOk;

        RegionOk = FALSE;
        StartAddressOk = FALSE;

        /* Scan through the cache control LUT to check that the caller
         * supplied region is on a valid start/end boundary, and does not
         * span a non-cacheable area.
         */
        for ( CacheLUT_p = CacheControlLUT;
              CacheLUT_p->CacheEnableBitMask != 0;
              CacheLUT_p++ )
        {
            /* Check for end of region marker */
            if ( CacheLUT_p->CacheEnableBitMask == ((U8)-1) )
            {
                StartAddressOk = FALSE;
                continue;               /* Next region */
            }

            /* Check for valid start address */
            if ( !StartAddressOk )
            {
                if ( (U32)CacheMap_p->StartAddress == CacheLUT_p->StartAddress )
                    StartAddressOk = TRUE;
            }

            /* If start address ok, check for valid end address */
            if ( StartAddressOk )
            {
                if ( (U32)CacheMap_p->EndAddress == CacheLUT_p->EndAddress )
                {
                    RegionOk = TRUE;
                    break;
                }
            }
        }

        if ( !RegionOk )
            return TRUE;                /* Invalid region specified */
    }

#if !defined(ST_5100)
    /* 2. Iterate over the dcache map to configure the cache control
     *    registers.
     */

    for ( CacheMap_p = DCacheMap;
          ( CacheMap_p->StartAddress != NULL &&
            CacheMap_p->EndAddress != NULL );
          CacheMap_p++ )
    {
        /* Scan through the cache control LUT to configure the cache
         * configuration registers, according to the current cache
         * map entry.
         */
        for ( CacheLUT_p = CacheControlLUT;
              CacheLUT_p->CacheEnableBitMask != 0;
              CacheLUT_p++ )
        {
            /* We calculate whether or not the user-specified area is
             * completely "disconnected" from the cacheable area.
             * If not then we must enable the area.
             */

			BOOL DisableRegion = ((U32)CacheMap_p->StartAddress < CacheLUT_p->StartAddress &&
                  		(U32)CacheMap_p->EndAddress   <= CacheLUT_p->StartAddress) ||
                  		((U32)CacheMap_p->StartAddress > CacheLUT_p->EndAddress &&
                  		(U32)CacheMap_p->EndAddress   >= CacheLUT_p->EndAddress);

            if (!DisableRegion)
            {
                U16 Val;

                /* Read current value and set the new bitmask */
                Val = STSYS_ReadRegDev16LE(
                          (CacheDevice_p+CacheLUT_p->CacheEnableOffset));
                Val |= CacheLUT_p->CacheEnableBitMask;
                STSYS_WriteRegDev16LE(
                    (CacheDevice_p+CacheLUT_p->CacheEnableOffset), Val);
            }
        }
    }
    
    
    CacheDevice_p[INVALIDATE_DCACHE] = 1; /* Invalidate DCACHE */
    CacheDevice_p[DCACHE_NOT_SRAM] = 1;   /* Enable DCACHE */
#endif

#if defined(ST_5100)
    CacheMap_p = DCacheMap;
    do
    {
        if ((CacheMap_p->StartAddress != NULL) && (CacheMap_p->EndAddress != NULL))
        {
           	CachingAddressStart = (U32) CacheMap_p->StartAddress;
           	CachingAddressEnd = (U32) CacheMap_p->EndAddress;
        }
        Error = cache_config_data((void*) CachingAddressStart, (void*)CachingAddressEnd, cache_config_enable);
        if ( Error != 0 )
        {
       	    return TRUE;
        }
        
        CacheMap_p++;
    }
    while((CacheMap_p->StartAddress != NULL) || (CacheMap_p->EndAddress != NULL));
    
    Error = cache_enable_data(); /*typically cache should be enabled AFTER an invalidate call. OS20 takes care of this when using this call*/
    if(Error != 0)
    {
    	return TRUE;
    }
    
    Error = cache_flush_data(NULL, NULL);   /* Flush DCACHE -->required for 5100 dcache bug*/
    if(Error != ST_NO_ERROR)
    {
    	return TRUE;
    }
#endif

    return FALSE;                       /* Success */
} /* InitDCache() */


/*****************************************************************************
Name: stboot_LockCaches()
Description:
    Locks the cache control registers to prevent further
    changes to the cache configuration.
    
Parameters:
    CacheDevice_p,  pointer to device base address.

Return Value:
    TRUE,           there was a problem with the dcache map.

⌨️ 快捷键说明

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