mpfs: introduce OpenSBI

OpenSBI may be compiled as an external library. OpenSBI commit d249d65
(Dec. 11, 2021) needs to be reverted as it causes memcpy / memcmp to
end up in the wrong section. That issue has yet no known workaround.

OpenSBI may be lauched from the hart0 (e51). It will start the U-Boot
and eventually the Linux kernel on harts 1-4.

OpenSBI, once initialized properly, will trap and handle illegal
instructions (for example, CSR time) and unaligned address accesses
among other things.

Due to size size limitations for the mpfs eNVM area where the NuttX
is located, we actually set up the OpenSBI on its own section which
is in the bottom of the DDR memory. Special care must be taken so that
the kernel doesn't override the OpenSBI. For example, the Linux device
tree may reserve some space from the beginning:

  opensbi_reserved: opensbi@80000000 {
      reg = <0x80000000 0x200000>;
      label = "opensbi-reserved";
  };

The resulting nuttx.bin file is very large, but objcopy is used to
create the final binary images for the regions (eNVM and DDR) using
the nuttx elf file.

Co-authored-by: Petro Karashchenko <petro.karashchenko@gmail.com>
Signed-off-by: Eero Nurkkala <eero.nurkkala@offcode.fi>
This commit is contained in:
Eero Nurkkala 2021-12-20 14:20:47 +02:00 committed by Xiang Xiao
parent 491ae6cc53
commit b128ce334f
14 changed files with 1215 additions and 2 deletions

32
LICENSE
View file

@ -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.
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.

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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:

View file

@ -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 <nuttx/config.h>
#include <assert.h>
#include <errno.h>
#include <stdint.h>
#include <riscv_internal.h>
#include <riscv_arch.h>
#include <hardware/mpfs_plic.h>
#include <hardware/mpfs_memorymap.h>
#include <hardware/mpfs_clint.h>
#include <hardware/mpfs_sysreg.h>
/* OpenSBI will also define NULL. Undefine NULL in order to avoid warning:
* 'warning: "NULL" redefined'
*/
#ifdef NULL
#undef NULL
#endif
#include <sbi/sbi_types.h>
#include <sbi/riscv_atomic.h>
#include <sbi/riscv_asm.h>
#include <sbi/riscv_io.h>
#include <sbi/riscv_encoding.h>
#include <sbi/sbi_hart.h>
#include <sbi/sbi_console.h>
#include <sbi/sbi_platform.h>
#include <sbi/sbi_domain.h>
#include <sbi/sbi_timer.h>
#include <sbi/sbi_init.h>
#include <sbi/sbi_scratch.h>
#include <sbi_utils/irqchip/plic.h>
#include <sbi_utils/ipi/aclint_mswi.h>
#include <sbi_utils/timer/aclint_mtimer.h>
/****************************************************************************
* 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();
}

View file

@ -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 <nuttx/config.h>
#include <sbi/riscv_asm.h>
#include <sbi/sbi_platform.h>
#include <sbi/sbi_scratch.h>
#include <sbi/sbi_trap.h>
#include <sbi/riscv_encoding.h>
/****************************************************************************
* 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

3
arch/risc-v/src/opensbi/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
/.opensbi_unpack
/opensbi-3rdparty
/*tar.gz

View file

@ -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.

View file

@ -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

View file

@ -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"

View file

@ -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

View file

@ -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) }
}