This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new aee45c9c43 riscv/addrenv: Create utility function for dynamic mappings
aee45c9c43 is described below

commit aee45c9c43186cad56727fb01323bf58797996f8
Author: Ville Juven <[email protected]>
AuthorDate: Thu May 11 11:08:36 2023 +0300

    riscv/addrenv: Create utility function for dynamic mappings
    
    Move the mapping functionality from up_shmat/shmdt into two generic
    mapping functions. This makes it possible to do other mappings besides
    user shared memory area mappings.
---
 arch/risc-v/src/common/addrenv.h             |  45 +++++++++++
 arch/risc-v/src/common/riscv_addrenv_shm.c   |  78 ++----------------
 arch/risc-v/src/common/riscv_addrenv_utils.c | 117 +++++++++++++++++++++++++++
 3 files changed, 170 insertions(+), 70 deletions(-)

diff --git a/arch/risc-v/src/common/addrenv.h b/arch/risc-v/src/common/addrenv.h
index e21bb72460..051d04758f 100644
--- a/arch/risc-v/src/common/addrenv.h
+++ b/arch/risc-v/src/common/addrenv.h
@@ -67,5 +67,50 @@
 
 uintptr_t riscv_get_pgtable(arch_addrenv_t *addrenv, uintptr_t vaddr);
 
+/****************************************************************************
+ * Name: riscv_map_pages
+ *
+ * Description:
+ *   Map physical pages into a continuous virtual memory block.
+ *
+ * Input Parameters:
+ *   addrenv - Pointer to a structure describing the address environment.
+ *   pages - A pointer to the first element in a array of physical address,
+ *     each corresponding to one page of memory.
+ *   npages - The number of pages in the list of physical pages to be mapped.
+ *   vaddr - The virtual address corresponding to the beginning of the
+ *     (continuous) virtual address region.
+ *   prot - MMU flags to use.
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success; a negated errno value is returned
+ *   on failure.
+ *
+ ****************************************************************************/
+
+int riscv_map_pages(arch_addrenv_t *addrenv, uintptr_t *pages,
+                    unsigned int npages, uintptr_t vaddr, int prot);
+
+/****************************************************************************
+ * Name: riscv_unmap_pages
+ *
+ * Description:
+ *   Unmap a previously mapped virtual memory region.
+ *
+ * Input Parameters:
+ *   addrenv - Pointer to a structure describing the address environment.
+ *   vaddr - The virtual address corresponding to the beginning of the
+ *     (continuous) virtual address region.
+ *   npages - The number of pages to be unmapped
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success; a negated errno value is returned
+ *   on failure.
+ *
+ ****************************************************************************/
+
+int riscv_unmap_pages(arch_addrenv_t *addrenv, uintptr_t vaddr,
+                      unsigned int npages);
+
 #endif /* CONFIG_ARCH_ADDRENV */
 #endif /* __ARCH_RISC_V_SRC_COMMON_ADDRENV_H */
diff --git a/arch/risc-v/src/common/riscv_addrenv_shm.c 
b/arch/risc-v/src/common/riscv_addrenv_shm.c
index 0183537db2..bd53a5eb05 100644
--- a/arch/risc-v/src/common/riscv_addrenv_shm.c
+++ b/arch/risc-v/src/common/riscv_addrenv_shm.c
@@ -66,11 +66,8 @@
 
 int up_shmat(uintptr_t *pages, unsigned int npages, uintptr_t vaddr)
 {
-  struct tcb_s          *tcb = nxsched_self();
-  struct arch_addrenv_s *addrenv;
-  uintptr_t              ptlast;
-  uintptr_t              ptlevel;
-  uintptr_t              paddr;
+  struct tcb_s          *tcb     = nxsched_self();
+  struct arch_addrenv_s *addrenv = &tcb->addrenv_own->addrenv;
 
   /* Sanity checks */
 
@@ -79,33 +76,9 @@ int up_shmat(uintptr_t *pages, unsigned int npages, 
uintptr_t vaddr)
   DEBUGASSERT(vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr < ARCH_SHM_VEND);
   DEBUGASSERT(MM_ISALIGNED(vaddr));
 
-  addrenv = &tcb->addrenv_own->addrenv;
-  ptlevel =  RV_MMU_PT_LEVELS;
+  /* Let riscv_map_pages do the work */
 
-  /* Add the references to pages[] into the caller's address environment */
-
-  for (; npages > 0; npages--)
-    {
-      /* Get the address of the last level page table */
-
-      ptlast = riscv_pgvaddr(riscv_get_pgtable(addrenv, vaddr));
-      if (!ptlast)
-        {
-          return -ENOMEM;
-        }
-
-      /* Then add the reference */
-
-      paddr = *pages++;
-      mmu_ln_setentry(ptlevel, ptlast, paddr, vaddr, MMU_UDATA_FLAGS);
-      vaddr += MM_PGSIZE;
-    }
-
-  /* Flush the data cache, so the changes are committed to memory */
-
-  __DMB();
-
-  return OK;
+  return riscv_map_pages(addrenv, pages, npages, vaddr, MMU_UDATA_FLAGS);
 }
 
 /****************************************************************************
@@ -127,12 +100,8 @@ int up_shmat(uintptr_t *pages, unsigned int npages, 
uintptr_t vaddr)
 
 int up_shmdt(uintptr_t vaddr, unsigned int npages)
 {
-  struct tcb_s          *tcb = nxsched_self();
-  struct arch_addrenv_s *addrenv;
-  uintptr_t              ptlast;
-  uintptr_t              ptprev;
-  uintptr_t              ptlevel;
-  uintptr_t              paddr;
+  struct tcb_s          *tcb     = nxsched_self();
+  struct arch_addrenv_s *addrenv = &tcb->addrenv_own->addrenv;
 
   /* Sanity checks */
 
