diff --git a/include/nuttx/mm/map.h b/include/nuttx/mm/map.h index ac7d0c442e..af52c0ce60 100644 --- a/include/nuttx/mm/map.h +++ b/include/nuttx/mm/map.h @@ -28,6 +28,7 @@ #include #include #include +#include /**************************************************************************** * Forward declarations @@ -73,6 +74,11 @@ struct mm_map_entry_s struct mm_map_s { sq_queue_t mm_map_sq; + +#ifdef CONFIG_ARCH_VMA_MAPPING + GRAN_HANDLE mm_map_vpages; +#endif + rmutex_t mm_map_mutex; }; @@ -120,14 +126,15 @@ void mm_map_unlock(void); * Initialization function, called only by group_initialize * * Input Parameters: - * mm - Pointer to the mm_map structure to be initialized + * mm - Pointer to the mm_map structure to be initialized + * kernel - Indicates whether we are initializing a kernel task * * Returned Value: * None * ****************************************************************************/ -void mm_map_initialize(FAR struct mm_map_s *mm); +void mm_map_initialize(FAR struct mm_map_s *mm, bool kernel); /**************************************************************************** * Name: mm_map_destroy @@ -162,6 +169,46 @@ void mm_map_destroy(FAR struct mm_map_s *mm); * ****************************************************************************/ +#ifdef CONFIG_ARCH_VMA_MAPPING + +/**************************************************************************** + * Name: vm_alloc_region + * + * Description: + * Allocate virtual memory region from the process virtual memory area. + * + * Input Parameters: + * mm - A reference to the process mm_map struct + * vaddr - Virtual start address where the allocation starts, if NULL, will + * seek and return an address that satisfies the 'size' parameter + * size - Size of the area to allocate + * + * Returned Value: + * Pointer to reserved vaddr, or NULL if out-of-memory + * + ****************************************************************************/ + +FAR void *vm_alloc_region(FAR struct mm_map_s *mm, FAR void *vaddr, + size_t size); + +/**************************************************************************** + * Name: vm_release_region + * + * Description: + * Free a previously allocated virtual memory region + * + * Input Parameters: + * mm - A reference to the process' mm_map struct + * vaddr - Virtual start address where the allocation starts. + * size - Size of the allocated area. + * + ****************************************************************************/ + +void vm_release_region(FAR struct mm_map_s *mm, FAR void *vaddr, + size_t size); + +#endif + int mm_map_add(FAR struct mm_map_entry_s *entry); /**************************************************************************** diff --git a/mm/map/Make.defs b/mm/map/Make.defs index 1d1f602d2b..9a58507b27 100644 --- a/mm/map/Make.defs +++ b/mm/map/Make.defs @@ -22,6 +22,10 @@ CSRCS += mm_map.c +ifeq ($(CONFIG_ARCH_VMA_MAPPING),y) +CSRCS += vm_region.c +endif + # Add the shared memory directory to the build DEPPATH += --dep-path map diff --git a/mm/map/mm_map.c b/mm/map/mm_map.c index 22126bb4b7..1996184e2f 100644 --- a/mm/map/mm_map.c +++ b/mm/map/mm_map.c @@ -23,6 +23,8 @@ ****************************************************************************/ #include +#include +#include #include #include #include @@ -87,10 +89,29 @@ void mm_map_unlock(void) * ****************************************************************************/ -void mm_map_initialize(FAR struct mm_map_s *mm) +void mm_map_initialize(FAR struct mm_map_s *mm, bool kernel) { sq_init(&mm->mm_map_sq); nxrmutex_init(&mm->mm_map_mutex); + + /* Create the virtual pages allocator for user process */ + +#ifdef CONFIG_ARCH_VMA_MAPPING + if (!kernel) + { + mm->mm_map_vpages = gran_initialize((FAR void *)CONFIG_ARCH_SHM_VBASE, + ARCH_SHM_MAXPAGES << MM_PGSHIFT, + MM_PGSHIFT, MM_PGSHIFT); + if (!mm->mm_map_vpages) + { + merr("gran_initialize() failed\n"); + } + } + else + { + mm->mm_map_vpages = NULL; + } +#endif } /**************************************************************************** @@ -131,6 +152,15 @@ void mm_map_destroy(FAR struct mm_map_s *mm) } nxrmutex_destroy(&mm->mm_map_mutex); + + /* Release the virtual pages allocator */ + +#ifdef CONFIG_ARCH_VMA_MAPPING + if (mm->mm_map_vpages) + { + gran_release(mm->mm_map_vpages); + } +#endif } /**************************************************************************** diff --git a/mm/map/vm_region.c b/mm/map/vm_region.c new file mode 100644 index 0000000000..765f62bcbc --- /dev/null +++ b/mm/map/vm_region.c @@ -0,0 +1,94 @@ +/**************************************************************************** + * mm/map/vm_region.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 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: vm_alloc_region + * + * Description: + * Allocate virtual memory region from the process virtual memory area. + * + * Input Parameters: + * mm - A reference to the process mm_map struct + * vaddr - Virtual start address where the allocation starts, if NULL, will + * seek and return an address that satisfies the 'size' parameter + * size - Size of the area to allocate + * + * Returned Value: + * Pointer to reserved vaddr, or NULL if out-of-memory + * + ****************************************************************************/ + +FAR void *vm_alloc_region(FAR struct mm_map_s *mm, FAR void *vaddr, + size_t size) +{ + FAR void *ret = NULL; + + DEBUGASSERT(mm != NULL); + + if (mm->mm_map_vpages != NULL) + { + if (vaddr == NULL) + { + ret = gran_alloc(mm->mm_map_vpages, size); + } + else + { + ret = gran_reserve(mm->mm_map_vpages, (uintptr_t)vaddr, + size); + } + } + + return ret; +} + +/**************************************************************************** + * Name: vm_release_region + * + * Description: + * Free a previously allocated virtual memory region + * + * Input Parameters: + * mm - A reference to the process' mm_map struct + * vaddr - Virtual start address where the allocation starts. + * size - Size of the allocated area. + * + ****************************************************************************/ + +void vm_release_region(FAR struct mm_map_s *mm, FAR void *vaddr, size_t size) +{ + DEBUGASSERT(mm != NULL); + + if (mm->mm_map_vpages != NULL) + { + gran_free(mm->mm_map_vpages, vaddr, size); + } +} diff --git a/sched/group/group_create.c b/sched/group/group_create.c index 404f13e5af..9a35f82788 100644 --- a/sched/group/group_create.c +++ b/sched/group/group_create.c @@ -240,7 +240,8 @@ void group_initialize(FAR struct task_tcb_s *tcb) /* Allocate mm_map list if required */ - mm_map_initialize(&group->tg_mm_map); + mm_map_initialize(&group->tg_mm_map, + (tcb->cmn.flags & TCB_FLAG_TTYPE_KERNEL) != 0); #ifdef HAVE_GROUP_MEMBERS /* Assign the PID of this new task as a member of the group. */