1 /*
2  * Copyright 2021 Intel Corporation
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #ifndef ZEPHYR_INCLUDE_ARCH_XTENSA_CACHE_H_
6 #define ZEPHYR_INCLUDE_ARCH_XTENSA_CACHE_H_
7 
8 #include <xtensa/config/core-isa.h>
9 #include <sys/util.h>
10 
11 #ifdef __cplusplus
12 extern "C" {
13 #endif
14 
15 #define Z_DCACHE_MAX (XCHAL_DCACHE_SIZE / XCHAL_DCACHE_WAYS)
16 
17 #if XCHAL_DCACHE_SIZE
18 #define Z_IS_POW2(x) (((x) != 0) && (((x) & ((x)-1)) == 0))
19 BUILD_ASSERT(Z_IS_POW2(XCHAL_DCACHE_LINESIZE));
20 BUILD_ASSERT(Z_IS_POW2(Z_DCACHE_MAX));
21 #endif
22 
z_xtensa_cache_flush(void * addr,size_t bytes)23 static inline void z_xtensa_cache_flush(void *addr, size_t bytes)
24 {
25 #if XCHAL_DCACHE_SIZE
26 	size_t step = XCHAL_DCACHE_LINESIZE;
27 	size_t first = ROUND_DOWN(addr, step);
28 	size_t last = ROUND_UP(((long)addr) + bytes, step);
29 	size_t line;
30 
31 	for (line = first; bytes && line < last; line += step) {
32 		__asm__ volatile("dhwb %0, 0" :: "r"(line));
33 	}
34 #endif
35 }
36 
z_xtensa_cache_flush_inv(void * addr,size_t bytes)37 static inline void z_xtensa_cache_flush_inv(void *addr, size_t bytes)
38 {
39 #if XCHAL_DCACHE_SIZE
40 	size_t step = XCHAL_DCACHE_LINESIZE;
41 	size_t first = ROUND_DOWN(addr, step);
42 	size_t last = ROUND_UP(((long)addr) + bytes, step);
43 	size_t line;
44 
45 	for (line = first; bytes && line < last; line += step) {
46 		__asm__ volatile("dhwbi %0, 0" :: "r"(line));
47 	}
48 #endif
49 }
50 
z_xtensa_cache_inv(void * addr,size_t bytes)51 static inline void z_xtensa_cache_inv(void *addr, size_t bytes)
52 {
53 #if XCHAL_DCACHE_SIZE
54 	size_t step = XCHAL_DCACHE_LINESIZE;
55 	size_t first = ROUND_DOWN(addr, step);
56 	size_t last = ROUND_UP(((long)addr) + bytes, step);
57 	size_t line;
58 
59 	for (line = first; bytes && line < last; line += step) {
60 		__asm__ volatile("dhi %0, 0" :: "r"(line));
61 	}
62 #endif
63 }
64 
z_xtensa_cache_inv_all(void)65 static inline void z_xtensa_cache_inv_all(void)
66 {
67 	z_xtensa_cache_inv(NULL, Z_DCACHE_MAX);
68 }
69 
z_xtensa_cache_flush_all(void)70 static inline void z_xtensa_cache_flush_all(void)
71 {
72 	z_xtensa_cache_flush(NULL, Z_DCACHE_MAX);
73 }
74 
z_xtensa_cache_flush_inv_all(void)75 static inline void z_xtensa_cache_flush_inv_all(void)
76 {
77 	z_xtensa_cache_flush_inv(NULL, Z_DCACHE_MAX);
78 }
79 
80 #ifdef __cplusplus
81 } /* extern "C" */
82 #endif
83 
84 #endif /* ZEPHYR_INCLUDE_ARCH_XTENSA_CACHE_H_ */
85