litex: Support for kernel build with vexriscv-smp.
This commit is contained in:
parent
c4f3f8801f
commit
4cae98674d
@ -0,0 +1,35 @@
|
||||
=============
|
||||
Vexriscv Core
|
||||
=============
|
||||
|
||||
The vexriscv core only supports standard "Flat builds", consisting of a single binary.
|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
Build the minimal NSH application::
|
||||
|
||||
# Configure for NSH
|
||||
$ ./tools/configure.sh arty_a7:nsh
|
||||
|
||||
# Build Nuttx
|
||||
$ make
|
||||
|
||||
|
||||
Booting
|
||||
--------
|
||||
|
||||
Create a file, 'boot.json' in the Nuttx root directory, with the following content::
|
||||
|
||||
{
|
||||
"nuttx.bin": "0x40000000"
|
||||
}
|
||||
|
||||
Load the application over serial with::
|
||||
|
||||
$ litex_term --images=boot.json --speed=1e6 /dev/ttyUSB0
|
||||
|
||||
Update the baud rate and serial port to suit your configuration.
|
||||
|
||||
|
||||
|
@ -0,0 +1,55 @@
|
||||
==================
|
||||
VexRISCV_SMP Core
|
||||
==================
|
||||
|
||||
The vexrisc_smp core supports a two-pass build, producing the kernel (nuttx.bin), and a number of applications,
|
||||
compiled into the apps/bin directory. In the standard configuration, the applications are loaded to the FPGA in a RAMdisk.
|
||||
Although, for custom boards this could be extended to loading from SDCards, flash, or other mediums.
|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
Nuttx uses openSBI to configure and prepare the vexriscv_smp core. With this configuration,
|
||||
the Nuttx kernel is a binary payload for OpenSBI. The configuration used is
|
||||
identical to that used for Linux on Litex project (https://github.com/litex-hub/linux-on-litex-vexriscv).
|
||||
|
||||
To build OpenSBI::
|
||||
|
||||
$ git clone https://github.com/litex-hub/opensbi --branch 0.8-linux-on-litex-vexriscv
|
||||
$ cd opensbi
|
||||
$ make CROSS_COMPILE=riscv64-unknown-elf- PLATFORM=litex/vexriscv
|
||||
$ cp build/platform/litex/vexriscv/firmware/fw_jump.bin ../opensbi.bin"
|
||||
|
||||
Build the Nuttx kernel::
|
||||
|
||||
$ ./tools/configure.sh arty_a7:knsh
|
||||
$ make
|
||||
|
||||
Build the loadable applications::
|
||||
|
||||
$ make export -j16
|
||||
$ cd ../apps
|
||||
$ make ./tools/mkimport.sh -z -x ../nuttx/nuttx-export-*.tar.gz
|
||||
$ make import
|
||||
|
||||
Generate a romfs to be loaded to the FPGA as a ramdisk::
|
||||
|
||||
$ cd nuttx
|
||||
$ genromfs -f romfs.img -d ../apps/bin -V "NuttXBootVol"
|
||||
|
||||
Booting
|
||||
--------
|
||||
|
||||
Create a file, 'boot.json' in the Nuttx root directory, with the following content::
|
||||
|
||||
{
|
||||
"romfs.img": "0x40C00000",
|
||||
"nuttx.bin": "0x40000000",
|
||||
"opensbi.bin": "0x40f00000"
|
||||
}
|
||||
|
||||
Load the application over serial with::
|
||||
|
||||
litex_term --images=boot.json --speed=1e6 /dev/ttyUSB0
|
||||
|
||||
Update the baud rate and serial port to suit your configuration.
|
70
Documentation/platforms/risc-v/litex/index.rst
Normal file
70
Documentation/platforms/risc-v/litex/index.rst
Normal file
@ -0,0 +1,70 @@
|
||||
======================================
|
||||
Enjoy Digital LiteX FPGA's
|
||||
======================================
|
||||
|
||||
The LiteX framework provides a convenient and efficient infrastructure to create FPGA Cores/SoCs, to explore various digital design architectures and create full FPGA based systems.
|
||||
|
||||
Information specific to Litex and supported boards can be found on the project's homepage: https://github.com/enjoy-digital/litex
|
||||
|
||||
Nuttx has basic support for two softcores
|
||||
|
||||
- vexriscv: FPGA friendly RISC-V ISA CPU implementation
|
||||
- vexriscv_smp: A more fully featured, Linux compatible core.
|
||||
|
||||
Currently, the only configured development board in the Arty A7 https://digilent.com/reference/programmable-logic/arty-a7/start. However, many Litex supported boards
|
||||
should work with either core, requiring minimal adjustment to the configuration.
|
||||
|
||||
|
||||
Toolchain
|
||||
==============
|
||||
|
||||
Litex projects can be built with a generic RISC-V GCC toolchain. There are currently two options.
|
||||
|
||||
Prebuilt toolchain
|
||||
------------------
|
||||
|
||||
A prebuilt RISC-V toolchain from SiFive can be used to build Litex projects::
|
||||
|
||||
# Download the prebuilt toolchain
|
||||
$ curl https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-ubuntu14.tar.gz \
|
||||
> riscv64-unknown-elf-gcc.tar.gz
|
||||
|
||||
# Unpack the archive
|
||||
$ tar -xf riscv64-unknown-elf-gcc.tar.gz
|
||||
|
||||
# Add to path
|
||||
$ export PATH="$HOME/path/to/riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-ubuntu14/bin:$PATH
|
||||
|
||||
Custom built toolchain
|
||||
----------------------
|
||||
|
||||
The toolchain needs to be compiled locally in order to use a more modern version. At the time of writing,
|
||||
the source can be obtained from https://github.com/riscv-collab/riscv-gnu-toolchain and built with the following configuration::
|
||||
|
||||
$ CFLAGS="-g0 -Os"
|
||||
$ CXXFLAGS="-g0 -Os"
|
||||
$ LDFLAGS="-s"
|
||||
|
||||
$ ./configure \
|
||||
CFLAGS_FOR_TARGET='-O2 -mcmodel=medany' \
|
||||
CXXFLAGS_FOR_TARGET='-O2 -mcmodel=medany' \
|
||||
--prefix=path/to/install/to \
|
||||
--with-system-zlib \
|
||||
--with-arch=rv32ima \
|
||||
--with-abi=ilp32
|
||||
|
||||
$ make
|
||||
|
||||
.. important:: The vexriscv_smp core requires `with-arch=rv32imac`.
|
||||
|
||||
Check the linked github repository for other options, including building with multilib enabled.
|
||||
|
||||
Core specific information
|
||||
=========================
|
||||
|
||||
.. toctree::
|
||||
:glob:
|
||||
:maxdepth: 1
|
||||
|
||||
cores/*/*
|
||||
|
@ -354,6 +354,29 @@ config RISCV_SEMIHOSTING_HOSTFS_CACHE_COHERENCE
|
||||
|
||||
endif
|
||||
|
||||
if ARCH_CHIP_LITEX
|
||||
|
||||
choice
|
||||
prompt "LITEX Core Selection"
|
||||
default LITEX_CORE_VEXRISCV
|
||||
|
||||
config LITEX_CORE_VEXRISCV
|
||||
bool "vexriscv core"
|
||||
|
||||
config LITEX_CORE_VEXRISCV_SMP
|
||||
bool "vexriscv_smp core"
|
||||
select ARCH_HAVE_MPU
|
||||
select ARCH_HAVE_MMU
|
||||
select ARCH_RV_ISA_C
|
||||
select ARCH_MMU_TYPE_SV32
|
||||
select ARCH_HAVE_ADDRENV
|
||||
select ARCH_NEED_ADDRENV_MAPPING
|
||||
select ARCH_HAVE_S_MODE
|
||||
|
||||
endchoice
|
||||
|
||||
endif
|
||||
|
||||
source "arch/risc-v/src/opensbi/Kconfig"
|
||||
|
||||
if ARCH_CHIP_FE310
|
||||
|
@ -29,17 +29,19 @@
|
||||
#include CONFIG_LITEX_CUSTOM_IRQ_DEFINITIONS_PATH
|
||||
#else
|
||||
|
||||
#include <arch/mode.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Map RISC-V exception code to NuttX IRQ */
|
||||
|
||||
#define LITEX_IRQ_UART0 (RISCV_IRQ_MEXT + 1)
|
||||
#define LITEX_IRQ_TIMER0 (RISCV_IRQ_MEXT + 2)
|
||||
#define LITEX_IRQ_ETHMAC (RISCV_IRQ_MEXT + 3)
|
||||
#define LITEX_IRQ_SDCARD (RISCV_IRQ_MEXT + 4)
|
||||
#define LITEX_IRQ_GPIO (RISCV_IRQ_MEXT + 5)
|
||||
#define LITEX_IRQ_UART0 (RISCV_IRQ_EXT + 1)
|
||||
#define LITEX_IRQ_TIMER0 (RISCV_IRQ_EXT + 2)
|
||||
#define LITEX_IRQ_ETHMAC (RISCV_IRQ_EXT + 3)
|
||||
#define LITEX_IRQ_SDCARD (RISCV_IRQ_EXT + 4)
|
||||
#define LITEX_IRQ_GPIO (RISCV_IRQ_EXT + 5)
|
||||
|
||||
/* The last hardware IRQ number */
|
||||
|
||||
|
@ -148,3 +148,32 @@ config LITEX_EMAC_PHYADDR
|
||||
The 5-bit address of the PHY on the board. Default: 1
|
||||
|
||||
endmenu # PHY interface
|
||||
|
||||
menu "LITEX MMU options"
|
||||
depends on ARCH_USE_MMU
|
||||
|
||||
config LITEX_MMU_IO_BASE
|
||||
hex "IO base address."
|
||||
default 0x80000000
|
||||
---help---
|
||||
The base address for the IO MMU mapping.
|
||||
|
||||
config LITEX_MMU_IO_SIZE
|
||||
hex "IO base address."
|
||||
default 0x7F000000
|
||||
---help---
|
||||
The size for the IO MMU mapping.
|
||||
|
||||
config LITEX_MMU_L1_SIZE
|
||||
int "L1 page table size."
|
||||
default 1024
|
||||
---help---
|
||||
The size of the L1 page table. Each entry in the page table represents a 4MB L1 page.
|
||||
|
||||
config LITEX_MMU_L2_SIZE
|
||||
int "L2 page table size."
|
||||
default 4096
|
||||
---help---
|
||||
The size of the L2 page table. Each entry in the page table represents a 4kB L1 page.
|
||||
|
||||
endmenu # LITEX MMU options
|
||||
|
@ -22,7 +22,11 @@ include common/Make.defs
|
||||
|
||||
# Specify our HEAD assembly file. This will be linked as
|
||||
# the first object file, so it will appear at address 0
|
||||
ifeq ($(CONFIG_LITEX_CORE_VEXRISCV_SMP),y)
|
||||
HEAD_ASRC = litex_shead.S
|
||||
else
|
||||
HEAD_ASRC = litex_head.S
|
||||
endif
|
||||
|
||||
# Specify our C code within this directory to be included
|
||||
CHIP_CSRCS = litex_allocateheap.c litex_clockconfig.c
|
||||
@ -31,6 +35,9 @@ CHIP_CSRCS += litex_lowputc.c litex_serial.c
|
||||
CHIP_CSRCS += litex_start.c litex_timerisr.c
|
||||
CHIP_ASRCS += litex_cache.S
|
||||
|
||||
ifeq ($(CONFIG_BUILD_KERNEL),y)
|
||||
CHIP_CSRCS += litex_mm_init.c litex_pgalloc.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_LITEX_GPIO),y)
|
||||
CHIP_CSRCS += litex_gpio.c
|
||||
|
@ -29,4 +29,28 @@
|
||||
|
||||
#include "litex_memorymap.h"
|
||||
|
||||
#include "riscv_internal.h"
|
||||
#include "riscv_percpu.h"
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
|
||||
/****************************************************************************
|
||||
* Name: setintstack
|
||||
*
|
||||
* Description:
|
||||
* Set the current stack pointer to the "top" the correct interrupt stack.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 15
|
||||
#if !defined(CONFIG_SMP) && defined(CONFIG_ARCH_USE_S_MODE)
|
||||
.macro setintstack tmp0, tmp1
|
||||
csrr \tmp0, CSR_SCRATCH
|
||||
REGLOAD sp, RISCV_PERCPU_IRQSTACK(\tmp0)
|
||||
.endm
|
||||
#endif /* !defined(CONFIG_SMP) && defined(CONFIG_ARCH_USE_S_MODE) */
|
||||
#endif /* CONFIG_ARCH_INTERRUPTSTACK > 15 */
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __ARCH_RISCV_SRC_LITEX_CHIP_H */
|
||||
|
@ -24,9 +24,18 @@
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
#ifdef CONFIG_LITEX_CORE_VEXRISCV_SMP
|
||||
|
||||
#define LITEX_CLINT_MSIP (LITEX_CLINT_BASE + 0x0000)
|
||||
#define LITEX_CLINT_MTIMECMP (LITEX_CLINT_BASE + 0x4000)
|
||||
#define LITEX_CLINT_MTIME (LITEX_CLINT_BASE + 0xbff8)
|
||||
|
||||
#else
|
||||
|
||||
#define LITEX_CLINT_LATCH (LITEX_CPUTIMER_BASE)
|
||||
#define LITEX_CLINT_MTIME (LITEX_CPUTIMER_BASE + 0x04)
|
||||
#define LITEX_CLINT_MTIMECMP (LITEX_CPUTIMER_BASE + 0x0C)
|
||||
|
||||
#endif /* CONFIG_LITEX_CORE_VEXRISCV_SMP */
|
||||
|
||||
#endif /* __ARCH_RISCV_SRC_LITEX_HARDWARE_LITEX_CLINT_H */
|
||||
|
@ -35,20 +35,30 @@
|
||||
|
||||
/* Register Base Address ****************************************************/
|
||||
|
||||
/* litex vexRiscv does not follow RISC-V privileged specification and
|
||||
* uses two additional CSRs: mask and pending.
|
||||
*/
|
||||
|
||||
#define LITEX_CPUTIMER_BASE 0xf0000800
|
||||
#define LITEX_ETHMAC_BASE 0xf0001000
|
||||
#define LITEX_ETHPHY_BASE 0xf0001800
|
||||
#define LITEX_SDBLOCK2MEM_BASE 0xf0003000
|
||||
#define LITEX_SDCORE_BASE 0xf0003800
|
||||
#define LITEX_SDIRQ_BASE 0xf0004000
|
||||
#define LITEX_SDMEM2BLOCK_BASE 0xf0004800
|
||||
#define LITEX_SDPHY_BASE 0xf0005000
|
||||
#define LITEX_TIMER0_BASE 0xf0006000
|
||||
#define LITEX_UART0_BASE 0xf0006800
|
||||
#ifdef CONFIG_LITEX_CORE_VEXRISCV_SMP
|
||||
#define LITEX_CLINT_BASE 0xf0010000
|
||||
#define LITEX_PLIC_BASE 0xf0c00000
|
||||
#define LITEX_ETHMAC_BASE 0xf0002000
|
||||
#define LITEX_ETHPHY_BASE 0xf0002800
|
||||
#define LITEX_TIMER0_BASE 0xf0001800
|
||||
#define LITEX_UART0_BASE 0xf0001000
|
||||
#define LITEX_SDBLOCK2MEM_BASE 0xf0004000
|
||||
#define LITEX_SDCORE_BASE 0xf0004800
|
||||
#define LITEX_SDIRQ_BASE 0xf0005000
|
||||
#define LITEX_SDMEM2BLOCK_BASE 0xf0005800
|
||||
#define LITEX_SDPHY_BASE 0xf0006000
|
||||
#else
|
||||
#define LITEX_CPUTIMER_BASE 0xf0000800
|
||||
#define LITEX_ETHMAC_BASE 0xf0001000
|
||||
#define LITEX_ETHPHY_BASE 0xf0001800
|
||||
#define LITEX_TIMER0_BASE 0xf0006000
|
||||
#define LITEX_UART0_BASE 0xf0006800
|
||||
#define LITEX_SDBLOCK2MEM_BASE 0xf0003000
|
||||
#define LITEX_SDCORE_BASE 0xf0003800
|
||||
#define LITEX_SDIRQ_BASE 0xf0004000
|
||||
#define LITEX_SDMEM2BLOCK_BASE 0xf0004800
|
||||
#define LITEX_SDPHY_BASE 0xf0005000
|
||||
#endif
|
||||
|
||||
/* GPIO peripheral definitions.
|
||||
* - LITEX_GPIO_BASE is the first 32-bit address which contains a block
|
||||
|
@ -21,14 +21,32 @@
|
||||
#ifndef __ARCH_RISCV_SRC_LITEX_HARDWARE_LITEX_PLIC_H
|
||||
#define __ARCH_RISCV_SRC_LITEX_HARDWARE_LITEX_PLIC_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "litex_memorymap.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LITEX_CORE_VEXRISCV_SMP
|
||||
# define LITEX_PLIC_PRIORITY (LITEX_PLIC_BASE + 0x000000)
|
||||
# define LITEX_PLIC_PENDING1 (LITEX_PLIC_BASE + 0x001000)
|
||||
|
||||
# define LITEX_PLIC_ENABLE1 (LITEX_PLIC_BASE + 0x002080)
|
||||
# define LITEX_PLIC_ENABLE2 (LITEX_PLIC_BASE + 0x002084)
|
||||
# define LITEX_PLIC_THRESHOLD (LITEX_PLIC_BASE + 0x201000)
|
||||
# define LITEX_PLIC_CLAIM (LITEX_PLIC_BASE + 0x201004)
|
||||
#else
|
||||
|
||||
/* litex vexRiscv does not follow RISC-V privileged specification and
|
||||
* uses two additional CSRs: mask and pending.
|
||||
*/
|
||||
#define LITEX_MMASK_CSR 0xBC0
|
||||
#define LITEX_MPENDING_CSR 0xFC0
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __ARCH_RISCV_SRC_LITEX_HARDWARE_LITEX_PLIC_H */
|
||||
|
58
arch/risc-v/src/litex/hardware/litex_timer.h
Normal file
58
arch/risc-v/src/litex/hardware/litex_timer.h
Normal file
@ -0,0 +1,58 @@
|
||||
/****************************************************************************
|
||||
* arch/risc-v/src/litex/hardware/litex_timer.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_RISCV_SRC_LITEX_HARDWARE_LITEX_TIMER_H
|
||||
#define __ARCH_RISCV_SRC_LITEX_HARDWARE_LITEX_TIMER_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "hardware/litex_memorymap.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* LITEX_TIMER register offsets *********************************************/
|
||||
|
||||
#define LITEX_TIMER_LOAD_OFFSET 0x0000
|
||||
#define LITEX_TIMER_RELOAD_OFFSET 0x0004
|
||||
#define LITEX_TIMER_EN_OFFSET 0x0008
|
||||
#define LITEX_TIMER_UPDATE_VALUE_OFFSET 0x000C
|
||||
#define LITEX_TIMER_VALUE_OFFSET 0x0010
|
||||
#define LITEX_TIMER_EV_STATUS_OFFSET 0x0014
|
||||
#define LITEX_TIMER_EV_PENDING_OFFSET 0x0018
|
||||
#define LITEX_TIMER_EV_ENABLE_OFFSET 0x001C
|
||||
|
||||
/* LITEX_TIMER register addresses *******************************************/
|
||||
|
||||
#define LITEX_TIMER0_LOAD (LITEX_TIMER0_BASE+LITEX_TIMER_LOAD_OFFSET)
|
||||
#define LITEX_TIMER0_RELOAD (LITEX_TIMER0_BASE+LITEX_TIMER_RELOAD_OFFSET)
|
||||
#define LITEX_TIMER0_EN (LITEX_TIMER0_BASE+LITEX_TIMER_EN_OFFSET)
|
||||
#define LITEX_TIMER0_UPDATE_VALUE (LITEX_TIMER0_BASE+LITEX_TIMER_UPDATE_VALUE_OFFSET)
|
||||
#define LITEX_TIMER0_VALUE (LITEX_TIMER0_BASE+LITEX_TIMER_VALUE_OFFSET)
|
||||
#define LITEX_TIMER0_EV_STATUS (LITEX_TIMER0_BASE+LITEX_TIMER_EV_STATUS_OFFSET)
|
||||
#define LITEX_TIMER0_EV_PENDING (LITEX_TIMER0_BASE+LITEX_TIMER_EV_PENDING_OFFSET)
|
||||
#define LITEX_TIMER0_EV_ENABLE (LITEX_TIMER0_BASE+LITEX_TIMER_EV_ENABLE_OFFSET)
|
||||
|
||||
/* LITEX_TIMER register bit definitions *************************************/
|
||||
|
||||
#endif /* __ARCH_RISCV_SRC_LITEX_HARDWARE_LITEX_TIMER_H */
|
@ -29,10 +29,45 @@
|
||||
|
||||
#include "litex.h"
|
||||
|
||||
#ifdef CONFIG_MM_KERNEL_HEAP
|
||||
#include <arch/board/board_memorymap.h>
|
||||
#endif
|
||||
|
||||
#include "riscv_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_MM_KERNEL_HEAP
|
||||
#define KRAM_END KSRAM_END
|
||||
#else
|
||||
#define KRAM_END CONFIG_RAM_END
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_allocate_heap
|
||||
*
|
||||
* Description:
|
||||
* This function will be called to dynamically set aside the heap region
|
||||
* based on kernel or flat builds.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
void up_allocate_kheap(void **heap_start, size_t *heap_size)
|
||||
#else
|
||||
void up_allocate_heap(void **heap_start, size_t *heap_size)
|
||||
#endif /* CONFIG_BUILD_KERNEL */
|
||||
{
|
||||
*heap_start = (void *)g_idle_topstack;
|
||||
*heap_size = KRAM_END - g_idle_topstack;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: riscv_addregion
|
||||
*
|
||||
|
@ -51,7 +51,11 @@ void up_irqinitialize(void)
|
||||
|
||||
/* Disable all global interrupts */
|
||||
|
||||
#ifdef CONFIG_ARCH_USE_S_MODE
|
||||
putreg32(0x0, LITEX_PLIC_ENABLE1);
|
||||
#else
|
||||
asm volatile ("csrw %0, %1" :: "i"(LITEX_MMASK_CSR), "r"(0));
|
||||
#endif
|
||||
|
||||
/* Colorize the interrupt stack for debug purposes */
|
||||
|
||||
@ -62,6 +66,23 @@ void up_irqinitialize(void)
|
||||
|
||||
/* litex vexriscv dont have priority and threshold control */
|
||||
|
||||
#ifdef CONFIG_LITEX_CORE_VEXRISCV_SMP
|
||||
/* litex vexriscv_smp does. */
|
||||
|
||||
/* Set priority for all global interrupts to 1 (lowest) */
|
||||
|
||||
int id;
|
||||
|
||||
for (id = 1; id <= 31; id++)
|
||||
{
|
||||
putreg32(1, (uintptr_t)(LITEX_PLIC_PRIORITY + 4 * id));
|
||||
}
|
||||
|
||||
/* Set irq threshold to 0 (permits all global interrupts) */
|
||||
|
||||
putreg32(0, LITEX_PLIC_THRESHOLD);
|
||||
#endif
|
||||
|
||||
/* Attach the common interrupt handler */
|
||||
|
||||
riscv_exception_attach();
|
||||
@ -82,6 +103,41 @@ void up_irqinitialize(void)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LITEX_CORE_VEXRISCV_SMP
|
||||
void up_disable_irq(int irq)
|
||||
{
|
||||
int extirq;
|
||||
|
||||
if (irq == RISCV_IRQ_SOFT)
|
||||
{
|
||||
/* Read m/sstatus & clear machine software interrupt enable in m/sie */
|
||||
|
||||
CLEAR_CSR(CSR_IE, IE_SIE);
|
||||
}
|
||||
else if (irq == RISCV_IRQ_TIMER)
|
||||
{
|
||||
/* Read m/sstatus & clear timer interrupt enable in m/sie */
|
||||
|
||||
CLEAR_CSR(CSR_IE, IE_TIE);
|
||||
}
|
||||
else if (irq > RISCV_IRQ_EXT)
|
||||
{
|
||||
extirq = irq - RISCV_IRQ_EXT;
|
||||
|
||||
/* Clear enable bit for the irq */
|
||||
|
||||
if (1 <= extirq && extirq <= 31)
|
||||
{
|
||||
modifyreg32(LITEX_PLIC_ENABLE1 + (4 * (extirq / 32)),
|
||||
1 << (extirq % 32), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
PANIC();
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
void up_disable_irq(int irq)
|
||||
{
|
||||
int extirq;
|
||||
@ -118,6 +174,7 @@ void up_disable_irq(int irq)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_enable_irq
|
||||
@ -127,6 +184,41 @@ void up_disable_irq(int irq)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LITEX_CORE_VEXRISCV_SMP
|
||||
void up_enable_irq(int irq)
|
||||
{
|
||||
int extirq;
|
||||
|
||||
if (irq == RISCV_IRQ_SOFT)
|
||||
{
|
||||
/* Read sstatus and set supervisor software interrupt enable in sie */
|
||||
|
||||
SET_CSR(CSR_IE, IE_SIE);
|
||||
}
|
||||
else if (irq == RISCV_IRQ_TIMER)
|
||||
{
|
||||
/* Read sstatus & set timer interrupt enable in sie */
|
||||
|
||||
SET_CSR(CSR_IE, IE_TIE);
|
||||
}
|
||||
else if (irq >= RISCV_IRQ_EXT)
|
||||
{
|
||||
extirq = irq - RISCV_IRQ_EXT;
|
||||
|
||||
/* Set enable bit for the irq in plic */
|
||||
|
||||
if (0 <= extirq && extirq <= 31)
|
||||
{
|
||||
modifyreg32(LITEX_PLIC_ENABLE1 + (4 * (extirq / 32)),
|
||||
0, 1 << (extirq % 32));
|
||||
}
|
||||
else
|
||||
{
|
||||
PANIC();
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
void up_enable_irq(int irq)
|
||||
{
|
||||
int extirq;
|
||||
@ -163,6 +255,7 @@ void up_enable_irq(int irq)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: riscv_ack_irq
|
||||
@ -189,15 +282,15 @@ irqstate_t up_irq_enable(void)
|
||||
irqstate_t oldstat;
|
||||
|
||||
#if 1
|
||||
/* Enable MEIE (machine external interrupt enable) */
|
||||
/* Enable EIE (machine/supervisor external interrupt enable) */
|
||||
|
||||
/* TODO: should move to up_enable_irq() */
|
||||
|
||||
SET_CSR(mie, MIE_MEIE);
|
||||
SET_CSR(CSR_IE, IE_EIE);
|
||||
#endif
|
||||
|
||||
/* Read mstatus & set machine interrupt enable (MIE) in mstatus */
|
||||
/* Read s/mstatus & set interrupt enable (S/MIE) in s/mstatus */
|
||||
|
||||
oldstat = READ_AND_SET_CSR(mstatus, MSTATUS_MIE);
|
||||
oldstat = READ_AND_SET_CSR(CSR_STATUS, STATUS_IE);
|
||||
return oldstat;
|
||||
}
|
||||
|
@ -49,8 +49,48 @@
|
||||
|
||||
void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
|
||||
{
|
||||
int irq = (vector >> RV_IRQ_MASK) | (vector & 0xf);
|
||||
#ifdef CONFIG_LITEX_CORE_VEXRISCV_SMP
|
||||
int irq = (vector & 0x3f);
|
||||
|
||||
if ((vector & RISCV_IRQ_BIT) != 0)
|
||||
{
|
||||
irq += RISCV_IRQ_ASYNC;
|
||||
}
|
||||
|
||||
/* Firstly, check if the irq is machine external interrupt */
|
||||
|
||||
if (irq == RISCV_IRQ_EXT)
|
||||
{
|
||||
uint32_t ext = getreg32(LITEX_PLIC_CLAIM);
|
||||
|
||||
/* Add the value to nuttx irq which is offset to the ext */
|
||||
|
||||
irq = RISCV_IRQ_EXT + ext;
|
||||
}
|
||||
|
||||
/* Acknowledge the interrupt */
|
||||
|
||||
riscv_ack_irq(irq);
|
||||
|
||||
/* EXT means no interrupt */
|
||||
|
||||
if (irq != RISCV_IRQ_EXT)
|
||||
{
|
||||
/* Deliver the IRQ */
|
||||
|
||||
regs = riscv_doirq(irq, regs);
|
||||
}
|
||||
|
||||
if (irq > RISCV_IRQ_EXT)
|
||||
{
|
||||
/* Then write PLIC_CLAIM to clear pending in PLIC */
|
||||
|
||||
putreg32(irq - RISCV_IRQ_EXT, LITEX_PLIC_CLAIM);
|
||||
}
|
||||
|
||||
#else
|
||||
int i;
|
||||
int irq = (vector >> RV_IRQ_MASK) | (vector & 0xf);
|
||||
|
||||
/* Firstly, check if the irq is machine external interrupt */
|
||||
|
||||
@ -87,5 +127,6 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
|
||||
|
||||
regs = riscv_doirq(irq, regs);
|
||||
|
||||
#endif /* CONFIG_LITEX_CORE_VEXRISCV_SMP */
|
||||
return regs;
|
||||
}
|
||||
|
263
arch/risc-v/src/litex/litex_mm_init.c
Normal file
263
arch/risc-v/src/litex/litex_mm_init.c
Normal file
@ -0,0 +1,263 @@
|
||||
/****************************************************************************
|
||||
* arch/risc-v/src/litex/litex_mm_init.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <arch/board/board_memorymap.h>
|
||||
|
||||
#include "litex_memorymap.h"
|
||||
|
||||
#include "riscv_internal.h"
|
||||
#include "riscv_mmu.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Map the whole I/O memory with vaddr = paddr mappings */
|
||||
|
||||
#define MMU_IO_BASE CONFIG_LITEX_MMU_IO_BASE
|
||||
#define MMU_IO_SIZE CONFIG_LITEX_MMU_IO_SIZE
|
||||
|
||||
#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 (CONFIG_LITEX_MMU_L1_SIZE)
|
||||
#define PGT_L2_SIZE (CONFIG_LITEX_MMU_L2_SIZE)
|
||||
|
||||
#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
|
||||
|
||||
#else
|
||||
#error No valid MMU defined.
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct pgalloc_slab_s
|
||||
{
|
||||
sq_entry_t *next;
|
||||
void *memory;
|
||||
};
|
||||
typedef struct pgalloc_slab_s pgalloc_slab_t;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Kernel mappings simply here, mapping is vaddr=paddr */
|
||||
|
||||
static size_t m_l1_pgtable[PGT_L1_SIZE] locate_data(".pgtables");
|
||||
static size_t m_l2_pgtable[PGT_L2_SIZE] locate_data(".pgtables");
|
||||
|
||||
/* Kernel mappings (L1 base) */
|
||||
|
||||
uintptr_t g_kernel_mappings = PGT_L1_VBASE;
|
||||
uintptr_t g_kernel_pgt_pbase = PGT_L1_PBASE;
|
||||
|
||||
/* L2 page table allocator */
|
||||
|
||||
static sq_queue_t g_free_slabs;
|
||||
static pgalloc_slab_t g_slabs[SLAB_COUNT];
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: slab_init
|
||||
*
|
||||
* Description:
|
||||
* Initialize slab allocator for L2 page table entries
|
||||
*
|
||||
* Input Parameters:
|
||||
* start - Beginning of the L2 page table pool
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void slab_init(uintptr_t start)
|
||||
{
|
||||
int i;
|
||||
|
||||
sq_init(&g_free_slabs);
|
||||
|
||||
for (i = 0; i < SLAB_COUNT; i++)
|
||||
{
|
||||
g_slabs[i].memory = (void *)start;
|
||||
sq_addlast((sq_entry_t *)&g_slabs[i], (sq_queue_t *)&g_free_slabs);
|
||||
start += RV_MMU_PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: slab_alloc
|
||||
*
|
||||
* Description:
|
||||
* Allocate single slab for L2 page table entry
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uintptr_t slab_alloc(void)
|
||||
{
|
||||
pgalloc_slab_t *slab = (pgalloc_slab_t *)sq_remfirst(&g_free_slabs);
|
||||
return slab ? (uintptr_t)slab->memory : 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: map_region
|
||||
*
|
||||
* Description:
|
||||
* Map a region of physical memory to the L2 page table
|
||||
*
|
||||
* Input Parameters:
|
||||
* paddr - Beginning of the physical address mapping
|
||||
* vaddr - Beginning of the virtual address mapping
|
||||
* size - Size of the region in bytes
|
||||
* mmuflags - The MMU flags to use in the mapping
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void map_region(uintptr_t paddr, uintptr_t vaddr, size_t size,
|
||||
uint32_t mmuflags)
|
||||
{
|
||||
uintptr_t endaddr;
|
||||
uintptr_t pbase;
|
||||
int npages;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
/* How many pages */
|
||||
|
||||
npages = (size + RV_MMU_PAGE_MASK) >> RV_MMU_PAGE_SHIFT;
|
||||
endaddr = vaddr + size;
|
||||
|
||||
for (i = 0; i < npages; i += RV_MMU_PAGE_ENTRIES)
|
||||
{
|
||||
/* See if a L2 mapping exists ? */
|
||||
|
||||
pbase = mmu_pte_to_paddr(mmu_ln_getentry(
|
||||
KMM_SPBASE_IDX, KMM_SPBASE, vaddr));
|
||||
if (!pbase)
|
||||
{
|
||||
/* No, allocate 1 page, this must not fail */
|
||||
|
||||
pbase = slab_alloc();
|
||||
DEBUGASSERT(pbase);
|
||||
|
||||
/* Map it to the L2 table */
|
||||
|
||||
mmu_ln_setentry(
|
||||
KMM_SPBASE_IDX, KMM_SPBASE, pbase, vaddr, MMU_UPGT_FLAGS);
|
||||
}
|
||||
|
||||
/* Then add the L2 mappings */
|
||||
|
||||
for (j = 0; j < RV_MMU_PAGE_ENTRIES && vaddr < endaddr; j++)
|
||||
{
|
||||
mmu_ln_setentry(KMM_PBASE_IDX, pbase, paddr, vaddr, mmuflags);
|
||||
paddr += KMM_PAGE_SIZE;
|
||||
vaddr += KMM_PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: litex_kernel_mappings
|
||||
*
|
||||
* Description:
|
||||
* Setup kernel mappings when usinc CONFIG_BUILD_KERNEL. Sets up the kernel
|
||||
* MMU mappings.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void litex_kernel_mappings(void)
|
||||
{
|
||||
/* Initialize slab allocator for L2 page tables */
|
||||
|
||||
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
|
||||
* addresses and so forth. M-mode does not perform translations anyhow, so
|
||||
* this mapping is quite simple to do
|
||||
*/
|
||||
|
||||
binfo("map I/O regions\n");
|
||||
mmu_ln_map_region(1, PGT_L1_VBASE, MMU_IO_BASE, MMU_IO_BASE,
|
||||
MMU_IO_SIZE, MMU_IO_FLAGS);
|
||||
|
||||
/* Map the kernel text and data for L2 */
|
||||
|
||||
binfo("map kernel text\n");
|
||||
map_region(KFLASH_START, KFLASH_START, KFLASH_SIZE, MMU_KTEXT_FLAGS);
|
||||
|
||||
binfo("map kernel data\n");
|
||||
map_region(KSRAM_START, KSRAM_START, KSRAM_SIZE, MMU_KDATA_FLAGS);
|
||||
|
||||
binfo("map the page pool\n");
|
||||
map_region(PGPOOL_START, PGPOOL_START, PGPOOL_SIZE, MMU_KDATA_FLAGS);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: litex_mm_init
|
||||
*
|
||||
* Description:
|
||||
* Setup kernel mappings when using CONFIG_BUILD_KERNEL. Sets up kernel MMU
|
||||
* mappings. Function also sets the first address environment (satp value).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void litex_mm_init(void)
|
||||
{
|
||||
/* Setup the kernel mappings */
|
||||
|
||||
litex_kernel_mappings();
|
||||
|
||||
/* Enable MMU (note: system is still in M-mode) */
|
||||
|
||||
binfo("mmu_enable: satp=%" PRIuPTR "\n", g_kernel_pgt_pbase);
|
||||
mmu_enable(g_kernel_pgt_pbase, 0);
|
||||
}
|
58
arch/risc-v/src/litex/litex_mm_init.h
Normal file
58
arch/risc-v/src/litex/litex_mm_init.h
Normal file
@ -0,0 +1,58 @@
|
||||
/****************************************************************************
|
||||
* arch/risc-v/src/litex/litex_mm_init.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_RISC_V_SRC_LITEX_LITEX_MM_INIT_H
|
||||
#define __ARCH_RISC_V_SRC_LITEX_LITEX_MM_INIT_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include "riscv_mmu.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: litex_kernel_mappings
|
||||
*
|
||||
* Description:
|
||||
* Setup kernel mappings when using CONFIG_BUILD_KERNEL. Sets up the kernel
|
||||
* MMU mappings.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void litex_kernel_mappings(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: litex_mm_init
|
||||
*
|
||||
* Description:
|
||||
* Setup kernel mappings when using CONFIG_BUILD_KERNEL. Sets up kernel MMU
|
||||
* mappings. Function also sets the first address environment (satp value).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void litex_mm_init(void);
|
||||
|
||||
#endif /* __ARCH_RISC_V_SRC_LITEX_LITEX_MM_INIT_H */
|
67
arch/risc-v/src/litex/litex_pgalloc.c
Normal file
67
arch/risc-v/src/litex/litex_pgalloc.c
Normal file
@ -0,0 +1,67 @@
|
||||
/****************************************************************************
|
||||
* arch/risc-v/src/litex/litex_pgalloc.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/arch.h>
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/pgalloc.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <arch/board/board_memorymap.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_allocate_pgheap
|
||||
*
|
||||
* Description:
|
||||
* If there is a page allocator in the configuration, then this function
|
||||
* must be provided by the platform-specific code. The OS initialization
|
||||
* logic will call this function early in the initialization sequence to
|
||||
* get the page heap information needed to configure the page allocator.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_allocate_pgheap(void **heap_start, size_t *heap_size)
|
||||
{
|
||||
DEBUGASSERT(heap_start && heap_size);
|
||||
|
||||
*heap_start = (void *)PGPOOL_START;
|
||||
*heap_size = (size_t)PGPOOL_SIZE;
|
||||
}
|
94
arch/risc-v/src/litex/litex_shead.S
Normal file
94
arch/risc-v/src/litex/litex_shead.S
Normal file
@ -0,0 +1,94 @@
|
||||
/****************************************************************************
|
||||
* arch/risc-v/src/litex/litex_shead.S
|
||||
*
|
||||
* 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 <nuttx/irq.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "litex_memorymap.h"
|
||||
#include "riscv_internal.h"
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Public Symbols
|
||||
****************************************************************************/
|
||||
|
||||
/* Imported symbols */
|
||||
|
||||
.extern __trap_vec
|
||||
|
||||
.section .text
|
||||
.global __start
|
||||
|
||||
/****************************************************************************
|
||||
* Name: __start
|
||||
*
|
||||
* Description:
|
||||
* Supervisor mode start function.
|
||||
*
|
||||
* Input Parameters:
|
||||
* a0 - hartid
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
__start:
|
||||
/* Disable all interrupts in sie */
|
||||
|
||||
|
||||
csrw sie, zero
|
||||
csrw sip, zero
|
||||
|
||||
|
||||
/* Set the S-mode trap vector */
|
||||
|
||||
la t0, __trap_vec
|
||||
csrw stvec, t0
|
||||
|
||||
/* Clear sscratch */
|
||||
|
||||
csrw sscratch, zero
|
||||
csrw scause, zero
|
||||
csrw sepc, zero
|
||||
|
||||
/* initialize global pointer, global data */
|
||||
|
||||
|
||||
.option push
|
||||
.option norelax
|
||||
la gp, __global_pointer$
|
||||
|
||||
.option pop
|
||||
|
||||
lui sp, %hi(LITEX_IDLESTACK_TOP)
|
||||
addi sp, sp, %lo(LITEX_IDLESTACK_TOP)
|
||||
|
||||
/* Make sure the writes to CSR stick before continuing */
|
||||
|
||||
fence
|
||||
|
||||
/* Set stack pointer and jump to start */
|
||||
|
||||
/*la sp, LITEX_IDLESTACK_TOP*/
|
||||
j __litex_start
|
@ -33,6 +33,10 @@
|
||||
#include "litex.h"
|
||||
#include "chip.h"
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
# include "litex_mm_init.h"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
@ -43,6 +47,10 @@
|
||||
# define showprogress(c)
|
||||
#endif
|
||||
|
||||
#if defined (CONFIG_BUILD_KERNEL) && !defined (CONFIG_ARCH_USE_S_MODE)
|
||||
# error "Target requires kernel in S-mode, enable CONFIG_ARCH_USE_S_MODE"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
@ -96,6 +104,10 @@ void __litex_start(void)
|
||||
*dest++ = *src++;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LITEX_CORE_VEXRISCV_SMP
|
||||
riscv_percpu_add_hart(0);
|
||||
#endif
|
||||
|
||||
/* Setup PLL */
|
||||
|
||||
litex_clockconfig();
|
||||
@ -114,7 +126,11 @@ void __litex_start(void)
|
||||
|
||||
/* Do board initialization */
|
||||
|
||||
litex_boardinitialize();
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* Setup page tables for kernel and enable MMU */
|
||||
|
||||
litex_mm_init();
|
||||
#endif
|
||||
|
||||
showprogress('C');
|
||||
|
||||
|
@ -23,19 +23,17 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/clock.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
#include <arch/board/board.h>
|
||||
#include <nuttx/timers/arch_alarm.h>
|
||||
#include <nuttx/init.h>
|
||||
|
||||
#include <debug.h>
|
||||
#include "riscv_internal.h"
|
||||
|
||||
#include "litex.h"
|
||||
#include "litex_clockconfig.h"
|
||||
#include "hardware/litex_timer.h"
|
||||
#include "riscv_mtimer.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
@ -47,95 +45,33 @@
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static bool _b_tick_started = false;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/* litex mmio registers are a bit odd, by default they are byte-wide
|
||||
* registers that are on 32-bit word boundaries. So a "32-bit" registers
|
||||
* is actually broken into four bytes spanning a total address space of
|
||||
* 16 bytes.
|
||||
*/
|
||||
|
||||
static inline uint64_t litex_clint_time_read(void)
|
||||
{
|
||||
uint64_t r = getreg32(LITEX_CLINT_MTIME);
|
||||
r <<= 32;
|
||||
r |= getreg32(LITEX_CLINT_MTIME + 0x04);
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline uint64_t litex_clint_time_cmp_read(void)
|
||||
{
|
||||
uint64_t r = getreg32(LITEX_CLINT_MTIMECMP);
|
||||
r <<= 32;
|
||||
r |= getreg32(LITEX_CLINT_MTIMECMP + 0x04);
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline void litex_clint_time_cmp_write(uint64_t v)
|
||||
{
|
||||
putreg32(v >> 32, LITEX_CLINT_MTIMECMP);
|
||||
putreg32(v, LITEX_CLINT_MTIMECMP + 0x04);
|
||||
}
|
||||
|
||||
/* helper function to set/clear csr */
|
||||
|
||||
#define csr_clear(csr, val) \
|
||||
({ \
|
||||
unsigned long __v = (unsigned long)(val); \
|
||||
__asm__ __volatile__ ("csrc " #csr ", %0" \
|
||||
: : "rK" (__v)); \
|
||||
})
|
||||
|
||||
#define csr_set(csr, val) \
|
||||
({ \
|
||||
unsigned long __v = (unsigned long)(val); \
|
||||
__asm__ __volatile__ ("csrs " #csr ", %0" \
|
||||
: : "rK" (__v)); \
|
||||
})
|
||||
|
||||
/****************************************************************************
|
||||
* Name: litex_reload_mtimecmp
|
||||
****************************************************************************/
|
||||
|
||||
static void litex_reload_mtimecmp(void)
|
||||
{
|
||||
irqstate_t flags = spin_lock_irqsave(NULL);
|
||||
|
||||
uint64_t current;
|
||||
uint64_t next;
|
||||
|
||||
if (!_b_tick_started)
|
||||
{
|
||||
_b_tick_started = true;
|
||||
putreg32(1, LITEX_CLINT_LATCH);
|
||||
current = litex_clint_time_read();
|
||||
}
|
||||
else
|
||||
{
|
||||
current = litex_clint_time_cmp_read();
|
||||
}
|
||||
|
||||
next = current + TICK_COUNT;
|
||||
|
||||
litex_clint_time_cmp_write(next);
|
||||
putreg32(1, LITEX_CLINT_LATCH);
|
||||
csr_set(mie, MIE_MTIE);
|
||||
csr_clear(mip, MIP_MTIP);
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: litex_timerisr
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LITEX_CORE_VEXRISCV_SMP
|
||||
static void litex_mtimer_initialise(void)
|
||||
{
|
||||
struct oneshot_lowerhalf_s *lower = riscv_mtimer_initialize(
|
||||
LITEX_CLINT_MTIME, LITEX_CLINT_MTIMECMP,
|
||||
RISCV_IRQ_TIMER, litex_get_hfclk());
|
||||
|
||||
DEBUGASSERT(lower);
|
||||
|
||||
up_alarm_set_lowerhalf(lower);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int litex_timerisr(int irq, void *context, void *arg)
|
||||
{
|
||||
litex_reload_mtimecmp();
|
||||
/* Clear timer interrupt */
|
||||
|
||||
putreg32(0xffffffff, LITEX_TIMER0_EV_PENDING);
|
||||
|
||||
/* Process timer interrupt */
|
||||
|
||||
@ -143,6 +79,33 @@ static int litex_timerisr(int irq, void *context, void *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void litex_timer0_initialize(void)
|
||||
{
|
||||
/* Disable the timer and clear any pending interrupt */
|
||||
|
||||
putreg32(0, LITEX_TIMER0_EN);
|
||||
putreg32(getreg32(LITEX_TIMER0_EV_PENDING), LITEX_TIMER0_EV_PENDING);
|
||||
|
||||
/* Set the timer period */
|
||||
|
||||
putreg32(TICK_COUNT, LITEX_TIMER0_RELOAD);
|
||||
putreg32(getreg32(LITEX_TIMER0_RELOAD), LITEX_TIMER0_LOAD);
|
||||
|
||||
/* Attach timer interrupt handler */
|
||||
|
||||
irq_attach(LITEX_IRQ_TIMER0, litex_timerisr, NULL);
|
||||
|
||||
/* Enable the timer */
|
||||
|
||||
putreg32(1, LITEX_TIMER0_EN);
|
||||
|
||||
/* And enable the timer interrupt */
|
||||
|
||||
putreg32(1, LITEX_TIMER0_EV_ENABLE);
|
||||
up_enable_irq(LITEX_IRQ_TIMER0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -158,15 +121,9 @@ static int litex_timerisr(int irq, void *context, void *arg)
|
||||
|
||||
void up_timer_initialize(void)
|
||||
{
|
||||
/* Attach timer interrupt handler */
|
||||
|
||||
irq_attach(RISCV_IRQ_MTIMER, litex_timerisr, NULL);
|
||||
|
||||
/* Reload CLINT mtimecmp */
|
||||
|
||||
litex_reload_mtimecmp();
|
||||
|
||||
/* And enable the timer interrupt */
|
||||
|
||||
up_enable_irq(RISCV_IRQ_MTIMER);
|
||||
#ifdef CONFIG_LITEX_CORE_VEXRISCV_SMP
|
||||
litex_mtimer_initialise();
|
||||
#else
|
||||
litex_timer0_initialize();
|
||||
#endif
|
||||
}
|
||||
|
@ -25,4 +25,12 @@ config LITEX_SDIO_MOUNT_FSTYPE
|
||||
default "vfat"
|
||||
depends on LITEX_SDIO
|
||||
|
||||
config LITEX_APPLICATION_RAMDISK
|
||||
bool "Use application ramdisk"
|
||||
depends on BUILD_KERNEL
|
||||
---help---
|
||||
The application ramdisk is currently only intended only to hold
|
||||
application elfs in the romfs format. These applications must loaded
|
||||
externally into ram through litex_term, or similar method.
|
||||
|
||||
endif
|
||||
|
84
boards/risc-v/litex/arty_a7/configs/knsh/defconfig
Normal file
84
boards/risc-v/litex/arty_a7/configs/knsh/defconfig
Normal file
@ -0,0 +1,84 @@
|
||||
#
|
||||
# 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_DEBUG_OPT_UNUSED_SECTIONS is not set
|
||||
# CONFIG_NSH_DISABLE_LOSMART is not set
|
||||
# CONFIG_STANDARD_SERIAL is not set
|
||||
CONFIG_ALARM_ARCH=y
|
||||
CONFIG_ARCH="risc-v"
|
||||
CONFIG_ARCH_ADDRENV=y
|
||||
CONFIG_ARCH_BOARD="arty_a7"
|
||||
CONFIG_ARCH_BOARD_ARTY_A7=y
|
||||
CONFIG_ARCH_CHIP="litex"
|
||||
CONFIG_ARCH_CHIP_LITEX=y
|
||||
CONFIG_ARCH_DATA_NPAGES=128
|
||||
CONFIG_ARCH_DATA_VBASE=0x10400000
|
||||
CONFIG_ARCH_HEAP_NPAGES=128
|
||||
CONFIG_ARCH_HEAP_VBASE=0x10800000
|
||||
CONFIG_ARCH_INTERRUPTSTACK=8192
|
||||
CONFIG_ARCH_KERNEL_STACKSIZE=3072
|
||||
CONFIG_ARCH_PGPOOL_MAPPING=y
|
||||
CONFIG_ARCH_PGPOOL_PBASE=0x40800000
|
||||
CONFIG_ARCH_PGPOOL_SIZE=4194304
|
||||
CONFIG_ARCH_PGPOOL_VBASE=0x40800000
|
||||
CONFIG_ARCH_RISCV=y
|
||||
CONFIG_ARCH_STACKDUMP=y
|
||||
CONFIG_ARCH_TEXT_NPAGES=128
|
||||
CONFIG_ARCH_TEXT_VBASE=0x10000000
|
||||
CONFIG_ARCH_USE_MMU=y
|
||||
CONFIG_ARCH_USE_MPU=y
|
||||
CONFIG_ARCH_USE_S_MODE=y
|
||||
CONFIG_BOARDCTL_ROMDISK=y
|
||||
CONFIG_BOARD_LATE_INITIALIZE=y
|
||||
CONFIG_BOARD_LOOPSPERMSEC=10000
|
||||
CONFIG_BUILD_KERNEL=y
|
||||
CONFIG_DEV_ZERO=y
|
||||
CONFIG_ELF=y
|
||||
CONFIG_EXAMPLES_HELLO=y
|
||||
CONFIG_FS_PROCFS=y
|
||||
CONFIG_FS_PROCFS_EXCLUDE_ENVIRON=y
|
||||
CONFIG_FS_ROMFS=y
|
||||
CONFIG_IDLETHREAD_STACKSIZE=2048
|
||||
CONFIG_INIT_FILEPATH="/system/bin/init"
|
||||
CONFIG_INIT_MOUNT=y
|
||||
CONFIG_INIT_MOUNT_FLAGS=0x1
|
||||
CONFIG_INIT_MOUNT_TARGET="/system/bin"
|
||||
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_LITEX_APPLICATION_RAMDISK=y
|
||||
CONFIG_LITEX_CORE_VEXRISCV_SMP=y
|
||||
CONFIG_LITEX_SYS_CORE_FREQ_HZ=300000000
|
||||
CONFIG_MM_PGALLOC=y
|
||||
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
|
||||
CONFIG_NSH_FILEIOSIZE=512
|
||||
CONFIG_NSH_FILE_APPS=y
|
||||
CONFIG_NSH_READLINE=y
|
||||
CONFIG_ONESHOT=y
|
||||
CONFIG_PATH_INITIAL="/system/bin"
|
||||
CONFIG_RAM_SIZE=4194304
|
||||
CONFIG_RAM_START=0x40400000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_READLINE_CMD_HISTORY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_LPWORK=y
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_START_MONTH=12
|
||||
CONFIG_START_YEAR=2021
|
||||
CONFIG_SYMTAB_ORDEREDBYNAME=y
|
||||
CONFIG_SYSLOG_PROCESS_NAME=y
|
||||
CONFIG_SYSLOG_TIMESTAMP=y
|
||||
CONFIG_SYSTEM_CLE=y
|
||||
CONFIG_SYSTEM_NSH=y
|
||||
CONFIG_SYSTEM_NSH_PROGNAME="init"
|
||||
CONFIG_TESTING_GETPRIME=y
|
||||
CONFIG_UART0_RXBUFSIZE=128
|
||||
CONFIG_UART0_SERIAL_CONSOLE=y
|
||||
CONFIG_UART0_TXBUFSIZE=128
|
93
boards/risc-v/litex/arty_a7/include/board_memorymap.h
Normal file
93
boards/risc-v/litex/arty_a7/include/board_memorymap.h
Normal file
@ -0,0 +1,93 @@
|
||||
/****************************************************************************
|
||||
* boards/risc-v/litex/arty_a7/include/board_memorymap.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __BOARDS_RISCV_LITEX_ARTY_A7_INCLUDE_BOARD_MEMORYMAP_H
|
||||
#define __BOARDS_RISCV_LITEX_ARTY_A7_INCLUDE_BOARD_MEMORYMAP_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Kernel code memory (RX) */
|
||||
|
||||
#define KFLASH_START (uintptr_t)__kflash_start
|
||||
#define KFLASH_SIZE (uintptr_t)__kflash_size
|
||||
#define KSRAM_START (uintptr_t)__ksram_start
|
||||
#define KSRAM_SIZE (uintptr_t)__ksram_size
|
||||
#define KSRAM_END (uintptr_t)__ksram_end
|
||||
|
||||
/* Kernel RAM (RW) */
|
||||
|
||||
#define PGPOOL_START (uintptr_t)__pgheap_start
|
||||
#define PGPOOL_SIZE (uintptr_t)__pgheap_size
|
||||
|
||||
/* Page pool (RWX) */
|
||||
|
||||
#define PGPOOL_START (uintptr_t)__pgheap_start
|
||||
#define PGPOOL_SIZE (uintptr_t)__pgheap_size
|
||||
#define PGPOOL_END (PGPOOL_START + PGPOOL_SIZE)
|
||||
|
||||
/* User flash */
|
||||
|
||||
#define UFLASH_START (uintptr_t)__uflash_start
|
||||
#define UFLASH_SIZE (uintptr_t)__uflash_size
|
||||
|
||||
/* RAMDisk */
|
||||
|
||||
#define RAMDISK_START (uintptr_t)__ramdisk_start
|
||||
#define RAMDISK_SIZE (uintptr_t)__ramdisk_size
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Kernel code memory (RX) */
|
||||
|
||||
extern uint8_t __kflash_start[];
|
||||
extern uint8_t __kflash_size[];
|
||||
|
||||
/* Kernel RAM (RW) */
|
||||
|
||||
extern uint8_t __ksram_start[];
|
||||
extern uint8_t __ksram_size[];
|
||||
extern uint8_t __ksram_end[];
|
||||
|
||||
/* Page pool (RWX) */
|
||||
|
||||
extern uint8_t __pgheap_start[];
|
||||
extern uint8_t __pgheap_size[];
|
||||
|
||||
/* User code memory (RX) */
|
||||
|
||||
extern uint8_t __uflash_start[];
|
||||
extern uint8_t __uflash_size[];
|
||||
|
||||
/* ramdisk (RW) */
|
||||
|
||||
extern uint8_t __ramdisk_start[];
|
||||
extern uint8_t __ramdisk_size[];
|
||||
|
||||
#endif /* __BOARDS_RISC_V_LITEX_ARTY_A7_INCLUDE_BOARD_MEMORYMAP_H */
|
@ -22,7 +22,12 @@ include $(TOPDIR)/.config
|
||||
include $(TOPDIR)/tools/Config.mk
|
||||
include $(TOPDIR)/arch/risc-v/src/common/Toolchain.defs
|
||||
|
||||
ifeq ($(CONFIG_BUILD_KERNEL),y)
|
||||
LDSCRIPT = ld-kernel.script
|
||||
else
|
||||
LDSCRIPT = ld.script
|
||||
endif
|
||||
|
||||
ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT)
|
||||
|
||||
ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10
|
||||
@ -33,3 +38,11 @@ CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES
|
||||
CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
|
||||
CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS)
|
||||
AFLAGS += $(CFLAGS) -D__ASSEMBLY__
|
||||
|
||||
CELFFLAGS = $(CFLAGS)
|
||||
CXXELFFLAGS = $(CXXFLAGS)
|
||||
|
||||
LDELFFLAGS = --oformat elf32-littleriscv
|
||||
|
||||
LDELFFLAGS += -r -e main
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/binfmt/libelf/gnu-elf.ld)
|
135
boards/risc-v/litex/arty_a7/scripts/ld-kernel.script
Normal file
135
boards/risc-v/litex/arty_a7/scripts/ld-kernel.script
Normal file
@ -0,0 +1,135 @@
|
||||
/****************************************************************************
|
||||
* boards/risc-v/litex/arty_a7/scripts/ld-kernel.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 = 0x40000000, LENGTH = 4096K /* w/ cache */
|
||||
ksram (rwx) : ORIGIN = 0x40400000, LENGTH = 4096K /* w/ cache */
|
||||
pgram (rwx) : ORIGIN = 0x40800000, LENGTH = 4096K /* w/ cache */
|
||||
ramdisk (rwx) : ORIGIN = 0x40C00000, 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) + LENGTH(ramdisk);
|
||||
|
||||
/* Application ramdisk */
|
||||
|
||||
__ramdisk_start = ORIGIN(ramdisk);
|
||||
__ramdisk_size = LENGTH(ramdisk);
|
||||
__ramdisk_end = ORIGIN(ramdisk) + LENGTH(ramdisk);
|
||||
|
||||
ENTRY(_stext)
|
||||
EXTERN(__start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x40000000;
|
||||
.text : {
|
||||
_stext = ABSOLUTE(.);
|
||||
*(.start .start.*)
|
||||
*(.text .text.*)
|
||||
*(.fixup)
|
||||
*(.gnu.warning)
|
||||
*(.rodata .rodata.* .srodata .srodata.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.got)
|
||||
*(.gcc_except_table)
|
||||
*(.gnu.linkonce.r.*)
|
||||
_etext = ABSOLUTE(.);
|
||||
} > kflash
|
||||
|
||||
.init_section : ALIGN(4) {
|
||||
_sinit = ABSOLUTE(.);
|
||||
KEEP(*(.init_array .init_array.*))
|
||||
_einit = ABSOLUTE(.);
|
||||
} > kflash
|
||||
|
||||
_eronly = ABSOLUTE(.);
|
||||
|
||||
/* No init section */
|
||||
|
||||
.noinit (NOLOAD) : ALIGN(4) {
|
||||
*(.noinit)
|
||||
*(.noinit.*)
|
||||
} > ksram
|
||||
|
||||
.data : ALIGN(4) {
|
||||
_sdata = ABSOLUTE(.);
|
||||
*(.data .data.*)
|
||||
*(.sdata .sdata.* .sdata2.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
CONSTRUCTORS
|
||||
. = ALIGN(4);
|
||||
_edata = ABSOLUTE(.);
|
||||
} > ksram AT > kflash
|
||||
|
||||
PROVIDE(__global_pointer$ = _sdata + ((_edata - _sdata) / 2));
|
||||
|
||||
.bss : ALIGN(4) {
|
||||
_sbss = ABSOLUTE(.);
|
||||
*(.bss .bss.*)
|
||||
*(.sbss .sbss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(.gnu.linkonce.sb.*)
|
||||
*(COMMON)
|
||||
} > ksram
|
||||
/* Page tables here, align to 4K boundary */
|
||||
|
||||
.pgtables (NOLOAD) : ALIGN(0x1000) {
|
||||
*(.pgtables)
|
||||
. = ALIGN(4);
|
||||
} > 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) }
|
||||
}
|
@ -38,4 +38,8 @@ ifeq ($(CONFIG_LITEX_PWM),y)
|
||||
CSRCS += litex_pwm.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_LITEX_APPLICATION_RAMDISK),y)
|
||||
CSRCS += litex_ramdisk.c
|
||||
endif
|
||||
|
||||
include $(TOPDIR)/boards/Board.mk
|
||||
|
@ -161,4 +161,22 @@ bool litex_cardinserted(int slotno);
|
||||
int litex_pwm_setup(void);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: litex_mount_ramdisk
|
||||
*
|
||||
* Description:
|
||||
* Mount a ramdisk defined in the ld-kernel.script to /dev/ramX.
|
||||
* The ramdisk is intended to contain a romfs with applications which can
|
||||
* be spawned at runtime.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK is returned on success.
|
||||
* -ERRORNO is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LITEX_APPLICATION_RAMDISK
|
||||
int litex_mount_ramdisk(void);
|
||||
#endif
|
||||
|
||||
#endif /* __BOARDS_RISCV_LITEX_ARTY_A7_SRC_ARTY_A7_H */
|
||||
|
@ -73,3 +73,31 @@ int board_app_initialize(uintptr_t arg)
|
||||
return litex_bringup();
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_late_initialize
|
||||
*
|
||||
* Description:
|
||||
* If CONFIG_BOARD_LATE_INITIALIZE is selected, then an additional
|
||||
* initialization call will be performed in the boot-up sequence to a
|
||||
* function called board_late_initialize(). board_late_initialize() will
|
||||
* be called after up_initialize() and board_early_initialize() and just
|
||||
* before the initial application is started. This additional
|
||||
* initialization phase may be used, for example, to initialize board-
|
||||
* specific device drivers for which board_early_initialize() is not
|
||||
* suitable.
|
||||
*
|
||||
* Waiting for events, use of I2C, SPI, etc are permissible in the context
|
||||
* of board_late_initialize(). That is because board_late_initialize()
|
||||
* will run on a temporary, internal kernel thread.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void board_late_initialize(void)
|
||||
{
|
||||
#ifdef CONFIG_LITEX_APPLICATION_RAMDISK
|
||||
litex_mount_ramdisk();
|
||||
#endif
|
||||
|
||||
litex_bringup();
|
||||
}
|
||||
|
98
boards/risc-v/litex/arty_a7/src/litex_ramdisk.c
Normal file
98
boards/risc-v/litex/arty_a7/src/litex_ramdisk.c
Normal file
@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
* boards/risc-v/litex/arty_a7/src/litex_ramdisk.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 <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/board.h>
|
||||
|
||||
#include <arch/board/board_memorymap.h>
|
||||
#include <nuttx/drivers/ramdisk.h>
|
||||
#include <sys/boardctl.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include "litex.h"
|
||||
#include "arty_a7.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_BUILD_KERNEL
|
||||
#error "Ramdisk usage is intended to be used with kernel build only"
|
||||
#endif
|
||||
|
||||
#define SECTORSIZE 512
|
||||
#define NSECTORS(b) (((b) + SECTORSIZE - 1) / SECTORSIZE)
|
||||
#define RAMDISK_DEVICE_MINOR 0
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: litex_mount_ramdisk
|
||||
*
|
||||
* Description:
|
||||
* Mount a ramdisk defined in the ld-kernel.script to /dev/ramX.
|
||||
* The ramdisk is intended to contain a romfs with applications which can
|
||||
* be spawned at runtime.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK is returned on success.
|
||||
* -ERRORNO is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int litex_mount_ramdisk(void)
|
||||
{
|
||||
int ret;
|
||||
struct boardioc_romdisk_s desc;
|
||||
|
||||
desc.minor = RAMDISK_DEVICE_MINOR;
|
||||
desc.nsectors = NSECTORS((ssize_t)__ramdisk_size);
|
||||
desc.sectsize = SECTORSIZE;
|
||||
desc.image = __ramdisk_start;
|
||||
|
||||
ret = boardctl(BOARDIOC_ROMDISK, (uintptr_t)&desc);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "Ramdisk register failed: %s\n", strerror(errno));
|
||||
syslog(LOG_ERR, "Ramdisk mountpoint /dev/ram%d\n",
|
||||
RAMDISK_DEVICE_MINOR);
|
||||
syslog(LOG_ERR, "Ramdisk length %u, origin %x\n",
|
||||
(ssize_t)__ramdisk_size,
|
||||
(uintptr_t)__ramdisk_start);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
@ -564,6 +564,11 @@ int up_relocateadd(const Elf_Rela *rel, const Elf_Sym *sym,
|
||||
*(uint64_t *)addr += (uint64_t)(sym->st_value + rel->r_addend);
|
||||
}
|
||||
break;
|
||||
case R_RISCV_SUB16:
|
||||
{
|
||||
*(uint16_t *)addr -= (uint16_t)(sym->st_value + rel->r_addend);
|
||||
}
|
||||
break;
|
||||
case R_RISCV_SUB32:
|
||||
{
|
||||
*(uint32_t *)addr -= (uint32_t)(sym->st_value + rel->r_addend);
|
||||
@ -574,6 +579,11 @@ int up_relocateadd(const Elf_Rela *rel, const Elf_Sym *sym,
|
||||
*(uint64_t *)addr -= (uint64_t)(sym->st_value + rel->r_addend);
|
||||
}
|
||||
break;
|
||||
case R_RISCV_SET16:
|
||||
{
|
||||
*(uint16_t *)addr = (uint16_t)(sym->st_value + rel->r_addend);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
berr("ERROR: Unsupported relocation: %ld\n",
|
||||
ARCH_ELF_RELTYPE(rel->r_info));
|
||||
|
Loading…
Reference in New Issue
Block a user