mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 23:40:19 +08:00
litex: Support for kernel build with vexriscv-smp.
This commit is contained in:
@@ -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.
|
||||||
@@ -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
|
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"
|
source "arch/risc-v/src/opensbi/Kconfig"
|
||||||
|
|
||||||
if ARCH_CHIP_FE310
|
if ARCH_CHIP_FE310
|
||||||
|
|||||||
@@ -29,17 +29,19 @@
|
|||||||
#include CONFIG_LITEX_CUSTOM_IRQ_DEFINITIONS_PATH
|
#include CONFIG_LITEX_CUSTOM_IRQ_DEFINITIONS_PATH
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#include <arch/mode.h>
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* Map RISC-V exception code to NuttX IRQ */
|
/* Map RISC-V exception code to NuttX IRQ */
|
||||||
|
|
||||||
#define LITEX_IRQ_UART0 (RISCV_IRQ_MEXT + 1)
|
#define LITEX_IRQ_UART0 (RISCV_IRQ_EXT + 1)
|
||||||
#define LITEX_IRQ_TIMER0 (RISCV_IRQ_MEXT + 2)
|
#define LITEX_IRQ_TIMER0 (RISCV_IRQ_EXT + 2)
|
||||||
#define LITEX_IRQ_ETHMAC (RISCV_IRQ_MEXT + 3)
|
#define LITEX_IRQ_ETHMAC (RISCV_IRQ_EXT + 3)
|
||||||
#define LITEX_IRQ_SDCARD (RISCV_IRQ_MEXT + 4)
|
#define LITEX_IRQ_SDCARD (RISCV_IRQ_EXT + 4)
|
||||||
#define LITEX_IRQ_GPIO (RISCV_IRQ_MEXT + 5)
|
#define LITEX_IRQ_GPIO (RISCV_IRQ_EXT + 5)
|
||||||
|
|
||||||
/* The last hardware IRQ number */
|
/* 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
|
The 5-bit address of the PHY on the board. Default: 1
|
||||||
|
|
||||||
endmenu # PHY interface
|
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
|
# Specify our HEAD assembly file. This will be linked as
|
||||||
# the first object file, so it will appear at address 0
|
# 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
|
HEAD_ASRC = litex_head.S
|
||||||
|
endif
|
||||||
|
|
||||||
# Specify our C code within this directory to be included
|
# Specify our C code within this directory to be included
|
||||||
CHIP_CSRCS = litex_allocateheap.c litex_clockconfig.c
|
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_CSRCS += litex_start.c litex_timerisr.c
|
||||||
CHIP_ASRCS += litex_cache.S
|
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)
|
ifeq ($(CONFIG_LITEX_GPIO),y)
|
||||||
CHIP_CSRCS += litex_gpio.c
|
CHIP_CSRCS += litex_gpio.c
|
||||||
|
|||||||
@@ -29,4 +29,28 @@
|
|||||||
|
|
||||||
#include "litex_memorymap.h"
|
#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 */
|
#endif /* __ARCH_RISCV_SRC_LITEX_CHIP_H */
|
||||||
|
|||||||
@@ -24,9 +24,18 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* 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_LATCH (LITEX_CPUTIMER_BASE)
|
||||||
#define LITEX_CLINT_MTIME (LITEX_CPUTIMER_BASE + 0x04)
|
#define LITEX_CLINT_MTIME (LITEX_CPUTIMER_BASE + 0x04)
|
||||||
#define LITEX_CLINT_MTIMECMP (LITEX_CPUTIMER_BASE + 0x0C)
|
#define LITEX_CLINT_MTIMECMP (LITEX_CPUTIMER_BASE + 0x0C)
|
||||||
|
|
||||||
|
#endif /* CONFIG_LITEX_CORE_VEXRISCV_SMP */
|
||||||
|
|
||||||
#endif /* __ARCH_RISCV_SRC_LITEX_HARDWARE_LITEX_CLINT_H */
|
#endif /* __ARCH_RISCV_SRC_LITEX_HARDWARE_LITEX_CLINT_H */
|
||||||
|
|||||||
@@ -35,20 +35,30 @@
|
|||||||
|
|
||||||
/* Register Base Address ****************************************************/
|
/* Register Base Address ****************************************************/
|
||||||
|
|
||||||
/* litex vexRiscv does not follow RISC-V privileged specification and
|
#ifdef CONFIG_LITEX_CORE_VEXRISCV_SMP
|
||||||
* uses two additional CSRs: mask and pending.
|
#define LITEX_CLINT_BASE 0xf0010000
|
||||||
*/
|
#define LITEX_PLIC_BASE 0xf0c00000
|
||||||
|
#define LITEX_ETHMAC_BASE 0xf0002000
|
||||||
#define LITEX_CPUTIMER_BASE 0xf0000800
|
#define LITEX_ETHPHY_BASE 0xf0002800
|
||||||
#define LITEX_ETHMAC_BASE 0xf0001000
|
#define LITEX_TIMER0_BASE 0xf0001800
|
||||||
#define LITEX_ETHPHY_BASE 0xf0001800
|
#define LITEX_UART0_BASE 0xf0001000
|
||||||
#define LITEX_SDBLOCK2MEM_BASE 0xf0003000
|
#define LITEX_SDBLOCK2MEM_BASE 0xf0004000
|
||||||
#define LITEX_SDCORE_BASE 0xf0003800
|
#define LITEX_SDCORE_BASE 0xf0004800
|
||||||
#define LITEX_SDIRQ_BASE 0xf0004000
|
#define LITEX_SDIRQ_BASE 0xf0005000
|
||||||
#define LITEX_SDMEM2BLOCK_BASE 0xf0004800
|
#define LITEX_SDMEM2BLOCK_BASE 0xf0005800
|
||||||
#define LITEX_SDPHY_BASE 0xf0005000
|
#define LITEX_SDPHY_BASE 0xf0006000
|
||||||
#define LITEX_TIMER0_BASE 0xf0006000
|
#else
|
||||||
#define LITEX_UART0_BASE 0xf0006800
|
#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.
|
/* GPIO peripheral definitions.
|
||||||
* - LITEX_GPIO_BASE is the first 32-bit address which contains a block
|
* - 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
|
#ifndef __ARCH_RISCV_SRC_LITEX_HARDWARE_LITEX_PLIC_H
|
||||||
#define __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
|
* 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
|
/* litex vexRiscv does not follow RISC-V privileged specification and
|
||||||
* uses two additional CSRs: mask and pending.
|
* uses two additional CSRs: mask and pending.
|
||||||
*/
|
*/
|
||||||
#define LITEX_MMASK_CSR 0xBC0
|
#define LITEX_MMASK_CSR 0xBC0
|
||||||
#define LITEX_MPENDING_CSR 0xFC0
|
#define LITEX_MPENDING_CSR 0xFC0
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __ARCH_RISCV_SRC_LITEX_HARDWARE_LITEX_PLIC_H */
|
#endif /* __ARCH_RISCV_SRC_LITEX_HARDWARE_LITEX_PLIC_H */
|
||||||
|
|||||||
@@ -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"
|
#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
|
* 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
|
* Name: riscv_addregion
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -51,7 +51,11 @@ void up_irqinitialize(void)
|
|||||||
|
|
||||||
/* Disable all global interrupts */
|
/* 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));
|
asm volatile ("csrw %0, %1" :: "i"(LITEX_MMASK_CSR), "r"(0));
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Colorize the interrupt stack for debug purposes */
|
/* Colorize the interrupt stack for debug purposes */
|
||||||
|
|
||||||
@@ -62,6 +66,23 @@ void up_irqinitialize(void)
|
|||||||
|
|
||||||
/* litex vexriscv dont have priority and threshold control */
|
/* 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 */
|
/* Attach the common interrupt handler */
|
||||||
|
|
||||||
riscv_exception_attach();
|
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)
|
void up_disable_irq(int irq)
|
||||||
{
|
{
|
||||||
int extirq;
|
int extirq;
|
||||||
@@ -118,6 +174,7 @@ void up_disable_irq(int irq)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: up_enable_irq
|
* 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)
|
void up_enable_irq(int irq)
|
||||||
{
|
{
|
||||||
int extirq;
|
int extirq;
|
||||||
@@ -163,6 +255,7 @@ void up_enable_irq(int irq)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: riscv_ack_irq
|
* Name: riscv_ack_irq
|
||||||
@@ -189,15 +282,15 @@ irqstate_t up_irq_enable(void)
|
|||||||
irqstate_t oldstat;
|
irqstate_t oldstat;
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
/* Enable MEIE (machine external interrupt enable) */
|
/* Enable EIE (machine/supervisor external interrupt enable) */
|
||||||
|
|
||||||
/* TODO: should move to up_enable_irq() */
|
/* TODO: should move to up_enable_irq() */
|
||||||
|
|
||||||
SET_CSR(mie, MIE_MEIE);
|
SET_CSR(CSR_IE, IE_EIE);
|
||||||
#endif
|
#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;
|
return oldstat;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,8 +49,48 @@
|
|||||||
|
|
||||||
void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
|
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 i;
|
||||||
|
int irq = (vector >> RV_IRQ_MASK) | (vector & 0xf);
|
||||||
|
|
||||||
/* Firstly, check if the irq is machine external interrupt */
|
/* 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);
|
regs = riscv_doirq(irq, regs);
|
||||||
|
|
||||||
|
#endif /* CONFIG_LITEX_CORE_VEXRISCV_SMP */
|
||||||
return regs;
|
return regs;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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 */
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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 "litex.h"
|
||||||
#include "chip.h"
|
#include "chip.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_BUILD_KERNEL
|
||||||
|
# include "litex_mm_init.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -43,6 +47,10 @@
|
|||||||
# define showprogress(c)
|
# define showprogress(c)
|
||||||
#endif
|
#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
|
* Public Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -96,6 +104,10 @@ void __litex_start(void)
|
|||||||
*dest++ = *src++;
|
*dest++ = *src++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_LITEX_CORE_VEXRISCV_SMP
|
||||||
|
riscv_percpu_add_hart(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Setup PLL */
|
/* Setup PLL */
|
||||||
|
|
||||||
litex_clockconfig();
|
litex_clockconfig();
|
||||||
@@ -114,7 +126,11 @@ void __litex_start(void)
|
|||||||
|
|
||||||
/* Do board initialization */
|
/* Do board initialization */
|
||||||
|
|
||||||
litex_boardinitialize();
|
#ifdef CONFIG_BUILD_KERNEL
|
||||||
|
/* Setup page tables for kernel and enable MMU */
|
||||||
|
|
||||||
|
litex_mm_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
showprogress('C');
|
showprogress('C');
|
||||||
|
|
||||||
|
|||||||
@@ -23,19 +23,17 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <debug.h>
|
|
||||||
|
|
||||||
#include <nuttx/arch.h>
|
|
||||||
#include <nuttx/clock.h>
|
#include <nuttx/clock.h>
|
||||||
#include <nuttx/spinlock.h>
|
#include <nuttx/timers/arch_alarm.h>
|
||||||
#include <arch/board/board.h>
|
#include <nuttx/init.h>
|
||||||
|
|
||||||
|
#include <debug.h>
|
||||||
#include "riscv_internal.h"
|
#include "riscv_internal.h"
|
||||||
|
|
||||||
#include "litex.h"
|
#include "litex.h"
|
||||||
#include "litex_clockconfig.h"
|
#include "litex_clockconfig.h"
|
||||||
|
#include "hardware/litex_timer.h"
|
||||||
|
#include "riscv_mtimer.h"
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
@@ -47,95 +45,33 @@
|
|||||||
* Private Data
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static bool _b_tick_started = false;
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* 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
|
* 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)
|
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 */
|
/* Process timer interrupt */
|
||||||
|
|
||||||
@@ -143,6 +79,33 @@ static int litex_timerisr(int irq, void *context, void *arg)
|
|||||||
return 0;
|
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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -158,15 +121,9 @@ static int litex_timerisr(int irq, void *context, void *arg)
|
|||||||
|
|
||||||
void up_timer_initialize(void)
|
void up_timer_initialize(void)
|
||||||
{
|
{
|
||||||
/* Attach timer interrupt handler */
|
#ifdef CONFIG_LITEX_CORE_VEXRISCV_SMP
|
||||||
|
litex_mtimer_initialise();
|
||||||
irq_attach(RISCV_IRQ_MTIMER, litex_timerisr, NULL);
|
#else
|
||||||
|
litex_timer0_initialize();
|
||||||
/* Reload CLINT mtimecmp */
|
#endif
|
||||||
|
|
||||||
litex_reload_mtimecmp();
|
|
||||||
|
|
||||||
/* And enable the timer interrupt */
|
|
||||||
|
|
||||||
up_enable_irq(RISCV_IRQ_MTIMER);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,4 +25,12 @@ config LITEX_SDIO_MOUNT_FSTYPE
|
|||||||
default "vfat"
|
default "vfat"
|
||||||
depends on LITEX_SDIO
|
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
|
endif
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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)/tools/Config.mk
|
||||||
include $(TOPDIR)/arch/risc-v/src/common/Toolchain.defs
|
include $(TOPDIR)/arch/risc-v/src/common/Toolchain.defs
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_BUILD_KERNEL),y)
|
||||||
|
LDSCRIPT = ld-kernel.script
|
||||||
|
else
|
||||||
LDSCRIPT = ld.script
|
LDSCRIPT = ld.script
|
||||||
|
endif
|
||||||
|
|
||||||
ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT)
|
ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT)
|
||||||
|
|
||||||
ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10
|
ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10
|
||||||
@@ -33,3 +38,11 @@ CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES
|
|||||||
CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
|
CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
|
||||||
CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS)
|
CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS)
|
||||||
AFLAGS += $(CFLAGS) -D__ASSEMBLY__
|
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)
|
||||||
@@ -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
|
CSRCS += litex_pwm.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_LITEX_APPLICATION_RAMDISK),y)
|
||||||
|
CSRCS += litex_ramdisk.c
|
||||||
|
endif
|
||||||
|
|
||||||
include $(TOPDIR)/boards/Board.mk
|
include $(TOPDIR)/boards/Board.mk
|
||||||
|
|||||||
@@ -161,4 +161,22 @@ bool litex_cardinserted(int slotno);
|
|||||||
int litex_pwm_setup(void);
|
int litex_pwm_setup(void);
|
||||||
#endif
|
#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 */
|
#endif /* __BOARDS_RISCV_LITEX_ARTY_A7_SRC_ARTY_A7_H */
|
||||||
|
|||||||
@@ -73,3 +73,31 @@ int board_app_initialize(uintptr_t arg)
|
|||||||
return litex_bringup();
|
return litex_bringup();
|
||||||
#endif
|
#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();
|
||||||
|
}
|
||||||
|
|||||||
@@ -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);
|
*(uint64_t *)addr += (uint64_t)(sym->st_value + rel->r_addend);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case R_RISCV_SUB16:
|
||||||
|
{
|
||||||
|
*(uint16_t *)addr -= (uint16_t)(sym->st_value + rel->r_addend);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case R_RISCV_SUB32:
|
case R_RISCV_SUB32:
|
||||||
{
|
{
|
||||||
*(uint32_t *)addr -= (uint32_t)(sym->st_value + rel->r_addend);
|
*(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);
|
*(uint64_t *)addr -= (uint64_t)(sym->st_value + rel->r_addend);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case R_RISCV_SET16:
|
||||||
|
{
|
||||||
|
*(uint16_t *)addr = (uint16_t)(sym->st_value + rel->r_addend);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
berr("ERROR: Unsupported relocation: %ld\n",
|
berr("ERROR: Unsupported relocation: %ld\n",
|
||||||
ARCH_ELF_RELTYPE(rel->r_info));
|
ARCH_ELF_RELTYPE(rel->r_info));
|
||||||
|
|||||||
Reference in New Issue
Block a user