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.
This commit is contained in:
parent
1322f82802
commit
3d8ba496a2
82
arch/risc-v/src/common/pgalloc.h
Normal file
82
arch/risc-v/src/common/pgalloc.h
Normal file
@ -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 */
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user