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