diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 213cc22152..03d1ec0e1b 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -80,6 +80,14 @@ config XTENSA_HAVE_DCACHE bool default n +config XTENSA_HAVE_ICACHE_LOCK + bool + default n + +config XTENSA_HAVE_DCACHE_LOCK + bool + default n + config XTENSA_ICACHE bool "Use I-Cache" default n @@ -96,6 +104,24 @@ config XTENSA_DCACHE ---help--- Enable Xtensa D-Cache +config XTENSA_ICACHE_LOCK + bool "Use I-Cache lock & unlock feature" + default n + depends on XTENSA_HAVE_ICACHE + depends on XTENSA_HAVE_ICACHE_LOCK + select ARCH_ICACHE_LOCK + ---help--- + Enable Xtensa I-Cache lock & unlock feature + +config XTENSA_DCACHE_LOCK + bool "Use D-Cache lock & unlock feature" + default n + depends on XTENSA_HAVE_DCACHE + depends on XTENSA_HAVE_DCACHE_LOCK + select ARCH_DCACHE_LOCK + ---help--- + Enable Xtensa D-Cache lock & unlock feature + config ARCH_FAMILY_LX6 bool default n diff --git a/arch/xtensa/src/common/xtensa_cache.c b/arch/xtensa/src/common/xtensa_cache.c index e382017e16..5a0b1233d6 100644 --- a/arch/xtensa/src/common/xtensa_cache.c +++ b/arch/xtensa/src/common/xtensa_cache.c @@ -112,9 +112,9 @@ void up_disable_icache(void) ****************************************************************************/ #ifdef CONFIG_XTENSA_ICACHE -void up_invalidate_icache(uint32_t start, uint32_t end) +void up_invalidate_icache(uintptr_t start, uintptr_t end) { - /* align to XCHAL_ICACHE_SIZE */ + /* align to XCHAL_ICACHE_LINESIZE */ uint32_t addr = start - (start & (XCHAL_ICACHE_LINESIZE - 1)); @@ -155,6 +155,96 @@ void up_invalidate_icache_all(void) } #endif +/**************************************************************************** + * Name: up_lock_icache + * + * Description: + * Prefetch and lock the instruction cache within the specified region. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_XTENSA_ICACHE_LOCK +void up_lock_icache(uintptr_t start, uintptr_t end) +{ + /* align to XCHAL_ICACHE_LINESIZE */ + + uint32_t addr = start - (start & (XCHAL_ICACHE_LINESIZE - 1)); + + for (; addr < end; addr += XCHAL_ICACHE_LINESIZE) + { + __asm__ __volatile__ ("ipfl %0, 0\n": : "r"(addr)); + }; + + __asm__ __volatile__ ("isync\n"); +} +#endif + +/**************************************************************************** + * Name: up_unlock_icache + * + * Description: + * Unlock the instruction cache within the specified region. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_XTENSA_ICACHE_LOCK +void up_unlock_icache(uintptr_t start, uintptr_t end) +{ + /* align to XCHAL_ICACHE_LINESIZE */ + + uint32_t addr = start - (start & (XCHAL_ICACHE_LINESIZE - 1)); + + for (; addr < end; addr += XCHAL_ICACHE_LINESIZE) + { + __asm__ __volatile__ ("ihu %0, 0\n": : "r"(addr)); + }; + + __asm__ __volatile__ ("isync\n"); +} +#endif + +/**************************************************************************** + * Name: up_unlock_icache_all + * + * Description: + * Unlock the entire contents of instruction cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_XTENSA_ICACHE_LOCK +void up_unlock_icache_all(void) +{ + uint32_t index; + + for (index = 0; index < XCHAL_ICACHE_SIZE; index += XCHAL_ICACHE_LINESIZE) + { + __asm__ __volatile__ ("iiu %0, 0\n": : "r"(index)); + }; + + __asm__ __volatile__ ("isync\n"); +} +#endif + /**************************************************************************** * Name: up_enable_dcache * @@ -439,6 +529,96 @@ void up_flush_dcache_all(void) } #endif +/**************************************************************************** + * Name: up_lock_dcache + * + * Description: + * Prefetch and lock the data cache within the specified region. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_XTENSA_DCACHE_LOCK +void up_lock_dcache(uintptr_t start, uintptr_t end) +{ + /* align to XCHAL_DCACHE_LINESIZE */ + + uint32_t addr = start - (start & (XCHAL_DCACHE_LINESIZE - 1)); + + for (; addr < end; addr += XCHAL_DCACHE_LINESIZE) + { + __asm__ __volatile__ ("dpfl %0, 0\n": : "r"(addr)); + }; + + __asm__ __volatile__ ("dsync\n"); +} +#endif + +/**************************************************************************** + * Name: up_unlock_dcache + * + * Description: + * Unlock the data cache within the specified region. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_XTENSA_DCACHE_LOCK +void up_unlock_dcache(uintptr_t start, uintptr_t end) +{ + /* align to XCHAL_DCACHE_LINESIZE */ + + uint32_t addr = start - (start & (XCHAL_DCACHE_LINESIZE - 1)); + + for (; addr < end; addr += XCHAL_DCACHE_LINESIZE) + { + __asm__ __volatile__ ("dhu %0, 0\n": : "r"(addr)); + }; + + __asm__ __volatile__ ("dsync\n"); +} +#endif + +/**************************************************************************** + * Name: up_unlock_dcache_all + * + * Description: + * Unlock the entire contents of data cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_XTENSA_DCACHE_LOCK +void up_unlock_dcache_all(void) +{ + uint32_t index; + + for (index = 0; index < XCHAL_DCACHE_SIZE; index += XCHAL_DCACHE_LINESIZE) + { + __asm__ __volatile__ ("diu %0, 0\n" : : "r"(index)); + }; + + __asm__ __volatile__ ("dsync\n"); +} +#endif + /**************************************************************************** * Name: up_coherent_dcache *