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-05 16:43:28

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

Generated by: LCOV version 2.0-1