Line data Source code
1 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 1 : void arch_dcache_enable(void); 36 : 37 0 : #define cache_data_enable arch_dcache_enable 38 : 39 : /** 40 : * @brief Disable the d-cache 41 : * 42 : * Disable the data cache. 43 : */ 44 1 : void arch_dcache_disable(void); 45 : 46 0 : #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 1 : int arch_dcache_flush_all(void); 58 : 59 0 : #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 1 : int arch_dcache_invd_all(void); 71 : 72 0 : #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 1 : int arch_dcache_flush_and_invd_all(void); 84 : 85 0 : #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 1 : int arch_dcache_flush_range(void *addr, size_t size); 107 : 108 0 : #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 1 : int arch_dcache_invd_range(void *addr, size_t size); 131 : 132 0 : #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 1 : int arch_dcache_flush_and_invd_range(void *addr, size_t size); 156 : 157 0 : #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 1 : size_t arch_dcache_line_size_get(void); 176 : 177 0 : #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 1 : void arch_icache_enable(void); 191 : 192 0 : #define cache_instr_enable arch_icache_enable 193 : 194 : /** 195 : * @brief Disable the i-cache 196 : * 197 : * Disable the instruction cache. 198 : */ 199 1 : void arch_icache_disable(void); 200 : 201 0 : #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 1 : int arch_icache_flush_all(void); 213 : 214 0 : #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 1 : int arch_icache_invd_all(void); 226 : 227 0 : #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 1 : int arch_icache_flush_and_invd_all(void); 239 : 240 0 : #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 1 : int arch_icache_flush_range(void *addr, size_t size); 262 : 263 0 : #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 1 : int arch_icache_invd_range(void *addr, size_t size); 286 : 287 0 : #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 1 : int arch_icache_flush_and_invd_range(void *addr, size_t size); 310 : 311 0 : #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 1 : size_t arch_icache_line_size_get(void); 331 : 332 0 : #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 0 : bool arch_cache_is_ptr_cached(void *ptr); 340 0 : #define cache_is_ptr_cached(ptr) arch_cache_is_ptr_cached(ptr) 341 : 342 0 : bool arch_cache_is_ptr_uncached(void *ptr); 343 0 : #define cache_is_ptr_uncached(ptr) arch_cache_is_ptr_uncached(ptr) 344 : 345 0 : void __sparse_cache *arch_cache_cached_ptr_get(void *ptr); 346 0 : #define cache_cached_ptr(ptr) arch_cache_cached_ptr_get(ptr) 347 : 348 0 : void *arch_cache_uncached_ptr_get(void __sparse_cache *ptr); 349 0 : #define cache_uncached_ptr(ptr) arch_cache_uncached_ptr_get(ptr) 350 : #endif /* CONFIG_CACHE_DOUBLEMAP */ 351 : 352 : 353 0 : void arch_cache_init(void); 354 : 355 : /** 356 : * @} 357 : */ 358 : 359 : #endif /* ZEPHYR_INCLUDE_ARCH_CACHE_H_ */