📄 cache.c
字号:
/*****************************************************************************
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 + -