mm: introduce update memory flags api
There are cases when attributes of mapped virtual memory need to be updated. E.g. in case there is loadable library/module code loaded to the l2 memory then memory needs to be read-write. After the code is loaded and is ready to be executed then attributes of mapped memory should be updated to read-only/executable without loosing memory contents. Signed-off-by: Jaroslaw Stelter <Jaroslaw.Stelter@intel.com>
This commit is contained in:
parent
04a5988c55
commit
cf24124efa
4 changed files with 126 additions and 0 deletions
|
@ -434,3 +434,38 @@ out:
|
|||
|
||||
__weak FUNC_ALIAS(sys_mm_drv_simple_move_array,
|
||||
sys_mm_drv_move_array, int);
|
||||
|
||||
int sys_mm_drv_simple_update_region_flags(void *virt, size_t size, uint32_t flags)
|
||||
{
|
||||
k_spinlock_key_t key;
|
||||
int ret = 0;
|
||||
size_t offset;
|
||||
|
||||
CHECKIF(!sys_mm_drv_is_virt_addr_aligned(virt) ||
|
||||
!sys_mm_drv_is_size_aligned(size)) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
key = k_spin_lock(&sys_mm_drv_common_lock);
|
||||
|
||||
for (offset = 0; offset < size; offset += CONFIG_MM_DRV_PAGE_SIZE) {
|
||||
uint8_t *va = (uint8_t *)virt + offset;
|
||||
|
||||
int ret2 = sys_mm_drv_update_page_flags(va, flags);
|
||||
|
||||
if (ret2 != 0) {
|
||||
__ASSERT(false, "cannot update flags %p\n", va);
|
||||
|
||||
ret = ret2;
|
||||
}
|
||||
}
|
||||
|
||||
k_spin_unlock(&sys_mm_drv_common_lock, key);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
__weak FUNC_ALIAS(sys_mm_drv_simple_update_region_flags,
|
||||
sys_mm_drv_update_region_flags, int);
|
||||
|
|
|
@ -270,4 +270,27 @@ int sys_mm_drv_simple_move_array(void *virt_old, size_t size,
|
|||
void *virt_new,
|
||||
uintptr_t *phys_new, size_t phys_cnt);
|
||||
|
||||
/**
|
||||
* @brief Update memory region flags
|
||||
*
|
||||
* This changes the attributes of physical memory which is already
|
||||
* mapped to a virtual address. This is useful when use case of
|
||||
* specific memory region changes.
|
||||
* E.g. when the library/module code is copied to the memory then
|
||||
* it needs to be read-write and after it has already
|
||||
* been copied and library/module code is ready to be executed then
|
||||
* attributes need to be changed to read-only/executable.
|
||||
* Calling this API must not cause losing memory contents.
|
||||
*
|
||||
* @param virt Page-aligned virtual address to be updated
|
||||
* @param size Page-aligned size of the mapped memory region in bytes
|
||||
* @param flags Caching, access and control flags, see SYS_MM_MEM_* macros
|
||||
*
|
||||
* @retval 0 if successful
|
||||
* @retval -EINVAL if invalid arguments are provided
|
||||
* @retval -EFAULT if virtual addresses is not mapped
|
||||
*/
|
||||
|
||||
int sys_mm_drv_simple_update_region_flags(void *virt, size_t size, uint32_t flags);
|
||||
|
||||
#endif /* ZEPHYR_DRIVERS_SYSTEM_MM_DRV_COMMON_H_ */
|
||||
|
|
|
@ -261,6 +261,28 @@ int sys_mm_drv_page_flag_get(void *virt, uint32_t *flags)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int sys_mm_drv_update_page_flags(void *virt, uint32_t flags)
|
||||
{
|
||||
ARG_UNUSED(virt);
|
||||
ARG_UNUSED(flags);
|
||||
|
||||
/*
|
||||
* There are no caching mode, or R/W, or eXecution (etc.) bits.
|
||||
* So just return 0.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sys_mm_drv_update_region_flags(void *virt, size_t size,
|
||||
uint32_t flags)
|
||||
{
|
||||
void *va = z_soc_cached_ptr(virt);
|
||||
|
||||
return sys_mm_drv_simple_update_region_flags(va, size, flags);
|
||||
}
|
||||
|
||||
|
||||
int sys_mm_drv_remap_region(void *virt_old, size_t size,
|
||||
void *virt_new)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue