riscv32: added support for the SiFive Freedom E310 SOC
The SiFive Freedom E310 SOC follows the riscv privilege architecture specification and hence is declared within the riscv privilege SOC family. It also provides support for a riscv Platform Level Interrupt Controller (PLIC) Change-Id: I19ff0997eacc248f48444fc96566a105c6c02663 Signed-off-by: Jean-Paul Etienne <fractalclone@gmail.com>
This commit is contained in:
parent
cd14317c41
commit
4ae030c7b8
11 changed files with 382 additions and 0 deletions
|
@ -0,0 +1,47 @@
|
|||
if SOC_SERIES_RISCV32_FE310
|
||||
|
||||
config SOC_SERIES
|
||||
string
|
||||
default "fe310"
|
||||
|
||||
config SYS_CLOCK_HW_CYCLES_PER_SEC
|
||||
int
|
||||
default 32768
|
||||
|
||||
config RISCV_SOC_INTERRUPT_INIT
|
||||
bool
|
||||
default y
|
||||
|
||||
config RISCV_HAS_CPU_IDLE
|
||||
bool
|
||||
default y
|
||||
|
||||
config RISCV_HAS_PLIC
|
||||
bool
|
||||
default y
|
||||
|
||||
config NUM_IRQS
|
||||
int
|
||||
default 64
|
||||
|
||||
config XIP
|
||||
bool
|
||||
default y
|
||||
|
||||
config RISCV_ROM_BASE_ADDR
|
||||
hex
|
||||
default 0x20400000
|
||||
|
||||
config RISCV_ROM_SIZE
|
||||
hex
|
||||
default 0xC00000
|
||||
|
||||
config RISCV_RAM_BASE_ADDR
|
||||
hex
|
||||
default 0x80000000
|
||||
|
||||
config RISCV_RAM_SIZE
|
||||
hex
|
||||
default 0x4000
|
||||
|
||||
endif # SOC_SERIES_RISCV32_FE310
|
13
arch/riscv32/soc/riscv-privilege/fe310/Kconfig.series
Normal file
13
arch/riscv32/soc/riscv-privilege/fe310/Kconfig.series
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Kconfig - RISCV32_FE310 SOC implementation
|
||||
#
|
||||
# Copyright (c) 2017 Jean-Paul Etienne <fractalclone@gmail.com>
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
config SOC_SERIES_RISCV32_FE310
|
||||
bool "SiFive Freedom E310 SOC implementation"
|
||||
depends on RISCV32
|
||||
select SOC_FAMILY_RISCV_PRIVILEGE
|
||||
help
|
||||
Enable support for SiFive Freedom E310 SOC
|
16
arch/riscv32/soc/riscv-privilege/fe310/Kconfig.soc
Normal file
16
arch/riscv32/soc/riscv-privilege/fe310/Kconfig.soc
Normal file
|
@ -0,0 +1,16 @@
|
|||
# Kconfig - RISCV32_FE310 SOC configuration options
|
||||
#
|
||||
# Copyright (c) 2017 Jean-Paul Etienne <fractalclone@gmail.com>
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
choice
|
||||
prompt "SiFive Freedom E310 SOC implementation"
|
||||
depends on SOC_SERIES_RISCV32_FE310
|
||||
|
||||
config SOC_RISCV32_FE310
|
||||
bool "SiFive Freedom E310 SOC implementation"
|
||||
select ATOMIC_OPERATIONS_C
|
||||
|
||||
endchoice
|
7
arch/riscv32/soc/riscv-privilege/fe310/Makefile
Normal file
7
arch/riscv32/soc/riscv-privilege/fe310/Makefile
Normal file
|
@ -0,0 +1,7 @@
|
|||
soc-cflags := -I/$(srctree)/arch/$(ARCH)/soc/$(SOC_FAMILY)/common/
|
||||
|
||||
obj-y += vector.o fe310_idle.o
|
||||
|
||||
soc_ld_include := -I$(srctree)/arch/$(ARCH)/soc/$(SOC_FAMILY)/common/ \
|
||||
-I$(srctree)/arch/$(ARCH)/soc/$(SOC_PATH)/
|
||||
EXTRA_LINKER_CMD_OPT += $(soc_ld_include)
|
60
arch/riscv32/soc/riscv-privilege/fe310/fe310_idle.c
Normal file
60
arch/riscv32/soc/riscv-privilege/fe310/fe310_idle.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Jean-Paul Etienne <fractalclone@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <toolchain.h>
|
||||
#include <irq.h>
|
||||
#include <soc.h>
|
||||
|
||||
#include <logging/kernel_event_logger.h>
|
||||
|
||||
static ALWAYS_INLINE void fe310_idle(unsigned int key)
|
||||
{
|
||||
#ifdef CONFIG_KERNEL_EVENT_LOGGER_SLEEP
|
||||
_sys_k_event_logger_enter_sleep();
|
||||
#endif
|
||||
/* unlock interrupts */
|
||||
irq_unlock(key);
|
||||
|
||||
/* Wait for interrupt */
|
||||
__asm__ volatile("wfi");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Power save idle routine
|
||||
*
|
||||
* This function will be called by the kernel idle loop or possibly within
|
||||
* an implementation of _sys_power_save_idle in the microkernel when the
|
||||
* '_sys_power_save_flag' variable is non-zero.
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
void k_cpu_idle(void)
|
||||
{
|
||||
fe310_idle(SOC_MSTATUS_IEN);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Atomically re-enable interrupts and enter low power mode
|
||||
*
|
||||
* INTERNAL
|
||||
* The requirements for k_cpu_atomic_idle() are as follows:
|
||||
* 1) The enablement of interrupts and entering a low-power mode needs to be
|
||||
* atomic, i.e. there should be no period of time where interrupts are
|
||||
* enabled before the processor enters a low-power mode. See the comments
|
||||
* in k_lifo_get(), for example, of the race condition that
|
||||
* occurs if this requirement is not met.
|
||||
*
|
||||
* 2) After waking up from the low-power mode, the interrupt lockout state
|
||||
* must be restored as indicated in the 'imask' input parameter.
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
void k_cpu_atomic_idle(unsigned int key)
|
||||
{
|
||||
fe310_idle(key);
|
||||
}
|
11
arch/riscv32/soc/riscv-privilege/fe310/linker.ld
Normal file
11
arch/riscv32/soc/riscv-privilege/fe310/linker.ld
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Jean-Paul Etienne <fractalclone@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Linker script for the SiFive Freedom E310 processor
|
||||
*/
|
||||
|
||||
#include <arch/riscv32/common/linker.ld>
|
116
arch/riscv32/soc/riscv-privilege/fe310/soc.h
Normal file
116
arch/riscv32/soc/riscv-privilege/fe310/soc.h
Normal file
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Jean-Paul Etienne <fractalclone@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file SoC configuration macros for the SiFive Freedom E310 processor
|
||||
*/
|
||||
|
||||
#ifndef __RISCV32_FE310_SOC_H_
|
||||
#define __RISCV32_FE310_SOC_H_
|
||||
|
||||
#include <soc_common.h>
|
||||
|
||||
/* PLatform Level Interrupt Controller (PLIC) interrupt sources */
|
||||
|
||||
/* Watchdog Compare Interrupt */
|
||||
#define FE310_WDOGCMP_IRQ (RISCV_MAX_GENERIC_IRQ + 1)
|
||||
|
||||
/* RTC Compare Interrupt */
|
||||
#define FE310_RTCCMP_IRQ (RISCV_MAX_GENERIC_IRQ + 2)
|
||||
|
||||
/* UART Interrupts */
|
||||
#define FE310_UART_0_IRQ (RISCV_MAX_GENERIC_IRQ + 3)
|
||||
#define FE310_UART_1_IRQ (RISCV_MAX_GENERIC_IRQ + 4)
|
||||
|
||||
/* QSPI Interrupts */
|
||||
#define FE310_QSPI_0_IRQ (RISCV_MAX_GENERIC_IRQ + 5)
|
||||
#define FE310_QSPI_1_IRQ (RISCV_MAX_GENERIC_IRQ + 6)
|
||||
#define FE310_QSPI_2_IRQ (RISCV_MAX_GENERIC_IRQ + 7)
|
||||
|
||||
/* GPIO Interrupts */
|
||||
#define FE310_GPIO_0_IRQ (RISCV_MAX_GENERIC_IRQ + 8)
|
||||
#define FE310_GPIO_1_IRQ (RISCV_MAX_GENERIC_IRQ + 9)
|
||||
#define FE310_GPIO_2_IRQ (RISCV_MAX_GENERIC_IRQ + 10)
|
||||
#define FE310_GPIO_3_IRQ (RISCV_MAX_GENERIC_IRQ + 11)
|
||||
#define FE310_GPIO_4_IRQ (RISCV_MAX_GENERIC_IRQ + 12)
|
||||
#define FE310_GPIO_5_IRQ (RISCV_MAX_GENERIC_IRQ + 13)
|
||||
#define FE310_GPIO_6_IRQ (RISCV_MAX_GENERIC_IRQ + 14)
|
||||
#define FE310_GPIO_7_IRQ (RISCV_MAX_GENERIC_IRQ + 15)
|
||||
#define FE310_GPIO_8_IRQ (RISCV_MAX_GENERIC_IRQ + 16)
|
||||
#define FE310_GPIO_9_IRQ (RISCV_MAX_GENERIC_IRQ + 17)
|
||||
#define FE310_GPIO_10_IRQ (RISCV_MAX_GENERIC_IRQ + 18)
|
||||
#define FE310_GPIO_11_IRQ (RISCV_MAX_GENERIC_IRQ + 19)
|
||||
#define FE310_GPIO_12_IRQ (RISCV_MAX_GENERIC_IRQ + 20)
|
||||
#define FE310_GPIO_13_IRQ (RISCV_MAX_GENERIC_IRQ + 21)
|
||||
#define FE310_GPIO_14_IRQ (RISCV_MAX_GENERIC_IRQ + 22)
|
||||
#define FE310_GPIO_15_IRQ (RISCV_MAX_GENERIC_IRQ + 23)
|
||||
#define FE310_GPIO_16_IRQ (RISCV_MAX_GENERIC_IRQ + 24)
|
||||
#define FE310_GPIO_17_IRQ (RISCV_MAX_GENERIC_IRQ + 25)
|
||||
#define FE310_GPIO_18_IRQ (RISCV_MAX_GENERIC_IRQ + 26)
|
||||
#define FE310_GPIO_19_IRQ (RISCV_MAX_GENERIC_IRQ + 27)
|
||||
#define FE310_GPIO_20_IRQ (RISCV_MAX_GENERIC_IRQ + 28)
|
||||
#define FE310_GPIO_21_IRQ (RISCV_MAX_GENERIC_IRQ + 29)
|
||||
#define FE310_GPIO_22_IRQ (RISCV_MAX_GENERIC_IRQ + 30)
|
||||
#define FE310_GPIO_23_IRQ (RISCV_MAX_GENERIC_IRQ + 31)
|
||||
#define FE310_GPIO_24_IRQ (RISCV_MAX_GENERIC_IRQ + 32)
|
||||
#define FE310_GPIO_25_IRQ (RISCV_MAX_GENERIC_IRQ + 33)
|
||||
#define FE310_GPIO_26_IRQ (RISCV_MAX_GENERIC_IRQ + 34)
|
||||
#define FE310_GPIO_27_IRQ (RISCV_MAX_GENERIC_IRQ + 35)
|
||||
#define FE310_GPIO_28_IRQ (RISCV_MAX_GENERIC_IRQ + 36)
|
||||
#define FE310_GPIO_29_IRQ (RISCV_MAX_GENERIC_IRQ + 37)
|
||||
#define FE310_GPIO_30_IRQ (RISCV_MAX_GENERIC_IRQ + 38)
|
||||
#define FE310_GPIO_31_IRQ (RISCV_MAX_GENERIC_IRQ + 39)
|
||||
|
||||
/* PWM Interrupts */
|
||||
#define FE310_PWM_0_CMP_0_IRQ (RISCV_MAX_GENERIC_IRQ + 40)
|
||||
#define FE310_PWM_0_CMP_1_IRQ (RISCV_MAX_GENERIC_IRQ + 41)
|
||||
#define FE310_PWM_0_CMP_2_IRQ (RISCV_MAX_GENERIC_IRQ + 42)
|
||||
#define FE310_PWM_0_CMP_3_IRQ (RISCV_MAX_GENERIC_IRQ + 43)
|
||||
|
||||
#define FE310_PWM_1_CMP_0_IRQ (RISCV_MAX_GENERIC_IRQ + 44)
|
||||
#define FE310_PWM_1_CMP_1_IRQ (RISCV_MAX_GENERIC_IRQ + 45)
|
||||
#define FE310_PWM_1_CMP_2_IRQ (RISCV_MAX_GENERIC_IRQ + 46)
|
||||
#define FE310_PWM_1_CMP_3_IRQ (RISCV_MAX_GENERIC_IRQ + 47)
|
||||
|
||||
#define FE310_PWM_2_CMP_0_IRQ (RISCV_MAX_GENERIC_IRQ + 48)
|
||||
#define FE310_PWM_2_CMP_1_IRQ (RISCV_MAX_GENERIC_IRQ + 49)
|
||||
#define FE310_PWM_2_CMP_2_IRQ (RISCV_MAX_GENERIC_IRQ + 50)
|
||||
#define FE310_PWM_2_CMP_3_IRQ (RISCV_MAX_GENERIC_IRQ + 51)
|
||||
|
||||
/* UART Configuration */
|
||||
#define FE310_UART_0_BASE_ADDR 0x10013000
|
||||
#define FE310_UART_1_BASE_ADDR 0x10023000
|
||||
|
||||
/* GPIO Configuration */
|
||||
#define FE310_GPIO_0_BASE_ADDR 0x10012000
|
||||
|
||||
/* PINMUX Configuration */
|
||||
#define FE310_PINMUX_0_BASE_ADDR (FE310_GPIO_0_BASE_ADDR + 0x38)
|
||||
|
||||
/* PINMUX IO Hardware Functions */
|
||||
#define FE310_PINMUX_IOF0 0x00
|
||||
#define FE310_PINMUX_IOF1 0x01
|
||||
|
||||
/* PINMUX MAX PINS */
|
||||
#define FE310_PINMUX_PINS 32
|
||||
|
||||
/* Platform Level Interrupt Controller Configuration */
|
||||
#define FE310_PLIC_BASE_ADDR 0x0C000000
|
||||
#define FE310_PLIC_PRIO_BASE_ADDR FE310_PLIC_BASE_ADDR
|
||||
#define FE310_PLIC_IRQ_EN_BASE_ADDR (FE310_PLIC_BASE_ADDR + 0x2000)
|
||||
#define FE310_PLIC_REG_BASE_ADDR (FE310_PLIC_BASE_ADDR + 0x200000)
|
||||
|
||||
#define FE310_PLIC_MAX_PRIORITY 7
|
||||
|
||||
/* Timer configuration */
|
||||
#define RISCV_MTIME_BASE 0x0200BFF8
|
||||
#define RISCV_MTIMECMP_BASE 0x02004000
|
||||
|
||||
/* lib-c hooks required RAM defined variables */
|
||||
#define RISCV_RAM_BASE CONFIG_RISCV_RAM_BASE_ADDR
|
||||
#define RISCV_RAM_SIZE CONFIG_RISCV_RAM_SIZE
|
||||
|
||||
#endif /* __RISCV32_FE310_SOC_H_ */
|
24
arch/riscv32/soc/riscv-privilege/fe310/vector.S
Normal file
24
arch/riscv32/soc/riscv-privilege/fe310/vector.S
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Jean-Paul Etienne <fractalclone@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <toolchain.h>
|
||||
|
||||
/* imports */
|
||||
GTEXT(__start)
|
||||
GTEXT(__irq_wrapper)
|
||||
|
||||
SECTION_FUNC(vectors, vinit)
|
||||
.option norvc;
|
||||
|
||||
/*
|
||||
* Set mtvec (Machine Trap-Vector Base-Address Register)
|
||||
* to __irq_wrapper.
|
||||
*/
|
||||
la t0, __irq_wrapper
|
||||
csrw mtvec, t0
|
||||
|
||||
/* Jump to __start */
|
||||
tail __start
|
|
@ -127,6 +127,8 @@ extern uint32_t _timer_cycle_get_32(void);
|
|||
#include <arch/riscv32/pulpino/asm_inline.h>
|
||||
#elif defined(CONFIG_SOC_RISCV32_QEMU)
|
||||
#include <arch/riscv32/riscv32-qemu/asm_inline.h>
|
||||
#elif defined(CONFIG_SOC_RISCV32_FE310)
|
||||
#include <arch/riscv32/fe310/asm_inline.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
21
include/arch/riscv32/fe310/asm_inline.h
Normal file
21
include/arch/riscv32/fe310/asm_inline.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Jean-Paul Etienne <fractalclone@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _ASM_INLINE_PUBLIC_H
|
||||
#define _ASM_INLINE_PUBLIC_H
|
||||
|
||||
/*
|
||||
* The file must not be included directly
|
||||
* Include arch/cpu.h instead
|
||||
*/
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#include <arch/riscv32/fe310/asm_inline_gcc.h>
|
||||
#else
|
||||
#error "Supports only GNU C compiler"
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_INLINE_PUBLIC_H */
|
65
include/arch/riscv32/fe310/asm_inline_gcc.h
Normal file
65
include/arch/riscv32/fe310/asm_inline_gcc.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Jean-Paul Etienne <fractalclone@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _ASM_INLINE_GCC_H
|
||||
#define _ASM_INLINE_GCC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The file must not be included directly
|
||||
* Include arch/cpu.h instead
|
||||
* TEMPORARY
|
||||
*/
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
|
||||
#include <toolchain.h>
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief find least significant bit set in a 32-bit word
|
||||
*
|
||||
* This routine finds the first bit set starting from the least significant bit
|
||||
* in the argument passed in and returns the index of that bit. Bits are
|
||||
* numbered starting at 1 from the least significant bit. A return value of
|
||||
* zero indicates that the value passed is zero.
|
||||
*
|
||||
* @return least significant bit set, 0 if @a op is 0
|
||||
*/
|
||||
static ALWAYS_INLINE unsigned int find_lsb_set(uint32_t op)
|
||||
{
|
||||
return __builtin_ffs(op);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief find most significant bit set in a 32-bit word
|
||||
*
|
||||
* This routine finds the first bit set starting from the most significant bit
|
||||
* in the argument passed in and returns the index of that bit. Bits are
|
||||
* numbered starting at 1 from the least significant bit. A return value of
|
||||
* zero indicates that the value passed is zero.
|
||||
*
|
||||
* @return most significant bit set, 0 if @a op is 0
|
||||
*/
|
||||
static ALWAYS_INLINE unsigned int find_msb_set(uint32_t op)
|
||||
{
|
||||
if (!op)
|
||||
return 0;
|
||||
|
||||
return 32 - __builtin_clz(op);
|
||||
}
|
||||
|
||||
#endif /* _ASMLANGUAGE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_INLINE_GCC_PUBLIC_GCC_H */
|
Loading…
Add table
Add a link
Reference in a new issue