armv7/8 cache:CSSELR should be set before getting cache info

According to the ARMv7a/r/m and ARMv8m architecture manuals
The allowed values are
0 Data or unified cache.
1 Instruction cache.

"One CCSIDR is implemented for each cache that can be accessed by the processor. CSSELR selects which Cache Size ID Register is accessible, see c0, Cache Size Selection Register (CSSELR)."

Signed-off-by: chenrun1 <chenrun1@xiaomi.com>
This commit is contained in:
chenrun1 2023-05-06 16:19:42 +08:00 committed by Xiang Xiao
parent 6c1a7c4265
commit 09da8fb651
12 changed files with 322 additions and 152 deletions

View File

@ -31,40 +31,6 @@
#include "barriers.h"
#include "l2cc.h"
/****************************************************************************
* Private Functions
****************************************************************************/
#if defined(CONFIG_ARCH_ICACHE) || defined(CONFIG_ARCH_DCACHE)
/****************************************************************************
* Name: up_get_cache_linesize
*
* Description:
* Get cache linesize
*
* Input Parameters:
* None
*
* Returned Value:
* Cache line size
*
****************************************************************************/
static size_t up_get_cache_linesize(void)
{
static uint32_t clsize;
if (clsize == 0)
{
clsize = MAX(cp15_cache_linesize(), l2cc_get_linesize());
}
return clsize;
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -87,7 +53,14 @@ static size_t up_get_cache_linesize(void)
size_t up_get_icache_linesize(void)
{
return up_get_cache_linesize();
static uint32_t clsize;
if (clsize == 0)
{
clsize = MAX(cp15_icache_linesize(), l2cc_linesize());
}
return clsize;
}
/****************************************************************************
@ -189,7 +162,14 @@ void up_disable_icache(void)
size_t up_get_dcache_linesize(void)
{
return up_get_cache_linesize();
static uint32_t clsize;
if (clsize == 0)
{
clsize = MAX(cp15_dcache_linesize(), l2cc_linesize());
}
return clsize;
}
/****************************************************************************
@ -272,7 +252,7 @@ void up_invalidate_dcache_all(void)
void up_clean_dcache(uintptr_t start, uintptr_t end)
{
if ((end - start) < cp15_cache_size())
if ((end - start) < cp15_dcache_size())
{
cp15_clean_dcache(start, end);
}
@ -336,7 +316,7 @@ void up_clean_dcache_all(void)
void up_flush_dcache(uintptr_t start, uintptr_t end)
{
if ((end - start) < cp15_cache_size())
if ((end - start) < cp15_dcache_size())
{
cp15_flush_dcache(start, end);
}

View File

@ -397,7 +397,7 @@ void arm_l2ccinitialize(void)
}
/****************************************************************************
* Name: l2cc_get_linesize
* Name: l2cc_linesize
*
* Description:
* Get L2CC-P310 L2 cache linesize
@ -410,7 +410,7 @@ void arm_l2ccinitialize(void)
*
****************************************************************************/
uint32_t l2cc_get_linesize(void)
uint32_t l2cc_linesize(void)
{
return PL310_CACHE_LINE_SIZE;
}

View File

@ -44,9 +44,19 @@ static inline uint32_t ilog2(uint32_t u)
return i;
}
static inline uint32_t cp15_cache_get_info(uint32_t *sets, uint32_t *ways)
static inline uint32_t cp15_cache_get_info(uint32_t *sets, uint32_t *ways,
bool icache)
{
uint32_t ccsidr = CP15_GET(CCSIDR);
uint32_t ccsidr;
uint32_t csselr;
csselr = CP15_GET(CSSELR);
csselr = (csselr & ~0x01) | (icache & 0x01);
CP15_SET(CSSELR, csselr);
ccsidr = CP15_GET(CCSIDR);
if (sets)
{
@ -93,7 +103,7 @@ static void cp15_dcache_op_mva(uintptr_t start, uintptr_t end, int op)
{
uint32_t line;
line = cp15_cache_get_info(NULL, NULL);
line = cp15_dcache_linesize();
ARM_DSB();
@ -158,7 +168,7 @@ void cp15_dcache_op_level(uint32_t level, int op)
/* Get cache info */
line = cp15_cache_get_info(&sets, &ways);
line = cp15_cache_get_info(&sets, &ways, false);
way_shift = 32 - ilog2(ways);
set_shift = ilog2(line);
@ -209,7 +219,7 @@ void cp15_invalidate_icache(uintptr_t start, uintptr_t end)
{
uint32_t line;
line = cp15_cache_get_info(NULL, NULL);
line = cp15_icache_linesize();
start &= ~(line - 1);
ARM_DSB();
@ -259,18 +269,60 @@ void cp15_flush_dcache_all(void)
cp15_dcache_op(CP15_CACHE_CLEANINVALIDATE);
}
uint32_t cp15_cache_size(void)
uint32_t cp15_icache_size(void)
{
uint32_t sets;
uint32_t ways;
uint32_t line;
static uint32_t csize;
line = cp15_cache_get_info(&sets, &ways);
if (csize == 0)
{
uint32_t sets;
uint32_t ways;
uint32_t line;
return sets * ways * line;
line = cp15_cache_get_info(&sets, &ways, true);
csize = sets * ways * line;
}
return csize;
}
uint32_t cp15_cache_linesize(void)
uint32_t cp15_dcache_size(void)
{
return cp15_cache_get_info(NULL, NULL);
static uint32_t csize;
if (csize == 0)
{
uint32_t sets;
uint32_t ways;
uint32_t line;
line = cp15_cache_get_info(&sets, &ways, false);
csize = sets * ways * line;
}
return csize;
}
uint32_t cp15_icache_linesize(void)
{
static uint32_t clsize;
if (clsize == 0)
{
clsize = cp15_cache_get_info(NULL, NULL, true);
}
return clsize;
}
uint32_t cp15_dcache_linesize(void)
{
static uint32_t clsize;
if (clsize == 0)
{
clsize = cp15_cache_get_info(NULL, NULL, false);
}
return clsize;
}

View File

@ -1091,10 +1091,10 @@ void cp15_flush_dcache(uintptr_t start, uintptr_t end);
void cp15_flush_dcache_all(void);
/****************************************************************************
* Name: cp15_cache_size
* Name: cp15_icache_size
*
* Description:
* Get cp15 cache size in byte
* Get cp15 icache size in byte
*
* Input Parameters:
* None
@ -1104,23 +1104,55 @@ void cp15_flush_dcache_all(void);
*
****************************************************************************/
uint32_t cp15_cache_size(void);
uint32_t cp15_icache_size(void);
/****************************************************************************
* Name: cp15_cache_linesize
* Name: cp15_cache_size
*
* Description:
* Get cp15 cache linesize in byte
* Get cp15 dcache size in byte
*
* Input Parameters:
* None
*
* Returned Value:
* Cache linesize in byte
* Cache size in byte
*
****************************************************************************/
uint32_t cp15_cache_linesize(void);
uint32_t cp15_dcache_size(void);
/****************************************************************************
* Name: cp15_icache_linesize
*
* Description:
* Get cp15 icache linesize in byte
*
* Input Parameters:
* None
*
* Returned Value:
* ICache linesize in byte
*
****************************************************************************/
uint32_t cp15_icache_linesize(void);
/****************************************************************************
* Name: cp15_dcache_linesize
*
* Description:
* Get cp15 dcache linesize in byte
*
* Input Parameters:
* None
*
* Returned Value:
* DCache linesize in byte
*
****************************************************************************/
uint32_t cp15_dcache_linesize(void);
#undef EXTERN
#ifdef __cplusplus

View File

@ -71,7 +71,7 @@ void arm_l2ccinitialize(void);
#endif
/****************************************************************************
* Name: l2cc_get_linesize
* Name: l2cc_linesize
*
* Description:
* Get L2 cache linesize
@ -84,7 +84,7 @@ void arm_l2ccinitialize(void);
*
****************************************************************************/
uint32_t l2cc_get_linesize(void);
uint32_t l2cc_linesize(void);
/****************************************************************************
* Name: l2cc_enable
@ -245,7 +245,7 @@ void l2cc_flush(uint32_t startaddr, uint32_t endaddr);
* compilation in one place.
*/
# define l2cc_get_linesize() 0
# define l2cc_linesize() 0
# define l2cc_enable()
# define l2cc_disable()
# define l2cc_sync()

View File

@ -111,7 +111,7 @@ static inline uint32_t arm_clz(unsigned int value)
* Get cache linesize
*
* Input Parameters:
* None
* icache - Difference between icache and dcache.
*
* Returned Value:
* Cache line size
@ -119,21 +119,28 @@ static inline uint32_t arm_clz(unsigned int value)
****************************************************************************/
#if defined(CONFIG_ARMV7M_ICACHE) || defined(CONFIG_ARMV7M_DCACHE)
static size_t up_get_cache_linesize(void)
static size_t up_get_cache_linesize(bool icache)
{
static uint32_t clsize;
uint32_t ccsidr;
uint32_t csselr;
uint32_t sshift;
if (clsize == 0)
csselr = getreg32(NVIC_CSSELR);
if (icache)
{
uint32_t ccsidr;
uint32_t sshift;
ccsidr = getreg32(NVIC_CCSIDR);
sshift = CCSIDR_LSSHIFT(ccsidr) + 4; /* log2(cache-line-size-in-bytes) */
clsize = 1 << sshift;
csselr = (csselr & ~NVIC_CSSELR_IND) | NVIC_CSSELR_IND_ICACHE;
}
else
{
csselr = (csselr & ~NVIC_CSSELR_IND) | NVIC_CSSELR_IND_DCACHE;
}
return clsize;
putreg32(csselr, NVIC_CSSELR);
ccsidr = getreg32(NVIC_CCSIDR);
sshift = CCSIDR_LSSHIFT(ccsidr) + 4; /* log2(cache-line-size-in-bytes) */
return 1 << sshift;
}
#endif
@ -158,7 +165,14 @@ static size_t up_get_cache_linesize(void)
#ifdef CONFIG_ARMV7M_ICACHE
size_t up_get_icache_linesize(void)
{
return up_get_cache_linesize();
static uint32_t clsize;
if (clsize == 0)
{
clsize = up_get_cache_linesize(true);
}
return clsize;
}
#endif
@ -344,7 +358,14 @@ void up_invalidate_icache_all(void)
#ifdef CONFIG_ARMV7M_DCACHE
size_t up_get_dcache_linesize(void)
{
return up_get_cache_linesize();
static uint32_t clsize;
if (clsize == 0)
{
clsize = up_get_cache_linesize(false);
}
return clsize;
}
#endif

View File

@ -31,40 +31,6 @@
#include "barriers.h"
#include "l2cc.h"
/****************************************************************************
* Private Functions
****************************************************************************/
#if defined(CONFIG_ARCH_ICACHE) || defined(CONFIG_ARCH_DCACHE)
/****************************************************************************
* Name: up_get_cache_linesize
*
* Description:
* Get cache linesize
*
* Input Parameters:
* None
*
* Returned Value:
* Cache line size
*
****************************************************************************/
static size_t up_get_cache_linesize(void)
{
static uint32_t clsize;
if (clsize == 0)
{
clsize = MAX(cp15_cache_linesize(), l2cc_get_linesize());
}
return clsize;
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -87,7 +53,14 @@ static size_t up_get_cache_linesize(void)
size_t up_get_icache_linesize(void)
{
return up_get_cache_linesize();
static uint32_t clsize;
if (clsize == 0)
{
clsize = MAX(cp15_icache_linesize(), l2cc_linesize());
}
return clsize;
}
/****************************************************************************
@ -189,7 +162,14 @@ void up_disable_icache(void)
size_t up_get_dcache_linesize(void)
{
return up_get_cache_linesize();
static uint32_t clsize;
if (clsize == 0)
{
clsize = MAX(cp15_dcache_linesize(), l2cc_linesize());
}
return clsize;
}
/****************************************************************************
@ -272,7 +252,7 @@ void up_invalidate_dcache_all(void)
void up_clean_dcache(uintptr_t start, uintptr_t end)
{
if ((end - start) < cp15_cache_size())
if ((end - start) < cp15_dcache_size())
{
cp15_clean_dcache(start, end);
}
@ -336,7 +316,7 @@ void up_clean_dcache_all(void)
void up_flush_dcache(uintptr_t start, uintptr_t end)
{
if ((end - start) < cp15_cache_size())
if ((end - start) < cp15_dcache_size())
{
cp15_flush_dcache(start, end);
}

View File

@ -397,7 +397,7 @@ void arm_l2ccinitialize(void)
}
/****************************************************************************
* Name: l2cc_get_linesize
* Name: l2cc_linesize
*
* Description:
* Get L2CC-P310 L2 cache linesize
@ -410,7 +410,7 @@ void arm_l2ccinitialize(void)
*
****************************************************************************/
uint32_t l2cc_get_linesize(void)
uint32_t l2cc_linesize(void)
{
return PL310_CACHE_LINE_SIZE;
}

View File

@ -44,9 +44,19 @@ static inline uint32_t ilog2(uint32_t u)
return i;
}
static inline uint32_t cp15_cache_get_info(uint32_t *sets, uint32_t *ways)
static inline uint32_t cp15_cache_get_info(uint32_t *sets, uint32_t *ways,
bool icache)
{
uint32_t ccsidr = CP15_GET(CCSIDR);
uint32_t ccsidr;
uint32_t csselr;
csselr = CP15_GET(CSSELR);
csselr = (csselr & ~0x01) | (icache & 0x01);
CP15_SET(CSSELR, csselr);
ccsidr = CP15_GET(CCSIDR);
if (sets)
{
@ -93,7 +103,7 @@ static void cp15_dcache_op_mva(uintptr_t start, uintptr_t end, int op)
{
uint32_t line;
line = cp15_cache_get_info(NULL, NULL);
line = cp15_dcache_linesize();
ARM_DSB();
@ -158,7 +168,7 @@ void cp15_dcache_op_level(uint32_t level, int op)
/* Get cache info */
line = cp15_cache_get_info(&sets, &ways);
line = cp15_cache_get_info(&sets, &ways, false);
way_shift = 32 - ilog2(ways);
set_shift = ilog2(line);
@ -209,7 +219,7 @@ void cp15_invalidate_icache(uintptr_t start, uintptr_t end)
{
uint32_t line;
line = cp15_cache_get_info(NULL, NULL);
line = cp15_icache_linesize();
start &= ~(line - 1);
ARM_DSB();
@ -259,18 +269,60 @@ void cp15_flush_dcache_all(void)
cp15_dcache_op(CP15_CACHE_CLEANINVALIDATE);
}
uint32_t cp15_cache_size(void)
uint32_t cp15_icache_size(void)
{
uint32_t sets;
uint32_t ways;
uint32_t line;
static uint32_t csize;
line = cp15_cache_get_info(&sets, &ways);
if (csize == 0)
{
uint32_t sets;
uint32_t ways;
uint32_t line;
return sets * ways * line;
line = cp15_cache_get_info(&sets, &ways, true);
csize = sets * ways * line;
}
return csize;
}
uint32_t cp15_cache_linesize(void)
uint32_t cp15_dcache_size(void)
{
return cp15_cache_get_info(NULL, NULL);
static uint32_t csize;
if (csize == 0)
{
uint32_t sets;
uint32_t ways;
uint32_t line;
line = cp15_cache_get_info(&sets, &ways, false);
csize = sets * ways * line;
}
return csize;
}
uint32_t cp15_icache_linesize(void)
{
static uint32_t clsize;
if (clsize == 0)
{
clsize = cp15_cache_get_info(NULL, NULL, true);
}
return clsize;
}
uint32_t cp15_dcache_linesize(void)
{
static uint32_t clsize;
if (clsize == 0)
{
clsize = cp15_cache_get_info(NULL, NULL, false);
}
return clsize;
}

View File

@ -1098,10 +1098,10 @@ void cp15_flush_dcache(uintptr_t start, uintptr_t end);
void cp15_flush_dcache_all(void);
/****************************************************************************
* Name: cp15_cache_size
* Name: cp15_icache_size
*
* Description:
* Get cp15 cache size in byte
* Get cp15 icache size in byte
*
* Input Parameters:
* None
@ -1111,23 +1111,55 @@ void cp15_flush_dcache_all(void);
*
****************************************************************************/
uint32_t cp15_cache_size(void);
uint32_t cp15_icache_size(void);
/****************************************************************************
* Name: cp15_cache_linesize
* Name: cp15_cache_size
*
* Description:
* Get cp15 cache linesize in byte
* Get cp15 dcache size in byte
*
* Input Parameters:
* None
*
* Returned Value:
* Cache linesize in byte
* Cache size in byte
*
****************************************************************************/
uint32_t cp15_cache_linesize(void);
uint32_t cp15_dcache_size(void);
/****************************************************************************
* Name: cp15_icache_linesize
*
* Description:
* Get cp15 icache linesize in byte
*
* Input Parameters:
* None
*
* Returned Value:
* ICache linesize in byte
*
****************************************************************************/
uint32_t cp15_icache_linesize(void);
/****************************************************************************
* Name: cp15_dcache_linesize
*
* Description:
* Get cp15 dcache linesize in byte
*
* Input Parameters:
* None
*
* Returned Value:
* DCache linesize in byte
*
****************************************************************************/
uint32_t cp15_dcache_linesize(void);
#undef EXTERN
#ifdef __cplusplus

View File

@ -71,7 +71,7 @@ void arm_l2ccinitialize(void);
#endif
/****************************************************************************
* Name: l2cc_get_linesize
* Name: l2cc_linesize
*
* Description:
* Get L2 cache linesize
@ -84,7 +84,7 @@ void arm_l2ccinitialize(void);
*
****************************************************************************/
uint32_t l2cc_get_linesize(void);
uint32_t l2cc_linesize(void);
/****************************************************************************
* Name: l2cc_enable
@ -245,7 +245,7 @@ void l2cc_flush(uint32_t startaddr, uint32_t endaddr);
* compilation in one place.
*/
# define l2cc_get_linesize() 0
# define l2cc_linesize() 0
# define l2cc_enable()
# define l2cc_disable()
# define l2cc_sync()

View File

@ -111,7 +111,7 @@ static inline uint32_t arm_clz(unsigned int value)
* Get cache linesize
*
* Input Parameters:
* None
* icache - Difference between icache and dcache.
*
* Returned Value:
* Cache line size
@ -119,21 +119,28 @@ static inline uint32_t arm_clz(unsigned int value)
****************************************************************************/
#if defined(CONFIG_ARMV8M_ICACHE) || defined(CONFIG_ARMV8M_DCACHE)
static size_t up_get_cache_linesize(void)
static size_t up_get_cache_linesize(bool icache)
{
static uint32_t clsize;
uint32_t ccsidr;
uint32_t csselr;
uint32_t sshift;
if (clsize == 0)
csselr = getreg32(NVIC_CSSELR);
if (icache)
{
uint32_t ccsidr;
uint32_t sshift;
ccsidr = getreg32(NVIC_CCSIDR);
sshift = CCSIDR_LSSHIFT(ccsidr) + 4; /* log2(cache-line-size-in-bytes) */
clsize = 1 << sshift;
csselr = (csselr & ~NVIC_CSSELR_IND) | NVIC_CSSELR_IND_ICACHE;
}
else
{
csselr = (csselr & ~NVIC_CSSELR_IND) | NVIC_CSSELR_IND_DCACHE;
}
return clsize;
putreg32(csselr, NVIC_CSSELR);
ccsidr = getreg32(NVIC_CCSIDR);
sshift = CCSIDR_LSSHIFT(ccsidr) + 4; /* log2(cache-line-size-in-bytes) */
return 1 << sshift;
}
#endif
@ -158,7 +165,14 @@ static size_t up_get_cache_linesize(void)
#ifdef CONFIG_ARMV8M_ICACHE
size_t up_get_icache_linesize(void)
{
return up_get_cache_linesize();
static uint32_t clsize;
if (clsize == 0)
{
clsize = up_get_cache_linesize(true);
}
return clsize;
}
#endif
@ -344,7 +358,14 @@ void up_invalidate_icache_all(void)
#ifdef CONFIG_ARMV8M_DCACHE
size_t up_get_dcache_linesize(void)
{
return up_get_cache_linesize();
static uint32_t clsize;
if (clsize == 0)
{
clsize = up_get_cache_linesize(false);
}
return clsize;
}
#endif