MPFS: Add kernel space mappings

Mappings are done with vaddr=paddr.
- I/O space mapped with two gigapages
- Kernel space mapped to statically allocated page tables. 2MB of kernel
  memory is supported.
- Page pool is mapped to the kernel space, to allow virtual memory access
  for the kernel e.g. to initialize the page memory when it is allocated.
This commit is contained in:
Ville Juven
2022-03-17 11:21:09 +02:00
committed by Xiang Xiao
parent 2287ebcbcf
commit 31b916c485
6 changed files with 247 additions and 3 deletions
+4
View File
@@ -77,6 +77,10 @@ CHIP_CSRCS += mpfs_userspace.c
CMN_UASRCS += riscv_signal_handler.S
endif
ifeq ($(CONFIG_BUILD_KERNEL),y)
CHIP_CSRCS += mpfs_mm_init.c
endif
ifneq ($(CONFIG_BUILD_FLAT),y)
CMN_CSRCS += riscv_task_start.c
CMN_CSRCS += riscv_pthread_start.c
+144
View File
@@ -0,0 +1,144 @@
/****************************************************************************
* arch/risc-v/src/mpfs/mpfs_mm_init.c
*
* 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/arch.h>
#include <stdint.h>
#include <assert.h>
#include <debug.h>
#include <arch/board/board_memorymap.h>
#include "mpfs_memorymap.h"
#include "riscv_internal.h"
#include "riscv_mmu.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Map the whole I/O memory with vaddr = paddr mappings */
#define MMU_IO_BASE (0x00000000)
#define MMU_IO_SIZE (0x80000000)
/* Physical and virtual addresses to page tables (vaddr = paddr mapping) */
#define PGT_L1_PBASE (uintptr_t)&m_l1_pgtable
#define PGT_L2_PBASE (uintptr_t)&m_l2_pgtable
#define PGT_L3_PBASE (uintptr_t)&m_l3_pgtable
#define PGT_L1_VBASE PGT_L1_PBASE
#define PGT_L2_VBASE PGT_L2_PBASE
#define PGT_L3_VBASE PGT_L3_PBASE
#define PGT_L1_SIZE (512) /* Enough to map 512 GiB */
#define PGT_L2_SIZE (512) /* Enough to map 1 GiB */
#define PGT_L3_SIZE (1024) /* Enough to map 4 MiB */
/****************************************************************************
* Private Data
****************************************************************************/
/* Kernel mappings simply here, mapping is vaddr=paddr */
static uint64_t m_l1_pgtable[PGT_L1_SIZE] locate_data(".pgtables");
static uint64_t m_l2_pgtable[PGT_L2_SIZE] locate_data(".pgtables");
static uint64_t m_l3_pgtable[PGT_L3_SIZE] locate_data(".pgtables");
/* Kernel mappings (L1 base) */
uintptr_t g_kernel_mappings = PGT_L1_VBASE;
uintptr_t g_kernel_pgt_pbase = PGT_L1_PBASE;
/****************************************************************************
* Private Functions
****************************************************************************/
static void map_region(uintptr_t paddr, uintptr_t vaddr, size_t size,
uint32_t mmuflags)
{
uintptr_t l3base;
uintptr_t end_vaddr;
/* Start index for the L3 table, kernel flash is always first */
l3base = PGT_L3_PBASE + ((paddr - KFLASH_START) / RV_MMU_PAGE_ENTRIES);
/* Map the region to the L3 table as a whole */
mmu_ln_map_region(3, l3base, paddr, vaddr, size, mmuflags);
/* Connect to L2 table */
end_vaddr = vaddr + size;
while (vaddr < end_vaddr)
{
mmu_ln_setentry(2, PGT_L2_VBASE, l3base, vaddr, PTE_G);
l3base += RV_MMU_L3_PAGE_SIZE;
vaddr += RV_MMU_L2_PAGE_SIZE;
}
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: mpfs_kernel_mappings
*
* Description:
* Setup kernel mappings when usinc CONFIG_BUILD_KERNEL. Sets up the kernel
* MMU mappings.
*
****************************************************************************/
void mpfs_kernel_mappings(void)
{
/* Begin mapping memory to MMU; note that at this point the MMU is not yet
* active, so the page table virtual addresses are actually physical
* addresses and so forth. M-mode does not perform translations anyhow, so
* this mapping is quite simple to do
*/
/* Map I/O region, use 2 gigapages for this */
mmu_ln_map_region(1, PGT_L1_VBASE, MMU_IO_BASE, MMU_IO_BASE,
MMU_IO_SIZE, MMU_IO_FLAGS);
/* Map the kernel text and data */
map_region(KFLASH_START, KFLASH_START, KFLASH_SIZE, MMU_KTEXT_FLAGS);
map_region(KSRAM_START, KSRAM_START, KSRAM_SIZE, MMU_KDATA_FLAGS);
/* Connect the L1 and L2 page tables */
mmu_ln_setentry(1, PGT_L1_VBASE, PGT_L2_PBASE, KFLASH_START, PTE_G);
/* Map the page pool */
mmu_ln_map_region(2, PGT_L2_VBASE, PGPOOL_START, PGPOOL_START, PGPOOL_SIZE,
MMU_KDATA_FLAGS);
}
+81
View File
@@ -0,0 +1,81 @@
/****************************************************************************
* arch/risc-v/src/mpfs/mpfs_mm_init.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_MPFS_MPFS_MM_INIT_H
#define __ARCH_RISC_V_SRC_MPFS_MPFS_MM_INIT_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include "riscv_mmu.h"
/****************************************************************************
* Public Data
****************************************************************************/
extern uintptr_t g_kernel_pgt_pbase;
/****************************************************************************
* Public Functions Prototypes
****************************************************************************/
/****************************************************************************
* Name: mpfs_kernel_mappings
*
* Description:
* Setup kernel mappings when using CONFIG_BUILD_KERNEL. Sets up the kernel
* MMU mappings.
*
****************************************************************************/
#ifdef CONFIG_BUILD_KERNEL
void mpfs_kernel_mappings(void);
#endif
/****************************************************************************
* Name: mpfs_mm_init
*
* Description:
* Setup kernel mappings when using CONFIG_BUILD_KERNEL. Sets up kernel MMU
* mappings. Function also sets the first address environment (satp value).
*
****************************************************************************/
#ifdef CONFIG_BUILD_KERNEL
static inline void mpfs_mm_init(void)
{
/* Setup the kernel mappings */
mpfs_kernel_mappings();
/* Allow satp writes from S-mode */
CLEAR_CSR(mstatus, MSTATUS_TVM);
/* Enable MMU (note: system is still in M-mode) */
mmu_enable(g_kernel_pgt_pbase, 0);
}
#endif
#endif /* __ARCH_RISC_V_SRC_MPFS_MPFS_MM_INIT_H */
+5
View File
@@ -33,6 +33,7 @@
#include "mpfs_clockconfig.h"
#include "mpfs_ddr.h"
#include "mpfs_cache.h"
#include "mpfs_mm_init.h"
#include "mpfs_userspace.h"
#include "riscv_internal.h"
@@ -209,6 +210,10 @@ void __mpfs_start(uint64_t mhartid)
showprogress('D');
#endif
#ifdef CONFIG_BUILD_KERNEL
mpfs_mm_init();
#endif
/* Call nx_start() */
nx_start();
@@ -31,6 +31,11 @@
* Pre-processor Definitions
****************************************************************************/
/* DDR start address */
#define MPFS_DDR_BASE (0x80000000)
#define MPFS_DDR_SIZE (0x40000000)
/* Kernel code memory (RX) */
#define KFLASH_START (uintptr_t)&__kflash_start
@@ -1,5 +1,5 @@
/****************************************************************************
* boards/risc-v/mpfs/icicle/scripts/ld.script
* boards/risc-v/mpfs/icicle/scripts/ld-kernel.script
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -93,15 +93,20 @@ SECTIONS
*(.gnu.linkonce.b.*)
*(.gnu.linkonce.sb.*)
*(COMMON)
} > ksram
/* Page tables here, align to 4K boundary */
.pgtables : ALIGN(0x1000) {
*(.pgtables)
. = ALIGN(4);
_ebss = ABSOLUTE(.);
} > ksram
/* Stack top */
.stack_top : {
. = ALIGN(32);
_default_stack_limit = ABSOLUTE(.);
_ebss = ABSOLUTE(.);
} > ksram
/* Stabs debugging sections. */