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 */