risc-v: SV32 MMU support for qemu-rv.

This commit is contained in:
Stuart Ianna 2023-03-27 10:01:47 +11:00 committed by Masayuki Ishikawa
parent 536739d2da
commit 01b0305ab5
11 changed files with 390 additions and 57 deletions

View File

@ -166,6 +166,7 @@ config ARCH_CHIP_QEMU_RV
select ARCH_HAVE_MPU select ARCH_HAVE_MPU
select ARCH_HAVE_MMU select ARCH_HAVE_MMU
select ARCH_MMU_TYPE_SV39 if ARCH_CHIP_QEMU_RV64 select ARCH_MMU_TYPE_SV39 if ARCH_CHIP_QEMU_RV64
select ARCH_MMU_TYPE_SV32 if ARCH_CHIP_QEMU_RV32
select ARCH_HAVE_ADDRENV select ARCH_HAVE_ADDRENV
select ARCH_NEED_ADDRENV_MAPPING select ARCH_NEED_ADDRENV_MAPPING
select ARCH_HAVE_S_MODE select ARCH_HAVE_S_MODE
@ -255,6 +256,10 @@ config ARCH_MMU_TYPE_SV39
bool bool
default n default n
config ARCH_MMU_TYPE_SV32
bool
default n
config ARCH_HAVE_S_MODE config ARCH_HAVE_S_MODE
bool bool
default n default n

View File

@ -44,6 +44,8 @@
#ifdef CONFIG_ARCH_MMU_TYPE_SV39 #ifdef CONFIG_ARCH_MMU_TYPE_SV39
# define ARCH_PGT_MAX_LEVELS (3) # define ARCH_PGT_MAX_LEVELS (3)
#elif CONFIG_ARCH_MMU_TYPE_SV32
# define ARCH_PGT_MAX_LEVELS (2)
#endif #endif
/* Amount of static page tables allocated for an address environment */ /* Amount of static page tables allocated for an address environment */

View File

