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