mm: introduce CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK
Sometimes the generic address range checker is not adequate (think Xtensa cached/uncached pointers). This provides a way to implement custom memory range checkers for those situations. When enabled, sys_mm_is_phys_addr_in_range() and sys_mm_is_virt_addr_in_range() must be implemented. Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
parent
68dfd819c1
commit
943e434559
|
@ -143,12 +143,53 @@ struct k_mem_paging_histogram_t {
|
|||
#endif /* CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Check if a physical address is within range of physical memory.
|
||||
*
|
||||
* This checks if the physical address (@p virt) is within
|
||||
* permissible range, e.g. between
|
||||
* :kconfig:option:`CONFIG_SRAM_BASE_ADDRESS` and
|
||||
* (:kconfig:option:`CONFIG_SRAM_BASE_ADDRESS` +
|
||||
* :kconfig:option:`CONFIG_SRAM_SIZE`).
|
||||
*
|
||||
* @note Only used if
|
||||
* :kconfig:option:`CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK`
|
||||
* is enabled.
|
||||
*
|
||||
* @param phys Physical address to be checked.
|
||||
*
|
||||
* @return True if physical address is within range, false if not.
|
||||
*/
|
||||
bool sys_mm_is_phys_addr_in_range(uintptr_t phys);
|
||||
|
||||
/**
|
||||
* @brief Check if a virtual address is within range of virtual memory.
|
||||
*
|
||||
* This checks if the virtual address (@p virt) is within
|
||||
* permissible range, e.g. between
|
||||
* :kconfig:option:`CONFIG_KERNEL_VM_BASE` and
|
||||
* (:kconfig:option:`CONFIG_KERNEL_VM_BASE` +
|
||||
* :kconfig:option:`CONFIG_KERNEL_VM_SIZE`).
|
||||
*
|
||||
* @note Only used if
|
||||
* :kconfig:option:`CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK`
|
||||
* is enabled.
|
||||
*
|
||||
* @param virt Virtual address to be checked.
|
||||
*
|
||||
* @return True if virtual address is within range, false if not.
|
||||
*/
|
||||
bool sys_mm_is_virt_addr_in_range(void *virt);
|
||||
|
||||
/* Just like Z_MEM_PHYS_ADDR() but with type safety and assertions */
|
||||
static inline uintptr_t z_mem_phys_addr(void *virt)
|
||||
{
|
||||
uintptr_t addr = (uintptr_t)virt;
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
#if defined(CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK)
|
||||
__ASSERT(sys_mm_is_virt_addr_in_range(virt),
|
||||
"address %p not in permanent mappings", virt);
|
||||
#elif defined(CONFIG_MMU)
|
||||
__ASSERT(
|
||||
#if CONFIG_KERNEL_VM_BASE != 0
|
||||
(addr >= CONFIG_KERNEL_VM_BASE) &&
|
||||
|
@ -178,6 +219,10 @@ static inline uintptr_t z_mem_phys_addr(void *virt)
|
|||
/* Just like Z_MEM_VIRT_ADDR() but with type safety and assertions */
|
||||
static inline void *z_mem_virt_addr(uintptr_t phys)
|
||||
{
|
||||
#if defined(CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK)
|
||||
__ASSERT(sys_mm_is_phys_addr_in_range(phys),
|
||||
"physical address 0x%lx not in RAM", (unsigned long)phys);
|
||||
#else
|
||||
__ASSERT(
|
||||
#if CONFIG_SRAM_BASE_ADDRESS != 0
|
||||
(phys >= CONFIG_SRAM_BASE_ADDRESS) &&
|
||||
|
@ -185,6 +230,7 @@ static inline void *z_mem_virt_addr(uintptr_t phys)
|
|||
(phys < (CONFIG_SRAM_BASE_ADDRESS +
|
||||
(CONFIG_SRAM_SIZE * 1024UL))),
|
||||
"physical address 0x%lx not in RAM", (unsigned long)phys);
|
||||
#endif
|
||||
|
||||
/* TODO add assertion that this page frame is pinned to boot mapping,
|
||||
* the above check won't be sufficient with demand paging
|
||||
|
|
|
@ -198,4 +198,13 @@ config DEMAND_PAGING_TIMING_HISTOGRAM_NUM_BINS
|
|||
endif # DEMAND_PAGING
|
||||
endif # MMU
|
||||
|
||||
config KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK
|
||||
bool
|
||||
help
|
||||
Use custom memory range check functions instead of the generic
|
||||
checks in z_mem_phys_addr() and z_mem_virt_addr().
|
||||
|
||||
sys_mm_is_phys_addr_in_range() and
|
||||
sys_mm_is_virt_addr_in_range() must be implemented.
|
||||
|
||||
endmenu # Virtual Memory Support
|
||||
|
|
Loading…
Reference in a new issue