include: Implement API's for cache flush and cache invalidate
arch: arc: core: Add Cache Implementation function & prototype for arc
Signed-off-by: Aastha Grover <aastha.grover@intel.com>
diff --git a/arch/arc/core/cache.c b/arch/arc/core/cache.c
index a59886d..2196fe4 100644
--- a/arch/arc/core/cache.c
+++ b/arch/arc/core/cache.c
@@ -67,34 +67,19 @@
dcache_dc_ctrl(DC_CTRL_DC_ENABLE);
}
-
-/**
- *
- * @brief Flush multiple d-cache lines to memory
- *
- * No alignment is required for either <start_addr> or <size>, but since
- * dcache_flush_mlines() iterates on the d-cache lines, a cache line
- * alignment for both is optimal.
- *
- * The d-cache line size is specified either via the CONFIG_CACHE_LINE_SIZE
- * kconfig option or it is detected at runtime.
- *
- * @param start_addr the pointer to start the multi-line flush
- * @param size the number of bytes that are to be flushed
- *
- * @return N/A
- */
-static void dcache_flush_mlines(uint32_t start_addr, uint32_t size)
+void arch_dcache_flush(void *start_addr_ptr, size_t size)
{
- uint32_t end_addr;
+ uintptr_t start_addr = (uintptr_t)start_addr_ptr;
+ uintptr_t end_addr;
unsigned int key;
if (!dcache_available() || (size == 0U)) {
return;
}
- end_addr = start_addr + size - 1;
- start_addr &= (uint32_t)(~(DCACHE_LINE_SIZE - 1));
+ end_addr = start_addr + size;
+
+ start_addr = ROUND_DOWN(start_addr, DCACHE_LINE_SIZE);
key = arch_irq_lock(); /* --enter critical section-- */
@@ -111,35 +96,35 @@
}
} while (1);
start_addr += DCACHE_LINE_SIZE;
- } while (start_addr <= end_addr);
+ } while (start_addr < end_addr);
arch_irq_unlock(key); /* --exit critical section-- */
}
-
-/**
- *
- * @brief Flush d-cache lines to main memory
- *
- * No alignment is required for either <virt> or <size>, but since
- * sys_cache_flush() iterates on the d-cache lines, a d-cache line alignment for
- * both is optimal.
- *
- * The d-cache line size is specified either via the CONFIG_CACHE_LINE_SIZE
- * kconfig option or it is detected at runtime.
- *
- * @param start_addr the pointer to start the multi-line flush
- * @param size the number of bytes that are to be flushed
- *
- * @return N/A
- */
-
-void sys_cache_flush(vaddr_t start_addr, size_t size)
+void arch_dcache_invd(void *start_addr_ptr, size_t size)
{
- dcache_flush_mlines((uint32_t)start_addr, (uint32_t)size);
-}
+ uintptr_t start_addr = (uintptr_t)start_addr_ptr;
+ uintptr_t end_addr;
+ unsigned int key;
+ if (!dcache_available() || (size == 0U)) {
+ return;
+ }
+ end_addr = start_addr + size;
+ start_addr = ROUND_DOWN(start_addr, DCACHE_LINE_SIZE);
+
+ key = arch_irq_lock(); /* -enter critical section- */
+
+ do {
+ z_arc_v2_aux_reg_write(_ARC_V2_DC_IVDL, start_addr);
+ __asm__ volatile("nop_s");
+ __asm__ volatile("nop_s");
+ __asm__ volatile("nop_s");
+ start_addr += DCACHE_LINE_SIZE;
+ } while (start_addr < end_addr);
+ irq_unlock(key); /* -exit critical section- */
+}
#if defined(CONFIG_CACHE_LINE_SIZE_DETECT)
size_t sys_cache_line_size;
@@ -155,6 +140,15 @@
}
#endif
+size_t arch_cache_line_size_get(void)
+{
+#if defined(CONFIG_CACHE_LINE_SIZE_DETECT)
+ return sys_cache_line_size;
+#else
+ return 0;
+#endif
+}
+
static int init_dcache(struct device *unused)
{
ARG_UNUSED(unused);
diff --git a/arch/x86/core/ia32/cache.c b/arch/x86/core/ia32/cache.c
index b04290d..414fcd4 100644
--- a/arch/x86/core/ia32/cache.c
+++ b/arch/x86/core/ia32/cache.c
@@ -97,6 +97,15 @@
#define init_cache_line_size() do { } while ((0))
#endif
+size_t arch_cache_line_size_get(void)
+{
+#if defined(CONFIG_CACHE_LINE_SIZE_DETECT)
+ return sys_cache_line_size;
+#else
+ return 0;
+#endif
+}
+
static int init_cache(struct device *unused)
{
ARG_UNUSED(unused);
diff --git a/include/arch/common/addr_types.h b/include/arch/common/addr_types.h
index 898fd05..1abc582 100644
--- a/include/arch/common/addr_types.h
+++ b/include/arch/common/addr_types.h
@@ -10,8 +10,8 @@
#define ZEPHYR_INCLUDE_ARCH_X86_ADDR_TYPES_H_
#ifndef _ASMLANGUAGE
-typedef unsigned int paddr_t;
-typedef unsigned int vaddr_t;
+typedef uintptr_t paddr_t;
+typedef void *vaddr_t;
#endif
#endif /* ZEPHYR_INCLUDE_ARCH_X86_ADDR_TYPES_H_ */
diff --git a/include/cache.h b/include/cache.h
index 5158730..6568644 100644
--- a/include/cache.h
+++ b/include/cache.h
@@ -13,45 +13,75 @@
extern "C" {
#endif
-#define _sys_cache_flush_sig(x) void (x)(vaddr_t virt, size_t size)
+void arch_dcache_flush(void *addr, size_t size);
+void arch_dcache_invd(void *addr, size_t size);
-#if defined(CONFIG_CACHE_FLUSHING)
-
-#if defined(CONFIG_ARCH_CACHE_FLUSH_DETECT)
- typedef _sys_cache_flush_sig(_sys_cache_flush_t);
- extern _sys_cache_flush_t *sys_cache_flush;
-#else
- extern _sys_cache_flush_sig(sys_cache_flush);
-#endif
-
-#else
-
-/*
- * Provide NOP APIs for systems that do not have caches.
+/**
*
- * An example is the Cortex-M chips. However, the functions are provided so
- * that code that need to manipulate caches can be written in an
- * architecture-agnostic manner. The functions do nothing. The cache line size
- * value is always 0.
+ * @brief Flush d-cache lines to main memory
+ *
+ * No alignment is required for either addr or size, but since
+ * sys_cache_flush() iterates on the d-cache lines, a d-cache line alignment for
+ * both is optimal.
+ *
+ * The d-cache line size is specified either via the CONFIG_CACHE_LINE_SIZE
+ * kconfig option or it is detected at runtime.
+ *
+ * @param addr the pointer to start the multi-line flush
+ * @param size the number of bytes that are to be flushed
+ *
+ * @return N/A
*/
-
-static inline _sys_cache_flush_sig(sys_cache_flush)
+static inline void sys_cache_flush(void *addr, size_t size)
{
- ARG_UNUSED(virt);
- ARG_UNUSED(size);
-
- /* do nothing */
+ if (IS_ENABLED(CONFIG_CACHE_FLUSHING)) {
+ arch_dcache_flush(addr, size);
+ }
}
-#endif /* CACHE_FLUSHING */
+/**
+ *
+ * @brief Invalidate d-cache lines
+ *
+ * No alignment is required for either addr or size, but since
+ * sys_cache_invd() iterates on the d-cache lines, a d-cache line alignment for
+ * both is optimal.
+ *
+ * The d-cache line size is specified either via the CONFIG_CACHE_LINE_SIZE
+ * kconfig option or it is detected at runtime.
+ *
+ * @param addr the pointer to start address
+ * @param size the number of bytes that are to be invalidated
+ *
+ * @return N/A
+ */
+static inline void sys_cache_invd(void *addr, size_t size)
+{
+ if (IS_ENABLED(CONFIG_CACHE_FLUSHING)) {
+ arch_dcache_invd(addr, size);
+ }
+}
-#if defined(CONFIG_CACHE_LINE_SIZE_DETECT)
- extern size_t sys_cache_line_size;
-#elif defined(CONFIG_CACHE_LINE_SIZE)
- #define sys_cache_line_size CONFIG_CACHE_LINE_SIZE
+/**
+ *
+ * @brief Get the d-cache line size.
+ *
+ * The API is provided to get the cache line size.
+ *
+ * @return size of the cache line or 0 if the cache is not enabled.
+ */
+static inline size_t sys_cache_line_size_get(void)
+{
+#ifdef CONFIG_CACHE_FLUSHING
+#ifdef CONFIG_CACHE_LINE_SIZE
+ return CONFIG_CACHE_LINE_SIZE;
#else
- #define sys_cache_line_size 0
-#endif
+ return arch_cache_line_size_get();
+#endif /* CONFIG_CACHE_LINE_SIZE */
+#else
+ return 0;
+#endif /* CONFIG_CACHE_FLUSHING */
+}
#ifdef __cplusplus
}
diff --git a/include/sys/arch_interface.h b/include/sys/arch_interface.h
index 9ceeef7..3aa8fc1 100644
--- a/include/sys/arch_interface.h
+++ b/include/sys/arch_interface.h
@@ -675,6 +675,41 @@
/** @} */
+/**
+ * @defgroup arch_cache Architecture-specific cache functions
+ * @ingroup arch-interface
+ * @{
+ */
+
+#ifdef CONFIG_CACHE_FLUSHING
+/**
+ *
+ * @brief Flush d-cache lines to main memory
+ *
+ * @see sys_cache_flush
+ */
+void arch_dcache_flush(void *addr, size_t size);
+
+/**
+ *
+ * @brief Invalidate d-cache lines
+ *
+ * @see sys_cache_invd
+ */
+void arch_dcache_invd(void *addr, size_t size);
+
+#ifndef CONFIG_CACHE_LINE_SIZE
+/**
+ *
+ * @brief Get d-cache line size
+ *
+ * @see sys_cache_line_size_get
+ */
+size_t arch_cache_line_size_get(void);
+#endif
+#endif
+/** @} */
+
#ifdef __cplusplus
}
#endif /* __cplusplus */