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 */
|
#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 */
|
/* Just like Z_MEM_PHYS_ADDR() but with type safety and assertions */
|
||||||
static inline uintptr_t z_mem_phys_addr(void *virt)
|
static inline uintptr_t z_mem_phys_addr(void *virt)
|
||||||
{
|
{
|
||||||
uintptr_t addr = (uintptr_t)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(
|
__ASSERT(
|
||||||
#if CONFIG_KERNEL_VM_BASE != 0
|
#if CONFIG_KERNEL_VM_BASE != 0
|
||||||
(addr >= CONFIG_KERNEL_VM_BASE) &&
|
(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 */
|
/* Just like Z_MEM_VIRT_ADDR() but with type safety and assertions */
|
||||||
static inline void *z_mem_virt_addr(uintptr_t phys)
|
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(
|
__ASSERT(
|
||||||
#if CONFIG_SRAM_BASE_ADDRESS != 0
|
#if CONFIG_SRAM_BASE_ADDRESS != 0
|
||||||
(phys >= CONFIG_SRAM_BASE_ADDRESS) &&
|
(phys >= CONFIG_SRAM_BASE_ADDRESS) &&
|
||||||
|
@ -185,6 +230,7 @@ static inline void *z_mem_virt_addr(uintptr_t phys)
|
||||||
(phys < (CONFIG_SRAM_BASE_ADDRESS +
|
(phys < (CONFIG_SRAM_BASE_ADDRESS +
|
||||||
(CONFIG_SRAM_SIZE * 1024UL))),
|
(CONFIG_SRAM_SIZE * 1024UL))),
|
||||||
"physical address 0x%lx not in RAM", (unsigned long)phys);
|
"physical address 0x%lx not in RAM", (unsigned long)phys);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* TODO add assertion that this page frame is pinned to boot mapping,
|
/* TODO add assertion that this page frame is pinned to boot mapping,
|
||||||
* the above check won't be sufficient with demand paging
|
* 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 # DEMAND_PAGING
|
||||||
endif # MMU
|
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
|
endmenu # Virtual Memory Support
|
||||||
|
|
Loading…
Reference in a new issue