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