X-Git-Url: https://git.librecmc.org/?p=oweals%2Fu-boot.git;a=blobdiff_plain;f=arch%2Fnds32%2Flib%2Fcache.c;h=21917e5da5e6618deadc4a9599148bb8ca575843;hp=866dc1a98a57e3ce6b9c36d60977772ab887eb72;hb=c27178ba3649f539c9f1890ea147f4c5415f63b5;hpb=5b9c79a81db80c3f9e50c77477957cd803429af8 diff --git a/arch/nds32/lib/cache.c b/arch/nds32/lib/cache.c index 866dc1a98a..21917e5da5 100644 --- a/arch/nds32/lib/cache.c +++ b/arch/nds32/lib/cache.c @@ -1,38 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2012 Andes Technology Corporation * Shawn Lin, Andes Technology Corporation * Macpaul Lin, Andes Technology Corporation - * - * SPDX-License-Identifier: GPL-2.0+ */ #include +#include +#if !(CONFIG_IS_ENABLED(SYS_ICACHE_OFF) && CONFIG_IS_ENABLED(SYS_DCACHE_OFF)) +#include +static inline unsigned long CACHE_SET(unsigned char cache) +{ + if (cache == ICACHE) + return 64 << ((GET_ICM_CFG() & ICM_CFG_MSK_ISET) \ + >> ICM_CFG_OFF_ISET); + else + return 64 << ((GET_DCM_CFG() & DCM_CFG_MSK_DSET) \ + >> DCM_CFG_OFF_DSET); +} + +static inline unsigned long CACHE_WAY(unsigned char cache) +{ + if (cache == ICACHE) + return 1 + ((GET_ICM_CFG() & ICM_CFG_MSK_IWAY) \ + >> ICM_CFG_OFF_IWAY); + else + return 1 + ((GET_DCM_CFG() & DCM_CFG_MSK_DWAY) \ + >> DCM_CFG_OFF_DWAY); +} static inline unsigned long CACHE_LINE_SIZE(enum cache_t cache) { if (cache == ICACHE) return 8 << (((GET_ICM_CFG() & ICM_CFG_MSK_ISZ) \ - >> ICM_CFG_OFF_ISZ) - 1); + >> ICM_CFG_OFF_ISZ) - 1); else return 8 << (((GET_DCM_CFG() & DCM_CFG_MSK_DSZ) \ - >> DCM_CFG_OFF_DSZ) - 1); + >> DCM_CFG_OFF_DSZ) - 1); } +#endif -void flush_dcache_range(unsigned long start, unsigned long end) +#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF) +void invalidate_icache_all(void) { - unsigned long line_size; + unsigned long end, line_size; + line_size = CACHE_LINE_SIZE(ICACHE); + end = line_size * CACHE_WAY(ICACHE) * CACHE_SET(ICACHE); + do { + end -= line_size; + __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL" : : "r" (end)); - line_size = CACHE_LINE_SIZE(DCACHE); + end -= line_size; + __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL" : : "r" (end)); - while (end > start) { - asm volatile ( - "\n\tcctl %0, L1D_VA_WB" - "\n\tcctl %0, L1D_VA_INVAL" - : - : "r" (start) - ); - start += line_size; - } + end -= line_size; + __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL" : : "r" (end)); + end -= line_size; + __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL" : : "r" (end)); + } while (end > 0); } void invalidate_icache_range(unsigned long start, unsigned long end) @@ -50,27 +75,6 @@ void invalidate_icache_range(unsigned long start, unsigned long end) } } -void invalidate_dcache_range(unsigned long start, unsigned long end) -{ - unsigned long line_size; - - line_size = CACHE_LINE_SIZE(DCACHE); - while (end > start) { - asm volatile ( - "\n\tcctl %0, L1D_VA_INVAL" - : - : "r"(start) - ); - start += line_size; - } -} - -void flush_cache(unsigned long addr, unsigned long size) -{ - flush_dcache_range(addr, addr + size); - invalidate_icache_range(addr, addr + size); -} - void icache_enable(void) { asm volatile ( @@ -107,6 +111,81 @@ int icache_status(void) return ret; } +#else +void invalidate_icache_all(void) +{ +} + +void invalidate_icache_range(unsigned long start, unsigned long end) +{ +} + +void icache_enable(void) +{ +} + +void icache_disable(void) +{ +} + +int icache_status(void) +{ + return 0; +} + +#endif + +#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) +void dcache_wbinval_all(void) +{ + unsigned long end, line_size; + line_size = CACHE_LINE_SIZE(DCACHE); + end = line_size * CACHE_WAY(DCACHE) * CACHE_SET(DCACHE); + do { + end -= line_size; + __asm__ volatile ("\n\tcctl %0, L1D_IX_WB" : : "r" (end)); + __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL" : : "r" (end)); + end -= line_size; + __asm__ volatile ("\n\tcctl %0, L1D_IX_WB" : : "r" (end)); + __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL" : : "r" (end)); + end -= line_size; + __asm__ volatile ("\n\tcctl %0, L1D_IX_WB" : : "r" (end)); + __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL" : : "r" (end)); + end -= line_size; + __asm__ volatile ("\n\tcctl %0, L1D_IX_WB" : : "r" (end)); + __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL" : : "r" (end)); + + } while (end > 0); +} + +void flush_dcache_range(unsigned long start, unsigned long end) +{ + unsigned long line_size; + + line_size = CACHE_LINE_SIZE(DCACHE); + + while (end > start) { + asm volatile ( + "\n\tcctl %0, L1D_VA_WB" + "\n\tcctl %0, L1D_VA_INVAL" : : "r" (start) + ); + start += line_size; + } +} + +void invalidate_dcache_range(unsigned long start, unsigned long end) +{ + unsigned long line_size; + + line_size = CACHE_LINE_SIZE(DCACHE); + while (end > start) { + asm volatile ( + "\n\tcctl %0, L1D_VA_INVAL" : : "r"(start) + ); + start += line_size; + } +} + void dcache_enable(void) { asm volatile ( @@ -131,7 +210,6 @@ void dcache_disable(void) int dcache_status(void) { int ret; - asm volatile ( "mfsr $p0, $mr8\n\t" "andi %0, $p0, 0x02\n\t" @@ -139,6 +217,52 @@ int dcache_status(void) : : "memory" ); - return ret; } + +#else +void dcache_wbinval_all(void) +{ +} + +void flush_dcache_range(unsigned long start, unsigned long end) +{ +} + +void invalidate_dcache_range(unsigned long start, unsigned long end) +{ +} + +void dcache_enable(void) +{ +} + +void dcache_disable(void) +{ +} + +int dcache_status(void) +{ + return 0; +} + +#endif + + +void flush_dcache_all(void) +{ + dcache_wbinval_all(); +} + +void cache_flush(void) +{ + flush_dcache_all(); + invalidate_icache_all(); +} + + +void flush_cache(unsigned long addr, unsigned long size) +{ + flush_dcache_range(addr, addr + size); + invalidate_icache_range(addr, addr + size); +}