1 /*
2  * Copyright (c) 2023 Carlo Caione <ccaione@baylibre.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * Public APIs for architectural cache controller drivers
10  */
11 
12 #ifndef ZEPHYR_INCLUDE_ARCH_CACHE_H_
13 #define ZEPHYR_INCLUDE_ARCH_CACHE_H_
14 
15 /**
16  * @defgroup arch-cache Architecture-specific cache controllers.
17  * @ingroup arch-interface
18  * @{
19  */
20 
21 #if defined(CONFIG_ARM64)
22 #include <zephyr/arch/arm64/cache.h>
23 #elif defined(CONFIG_XTENSA)
24 #include <zephyr/arch/xtensa/cache.h>
25 #endif
26 
27 #include <stddef.h>
28 #include <stdbool.h>
29 
30 #if defined(CONFIG_DCACHE) || defined(__DOXYGEN__)
31 
32 /**
33  * @brief Enable the d-cache
34  *
35  * Enable the data cache.
36  */
37 void arch_dcache_enable(void);
38 
39 #define cache_data_enable arch_dcache_enable
40 
41 /**
42  * @brief Disable the d-cache
43  *
44  * Disable the data cache.
45  */
46 void arch_dcache_disable(void);
47 
48 #define cache_data_disable arch_dcache_disable
49 
50 /**
51  * @brief Flush the d-cache
52  *
53  * Flush the whole data cache.
54  *
55  * @retval 0 If succeeded.
56  * @retval -ENOTSUP If not supported.
57  * @retval -errno Negative errno for other failures.
58  */
59 int arch_dcache_flush_all(void);
60 
61 #define cache_data_flush_all arch_dcache_flush_all
62 
63 /**
64  * @brief Invalidate the d-cache
65  *
66  * Invalidate the whole data cache.
67  *
68  * @retval 0 If succeeded.
69  * @retval -ENOTSUP If not supported.
70  * @retval -errno Negative errno for other failures.
71  */
72 int arch_dcache_invd_all(void);
73 
74 #define cache_data_invd_all arch_dcache_invd_all
75 
76 /**
77  * @brief Flush and Invalidate the d-cache
78  *
79  * Flush and Invalidate the whole data cache.
80  *
81  * @retval 0 If succeeded.
82  * @retval -ENOTSUP If not supported.
83  * @retval -errno Negative errno for other failures.
84  */
85 int arch_dcache_flush_and_invd_all(void);
86 
87 #define cache_data_flush_and_invd_all arch_dcache_flush_and_invd_all
88 
89 /**
90  * @brief Flush an address range in the d-cache
91  *
92  * Flush the specified address range of the data cache.
93  *
94  * @note the cache operations act on cache line. When multiple data structures
95  *       share the same cache line being flushed, all the portions of the
96  *       data structures sharing the same line will be flushed. This is usually
97  *       not a problem because writing back is a non-destructive process that
98  *       could be triggered by hardware at any time, so having an aligned
99  *       @p addr or a padded @p size is not strictly necessary.
100  *
101  * @param addr Starting address to flush.
102  * @param size Range size.
103  *
104  * @retval 0 If succeeded.
105  * @retval -ENOTSUP If not supported.
106  * @retval -errno Negative errno for other failures.
107  */
108 int arch_dcache_flush_range(void *addr, size_t size);
109 
110 #define cache_data_flush_range(addr, size) arch_dcache_flush_range(addr, size)
111 
112 /**
113  * @brief Invalidate an address range in the d-cache
114  *
115  * Invalidate the specified address range of the data cache.
116  *
117  * @note the cache operations act on cache line. When multiple data structures
118  *       share the same cache line being invalidated, all the portions of the
119  *       non-read-only data structures sharing the same line will be
120  *       invalidated as well. This is a destructive process that could lead to
121  *       data loss and/or corruption. When @p addr is not aligned to the cache
122  *       line and/or @p size is not a multiple of the cache line size the
123  *       behaviour is undefined.
124  *
125  * @param addr Starting address to invalidate.
126  * @param size Range size.
127  *
128  * @retval 0 If succeeded.
129  * @retval -ENOTSUP If not supported.
130  * @retval -errno Negative errno for other failures.
131  */
132 int arch_dcache_invd_range(void *addr, size_t size);
133 
134 #define cache_data_invd_range(addr, size) arch_dcache_invd_range(addr, size)
135 
136 /**
137  * @brief Flush and Invalidate an address range in the d-cache
138  *
139  * Flush and Invalidate the specified address range of the data cache.
140  *
141  * @note the cache operations act on cache line. When multiple data structures
142  *       share the same cache line being flushed, all the portions of the
143  *       data structures sharing the same line will be flushed before being
144  *       invalidated. This is usually not a problem because writing back is a
145  *       non-destructive process that could be triggered by hardware at any
146  *       time, so having an aligned @p addr or a padded @p size is not strictly
147  *       necessary.
148  *
149  * @param addr Starting address to flush and invalidate.
150  * @param size Range size.
151  *
152  * @retval 0 If succeeded.
153  * @retval -ENOTSUP If not supported.
154  * @retval -errno Negative errno for other failures.
155  */
156 
157 int arch_dcache_flush_and_invd_range(void *addr, size_t size);
158 
159 #define cache_data_flush_and_invd_range(addr, size) \
160 	arch_dcache_flush_and_invd_range(addr, size)
161 
162 #if defined(CONFIG_DCACHE_LINE_SIZE_DETECT) || defined(__DOXYGEN__)
163 
164 /**
165  *
166  * @brief Get the d-cache line size.
167  *
168  * The API is provided to dynamically detect the data cache line size at run
169  * time.
170  *
171  * The function must be implemented only when CONFIG_DCACHE_LINE_SIZE_DETECT is
172  * defined.
173  *
174  * @retval size Size of the d-cache line.
175  * @retval 0 If the d-cache is not enabled.
176  */
177 size_t arch_dcache_line_size_get(void);
178 
179 #define cache_data_line_size_get arch_dcache_line_size_get
180 
181 #endif /* CONFIG_DCACHE_LINE_SIZE_DETECT || __DOXYGEN__ */
182 
183 #endif /* CONFIG_DCACHE || __DOXYGEN__ */
184 
185 #if defined(CONFIG_ICACHE) || defined(__DOXYGEN__)
186 
187 /**
188  * @brief Enable the i-cache
189  *
190  * Enable the instruction cache.
191  */
192 void arch_icache_enable(void);
193 
194 #define cache_instr_enable arch_icache_enable
195 
196 /**
197  * @brief Disable the i-cache
198  *
199  * Disable the instruction cache.
200  */
201 void arch_icache_disable(void);
202 
203 #define cache_instr_disable arch_icache_disable
204 
205 /**
206  * @brief Flush the i-cache
207  *
208  * Flush the whole instruction cache.
209  *
210  * @retval 0 If succeeded.
211  * @retval -ENOTSUP If not supported.
212  * @retval -errno Negative errno for other failures.
213  */
214 int arch_icache_flush_all(void);
215 
216 #define cache_instr_flush_all arch_icache_flush_all
217 
218 /**
219  * @brief Invalidate the i-cache
220  *
221  * Invalidate the whole instruction cache.
222  *
223  * @retval 0 If succeeded.
224  * @retval -ENOTSUP If not supported.
225  * @retval -errno Negative errno for other failures.
226  */
227 int arch_icache_invd_all(void);
228 
229 #define cache_instr_invd_all arch_icache_invd_all
230 
231 /**
232  * @brief Flush and Invalidate the i-cache
233  *
234  * Flush and Invalidate the whole instruction cache.
235  *
236  * @retval 0 If succeeded.
237  * @retval -ENOTSUP If not supported.
238  * @retval -errno Negative errno for other failures.
239  */
240 int arch_icache_flush_and_invd_all(void);
241 
242 #define cache_instr_flush_and_invd_all arch_icache_flush_and_invd_all
243 
244 /**
245  * @brief Flush an address range in the i-cache
246  *
247  * Flush the specified address range of the instruction cache.
248  *
249  * @note the cache operations act on cache line. When multiple data structures
250  *       share the same cache line being flushed, all the portions of the
251  *       data structures sharing the same line will be flushed. This is usually
252  *       not a problem because writing back is a non-destructive process that
253  *       could be triggered by hardware at any time, so having an aligned
254  *       @p addr or a padded @p size is not strictly necessary.
255  *
256  * @param addr Starting address to flush.
257  * @param size Range size.
258  *
259  * @retval 0 If succeeded.
260  * @retval -ENOTSUP If not supported.
261  * @retval -errno Negative errno for other failures.
262  */
263 int arch_icache_flush_range(void *addr, size_t size);
264 
265 #define cache_instr_flush_range(addr, size) arch_icache_flush_range(addr, size)
266 
267 /**
268  * @brief Invalidate an address range in the i-cache
269  *
270  * Invalidate the specified address range of the instruction cache.
271  *
272  * @note the cache operations act on cache line. When multiple data structures
273  *       share the same cache line being invalidated, all the portions of the
274  *       non-read-only data structures sharing the same line will be
275  *       invalidated as well. This is a destructive process that could lead to
276  *       data loss and/or corruption. When @p addr is not aligned to the cache
277  *       line and/or @p size is not a multiple of the cache line size the
278  *       behaviour is undefined.
279  *
280  * @param addr Starting address to invalidate.
281  * @param size Range size.
282  *
283  * @retval 0 If succeeded.
284  * @retval -ENOTSUP If not supported.
285  * @retval -errno Negative errno for other failures.
286  */
287 int arch_icache_invd_range(void *addr, size_t size);
288 
289 #define cache_instr_invd_range(addr, size) arch_icache_invd_range(addr, size)
290 
291 /**
292  * @brief Flush and Invalidate an address range in the i-cache
293  *
294  * Flush and Invalidate the specified address range of the instruction cache.
295  *
296  * @note the cache operations act on cache line. When multiple data structures
297  *       share the same cache line being flushed, all the portions of the
298  *       data structures sharing the same line will be flushed before being
299  *       invalidated. This is usually not a problem because writing back is a
300  *       non-destructive process that could be triggered by hardware at any
301  *       time, so having an aligned @p addr or a padded @p size is not strictly
302  *       necessary.
303  *
304  * @param addr Starting address to flush and invalidate.
305  * @param size Range size.
306  *
307  * @retval 0 If succeeded.
308  * @retval -ENOTSUP If not supported.
309  * @retval -errno Negative errno for other failures.
310  */
311 int arch_icache_flush_and_invd_range(void *addr, size_t size);
312 
313 #define cache_instr_flush_and_invd_range(addr, size) \
314 	arch_icache_flush_and_invd_range(addr, size)
315 
316 #if defined(CONFIG_ICACHE_LINE_SIZE_DETECT) || defined(__DOXYGEN__)
317 
318 /**
319  *
320  * @brief Get the i-cache line size.
321  *
322  * The API is provided to dynamically detect the instruction cache line size at
323  * run time.
324  *
325  * The function must be implemented only when CONFIG_ICACHE_LINE_SIZE_DETECT is
326  * defined.
327  *
328  * @retval size Size of the d-cache line.
329  * @retval 0 If the d-cache is not enabled.
330  */
331 
332 size_t arch_icache_line_size_get(void);
333 
334 #define cache_instr_line_size_get arch_icache_line_size_get
335 
336 #endif /* CONFIG_ICACHE_LINE_SIZE_DETECT || __DOXYGEN__ */
337 
338 #endif /* CONFIG_ICACHE || __DOXYGEN__ */
339 
340 #if CONFIG_CACHE_HAS_MIRRORED_MEMORY_REGIONS  || __DOXYGEN__
341 bool arch_cache_is_ptr_cached(void *ptr);
342 #define cache_is_ptr_cached(ptr) arch_cache_is_ptr_cached(ptr)
343 
344 bool arch_cache_is_ptr_uncached(void *ptr);
345 #define cache_is_ptr_uncached(ptr) arch_cache_is_ptr_uncached(ptr)
346 
347 void __sparse_cache *arch_cache_cached_ptr_get(void *ptr);
348 #define cache_cached_ptr(ptr) arch_cache_cached_ptr_get(ptr)
349 
350 void *arch_cache_uncached_ptr_get(void __sparse_cache *ptr);
351 #define cache_uncached_ptr(ptr) arch_cache_uncached_ptr_get(ptr)
352 #endif /* CONFIG_CACHE_HAS_MIRRORED_MEMORY_REGIONS */
353 
354 
355 void arch_cache_init(void);
356 
357 #if defined(CONFIG_CACHE_CAN_SAY_MEM_COHERENCE) || defined(__DOXYGEN__)
358 #define cache_is_mem_coherent(ptr) arch_mem_coherent(ptr)
359 #endif
360 
361 /**
362  * @}
363  */
364 
365 #endif /* ZEPHYR_INCLUDE_ARCH_CACHE_H_ */
366