1 /*
2  * Copyright 2021 Carlo Caione <ccaione@baylibre.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * Public APIs for external cache controller drivers
10  */
11 
12 #ifndef ZEPHYR_INCLUDE_DRIVERS_CACHE_H_
13 #define ZEPHYR_INCLUDE_DRIVERS_CACHE_H_
14 
15 #include <stddef.h>
16 
17 /**
18  * @brief External Cache Controller Interface
19  * @defgroup cache_external_interface External Cache Controller Interface
20  * @ingroup io_interfaces
21  * @{
22  */
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 #if defined(CONFIG_DCACHE)
29 
30 /**
31  * @brief Enable the d-cache
32  *
33  * Enable the data cache.
34  */
35 void cache_data_enable(void);
36 
37 /**
38  * @brief Disable the d-cache
39  *
40  * Disable the data cache.
41  */
42 void cache_data_disable(void);
43 
44 /**
45  * @brief Flush the d-cache
46  *
47  * Flush the whole data cache.
48  *
49  * @retval 0 If succeeded.
50  * @retval -ENOTSUP If not supported.
51  * @retval -errno Negative errno for other failures.
52  */
53 int cache_data_flush_all(void);
54 
55 /**
56  * @brief Invalidate the d-cache
57  *
58  * Invalidate the whole data cache.
59  *
60  * @retval 0 If succeeded.
61  * @retval -ENOTSUP If not supported.
62  * @retval -errno Negative errno for other failures.
63  */
64 int cache_data_invd_all(void);
65 
66 /**
67  * @brief Flush and Invalidate the d-cache
68  *
69  * Flush and Invalidate the whole data cache.
70  *
71  * @retval 0 If succeeded.
72  * @retval -ENOTSUP If not supported.
73  * @retval -errno Negative errno for other failures.
74  */
75 int cache_data_flush_and_invd_all(void);
76 
77 /**
78  * @brief Flush an address range in the d-cache
79  *
80  * Flush the specified address range of the data cache.
81  *
82  * @note the cache operations act on cache line. When multiple data structures
83  *       share the same cache line being flushed, all the portions of the
84  *       data structures sharing the same line will be flushed. This is usually
85  *       not a problem because writing back is a non-destructive process that
86  *       could be triggered by hardware at any time, so having an aligned
87  *       @p addr or a padded @p size is not strictly necessary.
88  *
89  * @param addr Starting address to flush.
90  * @param size Range size.
91  *
92  * @retval 0 If succeeded.
93  * @retval -ENOTSUP If not supported.
94  * @retval -errno Negative errno for other failures.
95  */
96 int cache_data_flush_range(void *addr, size_t size);
97 
98 /**
99  * @brief Invalidate an address range in the d-cache
100  *
101  * Invalidate the specified address range of the data cache.
102  *
103  * @note the cache operations act on cache line. When multiple data structures
104  *       share the same cache line being invalidated, all the portions of the
105  *       non-read-only data structures sharing the same line will be
106  *       invalidated as well. This is a destructive process that could lead to
107  *       data loss and/or corruption. When @p addr is not aligned to the cache
108  *       line and/or @p size is not a multiple of the cache line size the
109  *       behaviour is undefined.
110  *
111  * @param addr Starting address to invalidate.
112  * @param size Range size.
113  *
114  * @retval 0 If succeeded.
115  * @retval -ENOTSUP If not supported.
116  * @retval -errno Negative errno for other failures.
117  */
118 int cache_data_invd_range(void *addr, size_t size);
119 
120 /**
121  * @brief Flush and Invalidate an address range in the d-cache
122  *
123  * Flush and Invalidate the specified address range of the data cache.
124  *
125  * @note the cache operations act on cache line. When multiple data structures
126  *       share the same cache line being flushed, all the portions of the
127  *       data structures sharing the same line will be flushed before being
128  *       invalidated. This is usually not a problem because writing back is a
129  *       non-destructive process that could be triggered by hardware at any
130  *       time, so having an aligned @p addr or a padded @p size is not strictly
131  *       necessary.
132  *
133  * @param addr Starting address to flush and invalidate.
134  * @param size Range size.
135  *
136  * @retval 0 If succeeded.
137  * @retval -ENOTSUP If not supported.
138  * @retval -errno Negative errno for other failures.
139  */
140 int cache_data_flush_and_invd_range(void *addr, size_t size);
141 
142 #if defined(CONFIG_DCACHE_LINE_SIZE_DETECT)
143 /**
144  *
145  * @brief Get the d-cache line size.
146  *
147  * The API is provided to dynamically detect the data cache line size at run
148  * time.
149  *
150  * The function must be implemented only when CONFIG_DCACHE_LINE_SIZE_DETECT is
151  * defined.
152  *
153  * @retval size Size of the d-cache line.
154  * @retval 0 If the d-cache is not enabled.
155  */
156 size_t cache_data_line_size_get(void);
157 
158 #endif /* CONFIG_DCACHE_LINE_SIZE_DETECT */
159 
160 #endif /* CONFIG_DCACHE */
161 
162 #if defined(CONFIG_ICACHE)
163 
164 /**
165  * @brief Enable the i-cache
166  *
167  * Enable the instruction cache.
168  */
169 void cache_instr_enable(void);
170 
171 /**
172  * @brief Disable the i-cache
173  *
174  * Disable the instruction cache.
175  */
176 void cache_instr_disable(void);
177 
178 /**
179  * @brief Flush the i-cache
180  *
181  * Flush the whole instruction cache.
182  *
183  * @retval 0 If succeeded.
184  * @retval -ENOTSUP If not supported.
185  * @retval -errno Negative errno for other failures.
186  */
187 int cache_instr_flush_all(void);
188 
189 /**
190  * @brief Invalidate the i-cache
191  *
192  * Invalidate the whole instruction cache.
193  *
194  * @retval 0 If succeeded.
195  * @retval -ENOTSUP If not supported.
196  * @retval -errno Negative errno for other failures.
197  */
198 int cache_instr_invd_all(void);
199 
200 /**
201  * @brief Flush and Invalidate the i-cache
202  *
203  * Flush and Invalidate the whole instruction cache.
204  *
205  * @retval 0 If succeeded.
206  * @retval -ENOTSUP If not supported.
207  * @retval -errno Negative errno for other failures.
208  */
209 int cache_instr_flush_and_invd_all(void);
210 
211 /**
212  * @brief Flush an address range in the i-cache
213  *
214  * Flush the specified address range of the instruction cache.
215  *
216  * @note the cache operations act on cache line. When multiple data structures
217  *       share the same cache line being flushed, all the portions of the
218  *       data structures sharing the same line will be flushed. This is usually
219  *       not a problem because writing back is a non-destructive process that
220  *       could be triggered by hardware at any time, so having an aligned
221  *       @p addr or a padded @p size is not strictly necessary.
222  *
223  * @param addr Starting address to flush.
224  * @param size Range size.
225  *
226  * @retval 0 If succeeded.
227  * @retval -ENOTSUP If not supported.
228  * @retval -errno Negative errno for other failures.
229  */
230 int cache_instr_flush_range(void *addr, size_t size);
231 
232 /**
233  * @brief Invalidate an address range in the i-cache
234  *
235  * Invalidate the specified address range of the instruction cache.
236  *
237  * @note the cache operations act on cache line. When multiple data structures
238  *       share the same cache line being invalidated, all the portions of the
239  *       non-read-only data structures sharing the same line will be
240  *       invalidated as well. This is a destructive process that could lead to
241  *       data loss and/or corruption. When @p addr is not aligned to the cache
242  *       line and/or @p size is not a multiple of the cache line size the
243  *       behaviour is undefined.
244  *
245  * @param addr Starting address to invalidate.
246  * @param size Range size.
247  *
248  * @retval 0 If succeeded.
249  * @retval -ENOTSUP If not supported.
250  * @retval -errno Negative errno for other failures.
251  */
252 int cache_instr_invd_range(void *addr, size_t size);
253 
254 /**
255  * @brief Flush and Invalidate an address range in the i-cache
256  *
257  * Flush and Invalidate the specified address range of the instruction cache.
258  *
259  * @note the cache operations act on cache line. When multiple data structures
260  *       share the same cache line being flushed, all the portions of the
261  *       data structures sharing the same line will be flushed before being
262  *       invalidated. This is usually not a problem because writing back is a
263  *       non-destructive process that could be triggered by hardware at any
264  *       time, so having an aligned @p addr or a padded @p size is not strictly
265  *       necessary.
266  *
267  * @param addr Starting address to flush and invalidate.
268  * @param size Range size.
269  *
270  * @retval 0 If succeeded.
271  * @retval -ENOTSUP If not supported.
272  * @retval -errno Negative errno for other failures.
273  */
274 int cache_instr_flush_and_invd_range(void *addr, size_t size);
275 
276 #ifdef CONFIG_ICACHE_LINE_SIZE_DETECT
277 /**
278  *
279  * @brief Get the i-cache line size.
280  *
281  * The API is provided to dynamically detect the instruction cache line size at
282  * run time.
283  *
284  * The function must be implemented only when CONFIG_ICACHE_LINE_SIZE_DETECT is
285  * defined.
286  *
287  * @retval size Size of the d-cache line.
288  * @retval 0 If the d-cache is not enabled.
289  */
290 size_t cache_instr_line_size_get(void);
291 
292 #endif /* CONFIG_ICACHE_LINE_SIZE_DETECT */
293 
294 #endif /* CONFIG_ICACHE */
295 
296 #ifdef __cplusplus
297 }
298 #endif
299 
300 /**
301  * @}
302  */
303 
304 #endif /* ZEPHYR_INCLUDE_DRIVERS_CACHE_H_ */
305