LCOV - code coverage report
Current view: top level - zephyr/drivers/mm - system_mm.h Coverage Total Hit
Test: new.info Lines: 100.0 % 28 28
Test Date: 2025-09-05 16:43:28

            Line data    Source code
       1            1 : /*
       2              :  * Copyright (c) 2021 Intel Corporation.
       3              :  *
       4              :  * SPDX-License-Identifier: Apache-2.0
       5              :  */
       6              : 
       7              : /**
       8              :  * @file
       9              :  * @brief Memory Management Driver APIs
      10              :  *
      11              :  * This contains APIs for a system-wide memory management
      12              :  * driver. Only one instance is permitted on the system.
      13              :  */
      14              : 
      15              : #ifndef ZEPHYR_INCLUDE_DRIVERS_SYSTEM_MM_H_
      16              : #define ZEPHYR_INCLUDE_DRIVERS_SYSTEM_MM_H_
      17              : 
      18              : #include <zephyr/types.h>
      19              : 
      20              : #ifndef _ASMLANGUAGE
      21              : 
      22              : #ifdef __cplusplus
      23              : extern "C" {
      24              : #endif
      25              : 
      26              : /**
      27              :  * @brief Memory Management Driver APIs
      28              :  * @defgroup mm_drv_apis Memory Management Driver APIs
      29              :  *
      30              :  * This contains APIs for a system-wide memory management
      31              :  * driver. Only one instance is permitted on the system.
      32              :  *
      33              :  * @ingroup memory_management
      34              :  * @{
      35              :  */
      36              : 
      37              : /**
      38              :  * @name Caching mode definitions.
      39              :  *
      40              :  * These are mutually exclusive.
      41              :  *
      42              :  * @{
      43              :  */
      44              : 
      45              : /** No caching */
      46            1 : #define SYS_MM_MEM_CACHE_NONE           2
      47              : 
      48              : /** Write-through caching */
      49            1 : #define SYS_MM_MEM_CACHE_WT             1
      50              : 
      51              : /** Full write-back caching */
      52            1 : #define SYS_MM_MEM_CACHE_WB             0
      53              : 
      54              : /** Reserved bits for cache modes */
      55            1 : #define SYS_MM_MEM_CACHE_MASK           (BIT(3) - 1)
      56              : 
      57              : /**
      58              :  * @brief Represents an available memory region.
      59              :  *
      60              :  * A memory region that can be used by allocators. Driver defined
      61              :  * attributes can be used to guide the proper usage of each region.
      62              :  */
      63            1 : struct sys_mm_drv_region {
      64            1 :         void *addr; /**< @brief Address of the memory region */
      65            1 :         size_t size; /**< @brief Size of the memory region */
      66            1 :         uint32_t attr; /**< @brief Driver defined attributes of the memory region */
      67              : };
      68              : 
      69              : /**
      70              :  * @}
      71              :  */
      72              : 
      73              : /**
      74              :  * @name Region permission attributes.
      75              :  *
      76              :  * Default should be read-only, no user, no exec.
      77              :  *
      78              :  * @{
      79              :  */
      80              : 
      81              : /** Region will have read/write access (and not read-only) */
      82            1 : #define SYS_MM_MEM_PERM_RW              BIT(3)
      83              : 
      84              : /** Region will be executable (normally forbidden) */
      85            1 : #define SYS_MM_MEM_PERM_EXEC            BIT(4)
      86              : 
      87              : /** Region will be accessible to user mode (normally supervisor-only) */
      88            1 : #define SYS_MM_MEM_PERM_USER            BIT(5)
      89              : 
      90              : /**
      91              :  * @}
      92              :  */
      93              : 
      94              : /**
      95              :  * @name Memory Mapping and Unmapping
      96              :  *
      97              :  * On mapping and unmapping of memory.
      98              :  *
      99              :  * @{
     100              :  */
     101              : 
     102              : /**
     103              :  * @brief Map one physical page into the virtual address space
     104              :  *
     105              :  * This maps one physical page into the virtual address space.
     106              :  * Behavior when providing unaligned address is undefined, this
     107              :  * is assumed to be page aligned.
     108              :  *
     109              :  * The memory range itself is never accessed by this operation.
     110              :  *
     111              :  * This API must be safe to call in ISRs or exception handlers. Calls
     112              :  * to this API are assumed to be serialized.
     113              :  *
     114              :  * @param virt Page-aligned destination virtual address to map
     115              :  * @param phys Page-aligned source physical address to map
     116              :  * @param flags Caching, access and control flags, see SYS_MM_MEM_* macros
     117              :  *
     118              :  * @retval 0 if successful
     119              :  * @retval -EINVAL if invalid arguments are provided
     120              :  * @retval -EFAULT if virtual address has already been mapped
     121              :  */
     122            1 : int sys_mm_drv_map_page(void *virt, uintptr_t phys, uint32_t flags);
     123              : 
     124              : /**
     125              :  * @brief Map one physical page into the virtual address space with region check
     126              :  *
     127              :  * This maps one physical page into the virtual address space by calling
     128              :  * sys_mm_drv_map_page. Refer to sys_mm_drv_map_page for references
     129              :  *
     130              :  * Before call it performs a safety check by verifying if the mapped virtual memory page
     131              :  * fits into a given virtual region
     132              :  */
     133            1 : int sys_mm_drv_map_page_safe(const struct sys_mm_drv_region *virtual_region,
     134              :                              void *virt, uintptr_t phys, uint32_t flags);
     135              : 
     136              : /**
     137              :  * @brief Map a region of physical memory into the virtual address space
     138              :  *
     139              :  * This maps a region of physical memory into the virtual address space.
     140              :  * Behavior when providing unaligned addresses/sizes is undefined, these
     141              :  * are assumed to be page aligned.
     142              :  *
     143              :  * The memory range itself is never accessed by this operation.
     144              :  *
     145              :  * This API must be safe to call in ISRs or exception handlers. Calls
     146              :  * to this API are assumed to be serialized.
     147              :  *
     148              :  * @param virt Page-aligned destination virtual address to map
     149              :  * @param phys Page-aligned source physical address to map
     150              :  * @param size Page-aligned size of the mapped memory region in bytes
     151              :  * @param flags Caching, access and control flags, see SYS_MM_MEM_* macros
     152              :  *
     153              :  * @retval 0 if successful
     154              :  * @retval -EINVAL if invalid arguments are provided
     155              :  * @retval -EFAULT if any virtual addresses have already been mapped
     156              :  */
     157            1 : int sys_mm_drv_map_region(void *virt, uintptr_t phys,
     158              :                           size_t size, uint32_t flags);
     159              : 
     160              : /**
     161              :  * @brief Map a region of physical memory into the virtual address space with region check
     162              :  *
     163              :  * This maps a region of physical memory into the virtual address space by calling
     164              :  * sys_mm_drv_map_region. Refer to sys_mm_drv_map_region for references
     165              :  *
     166              :  * Before call it performs a safety check by verifying if the mapped virtual memory pages
     167              :  * fit into a given virtual region
     168              :  */
     169            1 : int sys_mm_drv_map_region_safe(const struct sys_mm_drv_region *virtual_region,
     170              :                                void *virt, uintptr_t phys, size_t size,
     171              :                                uint32_t flags);
     172              : 
     173              : /**
     174              :  * @brief Map an array of physical memory into the virtual address space
     175              :  *
     176              :  * This maps an array of physical pages into a continuous virtual address
     177              :  * space. Behavior when providing unaligned addresses is undefined, these
     178              :  * are assumed to be page aligned.
     179              :  *
     180              :  * The physical memory pages are never accessed by this operation.
     181              :  *
     182              :  * This API must be safe to call in ISRs or exception handlers. Calls
     183              :  * to this API are assumed to be serialized.
     184              :  *
     185              :  * @param virt Page-aligned destination virtual address to map
     186              :  * @param phys Array of pge-aligned source physical address to map
     187              :  * @param cnt Number of elements in the physical page array
     188              :  * @param flags Caching, access and control flags, see SYS_MM_MEM_* macros
     189              :  *
     190              :  * @retval 0 if successful
     191              :  * @retval -EINVAL if invalid arguments are provided
     192              :  * @retval -EFAULT if any virtual addresses have already been mapped
     193              :  */
     194            1 : int sys_mm_drv_map_array(void *virt, uintptr_t *phys,
     195              :                          size_t cnt, uint32_t flags);
     196              : 
     197              : /**
     198              :  * @brief Remove mapping for one page of the provided virtual address
     199              :  *
     200              :  * This unmaps one page from the virtual address space.
     201              :  *
     202              :  * When this completes, the relevant translation table entries will be
     203              :  * updated as if no mapping was ever made for that memory page. No previous
     204              :  * context needs to be preserved. This function must update mapping in
     205              :  * all active translation tables.
     206              :  *
     207              :  * Behavior when providing unaligned address is undefined, this
     208              :  * is assumed to be page aligned.
     209              :  *
     210              :  * Implementations must invalidate translation caching as necessary.
     211              :  *
     212              :  * @param virt Page-aligned virtual address to un-map
     213              :  *
     214              :  * @retval 0 if successful
     215              :  * @retval -EINVAL if invalid arguments are provided
     216              :  * @retval -EFAULT if virtual address is not mapped
     217              :  */
     218            1 : int sys_mm_drv_unmap_page(void *virt);
     219              : 
     220              : /**
     221              :  * @brief Remove mappings for a provided virtual address range
     222              :  *
     223              :  * This unmaps pages in the provided virtual address range.
     224              :  *
     225              :  * When this completes, the relevant translation table entries will be
     226              :  * updated as if no mapping was ever made for that memory range. No previous
     227              :  * context needs to be preserved. This function must update mappings in
     228              :  * all active translation tables.
     229              :  *
     230              :  * Behavior when providing unaligned address is undefined, this
     231              :  * is assumed to be page aligned.
     232              :  *
     233              :  * Implementations must invalidate translation caching as necessary.
     234              :  *
     235              :  * @param virt Page-aligned base virtual address to un-map
     236              :  * @param size Page-aligned region size
     237              :  *
     238              :  * @retval 0 if successful
     239              :  * @retval -EINVAL if invalid arguments are provided
     240              :  * @retval -EFAULT if virtual address is not mapped
     241              :  */
     242            1 : int sys_mm_drv_unmap_region(void *virt, size_t size);
     243              : 
     244              : /**
     245              :  * @brief Remap virtual pages into new address
     246              :  *
     247              :  * This remaps a virtual memory region starting at @p virt_old
     248              :  * of size @p size into a new virtual memory region starting at
     249              :  * @p virt_new. In other words, physical memory at @p virt_old is
     250              :  * remapped to appear at @p virt_new. Both addresses must be page
     251              :  * aligned and valid.
     252              :  *
     253              :  * Note that the virtual memory at both the old and new addresses
     254              :  * must be unmapped in the memory domains of any runnable Zephyr
     255              :  * thread as this does not deal with memory domains.
     256              :  *
     257              :  * Note that overlapping of old and new virtual memory regions
     258              :  * is usually not supported for simpler implementation. Refer to
     259              :  * the actual driver to make sure if overlapping is allowed.
     260              :  *
     261              :  * @param virt_old Page-aligned base virtual address of existing memory
     262              :  * @param size Page-aligned size of the mapped memory region in bytes
     263              :  * @param virt_new Page-aligned base virtual address to which to remap
     264              :  *                 the memory
     265              :  *
     266              :  * @retval 0 if successful
     267              :  * @retval -EINVAL if invalid arguments are provided
     268              :  * @retval -EFAULT if old virtual addresses are not all mapped or
     269              :  *                 new virtual addresses are not all unmapped
     270              :  */
     271            1 : int sys_mm_drv_remap_region(void *virt_old, size_t size, void *virt_new);
     272              : 
     273              : /**
     274              :  * @}
     275              :  */
     276              : 
     277              : /**
     278              :  * @name Memory Moving
     279              :  *
     280              :  * On moving already mapped memory.
     281              :  *
     282              :  * @{
     283              :  */
     284              : 
     285              : /**
     286              :  * @brief Physically move memory, with copy
     287              :  *
     288              :  * This maps a region of physical memory into the new virtual address space
     289              :  * (@p virt_new), and copy region of size @p size from the old virtual
     290              :  * address space (@p virt_old). The new virtual memory region is mapped
     291              :  * from physical memory starting at @p phys_new of size @p size.
     292              :  *
     293              :  * Behavior when providing unaligned addresses/sizes is undefined, these
     294              :  * are assumed to be page aligned.
     295              :  *
     296              :  * Note that the virtual memory at both the old and new addresses
     297              :  * must be unmapped in the memory domains of any runnable Zephyr
     298              :  * thread as this does not deal with memory domains.
     299              :  *
     300              :  * Note that overlapping of old and new virtual memory regions
     301              :  * is usually not supported for simpler implementation. Refer to
     302              :  * the actual driver to make sure if overlapping is allowed.
     303              :  *
     304              :  * @param virt_old Page-aligned base virtual address of existing memory
     305              :  * @param size Page-aligned size of the mapped memory region in bytes
     306              :  * @param virt_new Page-aligned base virtual address to which to map
     307              :  *                 new physical pages
     308              :  * @param phys_new Page-aligned base physical address to contain
     309              :  *                 the moved memory
     310              :  *
     311              :  * @retval 0 if successful
     312              :  * @retval -EINVAL if invalid arguments are provided
     313              :  * @retval -EFAULT if old virtual addresses are not all mapped or
     314              :  *                 new virtual addresses are not all unmapped
     315              :  */
     316            1 : int sys_mm_drv_move_region(void *virt_old, size_t size, void *virt_new,
     317              :                            uintptr_t phys_new);
     318              : 
     319              : /**
     320              :  * @brief Physically move memory, with copy
     321              :  *
     322              :  * This maps a region of physical memory into the new virtual address space
     323              :  * (@p virt_new), and copy region of size @p size from the old virtual
     324              :  * address space (@p virt_old). The new virtual memory region is mapped
     325              :  * from an array of physical pages.
     326              :  *
     327              :  * Behavior when providing unaligned addresses/sizes is undefined, these
     328              :  * are assumed to be page aligned.
     329              :  *
     330              :  * Note that the virtual memory at both the old and new addresses
     331              :  * must be unmapped in the memory domains of any runnable Zephyr
     332              :  * thread as this does not deal with memory domains.
     333              :  *
     334              :  * Note that overlapping of old and new virtual memory regions
     335              :  * is usually not supported for simpler implementation. Refer to
     336              :  * the actual driver to make sure if overlapping is allowed.
     337              :  *
     338              :  * @param virt_old Page-aligned base virtual address of existing memory
     339              :  * @param size Page-aligned size of the mapped memory region in bytes
     340              :  * @param virt_new Page-aligned base virtual address to which to map
     341              :  *                 new physical pages
     342              :  * @param phys_new Array of page-aligned physical address to contain
     343              :  *                 the moved memory
     344              :  * @param phys_cnt Number of elements in the physical page array
     345              :  *
     346              :  * @retval 0 if successful
     347              :  * @retval -EINVAL if invalid arguments are provided
     348              :  * @retval -EFAULT if old virtual addresses are not all mapped or
     349              :  *                 new virtual addresses are not all unmapped
     350              :  */
     351            1 : int sys_mm_drv_move_array(void *virt_old, size_t size, void *virt_new,
     352              :                           uintptr_t *phys_new, size_t phys_cnt);
     353              : 
     354              : /**
     355              :  * @}
     356              :  */
     357              : 
     358              : /**
     359              :  * @name Memory Mapping Attributes
     360              :  *
     361              :  * On manipulating attributes of already mapped memory.
     362              :  *
     363              :  * @{
     364              :  */
     365              : 
     366              : /**
     367              :  * @brief Update memory page flags
     368              :  *
     369              :  * This changes the attributes of physical memory page which is already
     370              :  * mapped to a virtual address. This is useful when use case of
     371              :  * specific memory region  changes.
     372              :  * E.g. when the library/module code is copied to the memory then
     373              :  * it needs to be read-write and after it has already
     374              :  * been copied and library/module code is ready to be executed then
     375              :  * attributes need to be changed to read-only/executable.
     376              :  * Calling this API must not cause losing memory contents.
     377              :  *
     378              :  * @param virt Page-aligned virtual address to be updated
     379              :  * @param flags Caching, access and control flags, see SYS_MM_MEM_* macros
     380              :  *
     381              :  * @retval 0 if successful
     382              :  * @retval -EINVAL if invalid arguments are provided
     383              :  * @retval -EFAULT if virtual addresses is not mapped
     384              :  */
     385              : 
     386            1 : int sys_mm_drv_update_page_flags(void *virt, uint32_t flags);
     387              : 
     388              : /**
     389              :  * @brief Update memory region flags
     390              :  *
     391              :  * This changes the attributes of physical memory which is already
     392              :  * mapped to a virtual address. This is useful when use case of
     393              :  * specific memory region  changes.
     394              :  * E.g. when the library/module code is copied to the memory then
     395              :  * it needs to be read-write and after it has already
     396              :  * been copied and library/module code is ready to be executed then
     397              :  * attributes need to be changed to read-only/executable.
     398              :  * Calling this API must not cause losing memory contents.
     399              :  *
     400              :  * @param virt Page-aligned virtual address to be updated
     401              :  * @param size Page-aligned size of the mapped memory region in bytes
     402              :  * @param flags Caching, access and control flags, see SYS_MM_MEM_* macros
     403              :  *
     404              :  * @retval 0 if successful
     405              :  * @retval -EINVAL if invalid arguments are provided
     406              :  * @retval -EFAULT if virtual addresses is not mapped
     407              :  */
     408              : 
     409            1 : int sys_mm_drv_update_region_flags(void *virt, size_t size, uint32_t flags);
     410              : 
     411              : /**
     412              :  * @}
     413              :  */
     414              : 
     415              : /**
     416              :  * @name Memory Mappings Query
     417              :  *
     418              :  * On querying information on memory mappings.
     419              :  *
     420              :  * @{
     421              :  */
     422              : 
     423              : /**
     424              :  * @brief Get the mapped physical memory address from virtual address.
     425              :  *
     426              :  * The function queries the translation tables to find the physical
     427              :  * memory address of a mapped virtual address.
     428              :  *
     429              :  * Behavior when providing unaligned address is undefined, this
     430              :  * is assumed to be page aligned.
     431              :  *
     432              :  * @param      virt Page-aligned virtual address
     433              :  * @param[out] phys Mapped physical address (can be NULL if only checking
     434              :  *                  if virtual address is mapped)
     435              :  *
     436              :  * @retval 0 if mapping is found and valid
     437              :  * @retval -EINVAL if invalid arguments are provided
     438              :  * @retval -EFAULT if virtual address is not mapped
     439              :  */
     440            1 : int sys_mm_drv_page_phys_get(void *virt, uintptr_t *phys);
     441              : 
     442              : /* TODO is it safe to assume no valid region has size == 0? */
     443              : /**
     444              :  * @brief Iterates over an array of regions returned by #sys_mm_drv_query_memory_regions
     445              :  *
     446              :  * Note that a sentinel item marking the end of the array is expected for
     447              :  * this macro to work.
     448              :  */
     449            1 : #define SYS_MM_DRV_MEMORY_REGION_FOREACH(regions, iter) \
     450              :         for (iter = regions; iter->size; iter++)
     451              : 
     452              : /**
     453              :  * @brief Query available memory regions
     454              :  *
     455              :  * Returns an array of available memory regions. One can iterate over
     456              :  * the array using #SYS_MM_DRV_MEMORY_REGION_FOREACH. Note that the last
     457              :  * item of the array is a sentinel marking the end, and it's identified
     458              :  * by it's size attribute, which is zero.
     459              :  *
     460              :  * @retval regions A possibly empty array - i.e. containing only the sentinel
     461              :  *         marking at the end - of memory regions.
     462              :  */
     463            1 : const struct sys_mm_drv_region *sys_mm_drv_query_memory_regions(void);
     464              : 
     465              : /**
     466              :  * @brief Free the memory array returned by #sys_mm_drv_query_memory_regions
     467              :  *
     468              :  * The driver may have dynamically allocated the memory for the array of
     469              :  * regions returned by #sys_mm_drv_query_memory_regions. This method provides
     470              :  * it the opportunity to free any related resources.
     471              :  *
     472              :  * @param regions Array of regions previously returned by
     473              :  *                #sys_mm_drv_query_memory_regions
     474              :  */
     475            1 : void sys_mm_drv_query_memory_regions_free(const struct sys_mm_drv_region *regions);
     476              : 
     477              : /**
     478              :  * @}
     479              :  */
     480              : 
     481              : /**
     482              :  * @}
     483              :  */
     484              : 
     485              : #ifdef __cplusplus
     486              : }
     487              : #endif
     488              : 
     489              : #endif /* _ASMLANGUAGE */
     490              : 
     491              : #endif /* ZEPHYR_INCLUDE_DRIVERS_SYSTEM_MM_H_ */
        

Generated by: LCOV version 2.0-1