@ -48,6 +48,11 @@ static const size_t g_pgt_sizes[] =
{ {
RV_MMU_L1_PAGE_SIZE, RV_MMU_L2_PAGE_SIZE, RV_MMU_L3_PAGE_SIZE RV_MMU_L1_PAGE_SIZE, RV_MMU_L2_PAGE_SIZE, RV_MMU_L3_PAGE_SIZE
}; };
#elif CONFIG_ARCH_MMU_TYPE_SV32
static const size_t g_pgt_sizes[] =
{
RV_MMU_L1_PAGE_SIZE, RV_MMU_L2_PAGE_SIZE
};
#endif #endif
/**************************************************************************** /****************************************************************************

View File

@ -31,27 +31,6 @@
#define RV_MMU_PAGE_ENTRIES (RV_MMU_PAGE_SIZE / sizeof(uintptr_t)) #define RV_MMU_PAGE_ENTRIES (RV_MMU_PAGE_SIZE / sizeof(uintptr_t))
/* Supervisor Address Translation and Protection (satp) */
#define SATP_PPN_SHIFT (0)
#define SATP_PPN_MASK (((1ul << 44) - 1) << SATP_PPN_SHIFT)
#define SATP_ASID_SHIFT (44)
#define SATP_ASID_MASK (((1ul << 16) - 1) << SATP_ASID_SHIFT)
#define SATP_MODE_SHIFT (60)
#define SATP_MODE_MASK (((1ul << 4) - 1) << SATP_MODE_SHIFT)
/* Modes, for RV32 only 1 is valid, for RV64 1-7 and 10-15 are reserved */
#define SATP_MODE_BARE (0ul)
#define SATP_MODE_SV32 (1ul)
#define SATP_MODE_SV39 (8ul)
#define SATP_MODE_SV48 (9ul)
/* satp address to PPN translation */
#define SATP_ADDR_TO_PPN(_addr) ((_addr) >> RV_MMU_PAGE_SHIFT)
#define SATP_PPN_TO_ADDR(_ppn) ((_ppn) << RV_MMU_PAGE_SHIFT)
/* Common Page Table Entry (PTE) bits */ /* Common Page Table Entry (PTE) bits */
#define PTE_VALID (1 << 0) /* PTE is valid */ #define PTE_VALID (1 << 0) /* PTE is valid */
@ -85,24 +64,32 @@
#define MMU_KTEXT_FLAGS (PTE_R | PTE_X | PTE_G) #define MMU_KTEXT_FLAGS (PTE_R | PTE_X | PTE_G)
#define MMU_KDATA_FLAGS (PTE_R | PTE_W | PTE_G) #define MMU_KDATA_FLAGS (PTE_R | PTE_W | PTE_G)
/* SvX definitions, only Sv39 is currently supported, but it should be /* Modes, for RV32 only 1 is valid, for RV64 1-7 and 10-15 are reserved */
* trivial to extend the driver to support other SvX implementations
* #define SATP_MODE_BARE (0ul)
* Sv39 has: #define SATP_MODE_SV32 (1ul)
#define SATP_MODE_SV39 (8ul)
#define SATP_MODE_SV48 (9ul)
#if CONFIG_ARCH_HAVE_MMU
#define RV_MMU_PTE_PADDR_SHIFT (10)
#define RV_MMU_PTE_PPN_SHIFT (2)
#define RV_MMU_VADDR_SHIFT(_n) (RV_MMU_PAGE_SHIFT + RV_MMU_VPN_WIDTH * \
(RV_MMU_PT_LEVELS - (_n)))
/* Sv39 has:
* - 4K page size * - 4K page size
* - 3 page table levels * - 3 page table levels
* - 9-bit VPN width * - 9-bit VPN width
*/ */
#ifdef CONFIG_ARCH_MMU_TYPE_SV39 #ifdef CONFIG_ARCH_MMU_TYPE_SV39
#define RV_MMU_PTE_PADDR_SHIFT (10) #define RV_MMU_PPN_WIDTH 44
#define RV_MMU_PTE_PPN_MASK (((1ul << 44) - 1) << RV_MMU_PTE_PADDR_SHIFT) #define RV_MMU_ASID_WIDTH 16
#define RV_MMU_PTE_PPN_SHIFT (2) #define RV_MMU_MODE_WIDTH 4
#define RV_MMU_PTE_PPN_MASK (((1ul << RV_MMU_PPN_WIDTH) - 1) << RV_MMU_PTE_PADDR_SHIFT)
#define RV_MMU_VPN_WIDTH (9) #define RV_MMU_VPN_WIDTH (9)
#define RV_MMU_VPN_MASK ((1ul << RV_MMU_VPN_WIDTH) - 1) #define RV_MMU_VPN_MASK ((1ul << RV_MMU_VPN_WIDTH) - 1)
#define RV_MMU_PT_LEVELS (3) #define RV_MMU_PT_LEVELS (3)
#define RV_MMU_VADDR_SHIFT(_n) (RV_MMU_PAGE_SHIFT + RV_MMU_VPN_WIDTH * \
(RV_MMU_PT_LEVELS - (_n)))
#define RV_MMU_SATP_MODE (SATP_MODE_SV39) #define RV_MMU_SATP_MODE (SATP_MODE_SV39)
#define RV_MMU_L1_PAGE_SIZE (0x40000000) /* 1G */ #define RV_MMU_L1_PAGE_SIZE (0x40000000) /* 1G */
#define RV_MMU_L2_PAGE_SIZE (0x200000) /* 2M */ #define RV_MMU_L2_PAGE_SIZE (0x200000) /* 2M */
@ -112,9 +99,46 @@
#define RV_MMU_SECTION_ALIGN (RV_MMU_L2_PAGE_SIZE) #define RV_MMU_SECTION_ALIGN (RV_MMU_L2_PAGE_SIZE)
#define RV_MMU_SECTION_ALIGN_MASK (RV_MMU_SECTION_ALIGN - 1) #define RV_MMU_SECTION_ALIGN_MASK (RV_MMU_SECTION_ALIGN - 1)
/* Sv32 has:
* - 4K page size
* - 2 page table levels
* - 10-bit VPN width
*/
#elif CONFIG_ARCH_MMU_TYPE_SV32
#define RV_MMU_PPN_WIDTH 22
#define RV_MMU_ASID_WIDTH 9
#define RV_MMU_MODE_WIDTH 1
#define RV_MMU_PTE_PPN_MASK (((1ul << RV_MMU_PPN_WIDTH) - 1) << RV_MMU_PTE_PADDR_SHIFT)
#define RV_MMU_VPN_WIDTH (10)
#define RV_MMU_VPN_MASK ((1ul << RV_MMU_VPN_WIDTH) - 1)
#define RV_MMU_PT_LEVELS (2)
#define RV_MMU_SATP_MODE (SATP_MODE_SV32)
#define RV_MMU_L1_PAGE_SIZE (0x400000) /* 4M */
#define RV_MMU_L2_PAGE_SIZE (0x1000) /* 4K */
#define RV_MMU_SECTION_ALIGN (RV_MMU_L1_PAGE_SIZE)
#define RV_MMU_SECTION_ALIGN_MASK (RV_MMU_SECTION_ALIGN - 1)
#else #else
#error "Unsupported RISC-V MMU implementation selected" #error "Unsupported RISC-V MMU implementation selected"
#endif /* CONFIG_ARCH_MMU_TYPE_SV39 */ #endif
#endif /* CONFIG_ARCH_HAVE_MMU */
/* Supervisor Address Translation and Protection (satp) */
#define SATP_PPN_SHIFT (0)
#define SATP_PPN_MASK (((1ul << RV_MMU_PPN_WIDTH) - 1) << SATP_PPN_SHIFT)
#define SATP_ASID_SHIFT (RV_MMU_PPN_WIDTH)
#define SATP_ASID_MASK (((1ul << RV_MMU_ASID_WIDTH) - 1) << SATP_ASID_SHIFT)
#define SATP_MODE_SHIFT (RV_MMU_PPN_WIDTH + RV_MMU_ASID_WIDTH)
#define SATP_MODE_MASK (((1ul << RV_MMU_MODE_WIDTH) - 1) << SATP_MODE_SHIFT)
/* satp address to PPN translation */
#define SATP_ADDR_TO_PPN(_addr) ((_addr) >> RV_MMU_PAGE_SHIFT)
#define SATP_PPN_TO_ADDR(_ppn) ((_ppn) << RV_MMU_PAGE_SHIFT)
/**************************************************************************** /****************************************************************************
* Public Data * Public Data

View File

@ -45,6 +45,28 @@
#define MMU_IO_BASE (0x00000000) #define MMU_IO_BASE (0x00000000)
#define MMU_IO_SIZE (0x80000000) #define MMU_IO_SIZE (0x80000000)
#ifdef CONFIG_ARCH_MMU_TYPE_SV32
/* 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_L1_VBASE PGT_L1_PBASE
#define PGT_L2_VBASE PGT_L2_PBASE
#define PGT_L1_SIZE (1024) /* Enough to map 4 GiB */
#define PGT_L2_SIZE (3072) /* Enough to map 12 MiB */
#define SLAB_COUNT (sizeof(m_l2_pgtable) / RV_MMU_PAGE_SIZE)
#define KMM_PAGE_SIZE RV_MMU_L2_PAGE_SIZE
#define KMM_PBASE PGT_L2_PBASE
#define KMM_PBASE_IDX 2
#define KMM_SPBASE PGT_L1_PBASE
#define KMM_SPBASE_IDX 1
#elif CONFIG_ARCH_MMU_TYPE_SV39
/* Physical and virtual addresses to page tables (vaddr = paddr mapping) */ /* Physical and virtual addresses to page tables (vaddr = paddr mapping) */
#define PGT_L1_PBASE (uintptr_t)&m_l1_pgtable #define PGT_L1_PBASE (uintptr_t)&m_l1_pgtable
@ -60,6 +82,16 @@
#define SLAB_COUNT (sizeof(m_l3_pgtable) / RV_MMU_PAGE_SIZE) #define SLAB_COUNT (sizeof(m_l3_pgtable) / RV_MMU_PAGE_SIZE)
#define KMM_PAGE_SIZE RV_MMU_L3_PAGE_SIZE
#define KMM_PBASE PGT_L3_PBASE
#define KMM_PBASE_IDX 3
#define KMM_SPBASE PGT_L2_PBASE
#define KMM_SPBASE_IDX 2
#else
#error No valid MMU defined.
#endif
/**************************************************************************** /****************************************************************************
* Private Types * Private Types
****************************************************************************/ ****************************************************************************/
@ -77,9 +109,11 @@ typedef struct pgalloc_slab_s pgalloc_slab_t;
/* Kernel mappings simply here, mapping is vaddr=paddr */ /* Kernel mappings simply here, mapping is vaddr=paddr */
static uint64_t m_l1_pgtable[PGT_L1_SIZE] locate_data(".pgtables"); static size_t m_l1_pgtable[PGT_L1_SIZE] locate_data(".pgtables");
static uint64_t m_l2_pgtable[PGT_L2_SIZE] locate_data(".pgtables"); static size_t m_l2_pgtable[PGT_L2_SIZE] locate_data(".pgtables");
static uint64_t m_l3_pgtable[PGT_L3_SIZE] locate_data(".pgtables"); #ifdef CONFIG_ARCH_MMU_TYPE_SV39
static size_t m_l3_pgtable[PGT_L3_SIZE] locate_data(".pgtables");
#endif
/* Kernel mappings (L1 base) */ /* Kernel mappings (L1 base) */
@ -99,10 +133,12 @@ static pgalloc_slab_t g_slabs[SLAB_COUNT];
* Name: slab_init * Name: slab_init
* *
* Description: * Description:
* Initialize slab allocator for L3 page table entries * Initialize slab allocator for L2 or L3 page table entries
*
* L2 Page table is used for SV32. L3 used for SV39
* *
* Input Parameters: * Input Parameters:
* start - Beginning of the L3 page table pool * start - Beginning of the L2 or L3 page table pool
* *
****************************************************************************/ ****************************************************************************/
@ -124,7 +160,9 @@ static void slab_init(uintptr_t start)
* Name: slab_alloc * Name: slab_alloc
* *
* Description: * Description:
* Allocate single slab for L3 page table entry * Allocate single slab for L2/L3 page table entry
*
* L2 Page table is used for SV32. L3 used for SV39
* *
****************************************************************************/ ****************************************************************************/
@ -152,7 +190,7 @@ static void map_region(uintptr_t paddr, uintptr_t vaddr, size_t size,
uint32_t mmuflags) uint32_t mmuflags)
{ {
uintptr_t endaddr; uintptr_t endaddr;
uintptr_t l3pbase; uintptr_t pbase;
int npages; int npages;
int i; int i;
int j; int j;
@ -164,28 +202,30 @@ static void map_region(uintptr_t paddr, uintptr_t vaddr, size_t size,
for (i = 0; i < npages; i += RV_MMU_PAGE_ENTRIES) for (i = 0; i < npages; i += RV_MMU_PAGE_ENTRIES)
{ {
/* See if a L3 mapping exists ? */ /* See if a mapping exists ? */
l3pbase = mmu_pte_to_paddr(mmu_ln_getentry(2, PGT_L2_VBASE, vaddr)); pbase = mmu_pte_to_paddr(mmu_ln_getentry(
if (!l3pbase) KMM_SPBASE_IDX, KMM_SPBASE, vaddr));
if (!pbase)
{ {
/* No, allocate 1 page, this must not fail */ /* No, allocate 1 page, this must not fail */
l3pbase = slab_alloc(); pbase = slab_alloc();
DEBUGASSERT(l3pbase); DEBUGASSERT(pbase);
/* Map it to the L3 table */ /* Map it to the new table */
mmu_ln_setentry(2, PGT_L2_VBASE, l3pbase, vaddr, MMU_UPGT_FLAGS); mmu_ln_setentry(
KMM_SPBASE_IDX, KMM_SPBASE, pbase, vaddr, MMU_UPGT_FLAGS);
} }
/* Then add the L3 mappings */ /* Then add the mappings */
for (j = 0; j < RV_MMU_PAGE_ENTRIES && vaddr < endaddr; j++) for (j = 0; j < RV_MMU_PAGE_ENTRIES && vaddr < endaddr; j++)
{ {
mmu_ln_setentry(3, l3pbase, paddr, vaddr, mmuflags); mmu_ln_setentry(KMM_PBASE_IDX, pbase, paddr, vaddr, mmuflags);
paddr += RV_MMU_L3_PAGE_SIZE; paddr += KMM_PAGE_SIZE;
vaddr += RV_MMU_L3_PAGE_SIZE; vaddr += KMM_PAGE_SIZE;
} }
} }
} }
@ -198,16 +238,16 @@ static void map_region(uintptr_t paddr, uintptr_t vaddr, size_t size,
* Name: qemu_rv_kernel_mappings * Name: qemu_rv_kernel_mappings
* *
* Description: * Description:
* Setup kernel mappings when usinc CONFIG_BUILD_KERNEL. Sets up the kernel * Setup kernel mappings when using CONFIG_BUILD_KERNEL. Sets up the kernel
* MMU mappings. * MMU mappings.
* *
****************************************************************************/ ****************************************************************************/
void qemu_rv_kernel_mappings(void) void qemu_rv_kernel_mappings(void)
{ {
/* Initialize slab allocator for L3 page tables */ /* Initialize slab allocator for the L2/L3 page tables */
slab_init(PGT_L3_PBASE); slab_init(KMM_PBASE);
/* Begin mapping memory to MMU; note that at this point the MMU is not yet /* 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 * active, so the page table virtual addresses are actually physical
@ -215,7 +255,7 @@ void qemu_rv_kernel_mappings(void)
* this mapping is quite simple to do * this mapping is quite simple to do
*/ */
/* Map I/O region, use 2 L1 entries (i.e. 2 * 1GB address space) */ /* Map I/O region, use enough large page tables for the IO region. */
binfo("map I/O regions\n"); binfo("map I/O regions\n");
mmu_ln_map_region(1, PGT_L1_VBASE, MMU_IO_BASE, MMU_IO_BASE, mmu_ln_map_region(1, PGT_L1_VBASE, MMU_IO_BASE, MMU_IO_BASE,
@ -229,6 +269,8 @@ void qemu_rv_kernel_mappings(void)
binfo("map kernel data\n"); binfo("map kernel data\n");
map_region(KSRAM_START, KSRAM_START, KSRAM_SIZE, MMU_KDATA_FLAGS); map_region(KSRAM_START, KSRAM_START, KSRAM_SIZE, MMU_KDATA_FLAGS);
#ifdef CONFIG_ARCH_MMU_TYPE_SV39
/* Connect the L1 and L2 page tables for the kernel text and data */ /* Connect the L1 and L2 page tables for the kernel text and data */
binfo("connect the L1 and L2 page tables\n"); binfo("connect the L1 and L2 page tables\n");
@ -239,6 +281,10 @@ void qemu_rv_kernel_mappings(void)
binfo("map the page pool\n"); binfo("map the page pool\n");
mmu_ln_map_region(2, PGT_L2_VBASE, PGPOOL_START, PGPOOL_START, PGPOOL_SIZE, mmu_ln_map_region(2, PGT_L2_VBASE, PGPOOL_START, PGPOOL_START, PGPOOL_SIZE,
MMU_KDATA_FLAGS); MMU_KDATA_FLAGS);
#elif CONFIG_ARCH_MMU_TYPE_SV32
binfo("map the page pool\n");
map_region(PGPOOL_START, PGPOOL_START, PGPOOL_SIZE, MMU_KDATA_FLAGS);
#endif
} }
/**************************************************************************** /****************************************************************************
@ -258,6 +304,6 @@ void qemu_rv_mm_init(void)
/* Enable MMU (note: system is still in M-mode) */ /* Enable MMU (note: system is still in M-mode) */
binfo("mmu_enable: satp=%lx\n", g_kernel_pgt_pbase); binfo("mmu_enable: satp=%" PRIuPTR "\n", g_kernel_pgt_pbase);
mmu_enable(g_kernel_pgt_pbase, 0); mmu_enable(g_kernel_pgt_pbase, 0);
} }

View File

@ -20,14 +20,17 @@
$ ./tools/configure.sh rv-virt:nsh $ ./tools/configure.sh rv-virt:nsh
$ make V=1 -j7 $ make V=1 -j7
3.2 Configure and build NuttX for BUILD_KERNEL 3.2 Configure and build NuttX for BUILD_KERNEL, 64-bit or 32-bit
$ mkdir ./nuttx; cd ./nuttx $ mkdir ./nuttx; cd ./nuttx
$ git clone https://github.com/apache/nuttx.git nuttx $ git clone https://github.com/apache/nuttx.git nuttx
$ git clone https://github.com/apache/nuttx-apps.git apps $ git clone https://github.com/apache/nuttx-apps.git apps
$ cd nuttx $ cd nuttx
$ make distclean $ make distclean
$ ./tools/configure.sh rv-virt:knsh64 $ # For 64-bit build.
$ ./tools/configure.sh rv-virt:knsh64
$ # For 32-bit build.
$ ./tools/configure.sh rv-virt:knsh32
$ make V=1 -j7 $ make V=1 -j7
$ make export V=1 $ make export V=1
$ cd ../apps $ cd ../apps

View File

@ -0,0 +1,87 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_DISABLE_OS_API is not set
# CONFIG_NSH_DISABLE_LOSMART is not set
CONFIG_16550_ADDRWIDTH=0
CONFIG_16550_UART0=y
CONFIG_16550_UART0_BASE=0x10000000
CONFIG_16550_UART0_CLOCK=3686400
CONFIG_16550_UART0_IRQ=35
CONFIG_16550_UART0_SERIAL_CONSOLE=y
CONFIG_16550_UART=y
CONFIG_ARCH="risc-v"
CONFIG_ARCH_ADDRENV=y
CONFIG_ARCH_BOARD="rv-virt"
CONFIG_ARCH_BOARD_QEMU_RV_VIRT=y
CONFIG_ARCH_CHIP="qemu-rv"
CONFIG_ARCH_CHIP_QEMU_RV32=y
CONFIG_ARCH_CHIP_QEMU_RV=y
CONFIG_ARCH_CHIP_QEMU_RV_ISA_A=y
CONFIG_ARCH_CHIP_QEMU_RV_ISA_C=y
CONFIG_ARCH_CHIP_QEMU_RV_ISA_M=y
CONFIG_ARCH_DATA_NPAGES=128
CONFIG_ARCH_DATA_VBASE=0xC0400000
CONFIG_ARCH_HEAP_NPAGES=128
CONFIG_ARCH_HEAP_VBASE=0xC0800000
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_KERNEL_STACKSIZE=3072
CONFIG_ARCH_PGPOOL_MAPPING=y
CONFIG_ARCH_PGPOOL_PBASE=0x80800000
CONFIG_ARCH_PGPOOL_SIZE=4194304
CONFIG_ARCH_PGPOOL_VBASE=0x80800000
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_ARCH_TEXT_NPAGES=128
CONFIG_ARCH_TEXT_VBASE=0xC0000000
CONFIG_ARCH_USE_MMU=y
CONFIG_ARCH_USE_MPU=y
CONFIG_ARCH_USE_S_MODE=y
CONFIG_BOARD_LOOPSPERMSEC=6366
CONFIG_BUILD_KERNEL=y
CONFIG_DEV_ZERO=y
CONFIG_ELF=y
CONFIG_EXAMPLES_HELLO=m
CONFIG_FS_HOSTFS=y
CONFIG_FS_PROCFS=y
CONFIG_IDLETHREAD_STACKSIZE=3072
CONFIG_INIT_FILEPATH="/system/bin/init"
CONFIG_INIT_MOUNT=y
CONFIG_INIT_MOUNT_DATA="fs=../apps"
CONFIG_INIT_MOUNT_FLAGS=0x1
CONFIG_INIT_MOUNT_FSTYPE="hostfs"
CONFIG_INIT_MOUNT_SOURCE=""
CONFIG_INIT_MOUNT_TARGET="/system"
CONFIG_INIT_STACKSIZE=3072
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_ENVPATH=y
CONFIG_LIBC_EXECFUNCS=y
CONFIG_LIBC_PERROR_STDOUT=y
CONFIG_LIBC_STRERROR=y
CONFIG_MM_PGALLOC=y
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_FILE_APPS=y
CONFIG_NSH_READLINE=y
CONFIG_PATH_INITIAL="/system/bin"
CONFIG_RAM_SIZE=4194304
CONFIG_RAM_START=0x80400000
CONFIG_READLINE_CMD_HISTORY=y
CONFIG_RISCV_SEMIHOSTING_HOSTFS=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_LPWORK=y
CONFIG_SCHED_WAITPID=y
CONFIG_SERIAL_UART_ARCH_MMIO=y
CONFIG_START_MONTH=12
CONFIG_START_YEAR=2021
CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYSLOG_TIMESTAMP=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_NSH_PROGNAME="init"
CONFIG_TESTING_GETPRIME=y
CONFIG_USEC_PER_TICK=1000

View File

@ -24,7 +24,11 @@ include $(TOPDIR)/arch/risc-v/src/common/Toolchain.defs
ifeq ($(CONFIG_ARCH_CHIP_QEMU_RV),y) ifeq ($(CONFIG_ARCH_CHIP_QEMU_RV),y)
ifeq ($(CONFIG_BUILD_KERNEL),y) ifeq ($(CONFIG_BUILD_KERNEL),y)
LDSCRIPT = ld-kernel.script ifeq ($(CONFIG_ARCH_CHIP_QEMU_RV64),y)
LDSCRIPT = ld-kernel64.script
else
LDSCRIPT = ld-kernel32.script
endif
else else
LDSCRIPT = ld.script LDSCRIPT = ld.script
endif endif

View File

@ -0,0 +1,143 @@
/****************************************************************************
* boards/risc-v/qemu-rv/rv-virt/scripts/ld.script
*
* 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.
*
****************************************************************************/
MEMORY
{
kflash (rx) : ORIGIN = 0x80000000, LENGTH = 4096K /* w/ cache */
ksram (rwx) : ORIGIN = 0x80400000, LENGTH = 4096K /* w/ cache */
pgram (rwx) : ORIGIN = 0x80800000, LENGTH = 4096K /* w/ cache */
}
OUTPUT_ARCH("riscv")
/* Provide the kernel boundaries */
__kflash_start = ORIGIN(kflash);
__kflash_size = LENGTH(kflash);
__ksram_start = ORIGIN(ksram);
__ksram_size = LENGTH(ksram);
__ksram_end = ORIGIN(ksram) + LENGTH(ksram);
/* Page heap */
__pgheap_start = ORIGIN(pgram);
__pgheap_size = LENGTH(pgram);
SECTIONS
{
. = 0x80000000;
.text :
{
_stext = . ;
*(.text)
*(.text.*)
*(.gnu.warning)
*(.stub)
*(.glue_7)
*(.glue_7t)
*(.jcr)
/* C++ support: The .init and .fini sections contain specific logic
* to manage static constructors and destructors.
*/
*(.gnu.linkonce.t.*)
*(.init) /* Old ABI */
*(.fini) /* Old ABI */
_etext = . ;
}
.rodata :
{
_srodata = . ;
*(.rodata)
*(.rodata1)
*(.rodata.*)
*(.gnu.linkonce.r*)
_erodata = . ;
}
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
}
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
}
_eronly = ABSOLUTE(.);
.data :
{
_sdata = . ;
*(.data)
*(.data1)
*(.data.*)
*(.gnu.linkonce.d*)
. = ALIGN(4);
_edata = . ;
}
/* Page tables here, align to 4K boundary */
.pgtables (NOLOAD) : ALIGN(0x1000) {
*(.pgtables)
. = ALIGN(4);
} > ksram
.bss :
{
_sbss = . ;
*(.bss)
*(.bss.*)
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.b*)
*(COMMON)
_ebss = . ;
} > ksram
/* Stack top */
.stack_top : {
. = ALIGN(32);
_ebss = ABSOLUTE(.);
} > ksram
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_info 0 : { *(.debug_info) }
.debug_line 0 : { *(.debug_line) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_aranges 0 : { *(.debug_aranges) }
}

