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 */