diff --git a/boards/hifive1b/include/periph_conf.h b/boards/hifive1b/include/periph_conf.h index e1b1e1c8b0..fb1ab80388 100644 --- a/boards/hifive1b/include/periph_conf.h +++ b/boards/hifive1b/include/periph_conf.h @@ -21,6 +21,8 @@ #ifndef PERIPH_CONF_H #define PERIPH_CONF_H +#include "kernel_defines.h" +#include "macros/units.h" #include "periph_cpu.h" #include "clk_conf.h" diff --git a/cpu/fe310/Kconfig b/cpu/fe310/Kconfig index c86563c86d..a7323ad209 100644 --- a/cpu/fe310/Kconfig +++ b/cpu/fe310/Kconfig @@ -5,31 +5,15 @@ # directory for more details. # -config CPU_ARCH_RISCV - bool - select HAS_ARCH_RISCV - select HAS_NEWLIB - select HAS_PICOLIBC if '$(RIOT_CI_BUILD)' != '1' - select MODULE_MALLOC_THREAD_SAFE if TEST_KCONFIG - -config CPU_CORE_RV32M - bool - select CPU_ARCH_RISCV - select HAS_ARCH_32BIT - config CPU_FAM_FE310 bool - select CPU_CORE_RV32M + select CPU_CORE_RV32I select HAS_CPU_FE310 select HAS_PERIPH_CPUID select HAS_PERIPH_GPIO select HAS_PERIPH_GPIO_IRQ - select HAS_PERIPH_PLIC select HAS_PERIPH_PM select HAS_PERIPH_WDT - select HAS_CPP - select HAS_LIBSTDCPP - select HAS_SSP config CPU_MODEL_FE310_G000 bool @@ -39,24 +23,12 @@ config CPU_MODEL_FE310_G002 bool select CPU_FAM_FE310 -## Definition of specific features -config HAS_ARCH_RISCV - bool - help - Indicates that the current CPU has a RISC-V. - ## Definition of specific features config HAS_CPU_FE310 bool help Indicates that a 'fe310' cpu is being used. -config CPU_ARCH - default "risc-v" if CPU_ARCH_RISCV - -config CPU_CORE - default "rv32m" if CPU_CORE_RV32M - config CPU_FAM default "fe310" if CPU_FAM_FE310 @@ -68,3 +40,5 @@ config CPU default "fe310" if CPU_FAM_FE310 rsource "Kconfig.clk" + +source "$(RIOTCPU)/riscv_common/Kconfig" diff --git a/cpu/fe310/Makefile b/cpu/fe310/Makefile index 7faccb7655..fd024edf0e 100644 --- a/cpu/fe310/Makefile +++ b/cpu/fe310/Makefile @@ -2,6 +2,6 @@ MODULE = cpu # add a list of subdirectories, that should also be built -DIRS = periph vendor +DIRS = $(RIOTCPU)/riscv_common periph vendor include $(RIOTBASE)/Makefile.base diff --git a/cpu/fe310/Makefile.dep b/cpu/fe310/Makefile.dep index c22d106a21..bfe549b6db 100644 --- a/cpu/fe310/Makefile.dep +++ b/cpu/fe310/Makefile.dep @@ -5,10 +5,8 @@ ifneq (,$(filter newlib,$(USEMODULE))) USEMODULE += newlib_syscalls_default endif -USEMODULE += sifive_drivers_fe310 - USEMODULE += periph -USEMODULE += periph_pm +USEMODULE += sifive_drivers_fe310 FEATURES_REQUIRED += periph_plic @@ -16,5 +14,8 @@ ifneq (,$(filter periph_rtc,$(USEMODULE))) FEATURES_REQUIRED += periph_rtt endif -# Make calls to malloc and friends thread-safe -USEMODULE += malloc_thread_safe +ifneq (,$(filter periph_timer,$(USEMODULE))) + FEATURES_REQUIRED += periph_coretimer +endif + +include $(RIOTCPU)/riscv_common/Makefile.dep diff --git a/cpu/fe310/Makefile.features b/cpu/fe310/Makefile.features index 3691c9e139..b4998dd7b5 100644 --- a/cpu/fe310/Makefile.features +++ b/cpu/fe310/Makefile.features @@ -1,16 +1,6 @@ -FEATURES_PROVIDED += arch_32bit -FEATURES_PROVIDED += arch_riscv -FEATURES_PROVIDED += cpp -FEATURES_PROVIDED += libstdcpp -FEATURES_PROVIDED += newlib FEATURES_PROVIDED += periph_cpuid FEATURES_PROVIDED += periph_gpio periph_gpio_irq -FEATURES_PROVIDED += periph_plic FEATURES_PROVIDED += periph_pm FEATURES_PROVIDED += periph_wdt -FEATURES_PROVIDED += ssp -# RISC-V toolchain on CI does not work properly with picolibc yet -ifeq (,$(RIOT_CI_BUILD)) - FEATURES_PROVIDED += picolibc -endif +include $(RIOTCPU)/riscv_common/Makefile.features diff --git a/cpu/fe310/Makefile.include b/cpu/fe310/Makefile.include index 55d1ac9ab5..29ef4d5b62 100644 --- a/cpu/fe310/Makefile.include +++ b/cpu/fe310/Makefile.include @@ -11,24 +11,4 @@ else ifeq ($(CPU_MODEL), fe310_g002) ROM_LEN ?= 0x0006a120 endif -# All variables must be defined in the CPU configuration when using the common -# `ldscripts/fe310.ld` -ifneq (,$(ROM_START_ADDR)$(RAM_START_ADDR)$(ROM_LEN)$(RAM_LEN)) - $(if $(ROM_START_ADDR),,$(error ROM_START_ADDR is not defined)) - $(if $(RAM_START_ADDR),,$(error RAM_START_ADDR is not defined)) - $(if $(ROM_LEN),,$(error ROM_LEN is not defined)) - $(if $(RAM_LEN),,$(error RAM_LEN is not defined)) - LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_rom_start_addr=$(ROM_START_ADDR) - LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_ram_start_addr=$(RAM_START_ADDR) - LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_rom_length=$(ROM_LEN) - LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_ram_length=$(RAM_LEN) -endif - -ifneq (,$(ITIM_START_ADDR)) - LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_itim_start_addr=$(ITIM_START_ADDR) - LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_itim_length=$(ITIM_LEN) -endif - -LINKER_SCRIPT ?= fe310.ld - -include $(RIOTMAKE)/arch/riscv.inc.mk +include $(RIOTCPU)/riscv_common/Makefile.include diff --git a/cpu/fe310/clock.c b/cpu/fe310/clock.c index cd55807177..4e3e586561 100644 --- a/cpu/fe310/clock.c +++ b/cpu/fe310/clock.c @@ -26,7 +26,7 @@ static uint32_t _cpu_frequency = 0; #endif -void clock_init(void) +void fe310_clock_init(void) { /* Ensure that we aren't running off the PLL before we mess with it. */ if (PRCI_REG(PRCI_PLLCFG) & PLL_SEL(1)) { diff --git a/cpu/fe310/cpu.c b/cpu/fe310/cpu.c index f38fdc0c7e..a10ea94dd6 100644 --- a/cpu/fe310/cpu.c +++ b/cpu/fe310/cpu.c @@ -21,8 +21,7 @@ #include "periph/init.h" #include "periph_conf.h" -#include "vendor/encoding.h" -#include "vendor/plic_driver.h" +#include "vendor/riscv_csr.h" #include "stdio_uart.h" @@ -95,7 +94,7 @@ void flash_init(void) void cpu_init(void) { /* Initialize clock */ - clock_init(); + fe310_clock_init(); #if USE_CLOCK_HFROSC_PLL /* Initialize flash memory, only when using the PLL: in this @@ -104,14 +103,8 @@ void cpu_init(void) flash_init(); #endif - /* Enable FPU if present */ - if (read_csr(misa) & (1 << ('F' - 'A'))) { - write_csr(mstatus, MSTATUS_FS); /* allow FPU instructions without trapping */ - write_csr(fcsr, 0); /* initialize rounding mode, undefined at reset */ - } - - /* Initialize IRQs */ - irq_init(); + /* Common RISC-V initialization */ + riscv_init(); /* Initialize stdio */ stdio_init(); diff --git a/cpu/fe310/doc.txt b/cpu/fe310/doc.txt new file mode 100644 index 0000000000..ddeec1e123 --- /dev/null +++ b/cpu/fe310/doc.txt @@ -0,0 +1,9 @@ +/** + * @defgroup cpu_fe310 SiFive fe310 + * @ingroup cpu + * @brief SiFive fe310 RISC-V MCU specific implementation. + * + * This module contains SiFive fe310 specific code and definition. + * + * @see cpu_riscv_common + */ diff --git a/cpu/fe310/include/clk_conf.h b/cpu/fe310/include/clk_conf.h index deec164598..4a45657116 100644 --- a/cpu/fe310/include/clk_conf.h +++ b/cpu/fe310/include/clk_conf.h @@ -20,6 +20,7 @@ #define CLK_CONF_H #include "macros/units.h" +#include "kernel_defines.h" #ifdef __cplusplus extern "C" { diff --git a/cpu/fe310/include/cpu.h b/cpu/fe310/include/cpu.h deleted file mode 100644 index 2d22720c9d..0000000000 --- a/cpu/fe310/include/cpu.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2017 Ken Rabold - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -/** - * @defgroup cpu_fe310 SiFive FE310 - * @ingroup cpu - * @brief Common implementations and headers for RISC-V - * @{ - * - * @file - * @brief Basic definitions for the RISC-V common module - * - * When ever you want to do something hardware related, that is accessing MCUs - * registers, just include this file. It will then make sure that the MCU - * specific headers are included. - * - * @author Ken Rabold - */ - -#ifndef CPU_H -#define CPU_H - -#include "thread.h" -#include "macros/units.h" - -#include "vendor/platform.h" -#include "vendor/plic_driver.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Initialization of the CPU - */ -void cpu_init(void); - -/** - * @brief Initialization of the clock - */ -void clock_init(void); - -/** - * @brief Get and eventually compute the current CPU core clock frequency - * - * @return the cpu core clock frequency in Hz - */ -uint32_t cpu_freq(void); - -/** - * @brief Initialization of interrupts - */ -void irq_init(void); - -/** - * @brief Print the last instruction's address - * - * @todo: Not supported - */ -static inline void cpu_print_last_instruction(void) -{ - /* This function must exist else RIOT won't compile */ -} - -/** - * @brief Initialization of the Newlib-nano stub - */ -void nanostubs_init(void); - -#ifdef __cplusplus -} -#endif - -#endif /* CPU_H */ -/** @} */ diff --git a/cpu/fe310/include/cpu_conf.h b/cpu/fe310/include/cpu_conf.h index d4ad49ad78..0138911993 100644 --- a/cpu/fe310/include/cpu_conf.h +++ b/cpu/fe310/include/cpu_conf.h @@ -19,35 +19,23 @@ #ifndef CPU_CONF_H #define CPU_CONF_H -/** - * @name Configuration of default stack sizes - * @{ - */ -#ifndef THREAD_EXTRA_STACKSIZE_PRINTF -#define THREAD_EXTRA_STACKSIZE_PRINTF (256) -#endif -#ifndef THREAD_STACKSIZE_DEFAULT -#define THREAD_STACKSIZE_DEFAULT (1024) -#endif -#ifndef THREAD_STACKSIZE_IDLE -#define THREAD_STACKSIZE_IDLE (256) -#endif -/** @} */ - -/** - * @brief Declare the heap_stats function as available - */ -#define HAVE_HEAP_STATS - -/** - * @brief This arch uses the inlined irq API. - */ -#define IRQ_API_INLINED (1) +#include "cpu_conf_common.h" +#include "vendor/platform.h" #ifdef __cplusplus extern "C" { #endif +/** + * @brief Base address of the CLINT + */ +#define CLINT_BASE_ADDR (CLINT_CTRL_ADDR) + +/** + * @brief Base address of the PLIC peripheral + */ +#define PLIC_BASE_ADDR (PLIC_CTRL_ADDR) + #ifdef __cplusplus } #endif diff --git a/cpu/fe310/include/periph_cpu.h b/cpu/fe310/include/periph_cpu.h index 8e5cf719f0..d2593b1af0 100644 --- a/cpu/fe310/include/periph_cpu.h +++ b/cpu/fe310/include/periph_cpu.h @@ -21,24 +21,13 @@ #include +#include "periph_cpu_common.h" #include "cpu.h" #ifdef __cplusplus extern "C" { #endif -/** - * @name Power management configuration - * @{ - */ -#define PROVIDES_PM_SET_LOWEST -/** @} */ - -/** - * @brief Length of the CPU_ID in octets - */ -#define CPUID_LEN (12U) - #ifndef DOXYGEN /** * @brief Overwrite the default gpio_t type definition @@ -47,6 +36,11 @@ extern "C" { typedef uint8_t gpio_t; #endif +/** + * @brief Length of the CPU_ID in octets + */ +#define CPUID_LEN (12U) + /** * @brief Definition of a fitting UNDEF value */ @@ -66,10 +60,10 @@ typedef uint8_t gpio_t; * @brief Structure for UART configuration data */ typedef struct { - uint32_t addr; /**< UART control register address */ - gpio_t rx; /**< RX pin */ - gpio_t tx; /**< TX pin */ - plic_source isr_num; /**< ISR source number */ + uint32_t addr; /**< UART control register address */ + gpio_t rx; /**< RX pin */ + gpio_t tx; /**< TX pin */ + irqn_t isr_num; /**< ISR source number */ } uart_conf_t; /** @@ -180,6 +174,17 @@ typedef struct { #endif #endif +/** + * @brief Initialization of the clock + */ +void fe310_clock_init(void); + +/** + * @brief Get and eventually compute the current CPU core clock frequency + * + * @return the cpu core clock frequency in Hz + */ +uint32_t cpu_freq(void); /** @} */ diff --git a/cpu/fe310/periph/cpucycle.c b/cpu/fe310/periph/cpucycle.c index 71a1f7eb02..74d591438f 100644 --- a/cpu/fe310/periph/cpucycle.c +++ b/cpu/fe310/periph/cpucycle.c @@ -17,7 +17,6 @@ * @} */ #include "cpucycle.h" -#include "vendor/encoding.h" uint64_t get_cycle_count(void) diff --git a/cpu/fe310/periph/cpuid.c b/cpu/fe310/periph/cpuid.c index bd97ee415f..cd2e80e661 100644 --- a/cpu/fe310/periph/cpuid.c +++ b/cpu/fe310/periph/cpuid.c @@ -22,7 +22,7 @@ #include "periph/cpuid.h" #include "cpu.h" -#include "vendor/encoding.h" +#include "vendor/riscv_csr.h" #include "vendor/platform.h" void cpuid_get(void *id) diff --git a/cpu/fe310/periph/gpio.c b/cpu/fe310/periph/gpio.c index 91b4694848..3f3d790c05 100644 --- a/cpu/fe310/periph/gpio.c +++ b/cpu/fe310/periph/gpio.c @@ -26,9 +26,8 @@ #include "periph_conf.h" #include "periph/gpio.h" #include "plic.h" -#include "vendor/encoding.h" +#include "vendor/riscv_csr.h" #include "vendor/platform.h" -#include "vendor/plic_driver.h" /* Num of GPIOs supported */ #define GPIO_NUMOF (32) diff --git a/cpu/fe310/periph/rtt.c b/cpu/fe310/periph/rtt.c index c5f6b38aef..5799136f22 100644 --- a/cpu/fe310/periph/rtt.c +++ b/cpu/fe310/periph/rtt.c @@ -30,9 +30,8 @@ #include "periph_conf.h" #include "periph/rtt.h" #include "plic.h" -#include "vendor/encoding.h" +#include "vendor/riscv_csr.h" #include "vendor/platform.h" -#include "vendor/plic_driver.h" #define ENABLE_DEBUG 0 #include "debug.h" diff --git a/cpu/fe310/periph/uart.c b/cpu/fe310/periph/uart.c index 28cbedd84f..259f3e43fe 100644 --- a/cpu/fe310/periph/uart.c +++ b/cpu/fe310/periph/uart.c @@ -26,9 +26,8 @@ #include "cpu.h" #include "periph/uart.h" #include "plic.h" -#include "vendor/encoding.h" +#include "vendor/riscv_csr.h" #include "vendor/platform.h" -#include "vendor/plic_driver.h" #include "vendor/prci_driver.h" /** diff --git a/cpu/fe310/vendor/prci_driver.c b/cpu/fe310/vendor/prci_driver.c index ecdbd597fc..ecf056c765 100644 --- a/cpu/fe310/vendor/prci_driver.c +++ b/cpu/fe310/vendor/prci_driver.c @@ -3,7 +3,7 @@ #include #include -#include "vendor/encoding.h" +#include "vendor/riscv_csr.h" #include "vendor/platform.h" #include "vendor/prci_driver.h" @@ -36,31 +36,31 @@ uint32_t PRCI_measure_mcycle_freq(uint32_t mtime_ticks, uint32_t mtime_freq) do { start_mtime = CLINT_REG(CLINT_MTIME); } while (start_mtime == tmp); - + uint64_t start_mcycle; rdmcycle(&start_mcycle); - + while (CLINT_REG(CLINT_MTIME) < end_mtime) ; - + uint64_t end_mcycle; rdmcycle(&end_mcycle); uint32_t difference = (uint32_t) (end_mcycle - start_mcycle); uint64_t freq = ((uint64_t) difference * mtime_freq) / mtime_ticks; return (uint32_t) freq & 0xFFFFFFFF; - + } - + void PRCI_use_hfrosc(int div, int trim) { // Make sure the HFROSC is running at its default setting // It is OK to change this even if we are running off of it. - + PRCI_REG(PRCI_HFROSCCFG) = (ROSC_DIV(div) | ROSC_TRIM(trim) | ROSC_EN(1)); while ((PRCI_REG(PRCI_HFROSCCFG) & ROSC_RDY(1)) == 0); - + PRCI_REG(PRCI_PLLCFG) &= ~PLL_SEL(1); } @@ -73,12 +73,12 @@ void PRCI_use_pll(int refsel, int bypass, // Make sure the HFROSC is running at its default setting PRCI_use_hfrosc(4, 16); } - + // Set PLL Source to be HFXOSC if desired. uint32_t config_value = 0; config_value |= PLL_REFSEL(refsel); - + if (bypass) { // Bypass config_value |= PLL_BYPASS(1); @@ -89,14 +89,14 @@ void PRCI_use_pll(int refsel, int bypass, // Set our Final output divide to divide-by-1: PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV_BY_1(1) | PLL_FINAL_DIV(0)); } else { - + // To overclock, use the hfrosc if (hfrosctrim >= 0 && hfroscdiv >= 0) { PRCI_use_hfrosc(hfroscdiv, hfrosctrim); } - + // Set DIV Settings for PLL - + // (Legal values of f_REF are 6-48MHz) // Set DIVR to divide-by-2 to get 8MHz frequency @@ -134,7 +134,7 @@ void PRCI_use_pll(int refsel, int bypass, // So wait 4 ticks of RTC. uint32_t now = CLINT_REG(CLINT_MTIME); while (CLINT_REG(CLINT_MTIME) - now < 4) ; - + // Now it is safe to check for PLL Lock while ((PRCI_REG(PRCI_PLLCFG) & PLL_LOCK(1)) == 0); @@ -148,7 +148,7 @@ void PRCI_use_pll(int refsel, int bypass, if (refsel) { PRCI_REG(PRCI_HFROSCCFG) &= ~ROSC_EN(1); } - + } void PRCI_use_default_clocks(void) @@ -162,7 +162,7 @@ void PRCI_use_default_clocks(void) void PRCI_use_hfxosc(uint32_t finaldiv) { - + PRCI_use_pll(1, // Use HFXTAL 1, // Bypass = 1 0, // PLL settings don't matter @@ -216,20 +216,20 @@ uint32_t PRCI_set_hfrosctrim_for_f_cpu(uint32_t f_cpu, PRCI_freq_target target ) uint32_t desired_hfrosc_freq = (f_cpu/ 16); PRCI_use_hfrosc(hfroscdiv, hfrosctrim); - + // Ignore the first run (for icache reasons) uint32_t cpu_freq = PRCI_measure_mcycle_freq(3000, RTC_FREQ); cpu_freq = PRCI_measure_mcycle_freq(3000, RTC_FREQ); uint32_t prev_freq = cpu_freq; - + while ((cpu_freq < desired_hfrosc_freq) && (hfrosctrim < 0x1F)){ prev_trim = hfrosctrim; prev_freq = cpu_freq; hfrosctrim ++; PRCI_use_hfrosc(hfroscdiv, hfrosctrim); cpu_freq = PRCI_measure_mcycle_freq(3000, RTC_FREQ); - } + } // We couldn't go low enough if (prev_freq > desired_hfrosc_freq){ @@ -237,7 +237,7 @@ uint32_t PRCI_set_hfrosctrim_for_f_cpu(uint32_t f_cpu, PRCI_freq_target target ) cpu_freq = PRCI_measure_mcycle_freq(1000, RTC_FREQ); return cpu_freq; } - + // We couldn't go high enough if (cpu_freq < desired_hfrosc_freq){ PRCI_use_pll(0, 0, 1, 31, 1, 1, hfroscdiv, prev_trim); diff --git a/cpu/riscv_common/Kconfig b/cpu/riscv_common/Kconfig new file mode 100644 index 0000000000..635d3c8a09 --- /dev/null +++ b/cpu/riscv_common/Kconfig @@ -0,0 +1,34 @@ +# Copyright (c) 2020 Inria +# +# This file is subject to the terms and conditions of the GNU Lesser +# General Public License v2.1. See the file LICENSE in the top level +# directory for more details. + +config CPU_ARCH_RISCV + bool + select HAS_ARCH_RISCV + select HAS_CPP + select HAS_LIBSTDCPP + select HAS_NEWLIB + select HAS_PERIPH_CORETIMER + select HAS_PERIPH_PLIC + select HAS_PICOLIBC if '$(RIOT_CI_BUILD)' != '1' + select MODULE_MALLOC_THREAD_SAFE if TEST_KCONFIG + select HAS_SSP + +config CPU_CORE_RV32I + bool + select CPU_ARCH_RISCV + select HAS_ARCH_32BIT + +## Definition of specific features +config HAS_ARCH_RISCV + bool + help + Indicates that the current CPU has a RISC-V. + +config CPU_ARCH + default "risc-v" if CPU_ARCH_RISCV + +config CPU_CORE + default "rv32i" if CPU_CORE_RV32I diff --git a/cpu/riscv_common/Makefile b/cpu/riscv_common/Makefile new file mode 100644 index 0000000000..e09377cd1e --- /dev/null +++ b/cpu/riscv_common/Makefile @@ -0,0 +1,3 @@ +DIRS = periph + +include $(RIOTBASE)/Makefile.base diff --git a/cpu/riscv_common/Makefile.dep b/cpu/riscv_common/Makefile.dep new file mode 100644 index 0000000000..70aa523b8c --- /dev/null +++ b/cpu/riscv_common/Makefile.dep @@ -0,0 +1,8 @@ +# Tell the build system that the CPU depends on the risc-v common files: +USEMODULE += riscv_common + +# include common periph code +USEMODULE += riscv_common_periph + +# Make calls to malloc and friends thread-safe +USEMODULE += malloc_thread_safe diff --git a/cpu/riscv_common/Makefile.features b/cpu/riscv_common/Makefile.features new file mode 100644 index 0000000000..e73b5bdb50 --- /dev/null +++ b/cpu/riscv_common/Makefile.features @@ -0,0 +1,13 @@ +FEATURES_PROVIDED += arch_32bit +FEATURES_PROVIDED += arch_riscv +FEATURES_PROVIDED += cpp +FEATURES_PROVIDED += libstdcpp +FEATURES_PROVIDED += newlib +FEATURES_PROVIDED += periph_coretimer +FEATURES_PROVIDED += periph_plic +FEATURES_PROVIDED += ssp + +# RISC-V toolchain on CI does not work properly with picolibc yet +ifeq (,$(RIOT_CI_BUILD)) + FEATURES_PROVIDED += picolibc +endif diff --git a/cpu/riscv_common/Makefile.include b/cpu/riscv_common/Makefile.include new file mode 100644 index 0000000000..5b29fc9f8c --- /dev/null +++ b/cpu/riscv_common/Makefile.include @@ -0,0 +1,24 @@ +CFLAGS += -Wno-pedantic +INCLUDES += -I$(RIOTCPU)/riscv_common/include + +# All variables must be defined in the CPU configuration when using the common +# `ldscripts/riscv.ld` +ifneq (,$(ROM_START_ADDR)$(RAM_START_ADDR)$(ROM_LEN)$(RAM_LEN)) + $(if $(ROM_START_ADDR),,$(error ROM_START_ADDR is not defined)) + $(if $(RAM_START_ADDR),,$(error RAM_START_ADDR is not defined)) + $(if $(ROM_LEN),,$(error ROM_LEN is not defined)) + $(if $(RAM_LEN),,$(error RAM_LEN is not defined)) + LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_rom_start_addr=$(ROM_START_ADDR) + LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_ram_start_addr=$(RAM_START_ADDR) + LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_rom_length=$(ROM_LEN) + LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_ram_length=$(RAM_LEN) +endif + +ifneq (,$(ITIM_START_ADDR)) + LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_itim_start_addr=$(ITIM_START_ADDR) + LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_itim_length=$(ITIM_LEN) +endif + +LINKER_SCRIPT ?= riscv.ld + +include $(RIOTMAKE)/arch/riscv.inc.mk diff --git a/cpu/fe310/context_frame.c b/cpu/riscv_common/context_frame.c similarity index 98% rename from cpu/fe310/context_frame.c rename to cpu/riscv_common/context_frame.c index fc808260bf..e819e3cd2b 100644 --- a/cpu/fe310/context_frame.c +++ b/cpu/riscv_common/context_frame.c @@ -7,7 +7,7 @@ */ /** - * @ingroup cpu_fe310 + * @ingroup cpu_riscv_common * @ingroup cpu * @{ * diff --git a/cpu/fe310/include/architecture_arch.h b/cpu/riscv_common/include/architecture_arch.h similarity index 100% rename from cpu/fe310/include/architecture_arch.h rename to cpu/riscv_common/include/architecture_arch.h diff --git a/cpu/fe310/include/atomic_utils_arch.h b/cpu/riscv_common/include/atomic_utils_arch.h similarity index 100% rename from cpu/fe310/include/atomic_utils_arch.h rename to cpu/riscv_common/include/atomic_utils_arch.h diff --git a/cpu/fe310/include/c11_atomics_compat_cpu.hpp b/cpu/riscv_common/include/c11_atomics_compat_cpu.hpp similarity index 100% rename from cpu/fe310/include/c11_atomics_compat_cpu.hpp rename to cpu/riscv_common/include/c11_atomics_compat_cpu.hpp diff --git a/cpu/fe310/include/context_frame.h b/cpu/riscv_common/include/context_frame.h similarity index 99% rename from cpu/fe310/include/context_frame.h rename to cpu/riscv_common/include/context_frame.h index 214078baa6..00e7933cbf 100644 --- a/cpu/fe310/include/context_frame.h +++ b/cpu/riscv_common/include/context_frame.h @@ -7,7 +7,7 @@ */ /** - * @ingroup cpu_fe310 + * @ingroup cpu_riscv_common * @{ * * @file diff --git a/cpu/riscv_common/include/cpu.h b/cpu/riscv_common/include/cpu.h new file mode 100644 index 0000000000..7692c1909f --- /dev/null +++ b/cpu/riscv_common/include/cpu.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020, Koen Zandberg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @defgroup cpu_riscv_common RISC-V common + * @ingroup cpu + * @brief Common implementations and headers for the RISC-V CPU + * @{ + * + * @file + * @brief Basic definitions for the RISC-V CPU module + * + * @author Koen Zandberg + */ + +#include + +#include "irq_arch.h" + +#ifndef CPU_H +#define CPU_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialization of the CPU + */ +void cpu_init(void); + +/** + * @brief Initialize rv32i specific core parts of the CPU + * + * Initialized the interrupt controller and the enables the FPU if present + */ +void riscv_init(void); + +/** + * @brief Enable the rv32i FPU when present + */ +void riscv_fpu_init(void); + +/** + * @brief Initialization of the interrupt controller + */ +void riscv_irq_init(void); + +/** + * @brief Print the last instruction's address + * + * @todo: Not supported + */ +static inline void cpu_print_last_instruction(void) +{ + /* This function must exist else RIOT won't compile */ +} + +#ifdef __cplusplus +} +#endif + +#endif /* CPU_H */ +/** @} */ diff --git a/cpu/riscv_common/include/cpu_conf_common.h b/cpu/riscv_common/include/cpu_conf_common.h new file mode 100644 index 0000000000..fdce085f62 --- /dev/null +++ b/cpu/riscv_common/include/cpu_conf_common.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2020 Koen Zandberg + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @ingroup cpu_riscv_common + * @{ + * + * @file + * @brief RISC-V CPU configuration options + * + * @author Koen Zandberg + */ + +#ifndef CPU_CONF_COMMON_H +#define CPU_CONF_COMMON_H + +#include "vendor/riscv_csr.h" +#include "cpu_conf_common.h" + +/** + * @name Configuration of default stack sizes + * @{ + */ +#ifndef THREAD_EXTRA_STACKSIZE_PRINTF +#define THREAD_EXTRA_STACKSIZE_PRINTF (256) +#endif +#ifndef THREAD_STACKSIZE_DEFAULT +#define THREAD_STACKSIZE_DEFAULT (1024) +#endif +#ifndef THREAD_STACKSIZE_IDLE +#define THREAD_STACKSIZE_IDLE (256) +#endif +/** @} */ + +/** + * @brief Declare the heap_stats function as available + */ +#define HAVE_HEAP_STATS + +/** + * @brief This arch uses the inlined irq API. + */ +#define IRQ_API_INLINED (1) + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* CPU_CONF_COMMON_H */ +/** @} */ diff --git a/cpu/fe310/include/cpucycle.h b/cpu/riscv_common/include/cpucycle.h similarity index 95% rename from cpu/fe310/include/cpucycle.h rename to cpu/riscv_common/include/cpucycle.h index fb37d2a4b7..63dc495e60 100644 --- a/cpu/fe310/include/cpucycle.h +++ b/cpu/riscv_common/include/cpucycle.h @@ -7,7 +7,7 @@ */ /** - * @ingroup cpu_fe310 + * @ingroup cpu_riscv_common * @{ * * @file diff --git a/cpu/fe310/include/irq_arch.h b/cpu/riscv_common/include/irq_arch.h similarity index 92% rename from cpu/fe310/include/irq_arch.h rename to cpu/riscv_common/include/irq_arch.h index 3016a08c50..d6876de964 100644 --- a/cpu/fe310/include/irq_arch.h +++ b/cpu/riscv_common/include/irq_arch.h @@ -9,7 +9,7 @@ */ /** - * @ingroup cpu_fe310 + * @ingroup cpu_riscv_common * @{ * * @file @@ -24,17 +24,15 @@ #define IRQ_ARCH_H #include -#include "irq.h" -#include "cpu_conf.h" -#include "cpu.h" -#include "vendor/encoding.h" +#include "irq.h" +#include "vendor/riscv_csr.h" #ifdef __cplusplus extern "C" { #endif -extern volatile int fe310_in_isr; +extern volatile int riscv_in_isr; /** * @brief Enable all maskable interrupts @@ -91,7 +89,7 @@ static inline __attribute__((always_inline)) void irq_restore( */ static inline __attribute__((always_inline)) int irq_is_in(void) { - return fe310_in_isr; + return riscv_in_isr; } #ifdef __cplusplus diff --git a/cpu/riscv_common/include/periph_cpu_common.h b/cpu/riscv_common/include/periph_cpu_common.h new file mode 100644 index 0000000000..e573b8589e --- /dev/null +++ b/cpu/riscv_common/include/periph_cpu_common.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2020 Koen Zandberg + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @ingroup cpu_riscv_common + * @{ + * + * @file + * @brief CPU specific definitions for internal peripheral handling + * + * @author Koen Zandberg + */ + +#ifndef PERIPH_CPU_COMMON_H +#define PERIPH_CPU_COMMON_H + +#include + +#include "cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name Power management configuration + * @{ + */ +#define PROVIDES_PM_SET_LOWEST +/** @} */ + +/** + * @brief Convenience typedef for interrupt lines + */ +typedef unsigned irqn_t; + +#ifdef __cplusplus +} +#endif + +#endif /* PERIPH_CPU_COMMON_H */ +/** @} */ diff --git a/cpu/fe310/include/plic.h b/cpu/riscv_common/include/plic.h similarity index 97% rename from cpu/fe310/include/plic.h rename to cpu/riscv_common/include/plic.h index 4e49176603..3390d916cc 100644 --- a/cpu/fe310/include/plic.h +++ b/cpu/riscv_common/include/plic.h @@ -7,7 +7,7 @@ */ /** - * @ingroup cpu_fe310 + * @ingroup cpu_riscv_common * @{ * * @file diff --git a/cpu/fe310/include/thread_arch.h b/cpu/riscv_common/include/thread_arch.h similarity index 100% rename from cpu/fe310/include/thread_arch.h rename to cpu/riscv_common/include/thread_arch.h diff --git a/cpu/fe310/include/vendor/clint.h b/cpu/riscv_common/include/vendor/clint.h similarity index 60% rename from cpu/fe310/include/vendor/clint.h rename to cpu/riscv_common/include/vendor/clint.h index cd3e0c7a34..7dcb9768df 100644 --- a/cpu/fe310/include/vendor/clint.h +++ b/cpu/riscv_common/include/vendor/clint.h @@ -1,8 +1,5 @@ -// See LICENSE for license details - -#ifndef _SIFIVE_CLINT_H -#define _SIFIVE_CLINT_H - +#ifndef RISCV_CLINT_H +#define RISCV_CLINT_H #define CLINT_MSIP 0x0000 #define CLINT_MSIP_size 0x4 @@ -11,4 +8,4 @@ #define CLINT_MTIME 0xBFF8 #define CLINT_MTIME_size 0x8 -#endif /* _SIFIVE_CLINT_H */ +#endif /* RISCV_CLINT_H */ diff --git a/cpu/fe310/include/vendor/plic.h b/cpu/riscv_common/include/vendor/plic.h similarity index 100% rename from cpu/fe310/include/vendor/plic.h rename to cpu/riscv_common/include/vendor/plic.h diff --git a/cpu/fe310/include/vendor/encoding.h b/cpu/riscv_common/include/vendor/riscv_csr.h similarity index 98% rename from cpu/fe310/include/vendor/encoding.h rename to cpu/riscv_common/include/vendor/riscv_csr.h index 2573eb73e3..6648c452af 100644 --- a/cpu/fe310/include/vendor/encoding.h +++ b/cpu/riscv_common/include/vendor/riscv_csr.h @@ -1,7 +1,26 @@ -// See LICENSE for license details. +/* + * Copyright (C) 2020, Koen Zandberg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ -#ifndef RISCV_CSR_ENCODING_H -#define RISCV_CSR_ENCODING_H +/** + * @defgroup cpu_riscv_common_vendor + * @ingroup cpu_riscv_common + * @brief RISC-V CSR definitions + * @{ + * + * @file + * @brief Basic definitions for the RISC-V CSRs. Upstream usually calls + * this file `encoding.h` + * + * @author Koen Zandberg + */ + +#ifndef RISCV_CSR_H +#define RISCV_CSR_H #define MSTATUS_UIE 0x00000001 #define MSTATUS_SIE 0x00000002 @@ -1311,3 +1330,4 @@ DECLARE_CAUSE("supervisor_ecall", CAUSE_SUPERVISOR_ECALL) DECLARE_CAUSE("hypervisor_ecall", CAUSE_HYPERVISOR_ECALL) DECLARE_CAUSE("machine_ecall", CAUSE_MACHINE_ECALL) #endif + diff --git a/cpu/fe310/irq_arch.c b/cpu/riscv_common/irq_arch.c similarity index 97% rename from cpu/fe310/irq_arch.c rename to cpu/riscv_common/irq_arch.c index 227878327f..18326586f9 100644 --- a/cpu/fe310/irq_arch.c +++ b/cpu/riscv_common/irq_arch.c @@ -7,11 +7,12 @@ */ /** - * @ingroup cpu_fe310 + * @ingroup cpu_riscv_common * @{ * * @file cpu.c - * @brief Implementation of the CPU IRQ management for SiFive FE310 + * @brief Implementation of the CPU IRQ management for RISC-V clint/plic + * peripheral * * @author Ken Rabold * @} @@ -29,14 +30,12 @@ #include "sched.h" #include "plic.h" -#include "vendor/encoding.h" -#include "vendor/platform.h" -#include "vendor/plic_driver.h" +#include "vendor/riscv_csr.h" /* Default state of mstatus register */ #define MSTATUS_DEFAULT (MSTATUS_MPP | MSTATUS_MPIE) -volatile int fe310_in_isr = 0; +volatile int riscv_in_isr = 0; /** * @brief ISR trap vector @@ -48,7 +47,7 @@ static void trap_entry(void); */ void timer_isr(void); -void irq_init(void) +void riscv_irq_init(void) { /* Setup trap handler function */ write_csr(mtvec, &trap_entry); @@ -75,7 +74,7 @@ void handle_trap(uint32_t mcause) { /* Tell RIOT to set sched_context_switch_request instead of * calling thread_yield(). */ - fe310_in_isr = 1; + riscv_in_isr = 1; /* Check for INT or TRAP */ if ((mcause & MCAUSE_INT) == MCAUSE_INT) { @@ -125,7 +124,7 @@ void handle_trap(uint32_t mcause) } } /* ISR done - no more changes to thread states */ - fe310_in_isr = 0; + riscv_in_isr = 0; } /* Marking this as interrupt to ensure an mret at the end, provided by the diff --git a/cpu/fe310/ldscripts/fe310.ld b/cpu/riscv_common/ldscripts/riscv.ld similarity index 70% rename from cpu/fe310/ldscripts/fe310.ld rename to cpu/riscv_common/ldscripts/riscv.ld index c37ec4c519..72f9731c7e 100644 --- a/cpu/fe310/ldscripts/fe310.ld +++ b/cpu/riscv_common/ldscripts/riscv.ld @@ -7,24 +7,24 @@ */ /** - * @addtogroup cpu_fe310 + * @addtogroup cpu_riscv_common * @{ * * @file - * @brief Memory definitions for the SiFive FE310 + * @brief Memory definitions for the RISC-V CPU * * @author Ken Rabold * @author Koen Zandberg * * @} */ -INCLUDE fe310_vars.ld +INCLUDE riscv_vars.ld MEMORY { - flash (rxai!w) : ORIGIN = _rom_start_addr , LENGTH = _rom_length + flash (rxai!w) : ORIGIN = _rom_start_addr, LENGTH = _rom_length ram (wxa!ri) : ORIGIN = _ram_start_addr, LENGTH = _ram_length itim (wxa!ri) : ORIGIN = _itim_start_addr, LENGTH = _itim_length } -INCLUDE fe310_base.ld +INCLUDE riscv_base.ld diff --git a/cpu/fe310/ldscripts/fe310_base.ld b/cpu/riscv_common/ldscripts/riscv_base.ld similarity index 98% rename from cpu/fe310/ldscripts/fe310_base.ld rename to cpu/riscv_common/ldscripts/riscv_base.ld index 3a344dd5ec..44b62ac855 100644 --- a/cpu/fe310/ldscripts/fe310_base.ld +++ b/cpu/riscv_common/ldscripts/riscv_base.ld @@ -7,11 +7,11 @@ */ /** - * @addtogroup cpu_fe310 + * @addtogroup cpu_riscv_common * @{ * * @file - * @brief Common linker directives for the SiFive FE310 + * @brief Common linker directives for the RISC-V CPU * * @author Ken Rabold * diff --git a/cpu/fe310/ldscripts/fe310_vars.ld b/cpu/riscv_common/ldscripts/riscv_vars.ld similarity index 84% rename from cpu/fe310/ldscripts/fe310_vars.ld rename to cpu/riscv_common/ldscripts/riscv_vars.ld index e975736ae1..0efcc7f3c7 100644 --- a/cpu/fe310/ldscripts/fe310_vars.ld +++ b/cpu/riscv_common/ldscripts/riscv_vars.ld @@ -8,11 +8,11 @@ */ /** - * @addtogroup cpu_fe310 + * @addtogroup cpu_riscv_common * @{ * * @file - * @brief Linker variables for SiFive FE310 + * @brief Linker variables for the RISC-V CPU * * @author Koen Zandberg * diff --git a/cpu/fe310/panic.c b/cpu/riscv_common/panic.c similarity index 81% rename from cpu/fe310/panic.c rename to cpu/riscv_common/panic.c index 45f76ee80e..50cb7456e5 100644 --- a/cpu/fe310/panic.c +++ b/cpu/riscv_common/panic.c @@ -7,11 +7,11 @@ */ /** - * @ingroup cpu_fe310 + * @ingroup cpu_riscv_common * @{ * * @file cpu.c - * @brief Implementation of the CPU panic for SiFive FE310 + * @brief Implementation of the CPU panic for RISC-V * * @author Ken Rabold * @} diff --git a/cpu/riscv_common/periph/Makefile b/cpu/riscv_common/periph/Makefile new file mode 100644 index 0000000000..db019f82ea --- /dev/null +++ b/cpu/riscv_common/periph/Makefile @@ -0,0 +1,2 @@ +MODULE = riscv_common_periph +include $(RIOTMAKE)/periph.mk diff --git a/cpu/fe310/periph/timer.c b/cpu/riscv_common/periph/coretimer.c similarity index 74% rename from cpu/fe310/periph/timer.c rename to cpu/riscv_common/periph/coretimer.c index e20ef5f932..d3fa31a321 100644 --- a/cpu/fe310/periph/timer.c +++ b/cpu/riscv_common/periph/coretimer.c @@ -7,11 +7,21 @@ */ /** - * @ingroup cpu_fe310 + * @ingroup cpu_riscv_common * @{ * * @file timer.c - * @brief Low-level timer implementation + * @brief Low-level timer implementation based on the CLINT + * + * RISCV implementations using this peripheral must define the `CLINT_BASE_ADDR` + * in order to use the clint as timer. + * + * This implementation assumes the following registers at their offsets: + * + * - mtimecmp: 0x4000 + * - mtime: 0xBFF8 + * + * The MTIP flag in the mie csr is used to enable and disable the interrupt * * @author Ken Rabold * @} @@ -21,11 +31,15 @@ #include #include "cpu.h" +#include "cpu_conf.h" #include "periph_cpu.h" #include "periph_conf.h" #include "periph/timer.h" -#include "vendor/encoding.h" -#include "vendor/platform.h" +#include "vendor/riscv_csr.h" + +#ifndef CLINT_BASE_ADDR +#error CLINT_BASE_ADDR must be defined to use the CLINT as timer +#endif /** * @brief Save reference to the timer callback @@ -44,7 +58,6 @@ int timer_init(tim_t dev, uint32_t freq, timer_cb_t cb, void *arg) return -1; } - /* Built in timer for FE310 is 32KHz */ if (freq != RTC_FREQ) { return -1; } @@ -55,7 +68,7 @@ int timer_init(tim_t dev, uint32_t freq, timer_cb_t cb, void *arg) /* reset timer counter */ - volatile uint64_t *mtime = (uint64_t *)(CLINT_CTRL_ADDR + CLINT_MTIME); + volatile uint64_t *mtime = (uint64_t *)(CLINT_BASE_ADDR + CLINT_MTIME); *mtime = 0; @@ -64,9 +77,9 @@ int timer_init(tim_t dev, uint32_t freq, timer_cb_t cb, void *arg) int timer_set(tim_t dev, int channel, unsigned int timeout) { - volatile uint64_t *mtime = (uint64_t *)(CLINT_CTRL_ADDR + CLINT_MTIME); + volatile uint64_t *mtime = (uint64_t *)(CLINT_BASE_ADDR + CLINT_MTIME); volatile uint64_t *mtimecmp = - (uint64_t *)(CLINT_CTRL_ADDR + CLINT_MTIMECMP); + (uint64_t *)(CLINT_BASE_ADDR + CLINT_MTIMECMP); /* Compute delta for timer */ uint64_t now = *mtime; @@ -90,9 +103,9 @@ int timer_set(tim_t dev, int channel, unsigned int timeout) int timer_set_absolute(tim_t dev, int channel, unsigned int value) { - volatile uint64_t *mtime = (uint64_t *)(CLINT_CTRL_ADDR + CLINT_MTIME); + volatile uint64_t *mtime = (uint64_t *)(CLINT_BASE_ADDR + CLINT_MTIME); volatile uint64_t *mtimecmp = - (uint64_t *)(CLINT_CTRL_ADDR + CLINT_MTIMECMP); + (uint64_t *)(CLINT_BASE_ADDR + CLINT_MTIMECMP); /* Compute absolute for timer */ uint64_t now = *mtime; @@ -124,7 +137,7 @@ int timer_clear(tim_t dev, int channel) unsigned int timer_read(tim_t dev) { - uint32_t lo = *(volatile uint32_t *)(CLINT_CTRL_ADDR + CLINT_MTIME); + uint32_t lo = *(volatile uint32_t *)(CLINT_BASE_ADDR + CLINT_MTIME); if (dev != 0) { return 0; @@ -158,7 +171,7 @@ void timer_stop(tim_t dev) void timer_isr(void) { volatile uint64_t *mtimecmp = - (uint64_t *)(CLINT_CTRL_ADDR + CLINT_MTIMECMP); + (uint64_t *)(CLINT_BASE_ADDR + CLINT_MTIMECMP); /* Clear intr */ clear_csr(mie, MIP_MTIP); diff --git a/cpu/fe310/periph/plic.c b/cpu/riscv_common/periph/plic.c similarity index 85% rename from cpu/fe310/periph/plic.c rename to cpu/riscv_common/periph/plic.c index 2d9fa6b80d..27c429ac39 100644 --- a/cpu/fe310/periph/plic.c +++ b/cpu/riscv_common/periph/plic.c @@ -7,23 +7,32 @@ */ /** - * @ingroup cpu_fe310 + * @ingroup cpu_riscv_common * @{ * * @file * @brief Platform-Level interrupt controller driver * + * RISCV implementations using this peripheral must define the `PLIC_BASE_ADDR`, + * in order to use the PLIC as interrupt controller. Also required are: + * PLIC_NUM_INTERRUPTS and PLIC_NUM_PRIORITIES (future compatibility). + * * @author Koen Zandberg * @} */ #include -#include "vendor/encoding.h" -#include "vendor/platform.h" +#include "vendor/riscv_csr.h" + +#include "assert.h" #include "cpu.h" #include "plic.h" +/* Local macros to calculate register offsets */ +#define _REG32(p, i) (*(volatile uint32_t *) ((p) + (i))) +#define PLIC_REG(offset) _REG32(PLIC_CTRL_ADDR, offset) + /* PLIC external ISR function list */ static plic_isr_cb_t _ext_isrs[PLIC_NUM_INTERRUPTS]; diff --git a/cpu/riscv_common/riscv_init.c b/cpu/riscv_common/riscv_init.c new file mode 100644 index 0000000000..12c6a1cb13 --- /dev/null +++ b/cpu/riscv_common/riscv_init.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020, Koen Zandberg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_riscv_common + * @{ + * + * @file cpu.c + * @brief Common CPU initialization for RISC-V rv32i architecture + * + * @author Koen Zandberg + * @} + */ + +#include "cpu.h" +#include "cpu_conf_common.h" +#include "periph_cpu_common.h" + +void riscv_fpu_init(void) +{ + /* Enable FPU if present */ + if (read_csr(misa) & (1 << ('F' - 'A'))) { + write_csr(mstatus, MSTATUS_FS); /* allow FPU instructions without trapping */ + write_csr(fcsr, 0); /* initialize rounding mode, undefined at reset */ + } +} + +void riscv_init(void) +{ + riscv_fpu_init(); + riscv_irq_init(); +} diff --git a/cpu/fe310/start.S b/cpu/riscv_common/start.S similarity index 100% rename from cpu/fe310/start.S rename to cpu/riscv_common/start.S diff --git a/cpu/fe310/thread_arch.c b/cpu/riscv_common/thread_arch.c similarity index 99% rename from cpu/fe310/thread_arch.c rename to cpu/riscv_common/thread_arch.c index 96674a15c6..4cbe115fa7 100644 --- a/cpu/fe310/thread_arch.c +++ b/cpu/riscv_common/thread_arch.c @@ -7,11 +7,11 @@ */ /** - * @ingroup cpu_fe310 + * @ingroup cpu_riscv_common * @{ * * @file cpu.c - * @brief Implementation of the CPU thread management for SiFive FE310 + * @brief Implementation of the CPU thread management for RISC-V * * @author Ken Rabold * @} diff --git a/kconfigs/Kconfig.features b/kconfigs/Kconfig.features index f297e2aecd..f3d46df872 100644 --- a/kconfigs/Kconfig.features +++ b/kconfigs/Kconfig.features @@ -94,6 +94,11 @@ config HAS_PERIPH_CAN help Indicates that a CAN peripheral is present. +config HAS_PERIPH_CORETIMER + bool + help + Indicates that the CLINT timer can be used as timer peripheral + config HAS_PERIPH_CPUID bool help diff --git a/makefiles/arch/riscv.inc.mk b/makefiles/arch/riscv.inc.mk index 6d22f4e501..12f42cd64b 100644 --- a/makefiles/arch/riscv.inc.mk +++ b/makefiles/arch/riscv.inc.mk @@ -35,7 +35,7 @@ CFLAGS_LINK = -nostartfiles -ffunction-sections -fdata-sections CFLAGS_DBG ?= -g3 CFLAGS_OPT ?= -Os -LINKFLAGS += -L$(RIOTCPU)/$(CPU)/ldscripts +LINKFLAGS += -L$(RIOTCPU)/$(CPU)/ldscripts -L$(RIOTCPU)/riscv_common/ldscripts LINKER_SCRIPT ?= $(CPU_MODEL).ld LINKFLAGS += -T$(LINKER_SCRIPT)