diff --git a/arch/Kconfig b/arch/Kconfig index 11779a77f6..d244bee629 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -769,27 +769,17 @@ config ARCH_SHM_MAXREGIONS int "Max shared memory regions" default 1 ---help--- - The maximum number of regions that can allocated for the shared - memory space. This hard-coded value permits static allocation of + The maximum number of regions that can be used with SysV shared + memory interface. This hard-coded value permits static allocation of the shared memory data structures and serves no other purpose. Default is 1. - The size of the virtual shared memory address space is then - determined by the product of the maximum number of regions, the - maximum number of pages per region, and the configured size of - each page. - config ARCH_SHM_NPAGES - int "Max shared memory pages" + int "Max size of userspace VM mapping in pages" default 1 ---help--- - The maximum number of pages that can allocated per region for the shared memory - region. Default is 1. - - The size of the virtual shared memory address space is then - determined by the product of the maximum number of regions, the - maximum number of pages per region, and the configured size of - each page. + The max size of the virtual memory region for shared memory, + userspace device mappings etc. endif # ARCH_VMA_MAPPING diff --git a/include/nuttx/addrenv.h b/include/nuttx/addrenv.h index d8f0d7d462..686723255e 100644 --- a/include/nuttx/addrenv.h +++ b/include/nuttx/addrenv.h @@ -190,9 +190,7 @@ # define CONFIG_ARCH_SHM_NPAGES 1 # endif -# define ARCH_SHM_MAXPAGES (CONFIG_ARCH_SHM_NPAGES * CONFIG_ARCH_SHM_MAXREGIONS) -# define ARCH_SHM_REGIONSIZE (CONFIG_ARCH_SHM_NPAGES * CONFIG_MM_PGSIZE) -# define ARCH_SHM_SIZE (CONFIG_ARCH_SHM_MAXREGIONS * ARCH_SHM_REGIONSIZE) +# define ARCH_SHM_SIZE (CONFIG_ARCH_SHM_NPAGES * CONFIG_MM_PGSIZE) # define ARCH_SHM_VEND (CONFIG_ARCH_SHM_VBASE + ARCH_SHM_SIZE - 1) # define ARCH_SCRATCH_VBASE ARCH_SHM_VEND diff --git a/include/nuttx/mm/map.h b/include/nuttx/mm/map.h index 3879056eb3..ffcac4f98e 100644 --- a/include/nuttx/mm/map.h +++ b/include/nuttx/mm/map.h @@ -193,6 +193,45 @@ void vm_release_region(FAR struct mm_map_s *mm, FAR void *vaddr, #endif +#ifdef CONFIG_ARCH_VMA_MAPPING + +/**************************************************************************** + * Name: vm_map_region + * + * Description: + * Allocate virtual memory and maps given physical memory into user space + * of the current process. + * + * Input Parameters: + * paddr - Starting physical address + * size - Size of the address range + * + * Returned Value: + * Virtual address if success, or NULL if error + * + ****************************************************************************/ + +FAR void *vm_map_region(uintptr_t paddr, size_t size); + +/**************************************************************************** + * Name: vm_unmap_region + * + * Description: + * Unmap previously mapped userspace device and release the virtual memory. + * + * Input Parameters: + * vaddr - Starting virtual address of the mapped device + * size - Size of the address range + * + * Returned Value: + * OK for success or negative value for error + * + ****************************************************************************/ + +int vm_unmap_region(FAR void *vaddr, size_t size); + +#endif /* CONFIG_ARCH_VMA_MAPPING */ + /**************************************************************************** * Name: mm_map_add * diff --git a/mm/Kconfig b/mm/Kconfig index 1026b32ce6..ab67ee2dfd 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -191,8 +191,9 @@ config MM_SHM depends on MM_PGALLOC && BUILD_KERNEL select ARCH_VMA_MAPPING ---help--- - Build in support for the shared memory interfaces shmget(), shmat(), - shmctl(), and shmdt(). + Build support for mapping physical memory to user-space via + shared memory interfaces like shmget(), shmat(), shmctl(), + etc, or device mapping interfaces like vm_map_region() etc. config MM_KMAP bool "Support for dynamic kernel virtual mappings" diff --git a/mm/map/mm_map.c b/mm/map/mm_map.c index 6c0261ba1a..0756c00d22 100644 --- a/mm/map/mm_map.c +++ b/mm/map/mm_map.c @@ -117,8 +117,7 @@ void mm_map_initialize(FAR struct mm_map_s *mm, bool kernel) if (!kernel) { mm->mm_map_vpages = gran_initialize((FAR void *)CONFIG_ARCH_SHM_VBASE, - ARCH_SHM_MAXPAGES << MM_PGSHIFT, - MM_PGSHIFT, MM_PGSHIFT); + ARCH_SHM_SIZE, MM_PGSHIFT, MM_PGSHIFT); if (!mm->mm_map_vpages) { merr("gran_initialize() failed\n"); diff --git a/mm/map/vm_map.c b/mm/map/vm_map.c new file mode 100644 index 0000000000..ea50ab805f --- /dev/null +++ b/mm/map/vm_map.c @@ -0,0 +1,91 @@ +/**************************************************************************** + * mm/map/vm_map.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef CONFIG_ARCH_VMA_MAPPING + +/* map physical region to userspace */ + +FAR void *vm_map_region(uintptr_t paddr, size_t size) +{ + FAR void *vaddr; + uintptr_t tvaddr; + uint i = 0; + int ret = OK; + size_t npages = MM_NPAGES(size); + + DEBUGASSERT(npages > 0); + DEBUGASSERT(MM_ISALIGNED(paddr)); + + vaddr = vm_alloc_region(get_current_mm(), 0, size); + if (vaddr) + { + tvaddr = (uintptr_t)vaddr; + for (; i < npages; i++, tvaddr += MM_PGSIZE, paddr += MM_PGSIZE) + { + ret = up_shmat(&paddr, 1, tvaddr); + if (ret) + { + goto errorout; + } + } + } + + return vaddr; + +errorout: + if (i) /* undo mapped pages */ + { + up_shmdt((uintptr_t)vaddr, i); + } + + vm_release_region(get_current_mm(), vaddr, size); + return 0; +} + +/* unmap userspace device pointer */ + +int vm_unmap_region(FAR void *vaddr, size_t size) +{ + size_t npages = MM_NPAGES(size); + int ret; + + DEBUGASSERT(MM_ISALIGNED(vaddr)); + DEBUGASSERT(npages); + ret = up_shmdt((uintptr_t)vaddr, npages); + vm_release_region(get_current_mm(), vaddr, size); + return ret; +} + +#endif /* CONFIG_ARCH_VMA_MAPPING */