From aac760584b60119d2a97730373fca55cdbd5141f Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 4 Oct 2024 03:48:19 +0200 Subject: [PATCH] bsps/aarch64: Fix entire data cache flush/invalidate The cache maintenance operations affect only the current PE. Make sure that thread dispatching is disabled and interrupts cannot interfere. --- bsps/aarch64/shared/cache/cache.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/bsps/aarch64/shared/cache/cache.c b/bsps/aarch64/shared/cache/cache.c index b421947c39..46c9f5ce0c 100644 --- a/bsps/aarch64/shared/cache/cache.c +++ b/bsps/aarch64/shared/cache/cache.c @@ -247,9 +247,13 @@ static inline void AArch64_data_cache_clean_all_levels(void) static inline void _CPU_cache_flush_entire_data(void) { + rtems_interrupt_level isr_level; + + rtems_interrupt_local_disable(isr_level); _AARCH64_Data_synchronization_barrier(); AArch64_data_cache_clean_all_levels(); _AARCH64_Data_synchronization_barrier(); + rtems_interrupt_local_enable(isr_level); } static inline void AArch64_cache_invalidate_level(uint64_t level) @@ -303,19 +307,25 @@ static inline void AArch64_data_cache_invalidate_all_levels(void) static inline void _CPU_cache_invalidate_entire_data(void) { + rtems_interrupt_level isr_level; + + rtems_interrupt_local_disable(isr_level); + _AARCH64_Data_synchronization_barrier(); AArch64_data_cache_invalidate_all_levels(); + _AARCH64_Data_synchronization_barrier(); + rtems_interrupt_local_enable(isr_level); } static inline void _CPU_cache_enable_data(void) { - rtems_interrupt_level level; + rtems_interrupt_level isr_level; uint64_t sctlr; - rtems_interrupt_local_disable(level); + rtems_interrupt_local_disable(isr_level); sctlr = _AArch64_Read_sctlr_el1(); sctlr |= AARCH64_SCTLR_EL1_C; _AArch64_Write_sctlr_el1(sctlr); - rtems_interrupt_local_enable(level); + rtems_interrupt_local_enable(isr_level); } static RTEMS_NO_RETURN inline void _CPU_cache_disable_data(void) @@ -351,26 +361,26 @@ static inline void _CPU_cache_invalidate_entire_instruction(void) static inline void _CPU_cache_enable_instruction(void) { - rtems_interrupt_level level; + rtems_interrupt_level isr_level; uint64_t sctlr; - rtems_interrupt_local_disable(level); + rtems_interrupt_local_disable(isr_level); sctlr = _AArch64_Read_sctlr_el1(); sctlr |= AARCH64_SCTLR_EL1_I; _AArch64_Write_sctlr_el1(sctlr); - rtems_interrupt_local_enable(level); + rtems_interrupt_local_enable(isr_level); } static inline void _CPU_cache_disable_instruction(void) { - rtems_interrupt_level level; + rtems_interrupt_level isr_level; uint64_t sctlr; - rtems_interrupt_local_disable(level); + rtems_interrupt_local_disable(isr_level); sctlr = _AArch64_Read_sctlr_el1(); sctlr &= ~AARCH64_SCTLR_EL1_I; _AArch64_Write_sctlr_el1(sctlr); - rtems_interrupt_local_enable(level); + rtems_interrupt_local_enable(isr_level); } static inline size_t AArch64_get_cache_size( @@ -378,6 +388,7 @@ static inline size_t AArch64_get_cache_size( bool instruction ) { + rtems_interrupt_level isr_level; uint64_t clidr; uint64_t loc; uint64_t ccsidr; @@ -389,7 +400,9 @@ static inline size_t AArch64_get_cache_size( return 0; } + rtems_interrupt_local_disable(isr_level); ccsidr = AArch64_get_ccsidr_for_level(level, instruction); + rtems_interrupt_local_enable(isr_level); return (1U << (AArch64_ccsidr_get_line_power(ccsidr)+4)) * AArch64_ccsidr_get_associativity(ccsidr)