diff --git a/arch/arm/src/armv7-a/arm_cache.c b/arch/arm/src/armv7-a/arm_cache.c index 95eb5ebae3..e5120cb32f 100644 --- a/arch/arm/src/armv7-a/arm_cache.c +++ b/arch/arm/src/armv7-a/arm_cache.c @@ -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); } diff --git a/arch/arm/src/armv7-a/arm_l2cc_pl310.c b/arch/arm/src/armv7-a/arm_l2cc_pl310.c index ceb57a0e92..5744091ee7 100644 --- a/arch/arm/src/armv7-a/arm_l2cc_pl310.c +++ b/arch/arm/src/armv7-a/arm_l2cc_pl310.c @@ -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; } diff --git a/arch/arm/src/armv7-a/cp15_cacheops.c b/arch/arm/src/armv7-a/cp15_cacheops.c index 084e46df0c..d7bf4a4e5e 100644 --- a/arch/arm/src/armv7-a/cp15_cacheops.c +++ b/arch/arm/src/armv7-a/cp15_cacheops.c @@ -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; } diff --git a/arch/arm/src/armv7-a/cp15_cacheops.h b/arch/arm/src/armv7-a/cp15_cacheops.h index a680c4b5a9..8578746235 100644 --- a/arch/arm/src/armv7-a/cp15_cacheops.h +++ b/arch/arm/src/armv7-a/cp15_cacheops.h @@ -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 diff --git a/arch/arm/src/armv7-a/l2cc.h b/arch/arm/src/armv7-a/l2cc.h index eee2e80c73..e0d96974b8 100644 --- a/arch/arm/src/armv7-a/l2cc.h +++ b/arch/arm/src/armv7-a/l2cc.h @@ -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() diff --git a/arch/arm/src/armv7-m/arm_cache.c b/arch/arm/src/armv7-m/arm_cache.c index 34ee70441b..4588ea1e42 100644 --- a/arch/arm/src/armv7-m/arm_cache.c +++ b/arch/arm/src/armv7-m/arm_cache.c @@ -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 diff --git a/arch/arm/src/armv7-r/arm_cache.c b/arch/arm/src/armv7-r/arm_cache.c index 0163f176cb..323da0bce3 100644 --- a/arch/arm/src/armv7-r/arm_cache.c +++ b/arch/arm/src/armv7-r/arm_cache.c @@ -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); } diff --git a/arch/arm/src/armv7-r/arm_l2cc_pl310.c b/arch/arm/src/armv7-r/arm_l2cc_pl310.c index 39ce67cfd8..bd5e5a54b7 100644 --- a/arch/arm/src/armv7-r/arm_l2cc_pl310.c +++ b/arch/arm/src/armv7-r/arm_l2cc_pl310.c @@ -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; } diff --git a/arch/arm/src/armv7-r/cp15_cacheops.c b/arch/arm/src/armv7-r/cp15_cacheops.c index bc542fc35c..74da551a81 100644 --- a/arch/arm/src/armv7-r/cp15_cacheops.c +++ b/arch/arm/src/armv7-r/cp15_cacheops.c @@ -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; } diff --git a/arch/arm/src/armv7-r/cp15_cacheops.h b/arch/arm/src/armv7-r/cp15_cacheops.h index 4561844fc2..6b0cb759f5 100644 --- a/arch/arm/src/armv7-r/cp15_cacheops.h +++ b/arch/arm/src/armv7-r/cp15_cacheops.h @@ -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 diff --git a/arch/arm/src/armv7-r/l2cc.h b/arch/arm/src/armv7-r/l2cc.h index c0b659d534..fa62baf3bf 100644 --- a/arch/arm/src/armv7-r/l2cc.h +++ b/arch/arm/src/armv7-r/l2cc.h @@ -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() diff --git a/arch/arm/src/armv8-m/arm_cache.c b/arch/arm/src/armv8-m/arm_cache.c index eab92de3ab..4028f3d5a2 100644 --- a/arch/arm/src/armv8-m/arm_cache.c +++ b/arch/arm/src/armv8-m/arm_cache.c @@ -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