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;