diff --git a/arch/arm/src/armv7-a/arm_cache.c b/arch/arm/src/armv7-a/arm_cache.c index 8a203e45a8d..3a868f5a9ad 100644 --- a/arch/arm/src/armv7-a/arm_cache.c +++ b/arch/arm/src/armv7-a/arm_cache.c @@ -432,6 +432,15 @@ void up_flush_dcache_all(void) void up_enable_dcache(void) { + /* Check if the D-Cache is enabled */ + + if (cp15_dcache_is_enabled()) + { + return; + } + + up_invalidate_dcache_all(); + cp15_enable_dcache(); l2cc_enable(); } diff --git a/arch/arm/src/armv7-a/cp15_cacheops.h b/arch/arm/src/armv7-a/cp15_cacheops.h index 85787462358..9004620e2d1 100644 --- a/arch/arm/src/armv7-a/cp15_cacheops.h +++ b/arch/arm/src/armv7-a/cp15_cacheops.h @@ -551,6 +551,25 @@ #ifndef __ASSEMBLY__ +/**************************************************************************** + * Name: cp15_dcache_is_enabled + * + * Description: + * Check if L1 D Cache is enabled + * + * Input Parameters: + * None + * + * Returned Value: + * true if L1 D Cache is enabled, false otherwise + * + ****************************************************************************/ + +static inline int cp15_dcache_is_enabled(void) +{ + return (CP15_GET(SCTLR) & SCTLR_C) != 0; +} + /**************************************************************************** * Name: cp15_enable_dcache * @@ -1107,7 +1126,7 @@ void cp15_flush_dcache_all(void); uint32_t cp15_icache_size(void); /**************************************************************************** - * Name: cp15_cache_size + * Name: cp15_dcache_size * * Description: * Get cp15 dcache size in byte diff --git a/arch/arm/src/armv7-m/arm_cache.c b/arch/arm/src/armv7-m/arm_cache.c index db605c8450c..78cfbb3fc2a 100644 --- a/arch/arm/src/armv7-m/arm_cache.c +++ b/arch/arm/src/armv7-m/arm_cache.c @@ -496,12 +496,12 @@ void up_enable_dcache(void) uint32_t sets; uint32_t ways; - /* If dcache is already enabled, disable it first. */ + /* If dcache is already enabled, return. */ ccr = getreg32(NVIC_CFGCON); if ((ccr & NVIC_CFGCON_DC) != 0) { - up_disable_dcache(); + return; } /* Get the characteristics of the D-Cache */ diff --git a/arch/arm/src/armv7-r/arm_cache.c b/arch/arm/src/armv7-r/arm_cache.c index f7cac398cb4..c169b6ba1e0 100644 --- a/arch/arm/src/armv7-r/arm_cache.c +++ b/arch/arm/src/armv7-r/arm_cache.c @@ -432,6 +432,15 @@ void up_flush_dcache_all(void) void up_enable_dcache(void) { + /* Check if the D-Cache is enabled */ + + if (cp15_dcache_is_enabled()) + { + return; + } + + up_invalidate_dcache_all(); + cp15_enable_dcache(); l2cc_enable(); } diff --git a/arch/arm/src/armv7-r/cp15_cacheops.h b/arch/arm/src/armv7-r/cp15_cacheops.h index 6b0cb759f5c..725cc36e545 100644 --- a/arch/arm/src/armv7-r/cp15_cacheops.h +++ b/arch/arm/src/armv7-r/cp15_cacheops.h @@ -558,6 +558,25 @@ #ifndef __ASSEMBLY__ +/**************************************************************************** + * Name: cp15_dcache_is_enabled + * + * Description: + * Check if L1 D Cache is enabled + * + * Input Parameters: + * None + * + * Returned Value: + * true if L1 D Cache is enabled, false otherwise + * + ****************************************************************************/ + +static inline int cp15_dcache_is_enabled(void) +{ + return (CP15_GET(SCTLR) & SCTLR_C) != 0; +} + /**************************************************************************** * Name: cp15_enable_dcache * @@ -1114,7 +1133,7 @@ void cp15_flush_dcache_all(void); uint32_t cp15_icache_size(void); /**************************************************************************** - * Name: cp15_cache_size + * Name: cp15_dcache_size * * Description: * Get cp15 dcache size in byte diff --git a/arch/arm/src/armv8-m/arm_cache.c b/arch/arm/src/armv8-m/arm_cache.c index 0a14fa69d41..cc703db17f1 100644 --- a/arch/arm/src/armv8-m/arm_cache.c +++ b/arch/arm/src/armv8-m/arm_cache.c @@ -496,12 +496,12 @@ void up_enable_dcache(void) uint32_t sets; uint32_t ways; - /* If dcache is already enabled, disable it first. */ + /* If dcache is already enabled, return. */ ccr = getreg32(NVIC_CFGCON); if ((ccr & NVIC_CFGCON_DC) != 0) { - up_disable_dcache(); + return; } /* Get the characteristics of the D-Cache */ diff --git a/arch/arm/src/armv8-r/arm_cache.c b/arch/arm/src/armv8-r/arm_cache.c index 30545c99dba..17949f3c9fe 100644 --- a/arch/arm/src/armv8-r/arm_cache.c +++ b/arch/arm/src/armv8-r/arm_cache.c @@ -436,6 +436,15 @@ void up_flush_dcache_all(void) void up_enable_dcache(void) { + /* Check if the D-Cache is enabled */ + + if (cp15_dcache_is_enabled()) + { + return; + } + + up_invalidate_dcache_all(); + cp15_enable_dcache(); l2cc_enable(); } diff --git a/arch/arm/src/armv8-r/cp15_cacheops.h b/arch/arm/src/armv8-r/cp15_cacheops.h index 6e1b31d635b..87fae5a2ed6 100644 --- a/arch/arm/src/armv8-r/cp15_cacheops.h +++ b/arch/arm/src/armv8-r/cp15_cacheops.h @@ -558,6 +558,25 @@ #ifndef __ASSEMBLY__ +/**************************************************************************** + * Name: cp15_dcache_is_enabled + * + * Description: + * Check if L1 D Cache is enabled + * + * Input Parameters: + * None + * + * Returned Value: + * true if L1 D Cache is enabled, false otherwise + * + ****************************************************************************/ + +static inline int cp15_dcache_is_enabled(void) +{ + return (CP15_GET(SCTLR) & SCTLR_C) != 0; +} + /**************************************************************************** * Name: cp15_enable_dcache * diff --git a/arch/arm64/src/common/arm64_cache.c b/arch/arm64/src/common/arm64_cache.c index 95833fdf7b9..ddf2ddf2682 100644 --- a/arch/arm64/src/common/arm64_cache.c +++ b/arch/arm64/src/common/arm64_cache.c @@ -519,6 +519,17 @@ void up_clean_dcache_all(void) void up_enable_dcache(void) { uint64_t value = read_sysreg(sctlr_el1); + + /* Check if the D-Cache is enabled */ + + if ((value & SCTLR_C_BIT) != 0) + { + return; + } + + up_invalidate_dcache_all(); + + value = read_sysreg(sctlr_el1); write_sysreg((value | SCTLR_C_BIT), sctlr_el1); ARM64_ISB(); } diff --git a/arch/x86_64/src/intel64/intel64_cache.c b/arch/x86_64/src/intel64/intel64_cache.c index 3aa3e45fda1..13a05c6373d 100644 --- a/arch/x86_64/src/intel64/intel64_cache.c +++ b/arch/x86_64/src/intel64/intel64_cache.c @@ -116,6 +116,21 @@ static size_t x86_64_cache_size(int leaf) (ecx + 1)); } +/**************************************************************************** + * Name: x86_64_is_cache_enabled + ****************************************************************************/ + +static int x86_64_is_cache_enabled(void) +{ + unsigned long cr0; + + asm volatile("\t mov %%cr0, %0\n" + : "=r" (cr0) + :: "memory"); + + return (cr0 & 0x60000000) == 0; +} + /**************************************************************************** * Name: x86_64_cache_enable ****************************************************************************/ @@ -358,6 +373,14 @@ size_t up_get_dcache_size(void) #ifdef CONFIG_ARCH_DCACHE void up_enable_dcache(void) { + /* Check if the D-Cache is enabled */ + + if (x86_64_is_cache_enabled()) + { + return; + } + + up_invalidate_dcache_all(); x86_64_cache_enable(); } #endif /* CONFIG_ARCH_DCACHE */ diff --git a/arch/xtensa/src/common/xtensa_cache.c b/arch/xtensa/src/common/xtensa_cache.c index d64804e1d36..9161ad55c8b 100644 --- a/arch/xtensa/src/common/xtensa_cache.c +++ b/arch/xtensa/src/common/xtensa_cache.c @@ -346,6 +346,15 @@ void up_enable_dcache(void) __asm__ __volatile__ ("rsr %0, memctl\n" : "=r"(memctl) :); + /* Check if the D-Cache is enabled */ + + if ((memctl & MEMCTL_INV_EN) != 0) + { + return; + } + + up_invalidate_dcache_all(); + /* set ways allocatable & ways use */ memctl = memctl & ~(MEMCTL_DCWA_MASK | MEMCTL_DCWU_MASK);