You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2022/04/28 18:02:25 UTC

[incubator-nuttx] 03/05: RISC-V: Add pgpool to vaddr utility function

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/incubator-nuttx.git

commit 3d8ba496a29f8feee954cc779b489e35d17de758
Author: Ville Juven <vi...@unikie.com>
AuthorDate: Tue Feb 15 15:48:38 2022 +0200

    RISC-V: Add pgpool to vaddr utility function
    
    The only mapping that is supported now is vaddr=paddr, but the function
    DOES check that the address is within the page pool, so it is not
    useless.
---
 arch/risc-v/src/common/pgalloc.h       | 82 ++++++++++++++++++++++++++++++++++
 arch/risc-v/src/common/riscv_addrenv.c | 17 +++----
 arch/risc-v/src/common/riscv_pgalloc.c |  7 +--
 3 files changed, 95 insertions(+), 11 deletions(-)

diff --git a/arch/risc-v/src/common/pgalloc.h b/arch/risc-v/src/common/pgalloc.h
new file mode 100644
index 0000000000..25d94af02d
--- /dev/null
+++ b/arch/risc-v/src/common/pgalloc.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+ * arch/risc-v/src/common/pgalloc.h
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_RISC_V_SRC_COMMON_PGALLOC_H
+#define __ARCH_RISC_V_SRC_COMMON_PGALLOC_H
+
+#ifdef CONFIG_MM_PGALLOC
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <string.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifndef CONFIG_ARCH_PGPOOL_MAPPING
+#  error "RISC-V needs CONFIG_ARCH_PGPOOL_MAPPING"
+#endif
+
+/****************************************************************************
+ * Public Functions Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: riscv_pgvaddr
+ *
+ * Description:
+ *   Get virtual address for pgpool physical address. Note: this function
+ *   is minimalistic and is only usable for kernel mappings and only tests
+ *   if the paddr is in the pgpool. For user mapped addresses this does not
+ *   work.
+ *
+ * Note:
+ *   To get it to work with user addresses, a manual table walk needs to be
+ *   implemented. Not too complex, but not needed for anything -> not
+ *   implemented.
+ *
+ * Input Parameters:
+ *   paddr - Physical pgpool address
+ *
+ * Return:
+ *   vaddr - Virtual address for physical address
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ARCH_PGPOOL_MAPPING
+static inline uintptr_t riscv_pgvaddr(uintptr_t paddr)
+{
+  if (paddr >= CONFIG_ARCH_PGPOOL_PBASE && paddr < CONFIG_ARCH_PGPOOL_PEND)
+    {
+      return paddr - CONFIG_ARCH_PGPOOL_PBASE + CONFIG_ARCH_PGPOOL_VBASE;
+    }
+
+  return 0;
+}
+#endif /* CONFIG_ARCH_PGPOOL_MAPPING */
+
+#endif /* CONFIG_MM_PGALLOC */
+#endif /* __ARCH_RISC_V_SRC_COMMON_PGALLOC_H */
diff --git a/arch/risc-v/src/common/riscv_addrenv.c b/arch/risc-v/src/common/riscv_addrenv.c
index 539c179797..3dacbfb2e7 100644
--- a/arch/risc-v/src/common/riscv_addrenv.c
+++ b/arch/risc-v/src/common/riscv_addrenv.c
@@ -68,6 +68,7 @@
 
 #include <arch/barriers.h>
 
+#include "pgalloc.h"
 #include "riscv_mmu.h"
 
 /****************************************************************************
@@ -111,7 +112,7 @@ extern uintptr_t            g_kernel_mappings;
 
 static inline void wipe_page(uintptr_t paddr)
 {
-  uintptr_t vaddr = paddr;
+  uintptr_t vaddr = riscv_pgvaddr(paddr);
   memset((void *)vaddr, 0, MM_PGSIZE);
 }
 
@@ -133,7 +134,7 @@ static void map_spgtables(group_addrenv_t *addrenv, uintptr_t vaddr)
 
   /* Start from L1, and connect until max level - 1 */
 
-  prev = addrenv->spgtables[0];
+  prev = riscv_pgvaddr(addrenv->spgtables[0]);
 
   /* Check if the mapping already exists */
 
