From 01b0305ab5257c4e81250d0c2f53fed1849edbad Mon Sep 17 00:00:00 2001 From: Stuart Ianna Date: Mon, 27 Mar 2023 10:01:47 +1100 Subject: [PATCH] risc-v: SV32 MMU support for qemu-rv. --- arch/risc-v/Kconfig | 5 + arch/risc-v/include/arch.h | 2 + arch/risc-v/src/common/riscv_mmu.c | 5 + arch/risc-v/src/common/riscv_mmu.h | 86 +++++++---- arch/risc-v/src/qemu-rv/qemu_rv_mm_init.c | 92 ++++++++--- boards/risc-v/qemu-rv/rv-virt/README.txt | 7 +- .../qemu-rv/rv-virt/configs/knsh32/defconfig | 87 +++++++++++ .../risc-v/qemu-rv/rv-virt/scripts/Make.defs | 6 +- .../rv-virt/scripts/ld-kernel32.script | 143 ++++++++++++++++++ .../{ld-kernel.script => ld-kernel64.script} | 0 libs/libc/machine/risc-v/arch_elf.c | 14 ++ 11 files changed, 390 insertions(+), 57 deletions(-) create mode 100644 boards/risc-v/qemu-rv/rv-virt/configs/knsh32/defconfig create mode 100644 boards/risc-v/qemu-rv/rv-virt/scripts/ld-kernel32.script rename boards/risc-v/qemu-rv/rv-virt/scripts/{ld-kernel.script => ld-kernel64.script} (100%) diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig index ceedca8a63..f11df414bb 100644 --- a/arch/risc-v/Kconfig +++ b/arch/risc-v/Kconfig @@ -166,6 +166,7 @@ config ARCH_CHIP_QEMU_RV select ARCH_HAVE_MPU select ARCH_HAVE_MMU 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_NEED_ADDRENV_MAPPING select ARCH_HAVE_S_MODE @@ -255,6 +256,10 @@ config ARCH_MMU_TYPE_SV39 bool default n +config ARCH_MMU_TYPE_SV32 + bool + default n + config ARCH_HAVE_S_MODE bool default n diff --git a/arch/risc-v/include/arch.h b/arch/risc-v/include/arch.h index 3be03ccb73..1bf88a7622 100644 --- a/arch/risc-v/include/arch.h +++ b/arch/risc-v/include/arch.h @@ -44,6 +44,8 @@ #ifdef CONFIG_ARCH_MMU_TYPE_SV39 # define ARCH_PGT_MAX_LEVELS (3) +#elif CONFIG_ARCH_MMU_TYPE_SV32 +# define ARCH_PGT_MAX_LEVELS (2) #endif /* Amount of static page tables allocated for an address environment */ diff --git a/arch/risc-v/src/common/riscv_mmu.c b/arch/risc-v/src/common/riscv_mmu.c index 179abdf40f..ffb5418760 100644 --- a/arch/risc-v/src/common/riscv_mmu.c +++ b/arch/risc-v/src/common/riscv_mmu.c @@ -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 }; +#elif CONFIG_ARCH_MMU_TYPE_SV32 +static const size_t g_pgt_sizes[] = +{ + RV_MMU_L1_PAGE_SIZE, RV_MMU_L2_PAGE_SIZE +}; #endif /**************************************************************************** diff --git a/arch/risc-v/src/common/riscv_mmu.h b/arch/risc-v/src/common/riscv_mmu.h index df48f8d1d3..26e398fc1d 100644 --- a/arch/risc-v/src/common/riscv_mmu.h +++ b/arch/risc-v/src/common/riscv_mmu.h @@ -31,27 +31,6 @@ #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 */ #define PTE_VALID (1 << 0) /* PTE is valid */ @@ -85,24 +64,32 @@ #define MMU_KTEXT_FLAGS (PTE_R | PTE_X | PTE_G) #define MMU_KDATA_FLAGS (PTE_R | PTE_W | PTE_G) -/* SvX definitions, only Sv39 is currently supported, but it should be - * trivial to extend the driver to support other SvX implementations - * - * Sv39 has: +/* 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) + +#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 * - 3 page table levels * - 9-bit VPN width */ #ifdef CONFIG_ARCH_MMU_TYPE_SV39 -#define RV_MMU_PTE_PADDR_SHIFT (10) -#define RV_MMU_PTE_PPN_MASK (((1ul << 44) - 1) << RV_MMU_PTE_PADDR_SHIFT) -#define RV_MMU_PTE_PPN_SHIFT (2) +#define RV_MMU_PPN_WIDTH 44 +#define RV_MMU_ASID_WIDTH 16 +#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_MASK ((1ul << RV_MMU_VPN_WIDTH) - 1) #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_L1_PAGE_SIZE (0x40000000) /* 1G */ #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_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 #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 diff --git a/arch/risc-v/src/qemu-rv/qemu_rv_mm_init.c b/arch/risc-v/src/qemu-rv/qemu_rv_mm_init.c index cdf32365ef..4345e79a0a 100644 --- a/arch/risc-v/src/qemu-rv/qemu_rv_mm_init.c +++ b/arch/risc-v/src/qemu-rv/qemu_rv_mm_init.c @@ -45,6 +45,28 @@ #define MMU_IO_BASE (0x00000000) #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) */ #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 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 ****************************************************************************/ @@ -77,9 +109,11 @@ typedef struct pgalloc_slab_s pgalloc_slab_t; /* 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"); +static size_t m_l1_pgtable[PGT_L1_SIZE] locate_data(".pgtables"); +static size_t m_l2_pgtable[PGT_L2_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) */ @@ -99,10 +133,12 @@ static pgalloc_slab_t g_slabs[SLAB_COUNT]; * Name: slab_init * * 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: - * 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 * * 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) { uintptr_t endaddr; - uintptr_t l3pbase; + uintptr_t pbase; int npages; int i; 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) { - /* See if a L3 mapping exists ? */ + /* See if a mapping exists ? */ - l3pbase = mmu_pte_to_paddr(mmu_ln_getentry(2, PGT_L2_VBASE, vaddr)); - if (!l3pbase) + pbase = mmu_pte_to_paddr(mmu_ln_getentry( + KMM_SPBASE_IDX, KMM_SPBASE, vaddr)); + if (!pbase) { /* No, allocate 1 page, this must not fail */ - l3pbase = slab_alloc(); - DEBUGASSERT(l3pbase); + pbase = slab_alloc(); + 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++) { - mmu_ln_setentry(3, l3pbase, paddr, vaddr, mmuflags); - paddr += RV_MMU_L3_PAGE_SIZE; - vaddr += RV_MMU_L3_PAGE_SIZE; + mmu_ln_setentry(KMM_PBASE_IDX, pbase, paddr, vaddr, mmuflags); + paddr += KMM_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 * * 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. * ****************************************************************************/ 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 * 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 */ - /* 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"); 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"); 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 */ 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"); mmu_ln_map_region(2, PGT_L2_VBASE, PGPOOL_START, PGPOOL_START, PGPOOL_SIZE, 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) */ - 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); } diff --git a/boards/risc-v/qemu-rv/rv-virt/README.txt b/boards/risc-v/qemu-rv/rv-virt/README.txt index 079812ea19..cb3629ce14 100644 --- a/boards/risc-v/qemu-rv/rv-virt/README.txt +++ b/boards/risc-v/qemu-rv/rv-virt/README.txt @@ -20,14 +20,17 @@ $ ./tools/configure.sh rv-virt:nsh $ 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 $ git clone https://github.com/apache/nuttx.git nuttx $ git clone https://github.com/apache/nuttx-apps.git apps $ cd nuttx $ 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 export V=1 $ cd ../apps diff --git a/boards/risc-v/qemu-rv/rv-virt/configs/knsh32/defconfig b/boards/risc-v/qemu-rv/rv-virt/configs/knsh32/defconfig new file mode 100644 index 0000000000..86d381bd07 --- /dev/null +++ b/boards/risc-v/qemu-rv/rv-virt/configs/knsh32/defconfig @@ -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 diff --git a/boards/risc-v/qemu-rv/rv-virt/scripts/Make.defs b/boards/risc-v/qemu-rv/rv-virt/scripts/Make.defs index 2de012f277..ab13f19b9c 100644 --- a/boards/risc-v/qemu-rv/rv-virt/scripts/Make.defs +++ b/boards/risc-v/qemu-rv/rv-virt/scripts/Make.defs @@ -24,7 +24,11 @@ include $(TOPDIR)/arch/risc-v/src/common/Toolchain.defs ifeq ($(CONFIG_ARCH_CHIP_QEMU_RV),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 LDSCRIPT = ld.script endif diff --git a/boards/risc-v/qemu-rv/rv-virt/scripts/ld-kernel32.script b/boards/risc-v/qemu-rv/rv-virt/scripts/ld-kernel32.script new file mode 100644 index 0000000000..ae9c92bfb0 --- /dev/null +++ b/boards/risc-v/qemu-rv/rv-virt/scripts/ld-kernel32.script @@ -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) } +} diff --git a/boards/risc-v/qemu-rv/rv-virt/scripts/ld-kernel.script b/boards/risc-v/qemu-rv/rv-virt/scripts/ld-kernel64.script similarity index 100% rename from boards/risc-v/qemu-rv/rv-virt/scripts/ld-kernel.script rename to boards/risc-v/qemu-rv/rv-virt/scripts/ld-kernel64.script diff --git a/libs/libc/machine/risc-v/arch_elf.c b/libs/libc/machine/risc-v/arch_elf.c index d2e8475f03..50a20fb5cc 100644 --- a/libs/libc/machine/risc-v/arch_elf.c +++ b/libs/libc/machine/risc-v/arch_elf.c @@ -85,6 +85,7 @@ static struct rname_code_s _rname_table[] = {"JAL", R_RISCV_JAL}, {"RVC_JUMP", R_RISCV_RVC_JUMP}, {"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); } 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: { *(uint32_t *)addr += (uint32_t)(sym->st_value + rel->r_addend);