diff --git a/LICENSE b/LICENSE index a2a035cab7..d25a1a6f53 100644 --- a/LICENSE +++ b/LICENSE @@ -2499,4 +2499,34 @@ arch/arm/src/nrf52/sdk-nrfxlib GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file + OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +arch/risc-v/src/mpfs/mpfs_opensbi_utils.S +========================================= +OpenSBI is based on the 2-Clause BSD License: + +The 2-Clause BSD License +SPDX short identifier: BSD-2-Clause + +Copyright (c) 2019 Western Digital Corporation or its affiliates and other +contributors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig index 834f51d882..cb279f1704 100644 --- a/arch/risc-v/Kconfig +++ b/arch/risc-v/Kconfig @@ -148,6 +148,8 @@ config ARCH_RISCV_INTXCPT_EXTREGS endif +source "arch/risc-v/src/opensbi/Kconfig" + if ARCH_RV32IM source "arch/risc-v/src/rv32im/Kconfig" endif diff --git a/arch/risc-v/src/Makefile b/arch/risc-v/src/Makefile index cbff2cf4fa..72d87276ea 100644 --- a/arch/risc-v/src/Makefile +++ b/arch/risc-v/src/Makefile @@ -20,6 +20,9 @@ include $(TOPDIR)/Make.defs include chip/Make.defs +ifeq ($(CONFIG_OPENSBI),y) +include opensbi/Make.defs +endif ifeq ($(CONFIG_ARCH_RV32I),y) # Base Integer support ARCH_SUBDIR = rv32i @@ -37,6 +40,9 @@ INCLUDES += ${shell $(INCDIR) "$(CC)" $(ARCH_SRCDIR)$(DELIM)chip} INCLUDES += ${shell $(INCDIR) "$(CC)" $(ARCH_SRCDIR)$(DELIM)common} INCLUDES += ${shell $(INCDIR) "$(CC)" $(ARCH_SRCDIR)$(DELIM)$(ARCH_SUBDIR)} INCLUDES += ${shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)sched} +#ifeq ($(CONFIG_OPENSBI),y) +INCLUDES += $(shell $(INCDIR) "$(CC)" $(ARCH_SRCDIR)$(DELIM)opensbi$(DELIM)opensbi-3rdparty$(DELIM)include) +#endif CPPFLAGS += $(INCLUDES) CFLAGS += $(INCLUDES) @@ -63,9 +69,15 @@ STARTUP_OBJS ?= $(HEAD_OBJ) # Flat build or kernel-mode objects ASRCS = $(CHIP_ASRCS) $(CMN_ASRCS) +ifeq ($(CONFIG_OPENSBI),y) +ASRCS += $(OPENSBI_ASRCS) +endif AOBJS = $(ASRCS:.S=$(OBJEXT)) CSRCS = $(CHIP_CSRCS) $(CMN_CSRCS) +ifeq ($(CONFIG_OPENSBI),y) +CSRCS += $(OPENSBI_CSRCS) +endif COBJS = $(CSRCS:.c=$(OBJEXT)) SRCS = $(ASRCS) $(CSRCS) @@ -113,6 +125,9 @@ endif VPATH += chip VPATH += common +ifeq ($(CONFIG_OPENSBI),y) +VPATH += opensbi +endif VPATH += $(ARCH_SUBDIR) VPATH += $(CHIP_DIR) diff --git a/arch/risc-v/src/mpfs/Kconfig b/arch/risc-v/src/mpfs/Kconfig index 7e069d36f3..ba7574927a 100755 --- a/arch/risc-v/src/mpfs/Kconfig +++ b/arch/risc-v/src/mpfs/Kconfig @@ -19,6 +19,13 @@ config MPFS_BOOTLOADER ---help--- This NuttX image is used as a bootloader, which will boot only on one hart, putting the others in WFI +config MPFS_OPENSBI + bool "Use OpenSBI" + depends on MPFS_BOOTLOADER && OPENSBI + default n + ---help--- + This uses a ld-envm-opensbi.script linker script and the mpfs_opensbi.c code to use external OpenSBI. + config MPFS_BOOT_HART int "HART used for booting" depends on MPFS_BOOTLOADER diff --git a/arch/risc-v/src/mpfs/Make.defs b/arch/risc-v/src/mpfs/Make.defs index 309ece657c..07f29aae26 100755 --- a/arch/risc-v/src/mpfs/Make.defs +++ b/arch/risc-v/src/mpfs/Make.defs @@ -89,3 +89,8 @@ endif ifeq (${CONFIG_MPFS_BOOTLOADER},y) CHIP_CSRCS += mpfs_cache.c endif + +ifeq (${CONFIG_MPFS_OPENSBI},y) +CHIP_ASRCS += mpfs_opensbi_utils.S +CHIP_CSRCS += mpfs_opensbi.c +endif diff --git a/arch/risc-v/src/mpfs/mpfs_head.S b/arch/risc-v/src/mpfs/mpfs_head.S index 5995066f0d..ce774cff6f 100755 --- a/arch/risc-v/src/mpfs/mpfs_head.S +++ b/arch/risc-v/src/mpfs/mpfs_head.S @@ -163,9 +163,13 @@ __start_mpfs: csrw mie, zero csrw mip, zero +#ifdef CONFIG_MPFS_OPENSBI + jal mpfs_opensbi_prepare_hart +#else /* Jump to app (TODO: remove fixed address) */ li a1, 0x80000000 jr a1 +#endif .continue_boot: diff --git a/arch/risc-v/src/mpfs/mpfs_opensbi.c b/arch/risc-v/src/mpfs/mpfs_opensbi.c new file mode 100644 index 0000000000..ba874f4452 --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_opensbi.c @@ -0,0 +1,525 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_opensbi.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 +#include +#include +#include + +/* OpenSBI will also define NULL. Undefine NULL in order to avoid warning: + * 'warning: "NULL" redefined' + */ + +#ifdef NULL + #undef NULL +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define MPFS_SYS_CLK 1000000000 +#define MPFS_MAX_NUM_HARTS 5 +#define MPFS_HART_COUNT 5 + +#define MPFS_ACLINT_MSWI_ADDR MPFS_CLINT_MSIP0 +#define MPFS_ACLINT_MTIMER_ADDR MPFS_CLINT_MTIMECMP0 + +#define MPFS_PMP_DEFAULT_ADDR 0xfffffffff +#define MPFS_PMP_DEFAULT_PERM 0x000000009f + +#define UBOOT_LOAD_ADDR 0x80200000 /* We expect u-boot here */ + +/* The following define is not accessible with assember. Make sure it's in + * sync with the assembler usage in mpfs_opensbi_utils.S. + */ + +#if SBI_PLATFORM_DEFAULT_HART_STACK_SIZE != 8192 +# error "Fix define in file mpfs_opensbi_utils.S" +#endif + +#define MPFS_SYSREG_SOFT_RESET_CR (MPFS_SYSREG_BASE + \ + MPFS_SYSREG_SOFT_RESET_CR_OFFSET) +#define MPFS_SYSREG_SUBBLK_CLOCK_CR (MPFS_SYSREG_BASE + \ + MPFS_SYSREG_SUBBLK_CLOCK_CR_OFFSET) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct sbi_scratch_holder_s +{ + union + { + struct sbi_scratch scratch; + unsigned long buffer[SBI_SCRATCH_SIZE / sizeof(uintptr_t)]; + }; +}; + +typedef struct sbi_scratch_holder_s sbi_scratch_holder_t; + +/* Linker provided region start / end addresses */ + +extern const uint64_t __mpfs_nuttx_start; +extern const uint64_t __mpfs_nuttx_end; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static void mpfs_console_putc(char ch); +static int mpfs_early_init(bool cold_boot); +static int mpfs_opensbi_console_init(void); +static int mpfs_irqchip_init(bool cold_boot); +static int mpfs_ipi_init(bool cold_boot); +static int mpfs_timer_init(bool cold_boot); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static bool mpfs_console_ready = false; + +static struct plic_data mpfs_plic = +{ + .addr = MPFS_PLIC_BASE, + .num_src = MPFS_HART_COUNT, +}; + +static struct sbi_console_device mpfs_console = +{ + .name = "mpfs_uart", + .console_putc = mpfs_console_putc, + .console_getc = NULL, +}; + +static struct aclint_mtimer_data mpfs_mtimer = +{ + .mtime_freq = MPFS_SYS_CLK, + .mtime_addr = MPFS_ACLINT_MTIMER_ADDR + ACLINT_DEFAULT_MTIME_OFFSET, + .mtime_size = ACLINT_DEFAULT_MTIME_SIZE, + .mtimecmp_addr = MPFS_ACLINT_MTIMER_ADDR + ACLINT_DEFAULT_MTIMECMP_OFFSET, + .mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE, + .first_hartid = 0, + .hart_count = MPFS_HART_COUNT, + .has_64bit_mmio = TRUE, +}; + +static const struct sbi_platform_operations platform_ops = +{ + .console_init = mpfs_opensbi_console_init, + .early_init = mpfs_early_init, + .irqchip_init = mpfs_irqchip_init, + .irqchip_exit = NULL, + .ipi_init = mpfs_ipi_init, + .ipi_exit = NULL, + .timer_init = mpfs_timer_init, + .timer_exit = NULL, +}; + +static struct aclint_mswi_data mpfs_mswi = +{ + .addr = MPFS_ACLINT_MSWI_ADDR, + .size = ACLINT_MSWI_SIZE, + .first_hartid = 0, + .hart_count = MPFS_HART_COUNT, +}; + +const struct sbi_platform platform = +{ + .opensbi_version = OPENSBI_VERSION, + .platform_version = SBI_PLATFORM_VERSION(0x0, 0x01), + .name = "Microchip PolarFire(R) SoC", + .features = SBI_PLATFORM_DEFAULT_FEATURES, + .hart_count = MPFS_HART_COUNT, + .hart_stack_size = SBI_PLATFORM_DEFAULT_HART_STACK_SIZE, + .platform_ops_addr = (unsigned long)&platform_ops, + .firmware_context = 0 +}; + +/* This must go into l2_scratchpad region, starting at 0x0a000000. */ + +static sbi_scratch_holder_t g_scratches[MPFS_MAX_NUM_HARTS] \ + __attribute__((section(".l2_scratchpad"))); + +/* These stacks are used in the mpfs_opensbi_utils.S */ + +uint8_t g_hart_stacks[SBI_PLATFORM_DEFAULT_HART_STACK_SIZE * \ + MPFS_HART_COUNT] \ + __attribute__((section(".ddrstorage"))); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mpfs_hart_to_scratch + * + * Description: + * Returns the scratch area start for the given hart. + * + * Input Parameters: + * hartid (0,1..5) + * + * Returned Value: + * The scratch area in l2_scratchpad. + * + ****************************************************************************/ + +static unsigned long mpfs_hart_to_scratch(int hartid) +{ + DEBUGASSERT(hartid < MPFS_MAX_NUM_HARTS); + + return (unsigned long)(&g_scratches[hartid].scratch); +} + +/**************************************************************************** + * Name: mpfs_irqchip_init + * + * Description: + * Sets the interrupt priorities via the plic_cold_irqchip_init() call. + * Also this provides the proper PLIC base address for further irq + * property handling such as threshold levels. + * + * Input Parameters: + * cold_boot - True, if this is the hart doing the real boot + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * failure. + * + ****************************************************************************/ + +static int mpfs_irqchip_init(bool cold_boot) +{ + int rc; + uint32_t hartid = current_hartid(); + + if (cold_boot) + { + rc = plic_cold_irqchip_init(&mpfs_plic); + + if (rc) + { + return rc; + } + } + + return plic_warm_irqchip_init(&mpfs_plic, (hartid) ? (2 * hartid - 1) : 0, + (hartid) ? (2 * hartid) : -1); +} + +/**************************************************************************** + * Name: mpfs_console_putc + * + * Description: + * Sets the interrupt priorities via the plic_cold_irqchip_init() call. + * Also this provides the proper PLIC base address for further irq + * property handling such as threshold levels. + * + * Input Parameters: + * ch - Character to be printed out + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void mpfs_console_putc(char ch) +{ +#ifdef CONFIG_DEBUG_FEATURES + if (mpfs_console_ready) + { + riscv_lowputc(ch); + } +#endif +} + +/**************************************************************************** + * Name: mpfs_opensbi_console_init + * + * Description: + * Initializes the console for OpenSBI usage. OpenSBI expects this + * function to be present. + * + * Input Parameters: + * None + * + * Returned Value: + * Always zero indicating a success. + * + ****************************************************************************/ + +static int mpfs_opensbi_console_init(void) +{ + mpfs_console_ready = true; + + return 0; +} + +/**************************************************************************** + * Name: mpfs_ipi_init + * + * Description: + * Initializes the IPI for OpenSBI usage. Also adds the regions into + * OpenSBI domains. + * + * Input Parameters: + * cold_boot - Indicates the primary boot hart + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * failure. + * + ****************************************************************************/ + +static int mpfs_ipi_init(bool cold_boot) +{ + int rc; + + if (cold_boot) + { + rc = aclint_mswi_cold_init(&mpfs_mswi); + if (rc) + { + return rc; + } + } + + return aclint_mswi_warm_init(); +} + +/**************************************************************************** + * Name: mpfs_timer_init + * + * Description: + * Initializes the clint timer interface. Commands such as "csrr a0, time" + * (reading the CSR time register) will cause an illegal instruction + * exception, because the hardware has no support for it. That command is + * emulated via the CLINT timer in the OpenSBI trap handler. + * + * Input Parameters: + * cold_boot - If set, indicates the primary boot hart + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * failure. + * + ****************************************************************************/ + +static int mpfs_timer_init(bool cold_boot) +{ + int rc; + + if (cold_boot) + { + rc = aclint_mtimer_cold_init(&mpfs_mtimer, NULL); + if (rc) + { + return rc; + } + } + + return aclint_mtimer_warm_init(); +} + +/**************************************************************************** + * Name: mpfs_early_init + * + * Description: + * Initializes the clint timer interface. Commands such as "csrr a0, time" + * (reading the CSR time register) will cause an illegal instruction + * exception, because the hardware has no support for it. That command is + * emulated via the CLINT timer in the OpenSBI trap handler. + * + * Input Parameters: + * cold_boot - If set, indicates the primary boot hart + * + * Returned Value: + * Zero (OK) is returned on success. + * + ****************************************************************************/ + +static int mpfs_early_init(bool cold_boot) +{ + /* We expect that e51 has terminated the following irqs with + * up_disable_irq(): + * 1. MPFS_IRQ_MMC_MAIN + * 2. MPFS_IRQ_MTIMER + * + * U-boot will reuse eMMC and loads the kernel from there. OpenSBI will + * use CLINT timer. Upstream u-boot doesn't turn the clocks on itsef. + */ + + if (!cold_boot) + { + return 0; + } + + /* Explicitly reset eMMC */ + + modifyreg32(MPFS_SYSREG_SOFT_RESET_CR, 0, SYSREG_SOFT_RESET_CR_MMC); + modifyreg32(MPFS_SYSREG_SOFT_RESET_CR, SYSREG_SOFT_RESET_CR_MMC, 0); + + /* U-boot will use serial console 1, just turn on MMUART1 clocks now in + * order to see also u-boot traces. + */ + + modifyreg32(MPFS_SYSREG_SOFT_RESET_CR, SYSREG_SOFT_RESET_CR_MMUART1, 0); + modifyreg32(MPFS_SYSREG_SUBBLK_CLOCK_CR, 0, + SYSREG_SUBBLK_CLOCK_CR_MMUART1); + + /* There are other clocks that need to be enabled for the Linux kernel to + * run. For now, turn on all the clocks. + */ + + putreg32(0x0, MPFS_SYSREG_SOFT_RESET_CR); + putreg32(0x7fffffff, MPFS_SYSREG_SUBBLK_CLOCK_CR); + + return 0; +} + +/**************************************************************************** + * Name: mpfs_opensbi_scratch_setup + * + * Description: + * Initializes the scratch area per hart. The scratch area is used to save + * and restore registers (see mpfs_exception_opensbi), and to send and + * reveice messages to other harts via the IPI mechanism. + * + * Input Parameters: + * hartid - hart number to be prepared + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void mpfs_opensbi_scratch_setup(uint32_t hartid) +{ + DEBUGASSERT(hartid < MPFS_MAX_NUM_HARTS); + + g_scratches[hartid].scratch.options = SBI_SCRATCH_DEBUG_PRINTS; + g_scratches[hartid].scratch.hartid_to_scratch = + (unsigned long)mpfs_hart_to_scratch; + g_scratches[hartid].scratch.platform_addr = (unsigned long)&platform; + + /* Our FW area in l2lim section. OpenSBI needs to be aware of it in order + * to protect the area. However, we set the PMP values already and lock + * them so that OpenSBI has no chance override then. + */ + + g_scratches[hartid].scratch.fw_start = __mpfs_nuttx_start; + g_scratches[hartid].scratch.fw_size = __mpfs_nuttx_end; +} + +/**************************************************************************** + * Name: mpfs_opensbi_pmp_setup + * + * Description: + * Initializes the PMP registers in a known default state. All harts need + * to set these registers. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void mpfs_opensbi_pmp_setup(void) +{ + /* All access granted */ + + csr_write(pmpaddr0, MPFS_PMP_DEFAULT_ADDR); + csr_write(pmpcfg0, MPFS_PMP_DEFAULT_PERM); + csr_write(pmpcfg2, 0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mpfs_opensbi_setup + * + * Description: + * Calls the necessary OpenSBI init functions: + * - Sets up the PMP registers (to avoid OpenSBI overriding them) + * - Sets up the OpenSBI console + * - Sets up the mscratch registers + * - Sets up the firmware to be run (should be already at .next_addr) + * - Calls the sbi_init() that will not return + * + * Input Parameters: + * None + * + * Returned Value: + * None - this will never return + * + ****************************************************************************/ + +void __attribute__((noreturn)) mpfs_opensbi_setup(void) +{ + uint32_t hartid = current_hartid(); + + mpfs_opensbi_pmp_setup(); + + sbi_console_set_device(&mpfs_console); + mpfs_opensbi_scratch_setup(hartid); + + csr_write(mscratch, &g_scratches[hartid].scratch); + g_scratches[hartid].scratch.next_mode = PRV_S; + g_scratches[hartid].scratch.next_addr = UBOOT_LOAD_ADDR; + + sbi_init(&g_scratches[hartid].scratch); + + /* Will never get here */ + + DEBUGPANIC(); +} diff --git a/arch/risc-v/src/mpfs/mpfs_opensbi_utils.S b/arch/risc-v/src/mpfs/mpfs_opensbi_utils.S new file mode 100755 index 0000000000..8f912d0c6a --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_opensbi_utils.S @@ -0,0 +1,276 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_opensbi_utils.S + * + * mpfs_exception_opensbi function is based on OpenSBI fw_base.S + * + * The 2-Clause BSD License + * SPDX short identifier: BSD-2-Clause + * + * Copyright (c) 2019 Western Digital Corporation or its affiliates and other + * contributors. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef SBI_PLATFORM_DEFAULT_HART_STACK_SIZE +#define SBI_PLATFORM_DEFAULT_HART_STACK_SIZE 8192 +#endif + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .global mpfs_opensbi_prepare_hart + .global mpfs_exception_opensbi + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +mpfs_global_pointer: + .dword __global_pointer$ + +/**************************************************************************** + * Name: mpfs_opensbi_prepare_hart + * + * Description: + * Prepares the hart for OpenSBI execution. This installs the proper + * mtvec, global pointer and the stack (per hart) for the OpenSBI. + * mpfs_global_pointer is used to store the real __global_pointer$ as + * seen in the .map file. Loading gp, _global_pointer$ would default to + * mv gp, gp -instruction which isn't what we want. External libraties seem + * to link relative to gp. When trapping from the kernel, the gp has been + * utilized for other purposes, so we need to save and restore gp at all + * times. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + + .align 3 +mpfs_opensbi_prepare_hart: + + /* Setup OpenSBI exception handler */ + + la t0, mpfs_exception_opensbi + csrw mtvec, t0 + + /* la gp, __global_pointer$ will not work. We want to have the gp as seen + * in the .map file exactly. We need to restore gp in the trap handler. + */ + + la t0, mpfs_global_pointer + ld gp, 0(t0) + + /* Setup stacks per hart */ + + csrr a0, mhartid + mv t0, a0 + li t1, SBI_PLATFORM_DEFAULT_HART_STACK_SIZE + mul t0, a0, t1 + la sp, g_hart_stacks + add sp, sp, t0 + jal mpfs_opensbi_setup + +/**************************************************************************** + * Name: mpfs_exception_opensbi: + * + * Description: + * This is the trap entry into OpenSBI. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + + .align 3 +mpfs_exception_opensbi: + + /* Swap TP and MSCRATCH */ + + csrrw tp, CSR_MSCRATCH, tp + + /* Save T0 in scratch space */ + + REG_S t0, SBI_SCRATCH_TMP0_OFFSET(tp) + + /* + * Set T0 to appropriate exception stack + * + * Came_From_M_Mode = ((MSTATUS.MPP < PRV_M) ? 1 : 0) - 1; + * Exception_Stack = TP ^ (Came_From_M_Mode & (SP ^ TP)) + * + * Came_From_M_Mode = 0 ==> Exception_Stack = TP + * Came_From_M_Mode = -1 ==> Exception_Stack = SP + */ + + csrr t0, CSR_MSTATUS + srl t0, t0, MSTATUS_MPP_SHIFT + and t0, t0, PRV_M + slti t0, t0, PRV_M + add t0, t0, -1 + xor sp, sp, tp + and t0, t0, sp + xor sp, sp, tp + xor t0, tp, t0 + + /* Save original SP on exception stack */ + + REG_S sp, (SBI_TRAP_REGS_OFFSET(sp) - SBI_TRAP_REGS_SIZE)(t0) + + /* Set SP to exception stack and make room for trap registers */ + + add sp, t0, -(SBI_TRAP_REGS_SIZE) + + /* Restore T0 from scratch space */ + + REG_L t0, SBI_SCRATCH_TMP0_OFFSET(tp) + + /* Save T0 on stack */ + + REG_S t0, SBI_TRAP_REGS_OFFSET(t0)(sp) + + /* Swap TP and MSCRATCH */ + + csrrw tp, CSR_MSCRATCH, tp + + /* Save MEPC and MSTATUS CSRs */ + + csrr t0, CSR_MEPC + REG_S t0, SBI_TRAP_REGS_OFFSET(mepc)(sp) + csrr t0, CSR_MSTATUS + REG_S t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp) + REG_S zero, SBI_TRAP_REGS_OFFSET(mstatusH)(sp) + + /* Save all general regisers except SP and T0 */ + + REG_S zero, SBI_TRAP_REGS_OFFSET(zero)(sp) + REG_S ra, SBI_TRAP_REGS_OFFSET(ra)(sp) + REG_S gp, SBI_TRAP_REGS_OFFSET(gp)(sp) + REG_S tp, SBI_TRAP_REGS_OFFSET(tp)(sp) + REG_S t1, SBI_TRAP_REGS_OFFSET(t1)(sp) + REG_S t2, SBI_TRAP_REGS_OFFSET(t2)(sp) + REG_S s0, SBI_TRAP_REGS_OFFSET(s0)(sp) + REG_S s1, SBI_TRAP_REGS_OFFSET(s1)(sp) + REG_S a0, SBI_TRAP_REGS_OFFSET(a0)(sp) + REG_S a1, SBI_TRAP_REGS_OFFSET(a1)(sp) + REG_S a2, SBI_TRAP_REGS_OFFSET(a2)(sp) + REG_S a3, SBI_TRAP_REGS_OFFSET(a3)(sp) + REG_S a4, SBI_TRAP_REGS_OFFSET(a4)(sp) + REG_S a5, SBI_TRAP_REGS_OFFSET(a5)(sp) + REG_S a6, SBI_TRAP_REGS_OFFSET(a6)(sp) + REG_S a7, SBI_TRAP_REGS_OFFSET(a7)(sp) + REG_S s2, SBI_TRAP_REGS_OFFSET(s2)(sp) + REG_S s3, SBI_TRAP_REGS_OFFSET(s3)(sp) + REG_S s4, SBI_TRAP_REGS_OFFSET(s4)(sp) + REG_S s5, SBI_TRAP_REGS_OFFSET(s5)(sp) + REG_S s6, SBI_TRAP_REGS_OFFSET(s6)(sp) + REG_S s7, SBI_TRAP_REGS_OFFSET(s7)(sp) + REG_S s8, SBI_TRAP_REGS_OFFSET(s8)(sp) + REG_S s9, SBI_TRAP_REGS_OFFSET(s9)(sp) + REG_S s10, SBI_TRAP_REGS_OFFSET(s10)(sp) + REG_S s11, SBI_TRAP_REGS_OFFSET(s11)(sp) + REG_S t3, SBI_TRAP_REGS_OFFSET(t3)(sp) + REG_S t4, SBI_TRAP_REGS_OFFSET(t4)(sp) + REG_S t5, SBI_TRAP_REGS_OFFSET(t5)(sp) + REG_S t6, SBI_TRAP_REGS_OFFSET(t6)(sp) + + /* Restore GP */ + + la a0, mpfs_global_pointer + ld gp, 0(a0) + + /* Call C routine */ + + add a0, sp, zero + call sbi_trap_handler + + /* Restore all general regisers except A0 and T0 */ + + REG_L ra, SBI_TRAP_REGS_OFFSET(ra)(a0) + REG_L sp, SBI_TRAP_REGS_OFFSET(sp)(a0) + REG_L gp, SBI_TRAP_REGS_OFFSET(gp)(a0) + REG_L tp, SBI_TRAP_REGS_OFFSET(tp)(a0) + REG_L t1, SBI_TRAP_REGS_OFFSET(t1)(a0) + REG_L t2, SBI_TRAP_REGS_OFFSET(t2)(a0) + REG_L s0, SBI_TRAP_REGS_OFFSET(s0)(a0) + REG_L s1, SBI_TRAP_REGS_OFFSET(s1)(a0) + REG_L a1, SBI_TRAP_REGS_OFFSET(a1)(a0) + REG_L a2, SBI_TRAP_REGS_OFFSET(a2)(a0) + REG_L a3, SBI_TRAP_REGS_OFFSET(a3)(a0) + REG_L a4, SBI_TRAP_REGS_OFFSET(a4)(a0) + REG_L a5, SBI_TRAP_REGS_OFFSET(a5)(a0) + REG_L a6, SBI_TRAP_REGS_OFFSET(a6)(a0) + REG_L a7, SBI_TRAP_REGS_OFFSET(a7)(a0) + REG_L s2, SBI_TRAP_REGS_OFFSET(s2)(a0) + REG_L s3, SBI_TRAP_REGS_OFFSET(s3)(a0) + REG_L s4, SBI_TRAP_REGS_OFFSET(s4)(a0) + REG_L s5, SBI_TRAP_REGS_OFFSET(s5)(a0) + REG_L s6, SBI_TRAP_REGS_OFFSET(s6)(a0) + REG_L s7, SBI_TRAP_REGS_OFFSET(s7)(a0) + REG_L s8, SBI_TRAP_REGS_OFFSET(s8)(a0) + REG_L s9, SBI_TRAP_REGS_OFFSET(s9)(a0) + REG_L s10, SBI_TRAP_REGS_OFFSET(s10)(a0) + REG_L s11, SBI_TRAP_REGS_OFFSET(s11)(a0) + REG_L t3, SBI_TRAP_REGS_OFFSET(t3)(a0) + REG_L t4, SBI_TRAP_REGS_OFFSET(t4)(a0) + REG_L t5, SBI_TRAP_REGS_OFFSET(t5)(a0) + REG_L t6, SBI_TRAP_REGS_OFFSET(t6)(a0) + + /* Restore MEPC and MSTATUS CSRs */ + + REG_L t0, SBI_TRAP_REGS_OFFSET(mepc)(a0) + csrw CSR_MEPC, t0 + REG_L t0, SBI_TRAP_REGS_OFFSET(mstatus)(a0) + csrw CSR_MSTATUS, t0 + + /* Restore T0 */ + + REG_L t0, SBI_TRAP_REGS_OFFSET(t0)(a0) + + /* Restore A0 */ + + REG_L a0, SBI_TRAP_REGS_OFFSET(a0)(a0) + + mret diff --git a/arch/risc-v/src/opensbi/.gitignore b/arch/risc-v/src/opensbi/.gitignore new file mode 100644 index 0000000000..6dd75b4fac --- /dev/null +++ b/arch/risc-v/src/opensbi/.gitignore @@ -0,0 +1,3 @@ +/.opensbi_unpack +/opensbi-3rdparty +/*tar.gz diff --git a/arch/risc-v/src/opensbi/Kconfig b/arch/risc-v/src/opensbi/Kconfig new file mode 100644 index 0000000000..f24337e0b2 --- /dev/null +++ b/arch/risc-v/src/opensbi/Kconfig @@ -0,0 +1,12 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config OPENSBI + bool "OpenSBI support" + depends on ARCH_RISCV + default n + ---help--- + Enable or disable Open Source Supervisor Binary Interface (OpenSBI) features + for RISC-V. diff --git a/arch/risc-v/src/opensbi/Make.defs b/arch/risc-v/src/opensbi/Make.defs new file mode 100644 index 0000000000..a734e2b2b4 --- /dev/null +++ b/arch/risc-v/src/opensbi/Make.defs @@ -0,0 +1,89 @@ +############################################################################ +# arch/risc-v/src/opensbi/Make.defs +# +# 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. +# +############################################################################ + +ifeq ($(CONFIG_OPENSBI),y) + +DEPPATH += --dep-path opensbi/opensbi-3rdparty +VPATH += :opensbi/opensbi-3rdparty + +OPENSBI_CSRCS = opensbi/opensbi-3rdparty/lib/sbi/riscv_asm.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/riscv_atomic.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/riscv_locks.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_bitmap.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_bitops.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_console.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_domain.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_ecall.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_ecall_base.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_ecall_hsm.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_ecall_legacy.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_ecall_pmu.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_ecall_replace.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_ecall_vendor.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_emulate_csr.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_fifo.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_hart.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_hsm.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_illegal_insn.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_init.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_ipi.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_math.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_misaligned_ldst.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_platform.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_pmu.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_scratch.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_string.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_system.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_timer.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_tlb.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_trap.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_unpriv.c + +OPENSBI_ASRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_expected_trap.S +OPENSBI_ASRCS += opensbi/opensbi-3rdparty/lib/sbi/sbi_hfence.S + +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/utils/ipi/aclint_mswi.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/utils/irqchip/plic.c +OPENSBI_CSRCS += opensbi/opensbi-3rdparty/lib/utils/timer/aclint_mtimer.c + +OPENSBI_UNPACK = opensbi-3rdparty +OPENSBI_COMMIT = 69d7e536138ae71a24028ca849d401a4d64d564b +OPENSBI_URL = https://github.com/riscv-software-src/opensbi/tarball +OPENSBI_TARBALL = opensbi.tar.gz +OPENSBI_DIR = riscv-software-src-opensbi-69d7e53 + +$(OPENSBI_TARBALL): + $(Q) echo "Downloading: OpenSBI" + $(Q) curl -L $(OPENSBI_URL)/$(OPENSBI_COMMIT) -o opensbi/$(OPENSBI_TARBALL) + +.opensbi_unpack: $(OPENSBI_TARBALL) + $(Q) echo "Unpacking: OpenSBI" + $(Q) tar xzf opensbi/$(OPENSBI_TARBALL) -C opensbi + $(Q) mv opensbi/$(OPENSBI_DIR) opensbi/$(OPENSBI_UNPACK) + $(Q) touch opensbi/.opensbi_unpack + +context:: .opensbi_unpack + +distclean:: + $(call DELFILE, opensbi/.opensbi_unpack) + $(call DELFILE, opensbi/$(OPENSBI_TARBALL)) + $(call DELDIR, opensbi/$(OPENSBI_UNPACK)) + +endif diff --git a/boards/risc-v/mpfs/icicle/configs/opensbi/defconfig b/boards/risc-v/mpfs/icicle/configs/opensbi/defconfig new file mode 100644 index 0000000000..80bfe1ab16 --- /dev/null +++ b/boards/risc-v/mpfs/icicle/configs/opensbi/defconfig @@ -0,0 +1,118 @@ +# +# 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_MW is not set +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="icicle" +CONFIG_ARCH_BOARD_ICICLE_MPFS=y +CONFIG_ARCH_CHIP="mpfs" +CONFIG_ARCH_CHIP_MPFS=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARDCTL_MKRD=y +CONFIG_BOARD_LOOPSPERMSEC=54000 +CONFIG_BUILTIN=y +CONFIG_DEBUG_ASSERTIONS=y +CONFIG_DEBUG_ERROR=y +CONFIG_DEBUG_FEATURES=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEV_ZERO=y +CONFIG_EXPERIMENTAL=y +CONFIG_FAT_LCNAMES=y +CONFIG_FAT_LFN=y +CONFIG_FS_FAT=y +CONFIG_FS_PROCFS=y +CONFIG_FS_ROMFS=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_HOSTNAME="icicle" +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_MEMSET_64BIT=y +CONFIG_MEMSET_OPTSPEED=y +CONFIG_MMCSD=y +CONFIG_MMCSD_SDIO=y +CONFIG_MPFS_BOOTLOADER=y +CONFIG_MPFS_DDR_INIT=y +CONFIG_MPFS_EMMCSD=y +CONFIG_MPFS_OPENSBI=y +CONFIG_MPFS_UART0=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_DISABLE_BASENAME=y +CONFIG_NSH_DISABLE_CAT=y +CONFIG_NSH_DISABLE_CD=y +CONFIG_NSH_DISABLE_CMP=y +CONFIG_NSH_DISABLE_CP=y +CONFIG_NSH_DISABLE_DD=y +CONFIG_NSH_DISABLE_DF=y +CONFIG_NSH_DISABLE_DIRNAME=y +CONFIG_NSH_DISABLE_ECHO=y +CONFIG_NSH_DISABLE_ENV=y +CONFIG_NSH_DISABLE_EXEC=y +CONFIG_NSH_DISABLE_EXIT=y +CONFIG_NSH_DISABLE_EXPORT=y +CONFIG_NSH_DISABLE_FREE=y +CONFIG_NSH_DISABLE_GET=y +CONFIG_NSH_DISABLE_HELP=y +CONFIG_NSH_DISABLE_HEXDUMP=y +CONFIG_NSH_DISABLE_IFCONFIG=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_DISABLE_KILL=y +CONFIG_NSH_DISABLE_LOSETUP=y +CONFIG_NSH_DISABLE_LS=y +CONFIG_NSH_DISABLE_MKDIR=y +CONFIG_NSH_DISABLE_MKRD=y +CONFIG_NSH_DISABLE_MOUNT=y +CONFIG_NSH_DISABLE_MV=y +CONFIG_NSH_DISABLE_PRINTF=y +CONFIG_NSH_DISABLE_PS=y +CONFIG_NSH_DISABLE_PUT=y +CONFIG_NSH_DISABLE_PWD=y +CONFIG_NSH_DISABLE_RM=y +CONFIG_NSH_DISABLE_RMDIR=y +CONFIG_NSH_DISABLE_SET=y +CONFIG_NSH_DISABLE_SLEEP=y +CONFIG_NSH_DISABLE_SOURCE=y +CONFIG_NSH_DISABLE_TELNETD=y +CONFIG_NSH_DISABLE_TEST=y +CONFIG_NSH_DISABLE_TIME=y +CONFIG_NSH_DISABLE_TRUNCATE=y +CONFIG_NSH_DISABLE_UMOUNT=y +CONFIG_NSH_DISABLE_UNAME=y +CONFIG_NSH_DISABLE_UNSET=y +CONFIG_NSH_DISABLE_USLEEP=y +CONFIG_NSH_DISABLE_WGET=y +CONFIG_NSH_DISABLE_XD=y +CONFIG_NSH_LINELEN=160 +CONFIG_NSH_STRERROR=y +CONFIG_OPENSBI=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=1048576 +CONFIG_RAM_START=0x80000000 +CONFIG_RAW_BINARY=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_TABCOMPLETION=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_SERIAL_NPOLLWAITERS=2 +CONFIG_STACK_COLORATION=y +CONFIG_START_MONTH=4 +CONFIG_START_YEAR=2021 +CONFIG_SYSLOG_COLOR_OUTPUT=y +CONFIG_SYSTEM_CLE_CMD_HISTORY=y +CONFIG_SYSTEM_COLOR_CLE=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_TIME64=y +CONFIG_TASK_NAME_SIZE=20 +CONFIG_UART0_SERIAL_CONSOLE=y +CONFIG_USERMAIN_STACKSIZE=3072 +CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/boards/risc-v/mpfs/icicle/scripts/Make.defs b/boards/risc-v/mpfs/icicle/scripts/Make.defs index e1ed0ca8dc..52167e5857 100755 --- a/boards/risc-v/mpfs/icicle/scripts/Make.defs +++ b/boards/risc-v/mpfs/icicle/scripts/Make.defs @@ -23,7 +23,11 @@ include $(TOPDIR)/tools/Config.mk include $(TOPDIR)/arch/risc-v/src/rv64gc/Toolchain.defs ifeq ($(CONFIG_MPFS_BOOTLOADER),y) - LDSCRIPT = ld-envm.script + ifeq ($(CONFIG_MPFS_OPENSBI),y) + LDSCRIPT = ld-envm-opensbi.script + else + LDSCRIPT = ld-envm.script + endif else LDSCRIPT = ld.script endif diff --git a/boards/risc-v/mpfs/icicle/scripts/ld-envm-opensbi.script b/boards/risc-v/mpfs/icicle/scripts/ld-envm-opensbi.script new file mode 100755 index 0000000000..2d4e20f1d1 --- /dev/null +++ b/boards/risc-v/mpfs/icicle/scripts/ld-envm-opensbi.script @@ -0,0 +1,123 @@ +/**************************************************************************** + * boards/risc-v/mpfs/icicle/scripts/ld-envm.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 +{ + ddr (rx) : ORIGIN = 0x80000000, LENGTH = 4M /* w/ cache */ + envm (rx) : ORIGIN = 0x20220100, LENGTH = 128K - 256 /* 256 reserved for hss headers */ + l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 1024k + l2zerodevice (rwx) : ORIGIN = 0x0A000000, LENGTH = 512k +} + +OUTPUT_ARCH("riscv") + +ENTRY(_stext) +EXTERN(_vectors) +SECTIONS +{ + .text.sbi : { + sbi* + } > ddr + + .ddrstorage : { + *(.ddrstorage) + } > ddr + + .l2_scratchpad : ALIGN(0x10) + { + __l2_scratchpad_load = LOADADDR(.l2_scratchpad); + __l2_scratchpad_start = .; + __l2_scratchpad_vma_start = .; + *(.l2_scratchpad) + + . = ALIGN(0x10); + __l2_scratchpad_end = .; + __l2_scratchpad_vma_end = .; + } > l2zerodevice + + PROVIDE(__mpfs_nuttx_start = ORIGIN(l2lim)); + + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + *(.text .text.*) + *(.f-ixup) + *(.gnu.warning) + *(.rodata .rodata.* .srodata .srodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > envm + + .init_section : ALIGN(4) { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > envm + + _eronly = ABSOLUTE(.); + + .data : ALIGN(4) { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.sdata .sdata.* .sdata2.*) + *(.gnu.linkonce.d.*) + *(.gnu.linkonce.s.*) + CONSTRUCTORS + . = ALIGN(4); + _edata = ABSOLUTE(.); + } > l2lim AT > envm + + PROVIDE(__global_pointer$ = _sdata + ((_edata - _sdata) / 2)); + + .bss : ALIGN(4) { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.sbss .sbss.*) + *(.gnu.linkonce.b.*) + *(.gnu.linkonce.sb.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + . = ALIGN(32); + _default_stack_limit = ABSOLUTE(.); + } > l2lim + + PROVIDE(__mpfs_nuttx_end = .); + + /* 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) } +}