@@ -146,7 +147,7 @@ static void map_spgtables(group_addrenv_t *addrenv, uintptr_t vaddr)
 
   for (i = 0; i < (ARCH_SPGTS - 1); i++)
     {
-      uintptr_t next = addrenv->spgtables[i + 1];
+      uintptr_t next = riscv_pgvaddr(addrenv->spgtables[i + 1]);
       mmu_ln_setentry(i + 1, prev, next, vaddr, MMU_UPGT_FLAGS);
       prev = next;
     }
@@ -211,7 +212,7 @@ static int create_spgtables(group_addrenv_t *addrenv)
 
 static int copy_kernel_mappings(group_addrenv_t *addrenv)
 {
-  uintptr_t user_mappings = addrenv->spgtables[0];
+  uintptr_t user_mappings = riscv_pgvaddr(addrenv->spgtables[0]);
 
   /* Copy the L1 references */
 
@@ -258,7 +259,7 @@ static int create_region(group_addrenv_t *addrenv, uintptr_t vaddr,
 
   nmapped   = 0;
   npages    = MM_NPAGES(size);
-  ptprev    = addrenv->spgtables[ARCH_SPGTS - 1];
+  ptprev    = riscv_pgvaddr(addrenv->spgtables[ARCH_SPGTS - 1]);
   ptlevel   = ARCH_SPGTS;
 
   /* Create mappings for the lower level tables */
@@ -292,7 +293,7 @@ static int create_region(group_addrenv_t *addrenv, uintptr_t vaddr,
           wipe_page(paddr);
         }
 
-      ptlast = paddr;
+      ptlast = riscv_pgvaddr(paddr);
 
       /* Then allocate memory for the region data */
 
@@ -505,12 +506,12 @@ int up_addrenv_destroy(group_addrenv_t *addrenv)
 
   /* First destroy the allocated memory and the final level page table */
 
-  ptprev = (uintptr_t *)addrenv->spgtables[ARCH_SPGTS - 1];
+  ptprev = (uintptr_t *)riscv_pgvaddr(addrenv->spgtables[ARCH_SPGTS - 1]);
   if (ptprev)
     {
       for (i = 0; i < ENTRIES_PER_PGT; i++)
         {
-          ptlast = (uintptr_t *)mmu_pte_to_paddr(ptprev[i]);
+          ptlast = (uintptr_t *)riscv_pgvaddr(mmu_pte_to_paddr(ptprev[i]));
           if (ptlast)
             {
               /* Page table allocated, free any allocated memory */
diff --git a/arch/risc-v/src/common/riscv_pgalloc.c b/arch/risc-v/src/common/riscv_pgalloc.c
index 0542746530..ae78eb5a75 100644
--- a/arch/risc-v/src/common/riscv_pgalloc.c
+++ b/arch/risc-v/src/common/riscv_pgalloc.c
@@ -37,6 +37,7 @@
 
 #include <arch/barriers.h>
 
+#include "pgalloc.h"
 #include "riscv_mmu.h"
 
 #ifdef CONFIG_BUILD_KERNEL
@@ -66,7 +67,7 @@
 
 static inline void wipe_page(uintptr_t paddr)
 {
-  uintptr_t vaddr = paddr;
+  uintptr_t vaddr = riscv_pgvaddr(paddr);
   memset((void *)vaddr, 0, MM_PGSIZE);
 }
 
@@ -88,7 +89,7 @@ static uintptr_t get_pgtable(group_addrenv_t *addrenv, uintptr_t vaddr)
   /* Get the current level MAX_LEVELS-1 entry corresponding to this vaddr */
 
   ptlevel = ARCH_SPGTS;
-  ptprev  = addrenv->spgtables[ARCH_SPGTS - 1];
+  ptprev  = riscv_pgvaddr(addrenv->spgtables[ARCH_SPGTS - 1]);
   paddr   = mmu_pte_to_paddr(mmu_ln_getentry(ptlevel, ptprev, vaddr));
 
   if (!paddr)
@@ -188,7 +189,7 @@ uintptr_t pgalloc(uintptr_t brkaddr, unsigned int npages)
     {
       /* Get the address of the last level page table */
 
-      ptlast = get_pgtable(&group->tg_addrenv, vaddr);
+      ptlast = riscv_pgvaddr(get_pgtable(&group->tg_addrenv, vaddr));
       if (!ptlast)
         {
           return 0;