View File

@ -85,6 +85,7 @@ static struct rname_code_s _rname_table[] =
{"JAL", R_RISCV_JAL}, {"JAL", R_RISCV_JAL},
{"RVC_JUMP", R_RISCV_RVC_JUMP}, {"RVC_JUMP", R_RISCV_RVC_JUMP},
{"RVC_BRANCH", R_RISCV_RVC_BRANCH}, {"RVC_BRANCH", R_RISCV_RVC_BRANCH},
{"32_PCREL", R_RISCV_32_PCREL},
}; };
/**************************************************************************** /****************************************************************************
@ -540,6 +541,19 @@ int up_relocateadd(const Elf_Rela *rel, const Elf_Sym *sym,
offset, offset, val); offset, offset, val);
} }
break; break;
case R_RISCV_32_PCREL:
{
/* P.29 https://github.com/riscv-non-isa/riscv-elf-psabi-doc */
binfo("%s at %08" PRIxPTR " [%08" PRIx32 "] "
"to sym=%p st_value=%08lx\n",
_get_rname(relotype),
addr, _get_val((uint16_t *)addr),
sym, sym->st_value);
addr = (long)sym->st_value + (long)rel->r_addend - (long)addr;
}
break;
case R_RISCV_ADD32: case R_RISCV_ADD32:
{ {
*(uint32_t *)addr += (uint32_t)(sym->st_value + rel->r_addend); *(uint32_t *)addr += (uint32_t)(sym->st_value + rel->r_addend);