@@ -141,40 +110,9 @@ int up_shmdt(uintptr_t vaddr, unsigned int npages)
   DEBUGASSERT(vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr < ARCH_SHM_VEND);
   DEBUGASSERT(MM_ISALIGNED(vaddr));
 
-  addrenv = &tcb->addrenv_own->addrenv;
-  ptlevel =  ARCH_SPGTS;
-  ptprev  =  riscv_pgvaddr(addrenv->spgtables[ARCH_SPGTS - 1]);
-  if (!ptprev)
-    {
-      /* Something is very wrong */
-
-      return -EFAULT;
-    }
-
-  /* Remove the references from the caller's address environment */
-
-  for (; npages > 0; npages--)
-    {
-      /* Get the current final level entry corresponding to this vaddr */
-
-      paddr = mmu_pte_to_paddr(mmu_ln_getentry(ptlevel, ptprev, vaddr));
-      ptlast = riscv_pgvaddr(paddr);
-      if (!ptlast)
-        {
-          return -EFAULT;
-        }
-
-      /* Then wipe the reference */
-
-      mmu_ln_clear(ptlevel + 1, ptlast, vaddr);
-      vaddr += MM_PGSIZE;
-    }
-
-  /* Flush the data cache, so the changes are committed to memory */
-
-  __DMB();
+  /* Let riscv_unmap_pages do the work */
 
-  return OK;
+  return riscv_unmap_pages(addrenv, vaddr, npages);
 }
 
 #endif /* CONFIG_BUILD_KERNEL */
diff --git a/arch/risc-v/src/common/riscv_addrenv_utils.c 
b/arch/risc-v/src/common/riscv_addrenv_utils.c
index 0010368047..810563aedd 100644
--- a/arch/risc-v/src/common/riscv_addrenv_utils.c
+++ b/arch/risc-v/src/common/riscv_addrenv_utils.c
@@ -91,4 +91,121 @@ uintptr_t riscv_get_pgtable(arch_addrenv_t *addrenv, 
uintptr_t vaddr)
   return paddr;
 }
 
+/****************************************************************************
+ * Name: riscv_map_pages
+ *
+ * Description:
+ *   Map physical pages into a continuous virtual memory block.
+ *
+ * Input Parameters:
+ *   addrenv - Pointer to a structure describing the address environment.
+ *   pages - A pointer to the first element in a array of physical address,
+ *     each corresponding to one page of memory.
+ *   npages - The number of pages in the list of physical pages to be mapped.
+ *   vaddr - The virtual address corresponding to the beginning of the
+ *     (continuous) virtual address region.
+ *   prot - MMU flags to use.
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success; a negated errno value is returned
+ *   on failure.
+ *
+ ****************************************************************************/
+
+int riscv_map_pages(arch_addrenv_t *addrenv, uintptr_t *pages,
+                    unsigned int npages, uintptr_t vaddr, int prot)
+{
+  uintptr_t ptlast;
+  uintptr_t ptlevel;
+  uintptr_t paddr;
+
+  ptlevel =  RV_MMU_PT_LEVELS;
+
+  /* Add the references to pages[] into the caller's address environment */
+
+  for (; npages > 0; npages--)
+    {
+      /* Get the address of the last level page table */
+
+      ptlast = riscv_pgvaddr(riscv_get_pgtable(addrenv, vaddr));
+      if (!ptlast)
+        {
+          return -ENOMEM;
+        }
+
+      /* Then add the reference */
+
+      paddr = *pages++;
+      mmu_ln_setentry(ptlevel, ptlast, paddr, vaddr, prot);
+      vaddr += MM_PGSIZE;
+    }
+
+  /* Flush the data cache, so the changes are committed to memory */
+
+  __DMB();
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: riscv_unmap_pages
+ *
+ * Description:
+ *   Unmap a previously mapped virtual memory region.
+ *
+ * Input Parameters:
+ *   addrenv - Pointer to a structure describing the address environment.
+ *   vaddr - The virtual address corresponding to the beginning of the
+ *     (continuous) virtual address region.
+ *   npages - The number of pages to be unmapped
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success; a negated errno value is returned
+ *   on failure.
+ *
+ ****************************************************************************/
+
+int riscv_unmap_pages(arch_addrenv_t *addrenv, uintptr_t vaddr,
+                      unsigned int npages)
+{
+  uintptr_t ptlast;
+  uintptr_t ptprev;
+  uintptr_t ptlevel;
+  uintptr_t paddr;
+
+  ptlevel =  ARCH_SPGTS;
+  ptprev  =  riscv_pgvaddr(addrenv->spgtables[ARCH_SPGTS - 1]);
+  if (!ptprev)
+    {
+      /* Something is very wrong */
+
+      return -EFAULT;
+    }
+
+  /* Remove the references from the caller's address environment */
+
+  for (; npages > 0; npages--)
+    {
+      /* Get the current final level entry corresponding to this vaddr */
+
+      paddr = mmu_pte_to_paddr(mmu_ln_getentry(ptlevel, ptprev, vaddr));
+      ptlast = riscv_pgvaddr(paddr);
+      if (!ptlast)
+        {
+          return -EFAULT;
+        }
+
+      /* Then wipe the reference */
+
+      mmu_ln_clear(ptlevel + 1, ptlast, vaddr);
+      vaddr += MM_PGSIZE;
+    }
+
+  /* Flush the data cache, so the changes are committed to memory */
+
+  __DMB();
+
+  return OK;
+}
+
 #endif /* CONFIG_BUILD_KERNEL */

Reply via email to