kernel: mmu: add direct-map support in z_phys_map()
Many RTOS applications assume the virtual and physical address is 1:1 mapping, so add the 1:1 mapping support in z_phys_map() to easy adapt these applications. Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
This commit is contained in:
parent
5ab14730f5
commit
41520e8b5b
3 changed files with 47 additions and 4 deletions
|
|
@ -54,6 +54,13 @@
|
|||
/** Region will be accessible to user mode (normally supervisor-only) */
|
||||
#define K_MEM_PERM_USER BIT(5)
|
||||
|
||||
/*
|
||||
* Region mapping behaviour attributes
|
||||
*/
|
||||
|
||||
/** Region will be mapped to 1:1 virtual and physical address */
|
||||
#define K_MEM_DIRECT_MAP BIT(6)
|
||||
|
||||
/*
|
||||
* This is the offset to subtract from a virtual address mapped in the
|
||||
* kernel's permanent mapping of RAM, to obtain its physical address.
|
||||
|
|
|
|||
|
|
@ -80,6 +80,22 @@ config KERNEL_VM_SIZE
|
|||
implement a notion of "high" memory in Zephyr to work around physical
|
||||
RAM size larger than the defined bounds of the virtual address space.
|
||||
|
||||
config KERNEL_DIRECT_MAP
|
||||
bool "Memory region direct-map support"
|
||||
depends on MMU
|
||||
help
|
||||
This enables the direct-map support, namely the region can be 1:1
|
||||
mapping between virtual address and physical address.
|
||||
|
||||
If the specific memory region is in the virtual memory space and
|
||||
there isn't overlap with the existed mappings, it will reserve the
|
||||
region from the virtual memory space and do the mapping, otherwise
|
||||
it will fail. And any attempt across the boundary of the virtual
|
||||
memory space will fail.
|
||||
|
||||
Note that this is for compatibility and portable apps shouldn't
|
||||
be using it.
|
||||
|
||||
endif # KERNEL_VM_SUPPORT
|
||||
|
||||
menuconfig MMU
|
||||
|
|
|
|||
28
kernel/mmu.c
28
kernel/mmu.c
|
|
@ -237,9 +237,11 @@ static void virt_region_free(void *vaddr, size_t size)
|
|||
virt_region_init();
|
||||
}
|
||||
|
||||
#ifndef CONFIG_KERNEL_DIRECT_MAP
|
||||
__ASSERT((vaddr_u8 >= Z_VIRT_REGION_START_ADDR)
|
||||
&& ((vaddr_u8 + size - 1) < Z_VIRT_REGION_END_ADDR),
|
||||
"invalid virtual address region %p (%zu)", vaddr_u8, size);
|
||||
#endif
|
||||
if (!((vaddr_u8 >= Z_VIRT_REGION_START_ADDR)
|
||||
&& ((vaddr_u8 + size - 1) < Z_VIRT_REGION_END_ADDR))) {
|
||||
return;
|
||||
|
|
@ -721,7 +723,12 @@ void z_phys_map(uint8_t **virt_ptr, uintptr_t phys, size_t size, uint32_t flags)
|
|||
size_t aligned_size, align_boundary;
|
||||
k_spinlock_key_t key;
|
||||
uint8_t *dest_addr;
|
||||
size_t num_bits;
|
||||
size_t offset;
|
||||
|
||||
#ifndef CONFIG_KERNEL_DIRECT_MAP
|
||||
__ASSERT(!(flags & K_MEM_DIRECT_MAP), "The direct-map is not enabled");
|
||||
#endif
|
||||
addr_offset = k_mem_region_align(&aligned_phys, &aligned_size,
|
||||
phys, size,
|
||||
CONFIG_MMU_PAGE_SIZE);
|
||||
|
|
@ -733,10 +740,23 @@ void z_phys_map(uint8_t **virt_ptr, uintptr_t phys, size_t size, uint32_t flags)
|
|||
align_boundary = arch_virt_region_align(aligned_phys, aligned_size);
|
||||
|
||||
key = k_spin_lock(&z_mm_lock);
|
||||
/* Obtain an appropriately sized chunk of virtual memory */
|
||||
dest_addr = virt_region_alloc(aligned_size, align_boundary);
|
||||
if (!dest_addr) {
|
||||
goto fail;
|
||||
if (flags & K_MEM_DIRECT_MAP) {
|
||||
dest_addr = (uint8_t *)aligned_phys;
|
||||
/* Reserve from the virtual memory space */
|
||||
if (!(dest_addr + aligned_size < Z_VIRT_RAM_START ||
|
||||
dest_addr > Z_VIRT_RAM_END)) {
|
||||
num_bits = aligned_size / CONFIG_MMU_PAGE_SIZE;
|
||||
offset = virt_to_bitmap_offset(dest_addr, aligned_size);
|
||||
if (sys_bitarray_test_and_set_region(
|
||||
&virt_region_bitmap, num_bits, offset, true))
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
/* Obtain an appropriately sized chunk of virtual memory */
|
||||
dest_addr = virt_region_alloc(aligned_size, align_boundary);
|
||||
if (!dest_addr) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* If this fails there's something amiss with virt_region_get */
|
||||
|
|
|
|||
Loading…
Reference in a new issue