LCOV - code coverage report
Current view: top level - zephyr - cache.h Coverage Total Hit
Test: new.info Lines: 100.0 % 23 23
Test Date: 2025-09-25 19:22:35

            Line data    Source code
       1            1 : /*
       2              :  * Copyright (c) 2015 Wind River Systems, Inc.
       3              :  * Copyright (c) 2022 Carlo Caione <ccaione@baylibre.com>
       4              :  *
       5              :  * SPDX-License-Identifier: Apache-2.0
       6              :  */
       7              : 
       8              : #ifndef ZEPHYR_INCLUDE_CACHE_H_
       9              : #define ZEPHYR_INCLUDE_CACHE_H_
      10              : 
      11              : /**
      12              :  * @file
      13              :  * @brief cache API interface
      14              :  */
      15              : 
      16              : #include <zephyr/kernel.h>
      17              : #include <zephyr/arch/cpu.h>
      18              : #include <zephyr/debug/sparse.h>
      19              : 
      20              : #ifdef __cplusplus
      21              : extern "C" {
      22              : #endif
      23              : 
      24              : #if defined(CONFIG_EXTERNAL_CACHE)
      25              : #include <zephyr/drivers/cache.h>
      26              : 
      27              : #elif defined(CONFIG_ARCH_CACHE)
      28              : #include <zephyr/arch/cache.h>
      29              : 
      30              : #endif
      31              : 
      32              : /**
      33              :  * @defgroup cache_interface Cache Interface
      34              :  * @ingroup os_services
      35              :  * @{
      36              :  */
      37              : 
      38              : /**
      39              :  * @brief Enable the d-cache
      40              :  *
      41              :  * Enable the data cache
      42              :  *
      43              :  */
      44            1 : static ALWAYS_INLINE void sys_cache_data_enable(void)
      45              : {
      46              : #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE)
      47              :         cache_data_enable();
      48              : #endif
      49              : }
      50              : 
      51              : /**
      52              :  * @brief Disable the d-cache
      53              :  *
      54              :  * Disable the data cache
      55              :  *
      56              :  */
      57            1 : static ALWAYS_INLINE void sys_cache_data_disable(void)
      58              : {
      59              : #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE)
      60              :         cache_data_disable();
      61              : #endif
      62              : }
      63              : 
      64              : /**
      65              :  * @brief Enable the i-cache
      66              :  *
      67              :  * Enable the instruction cache
      68              :  *
      69              :  */
      70            1 : static ALWAYS_INLINE void sys_cache_instr_enable(void)
      71              : {
      72              : #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_ICACHE)
      73              :         cache_instr_enable();
      74              : #endif
      75              : }
      76              : 
      77              : /**
      78              :  * @brief Disable the i-cache
      79              :  *
      80              :  * Disable the instruction cache
      81              :  *
      82              :  */
      83            1 : static ALWAYS_INLINE void sys_cache_instr_disable(void)
      84              : {
      85              : #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_ICACHE)
      86              :         cache_instr_disable();
      87              : #endif
      88              : }
      89              : 
      90              : /**
      91              :  * @brief Flush the d-cache
      92              :  *
      93              :  * Flush the whole data cache.
      94              :  *
      95              :  * @retval 0 If succeeded.
      96              :  * @retval -ENOTSUP If not supported.
      97              :  * @retval -errno Negative errno for other failures.
      98              :  */
      99            1 : static ALWAYS_INLINE int sys_cache_data_flush_all(void)
     100              : {
     101              : #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE)
     102              :         return cache_data_flush_all();
     103              : #endif
     104              :         return -ENOTSUP;
     105              : }
     106              : 
     107              : /**
     108              :  * @brief Flush the i-cache
     109              :  *
     110              :  * Flush the whole instruction cache.
     111              :  *
     112              :  * @retval 0 If succeeded.
     113              :  * @retval -ENOTSUP If not supported.
     114              :  * @retval -errno Negative errno for other failures.
     115              :  */
     116            1 : static ALWAYS_INLINE int sys_cache_instr_flush_all(void)
     117              : {
     118              : #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_ICACHE)
     119              :         return cache_instr_flush_all();
     120              : #endif
     121              :         return -ENOTSUP;
     122              : }
     123              : 
     124              : /**
     125              :  * @brief Invalidate the d-cache
     126              :  *
     127              :  * Invalidate the whole data cache.
     128              :  *
     129              :  * @retval 0 If succeeded.
     130              :  * @retval -ENOTSUP If not supported.
     131              :  * @retval -errno Negative errno for other failures.
     132              :  */
     133            1 : static ALWAYS_INLINE int sys_cache_data_invd_all(void)
     134              : {
     135              : #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE)
     136              :         return cache_data_invd_all();
     137              : #endif
     138              :         return -ENOTSUP;
     139              : }
     140              : 
     141              : /**
     142              :  * @brief Invalidate the i-cache
     143              :  *
     144              :  * Invalidate the whole instruction cache.
     145              :  *
     146              :  * @retval 0 If succeeded.
     147              :  * @retval -ENOTSUP If not supported.
     148              :  * @retval -errno Negative errno for other failures.
     149              :  */
     150            1 : static ALWAYS_INLINE int sys_cache_instr_invd_all(void)
     151              : {
     152              : #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_ICACHE)
     153              :         return cache_instr_invd_all();
     154              : #endif
     155              :         return -ENOTSUP;
     156              : }
     157              : 
     158              : /**
     159              :  * @brief Flush and Invalidate the d-cache
     160              :  *
     161              :  * Flush and Invalidate the whole data cache.
     162              :  *
     163              :  * @retval 0 If succeeded.
     164              :  * @retval -ENOTSUP If not supported.
     165              :  * @retval -errno Negative errno for other failures.
     166              :  */
     167            1 : static ALWAYS_INLINE int sys_cache_data_flush_and_invd_all(void)
     168              : {
     169              : #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE)
     170              :         return cache_data_flush_and_invd_all();
     171              : #endif
     172              :         return -ENOTSUP;
     173              : }
     174              : 
     175              : /**
     176              :  * @brief Flush and Invalidate the i-cache
     177              :  *
     178              :  * Flush and Invalidate the whole instruction cache.
     179              :  *
     180              :  * @retval 0 If succeeded.
     181              :  * @retval -ENOTSUP If not supported.
     182              :  * @retval -errno Negative errno for other failures.
     183              :  */
     184            1 : static ALWAYS_INLINE int sys_cache_instr_flush_and_invd_all(void)
     185              : {
     186              : #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_ICACHE)
     187              :         return cache_instr_flush_and_invd_all();
     188              : #endif
     189              :         return -ENOTSUP;
     190              : }
     191              : 
     192              : /**
     193              :  * @brief Flush an address range in the d-cache
     194              :  *
     195              :  * Flush the specified address range of the data cache.
     196              :  *
     197              :  * @note the cache operations act on cache line. When multiple data structures
     198              :  *       share the same cache line being flushed, all the portions of the
     199              :  *       data structures sharing the same line will be flushed. This is usually
     200              :  *       not a problem because writing back is a non-destructive process that
     201              :  *       could be triggered by hardware at any time, so having an aligned
     202              :  *       @p addr or a padded @p size is not strictly necessary.
     203              :  *
     204              :  * @param addr Starting address to flush.
     205              :  * @param size Range size.
     206              :  *
     207              :  * @retval 0 If succeeded.
     208              :  * @retval -ENOTSUP If not supported.
     209              :  * @retval -errno Negative errno for other failures.
     210              :  */
     211            1 : __syscall_always_inline int sys_cache_data_flush_range(void *addr, size_t size);
     212              : 
     213              : static ALWAYS_INLINE int z_impl_sys_cache_data_flush_range(void *addr, size_t size)
     214              : {
     215              : #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE)
     216              :         return cache_data_flush_range(addr, size);
     217              : #endif
     218              :         ARG_UNUSED(addr);
     219              :         ARG_UNUSED(size);
     220              : 
     221              :         return -ENOTSUP;
     222              : }
     223              : 
     224              : /**
     225              :  * @brief Flush an address range in the i-cache
     226              :  *
     227              :  * Flush the specified address range of the instruction cache.
     228              :  *
     229              :  * @note the cache operations act on cache line. When multiple data structures
     230              :  *       share the same cache line being flushed, all the portions of the
     231              :  *       data structures sharing the same line will be flushed. This is usually
     232              :  *       not a problem because writing back is a non-destructive process that
     233              :  *       could be triggered by hardware at any time, so having an aligned
     234              :  *       @p addr or a padded @p size is not strictly necessary.
     235              :  *
     236              :  * @param addr Starting address to flush.
     237              :  * @param size Range size.
     238              :  *
     239              :  * @retval 0 If succeeded.
     240              :  * @retval -ENOTSUP If not supported.
     241              :  * @retval -errno Negative errno for other failures.
     242              :  */
     243            1 : static ALWAYS_INLINE int sys_cache_instr_flush_range(void *addr, size_t size)
     244              : {
     245              : #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_ICACHE)
     246              :         return cache_instr_flush_range(addr, size);
     247              : #endif
     248              :         ARG_UNUSED(addr);
     249              :         ARG_UNUSED(size);
     250              : 
     251              :         return -ENOTSUP;
     252              : }
     253              : 
     254              : /**
     255              :  * @brief Invalidate an address range in the d-cache
     256              :  *
     257              :  * Invalidate the specified address range of the data cache.
     258              :  *
     259              :  * @note the cache operations act on cache line. When multiple data structures
     260              :  *       share the same cache line being invalidated, all the portions of the
     261              :  *       non-read-only data structures sharing the same line will be
     262              :  *       invalidated as well. This is a destructive process that could lead to
     263              :  *       data loss and/or corruption. When @p addr is not aligned to the cache
     264              :  *       line and/or @p size is not a multiple of the cache line size the
     265              :  *       behaviour is undefined.
     266              :  *
     267              :  * @param addr Starting address to 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            1 : __syscall_always_inline int sys_cache_data_invd_range(void *addr, size_t size);
     275              : 
     276              : static ALWAYS_INLINE int z_impl_sys_cache_data_invd_range(void *addr, size_t size)
     277              : {
     278              : #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE)
     279              :         return cache_data_invd_range(addr, size);
     280              : #endif
     281              :         ARG_UNUSED(addr);
     282              :         ARG_UNUSED(size);
     283              : 
     284              :         return -ENOTSUP;
     285              : }
     286              : 
     287              : /**
     288              :  * @brief Invalidate an address range in the i-cache
     289              :  *
     290              :  * Invalidate the specified address range of the instruction cache.
     291              :  *
     292              :  * @note the cache operations act on cache line. When multiple data structures
     293              :  *       share the same cache line being invalidated, all the portions of the
     294              :  *       non-read-only data structures sharing the same line will be
     295              :  *       invalidated as well. This is a destructive process that could lead to
     296              :  *       data loss and/or corruption. When @p addr is not aligned to the cache
     297              :  *       line and/or @p size is not a multiple of the cache line size the
     298              :  *       behaviour is undefined.
     299              :  *
     300              :  * @param addr Starting address to invalidate.
     301              :  * @param size Range size.
     302              :  *
     303              :  * @retval 0 If succeeded.
     304              :  * @retval -ENOTSUP If not supported.
     305              :  * @retval -errno Negative errno for other failures.
     306              :  */
     307            1 : static ALWAYS_INLINE int sys_cache_instr_invd_range(void *addr, size_t size)
     308              : {
     309              : #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_ICACHE)
     310              :         return cache_instr_invd_range(addr, size);
     311              : #endif
     312              :         ARG_UNUSED(addr);
     313              :         ARG_UNUSED(size);
     314              : 
     315              :         return -ENOTSUP;
     316              : }
     317              : 
     318              : /**
     319              :  * @brief Flush and Invalidate an address range in the d-cache
     320              :  *
     321              :  * Flush and Invalidate the specified address range of the data cache.
     322              :  *
     323              :  * @note the cache operations act on cache line. When multiple data structures
     324              :  *       share the same cache line being flushed, all the portions of the
     325              :  *       data structures sharing the same line will be flushed before being
     326              :  *       invalidated. This is usually not a problem because writing back is a
     327              :  *       non-destructive process that could be triggered by hardware at any
     328              :  *       time, so having an aligned @p addr or a padded @p size is not strictly
     329              :  *       necessary.
     330              :  *
     331              :  * @param addr Starting address to flush and invalidate.
     332              :  * @param size Range size.
     333              :  *
     334              :  * @retval 0 If succeeded.
     335              :  * @retval -ENOTSUP If not supported.
     336              :  * @retval -errno Negative errno for other failures.
     337              :  */
     338            1 : __syscall_always_inline int sys_cache_data_flush_and_invd_range(void *addr, size_t size);
     339              : 
     340              : static ALWAYS_INLINE int z_impl_sys_cache_data_flush_and_invd_range(void *addr, size_t size)
     341              : {
     342              : #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE)
     343              :         return cache_data_flush_and_invd_range(addr, size);
     344              : #endif
     345              :         ARG_UNUSED(addr);
     346              :         ARG_UNUSED(size);
     347              : 
     348              :         return -ENOTSUP;
     349              : }
     350              : 
     351              : /**
     352              :  * @brief Flush and Invalidate an address range in the i-cache
     353              :  *
     354              :  * Flush and Invalidate the specified address range of the instruction cache.
     355              :  *
     356              :  * @note the cache operations act on cache line. When multiple data structures
     357              :  *       share the same cache line being flushed, all the portions of the
     358              :  *       data structures sharing the same line will be flushed before being
     359              :  *       invalidated. This is usually not a problem because writing back is a
     360              :  *       non-destructive process that could be triggered by hardware at any
     361              :  *       time, so having an aligned @p addr or a padded @p size is not strictly
     362              :  *       necessary.
     363              :  *
     364              :  * @param addr Starting address to flush and invalidate.
     365              :  * @param size Range size.
     366              :  *
     367              :  * @retval 0 If succeeded.
     368              :  * @retval -ENOTSUP If not supported.
     369              :  * @retval -errno Negative errno for other failures.
     370              :  */
     371            1 : static ALWAYS_INLINE int sys_cache_instr_flush_and_invd_range(void *addr, size_t size)
     372              : {
     373              : #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_ICACHE)
     374              :         return cache_instr_flush_and_invd_range(addr, size);
     375              : #endif
     376              :         ARG_UNUSED(addr);
     377              :         ARG_UNUSED(size);
     378              : 
     379              :         return -ENOTSUP;
     380              : }
     381              : 
     382              : /**
     383              :  *
     384              :  * @brief Get the d-cache line size.
     385              :  *
     386              :  * The API is provided to get the data cache line.
     387              :  *
     388              :  * The cache line size is calculated (in order of priority):
     389              :  *
     390              :  * - At run-time when @kconfig{CONFIG_DCACHE_LINE_SIZE_DETECT} is set.
     391              :  * - At compile time using the value set in @kconfig{CONFIG_DCACHE_LINE_SIZE}.
     392              :  * - 0 otherwise
     393              :  *
     394              :  * @retval size Size of the d-cache line.
     395              :  * @retval 0 If the d-cache is not enabled.
     396              :  */
     397            1 : static ALWAYS_INLINE size_t sys_cache_data_line_size_get(void)
     398              : {
     399              : #ifdef CONFIG_DCACHE_LINE_SIZE_DETECT
     400              :         return cache_data_line_size_get();
     401              : #elif defined(CONFIG_DCACHE_LINE_SIZE)
     402              :         return CONFIG_DCACHE_LINE_SIZE;
     403              : #else
     404              :         return 0;
     405              : #endif
     406              : }
     407              : 
     408              : /**
     409              :  *
     410              :  * @brief Get the i-cache line size.
     411              :  *
     412              :  * The API is provided to get the instruction cache line.
     413              :  *
     414              :  * The cache line size is calculated (in order of priority):
     415              :  *
     416              :  * - At run-time when @kconfig{CONFIG_ICACHE_LINE_SIZE_DETECT} is set.
     417              :  * - At compile time using the value set in @kconfig{CONFIG_ICACHE_LINE_SIZE}.
     418              :  * - 0 otherwise
     419              :  *
     420              :  * @retval size Size of the d-cache line.
     421              :  * @retval 0 If the d-cache is not enabled.
     422              :  */
     423            1 : static ALWAYS_INLINE size_t sys_cache_instr_line_size_get(void)
     424              : {
     425              : #ifdef CONFIG_ICACHE_LINE_SIZE_DETECT
     426              :         return cache_instr_line_size_get();
     427              : #elif defined(CONFIG_ICACHE_LINE_SIZE)
     428              :         return CONFIG_ICACHE_LINE_SIZE;
     429              : #else
     430              :         return 0;
     431              : #endif
     432              : }
     433              : 
     434              : /**
     435              :  * @brief Test if a pointer is in cached region.
     436              :  *
     437              :  * Some hardware may map the same physical memory twice
     438              :  * so that it can be seen in both (incoherent) cached mappings
     439              :  * and a coherent "shared" area. This tests if a particular
     440              :  * pointer is within the cached, coherent area.
     441              :  *
     442              :  * @param ptr Pointer
     443              :  *
     444              :  * @retval True if pointer is in cached region.
     445              :  * @retval False if pointer is not in cached region.
     446              :  */
     447            1 : static ALWAYS_INLINE bool sys_cache_is_ptr_cached(void *ptr)
     448              : {
     449              : #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_CACHE_DOUBLEMAP)
     450              :         return cache_is_ptr_cached(ptr);
     451              : #else
     452              :         ARG_UNUSED(ptr);
     453              : 
     454              :         return false;
     455              : #endif
     456              : }
     457              : 
     458              : /**
     459              :  * @brief Test if a pointer is in un-cached region.
     460              :  *
     461              :  * Some hardware may map the same physical memory twice
     462              :  * so that it can be seen in both (incoherent) cached mappings
     463              :  * and a coherent "shared" area. This tests if a particular
     464              :  * pointer is within the un-cached, incoherent area.
     465              :  *
     466              :  * @param ptr Pointer
     467              :  *
     468              :  * @retval True if pointer is not in cached region.
     469              :  * @retval False if pointer is in cached region.
     470              :  */
     471            1 : static ALWAYS_INLINE bool sys_cache_is_ptr_uncached(void *ptr)
     472              : {
     473              : #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_CACHE_DOUBLEMAP)
     474              :         return cache_is_ptr_uncached(ptr);
     475              : #else
     476              :         ARG_UNUSED(ptr);
     477              : 
     478              :         return false;
     479              : #endif
     480              : }
     481              : 
     482              : /**
     483              :  * @brief Return cached pointer to a RAM address
     484              :  *
     485              :  * This function takes a pointer to any addressable object (either in
     486              :  * cacheable memory or not) and returns a pointer that can be used to
     487              :  * refer to the same memory through the L1 data cache.  Data read
     488              :  * through the resulting pointer will reflect locally cached values on
     489              :  * the current CPU if they exist, and writes will go first into the
     490              :  * cache and be written back later.
     491              :  *
     492              :  * @note This API returns the same pointer if CONFIG_CACHE_DOUBLEMAP is not
     493              :  * enabled.
     494              :  *
     495              :  * @see arch_uncached_ptr()
     496              :  *
     497              :  * @param ptr A pointer to a valid C object
     498              :  * @return A pointer to the same object via the L1 dcache
     499              :  */
     500            1 : static ALWAYS_INLINE void __sparse_cache *sys_cache_cached_ptr_get(void *ptr)
     501              : {
     502              : #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_CACHE_DOUBLEMAP)
     503              :         return cache_cached_ptr(ptr);
     504              : #else
     505              :         return (__sparse_force void __sparse_cache *)ptr;
     506              : #endif
     507              : }
     508              : 
     509              : /**
     510              :  * @brief Return uncached pointer to a RAM address
     511              :  *
     512              :  * This function takes a pointer to any addressable object (either in
     513              :  * cacheable memory or not) and returns a pointer that can be used to
     514              :  * refer to the same memory while bypassing the L1 data cache.  Data
     515              :  * in the L1 cache will not be inspected nor modified by the access.
     516              :  *
     517              :  * @note This API returns the same pointer if CONFIG_CACHE_DOUBLEMAP is not
     518              :  * enabled.
     519              :  *
     520              :  * @see arch_cached_ptr()
     521              :  *
     522              :  * @param ptr A pointer to a valid C object
     523              :  * @return A pointer to the same object bypassing the L1 dcache
     524              :  */
     525            1 : static ALWAYS_INLINE void *sys_cache_uncached_ptr_get(void __sparse_cache *ptr)
     526              : {
     527              : #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_CACHE_DOUBLEMAP)
     528              :         return cache_uncached_ptr(ptr);
     529              : #else
     530              :         return (__sparse_force void *)ptr;
     531              : #endif
     532              : }
     533              : 
     534              : 
     535              : #ifdef CONFIG_LIBMETAL
     536              : static ALWAYS_INLINE void sys_cache_flush(void *addr, size_t size)
     537              : {
     538              :         sys_cache_data_flush_range(addr, size);
     539              : }
     540              : #endif
     541              : 
     542              : #include <zephyr/syscalls/cache.h>
     543              : #ifdef __cplusplus
     544              : }
     545              : #endif
     546              : 
     547              : /**
     548              :  * @}
     549              :  */
     550              : 
     551              : #endif /* ZEPHYR_INCLUDE_CACHE_H_ */
        

Generated by: LCOV version 2.0-1