diff --git a/arch/risc-v/src/mpfs/Make.defs b/arch/risc-v/src/mpfs/Make.defs index 8e8685998cc..2efe9299a55 100755 --- a/arch/risc-v/src/mpfs/Make.defs +++ b/arch/risc-v/src/mpfs/Make.defs @@ -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 diff --git a/arch/risc-v/src/mpfs/mpfs_mm_init.c b/arch/risc-v/src/mpfs/mpfs_mm_init.c new file mode 100644 index 00000000000..8a35df4b6c0 --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_mm_init.c @@ -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 +#include + +#include +#include +#include + +#include + +#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); +} diff --git a/arch/risc-v/src/mpfs/mpfs_mm_init.h b/arch/risc-v/src/mpfs/mpfs_mm_init.h new file mode 100644 index 00000000000..5fa67f62909 --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_mm_init.h @@ -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 + +#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 */ diff --git a/arch/risc-v/src/mpfs/mpfs_start.c b/arch/risc-v/src/mpfs/mpfs_start.c index 8c318218d9a..cf739534511 100755 --- a/arch/risc-v/src/mpfs/mpfs_start.c +++ b/arch/risc-v/src/mpfs/mpfs_start.c @@ -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(); diff --git a/boards/risc-v/mpfs/icicle/include/board_memorymap.h b/boards/risc-v/mpfs/icicle/include/board_memorymap.h index 6afed97646e..1dc7356e2b8 100644 --- a/boards/risc-v/mpfs/icicle/include/board_memorymap.h +++ b/boards/risc-v/mpfs/icicle/include/board_memorymap.h @@ -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 diff --git a/boards/risc-v/mpfs/icicle/scripts/ld-kernel.script b/boards/risc-v/mpfs/icicle/scripts/ld-kernel.script index ab81ad1bc79..910bc255c13 100755 --- a/boards/risc-v/mpfs/icicle/scripts/ld-kernel.script +++ b/boards/risc-v/mpfs/icicle/scripts/ld-kernel.script @@ -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. */