diff --git a/CODEOWNERS b/CODEOWNERS index 8df9488ad21f0..ca4554ead3cbf 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -74,6 +74,7 @@ /soc/riscv/openisa*/ @dleach02 /soc/riscv/riscv-privilege/andes_v5/ @cwshu @kevinwang821020 @jimmyzhe /soc/riscv/riscv-privilege/neorv32/ @henrikbrixandersen +/soc/riscv/riscv-privilege/gd32vf103/ @soburi /soc/x86/ @dcpleung @nashif @jenmwms @aasthagr /arch/xtensa/ @dcpleung @andyross @nashif /soc/xtensa/ @dcpleung @andyross @nashif @@ -152,6 +153,7 @@ /boards/riscv/rv32m1_vega/ @dleach02 /boards/riscv/beaglev_starlight_jh7100/ @rajnesh-kanwal /boards/riscv/adp_xc7k_ae350/ @cwshu @kevinwang821020 @jimmyzhe +/boards/riscv/longan_nano/ @soburi /boards/riscv/neorv32/ @henrikbrixandersen /boards/shields/ @erwango /boards/shields/atmel_rf2xx/ @nandojve @@ -274,6 +276,7 @@ /drivers/interrupt_controller/ @dcpleung @nashif /drivers/interrupt_controller/intc_gic.c @stephanosio /drivers/interrupt_controller/*esp32* @glaubermaroto +/drivers/interrupt_controller/intc_nuclei_eclic.c @soburi /drivers/ipm/ipm_mhu* @karl-zh /drivers/ipm/Kconfig.nrfx @masz-nordic /drivers/ipm/Kconfig.nrfx_ipc_channel @masz-nordic diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index eb827350ba4c4..35e49f8288864 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1380,14 +1380,18 @@ GD32 Platforms: maintainers: - nandojve - gmarull + collaborators: + - soburi files: - boards/arm/gd32*/ + - boards/riscv/longan_nano/ - drivers/*/*gd32*/ - drivers/*/*gd32* - - dts/arm/gigadevice/ + - dts/*/gigadevice/ - dts/bindings/*/*gd32* - modules/hal_gigadevice/ - soc/arm/gigadevice/ + - soc/riscv/riscv-privilege/gd32vf103/ - scripts/west_commands/*/*gd32* labels: - "platform: GD32" diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 524ce570415f4..cf19b29e565dc 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -102,6 +102,13 @@ config RISCV_SOC_INTERRUPT_INIT Enable SOC-based interrupt initialization (call soc_interrupt_init, within _IntLibInit when enabled) +config RISCV_SOC_MCAUSE_EXCEPTION_MASK + hex + default 0x7FFFFFFFFFFFFFFF if 64BIT + default 0x7FFFFFFF + help + Specify the bits to use for exception code in mcause register. + config RISCV_GENERIC_TOOLCHAIN bool "Compile using generic riscv32 toolchain" default y diff --git a/boards/riscv/longan_nano/Kconfig.board b/boards/riscv/longan_nano/Kconfig.board new file mode 100644 index 0000000000000..f656bdbf67a01 --- /dev/null +++ b/boards/riscv/longan_nano/Kconfig.board @@ -0,0 +1,10 @@ +# Copyright (c) 2021 Tokita, Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_LONGAN_NANO + bool "Sipeed Longan Nano target" + depends on SOC_GD32VF103 + +config BOARD_LONGAN_NANO_LITE + bool "Sipeed Longan Nano Lite target" + depends on SOC_GD32VF103 diff --git a/boards/riscv/longan_nano/Kconfig.defconfig b/boards/riscv/longan_nano/Kconfig.defconfig new file mode 100644 index 0000000000000..23b6a05ce6944 --- /dev/null +++ b/boards/riscv/longan_nano/Kconfig.defconfig @@ -0,0 +1,11 @@ +# Sipeed longan nano Development Board Configuration + +# Copyright (c) 2021 Tokita, Hiroshi + +if BOARD_LONGAN_NANO || BOARD_LONGAN_NANO_LITE + +config BOARD + default "longan_nano" if BOARD_LONGAN_NANO + default "longan_nano_lite" if BOARD_LONGAN_NANO_LITE + +endif # BOARD_LONGAN_NANO || BOARD_LONGAN_NANO_LITE diff --git a/boards/riscv/longan_nano/board.cmake b/boards/riscv/longan_nano/board.cmake new file mode 100644 index 0000000000000..17955424a250d --- /dev/null +++ b/boards/riscv/longan_nano/board.cmake @@ -0,0 +1,10 @@ +# Copyright (c) 2021 Tokita, Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(openocd --cmd-pre-init "source [find target/gd32vf103.cfg]") + +board_runner_args(openocd "--cmd-pre-load=gd32vf103-pre-load") +board_runner_args(openocd "--cmd-load=gd32vf103-load") +board_runner_args(openocd "--cmd-post-verify=gd32vf103-post-verify") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/riscv/longan_nano/doc/index.rst b/boards/riscv/longan_nano/doc/index.rst new file mode 100644 index 0000000000000..62065c2346977 --- /dev/null +++ b/boards/riscv/longan_nano/doc/index.rst @@ -0,0 +1,64 @@ +.. _longan_nano: + +Sipeed Longan Nano +################## + +Overview +******** + +The Sipeed Longan Nano and Longan Nano Lite is an simple and tiny development board with +an GigaDevice GD32VF103 SoC that based on N200 RISC-V IP core by Nuclei system technology. +More information can be found on: + +- `Sipeed Longan website `_ +- `GD32VF103 datasheet `_ +- `GD32VF103 user manual `_ +- `Nuclei website `_ +- `Nuclei Bumblebee core documents `_ +- `Nuclei ISA Spec `_ + +Programming and debugging +************************* + +Building +======== + +Applications for the ``logan_nano`` board configuration can be built as usual +(see :ref:`build_an_application`) using the corresponding board name: + +.. zephyr-app-commands:: + :board: logan_nano + :goals: build + +Flashing +======== + +In order to upload the application to the device, you'll need OpenOCD with +GD32V support. Download the tarball for your OS from the +`SiPEED longan nano download site +`_ and extract it. + +The Zephyr SDK uses a bundled version of OpenOCD by default. You can +overwrite that behavior by adding the +``-DOPENOCD=`` +parameter when building: + +.. zephyr-app-commands:: + :board: longan_nano + :goals: build + :gen-args: -DOPENOCD= + +When using a custom toolchain it should be enough to have the downloaded +version of the binary in your ``PATH``. + +Now you can flash the application as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details): + +.. code-block:: console + + west flash + +Debugging +========= + +Refer to the detailed overview about :ref:`application_debugging`. diff --git a/boards/riscv/longan_nano/longan_nano-pinctrl.dtsi b/boards/riscv/longan_nano/longan_nano-pinctrl.dtsi new file mode 100644 index 0000000000000..ff327094a7364 --- /dev/null +++ b/boards/riscv/longan_nano/longan_nano-pinctrl.dtsi @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2021, TOKITA Hiroshi + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + usart0_default: usart0_default { + group1 { + pinmux = , ; + }; + }; +}; diff --git a/boards/riscv/longan_nano/longan_nano.dts b/boards/riscv/longan_nano/longan_nano.dts new file mode 100644 index 0000000000000..5c9ad09c29b76 --- /dev/null +++ b/boards/riscv/longan_nano/longan_nano.dts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021 Tokita, Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "longan_nano-pinctrl.dtsi" + +/ { + model = "Sipeed Longan Nano"; + compatible = "sipeed,longan_nano"; + + chosen { + zephyr,console = &usart0; + zephyr,shell-uart = &usart0; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; +}; + +&usart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&usart0_default>; + pinctrl-names = "default"; +}; diff --git a/boards/riscv/longan_nano/longan_nano.yaml b/boards/riscv/longan_nano/longan_nano.yaml new file mode 100644 index 0000000000000..1d324ed52100c --- /dev/null +++ b/boards/riscv/longan_nano/longan_nano.yaml @@ -0,0 +1,9 @@ +identifier: longan_nano +name: Sipeed Longan Nano +type: mcu +arch: riscv32 +toolchain: + - zephyr + - xtools +flash: 128 +ram: 32 diff --git a/boards/riscv/longan_nano/longan_nano_defconfig b/boards/riscv/longan_nano/longan_nano_defconfig new file mode 100644 index 0000000000000..53367e5592807 --- /dev/null +++ b/boards/riscv/longan_nano/longan_nano_defconfig @@ -0,0 +1,21 @@ +# Sipeed longan nano Development Board Configuration +# +# Copyright (c) 2021 Tokita, Hiroshi +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SOC_SERIES_GD32VF103=y +CONFIG_SOC_GD32VF103=y +CONFIG_GD32_HXTAL_8MHZ=y + +# enable machine timer +CONFIG_RISCV_MACHINE_TIMER=y + +# enable uart driver +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/riscv/longan_nano/longan_nano_lite.dts b/boards/riscv/longan_nano/longan_nano_lite.dts new file mode 100644 index 0000000000000..02fed25ffc9c5 --- /dev/null +++ b/boards/riscv/longan_nano/longan_nano_lite.dts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021 Tokita, Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "longan_nano-pinctrl.dtsi" + +/ { + model = "Sipeed Longan Nano Lite"; + compatible = "sipeed,longan_nano_lite"; + + chosen { + zephyr,console = &usart0; + zephyr,shell-uart = &usart0; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; +}; + +&usart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&usart0_default>; + pinctrl-names = "default"; +}; diff --git a/boards/riscv/longan_nano/longan_nano_lite.yaml b/boards/riscv/longan_nano/longan_nano_lite.yaml new file mode 100644 index 0000000000000..64a216c611843 --- /dev/null +++ b/boards/riscv/longan_nano/longan_nano_lite.yaml @@ -0,0 +1,9 @@ +identifier: longan_nano_lite +name: Sipeed Longan Nano Lite +type: mcu +arch: riscv32 +toolchain: + - zephyr + - xtools +flash: 64 +ram: 20 diff --git a/boards/riscv/longan_nano/longan_nano_lite_defconfig b/boards/riscv/longan_nano/longan_nano_lite_defconfig new file mode 100644 index 0000000000000..3ff72bc7b3c24 --- /dev/null +++ b/boards/riscv/longan_nano/longan_nano_lite_defconfig @@ -0,0 +1,21 @@ +# Sipeed Longan Nano Lite board Configuration +# +# Copyright (c) 2021 Tokita, Hiroshi +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SOC_SERIES_GD32VF103=y +CONFIG_SOC_GD32VF103=y +CONFIG_GD32_HXTAL_8MHZ=y + +# enable machine timer +CONFIG_RISCV_MACHINE_TIMER=y + +# enable uart driver +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/riscv/longan_nano/support/openocd.cfg b/boards/riscv/longan_nano/support/openocd.cfg new file mode 100644 index 0000000000000..4ebb4a0505b53 --- /dev/null +++ b/boards/riscv/longan_nano/support/openocd.cfg @@ -0,0 +1,33 @@ +# Copyright (c) 2021 Tokita, Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +interface ftdi + +ftdi_device_desc "Dual RS232" +#ftdi_device_desc "Sipeed-Debug" +#ftdi_device_desc "JTAG Debugger" + +ftdi_vid_pid 0x0403 0x6010 +#ftdi_channel 0 + +ftdi_layout_init 0x0008 0x001b +ftdi_layout_signal nSRST -oe 0x0020 -data 0x0020 + +adapter_khz 2000 +transport select jtag + +proc gd32vf103-pre-load {} { + halt +} + +proc gd32vf103-load {file} { + flash protect 0 0 last off + flash write_image erase $file +} + + +proc gd32vf103-post-verify {} { + mww 0xe004200c 0x4b5a6978 + mww 0xe0042008 0x01 + resume +} diff --git a/drivers/interrupt_controller/CMakeLists.txt b/drivers/interrupt_controller/CMakeLists.txt index c6966334ca76c..ca292c203cc09 100644 --- a/drivers/interrupt_controller/CMakeLists.txt +++ b/drivers/interrupt_controller/CMakeLists.txt @@ -26,3 +26,4 @@ zephyr_library_sources_ifdef(CONFIG_INTC_ESP32 intc_esp32.c) zephyr_library_sources_ifdef(CONFIG_INTC_ESP32C3 intc_esp32c3.c) zephyr_library_sources_ifdef(CONFIG_SWERV_PIC intc_swerv_pic.c) zephyr_library_sources_ifdef(CONFIG_VEXRISCV_LITEX_IRQ intc_vexriscv_litex.c) +zephyr_library_sources_ifdef(CONFIG_NUCLEI_ECLIC intc_nuclei_eclic.c) diff --git a/drivers/interrupt_controller/Kconfig b/drivers/interrupt_controller/Kconfig index 9719686970314..706aaa2599d9d 100644 --- a/drivers/interrupt_controller/Kconfig +++ b/drivers/interrupt_controller/Kconfig @@ -73,4 +73,6 @@ source "drivers/interrupt_controller/Kconfig.esp32c3" source "drivers/interrupt_controller/Kconfig.xec" +source "drivers/interrupt_controller/Kconfig.eclic" + endmenu diff --git a/drivers/interrupt_controller/Kconfig.eclic b/drivers/interrupt_controller/Kconfig.eclic new file mode 100644 index 0000000000000..e0505372a2348 --- /dev/null +++ b/drivers/interrupt_controller/Kconfig.eclic @@ -0,0 +1,18 @@ +# Nuclei ECLIC interrupt-controller configuration + +# Copyright (c) 2021 Tokita, Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +DT_COMPAT_NUCLEI_ECLIC = nuclei,eclic + +config HAS_NUCLEI_ECLIC + bool + help + Indicate that the platform has ECLIC. + +config NUCLEI_ECLIC + bool "Enhanced Core Local Interrupt Controller (ECLIC)" + default $(dt_compat_enabled,$(DT_COMPAT_NUCLEI_ECLIC)) + depends on HAS_NUCLEI_ECLIC + help + Interrupt controller for Nuclei SoC core. diff --git a/drivers/interrupt_controller/intc_nuclei_eclic.c b/drivers/interrupt_controller/intc_nuclei_eclic.c new file mode 100644 index 0000000000000..7ad354453352e --- /dev/null +++ b/drivers/interrupt_controller/intc_nuclei_eclic.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2021 Tokita, Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief Driver for Nuclie's Extended Core Interrupt Controller + */ + +#include +#include +#include +#include +#include + +#include + +union CLICCFG { + struct { + uint8_t _reserved0 : 1; + /** number of interrupt level bits */ + uint8_t nlbits : 4; + uint8_t _reserved1 : 2; + uint8_t _reserved2 : 1; + } b; + uint8_t w; +}; + +union CLICINFO { + struct { + /** number of max supported interrupts */ + uint32_t numint : 13; + /** architecture version */ + uint32_t version : 8; + /** supported bits in the clicintctl */ + uint32_t intctlbits : 4; + uint32_t _reserved0 : 7; + } b; + uint32_t qw; +}; + +union CLICMTH { + uint8_t w; +}; + +union CLICINTIP { + struct { + /** Interrupt Pending */ + uint8_t IP : 1; + uint8_t reserved0 : 7; + } b; + uint8_t w; +}; + +union CLICINTIE { + struct { + /** Interrupt Enabled */ + uint8_t IE : 1; + uint8_t reserved0 : 7; + } b; + uint8_t w; +}; + +union CLICINTATTR { + struct { + /** 0: non-vectored 1:vectored */ + uint8_t shv : 1; + /** 0: level 1: rising edge 2: falling edge */ + uint8_t trg : 2; + uint8_t reserved0 : 3; + uint8_t reserved1 : 2; + } b; + uint8_t w; +}; + +struct CLICCTRL { + volatile union CLICINTIP INTIP; + volatile union CLICINTIE INTIE; + volatile union CLICINTATTR INTATTR; + volatile uint8_t INTCTRL; +}; + +/** ECLIC Mode mask for MTVT CSR Register */ +#define ECLIC_MODE_MTVEC_Msk 3U + +/** CLIC INTATTR: TRIG Position */ +#define CLIC_INTATTR_TRIG_Pos 1U +/** CLIC INTATTR: TRIG Mask */ +#define CLIC_INTATTR_TRIG_Msk (0x3UL << CLIC_INTATTR_TRIG_Pos) + +#define ECLIC_CFG (*((volatile union CLICCFG *)(DT_REG_ADDR_BY_IDX(DT_NODELABEL(eclic), 0)))) +#define ECLIC_INFO (*((volatile union CLICINFO *)(DT_REG_ADDR_BY_IDX(DT_NODELABEL(eclic), 1)))) +#define ECLIC_MTH (*((volatile union CLICMTH *)(DT_REG_ADDR_BY_IDX(DT_NODELABEL(eclic), 2)))) +#define ECLIC_CTRL ((volatile struct CLICCTRL *)(DT_REG_ADDR_BY_IDX(DT_NODELABEL(eclic), 3))) +#define ECLIC_CTRL_SIZE (DT_REG_SIZE_BY_IDX(DT_NODELABEL(eclic), 3)) + +#if CONFIG_3RD_LEVEL_INTERRUPTS +#define INTERRUPT_LEVEL 2 +#elif CONFIG_2ND_LEVEL_INTERRUPTS +#define INTERRUPT_LEVEL 1 +#else +#define INTERRUPT_LEVEL 0 +#endif + +static uint8_t nlbits; +static uint8_t intctlbits; +static uint8_t max_prio; +static uint8_t max_level; +static uint8_t intctrl_mask; + +static inline uint8_t leftalign8(uint8_t val, uint8_t shift) +{ + return (val << (8U - shift)); +} + +static inline uint8_t mask8(uint8_t len) +{ + return ((1 << len) - 1) & 0xFFFFU; +} + +/** + * @brief Enable interrupt + */ +void nuclei_eclic_irq_enable(uint32_t irq) +{ + ECLIC_CTRL[irq].INTIE.b.IE = 1; +} + +/** + * @brief Disable interrupt + */ +void nuclei_eclic_irq_disable(uint32_t irq) +{ + ECLIC_CTRL[irq].INTIE.b.IE = 0; +} + +/** + * @brief Get enable status of interrupt + */ +int nuclei_eclic_irq_is_enabled(uint32_t irq) +{ + return ECLIC_CTRL[irq].INTIE.b.IE; +} + +/** + * @brief Set priority and level of interrupt + */ +void nuclei_eclic_irq_priority_set(uint32_t irq, uint32_t pri, uint32_t flags) +{ + const uint8_t prio = leftalign8(MIN(pri, max_prio), intctlbits); + const uint8_t level = leftalign8(MIN((irq_get_level(irq) - 1), max_level), nlbits); + const uint8_t intctrl = (prio | level) | (~intctrl_mask); + + ECLIC_CTRL[irq].INTCTRL = intctrl; + + ECLIC_CTRL[irq].INTATTR.b.shv = 0; + ECLIC_CTRL[irq].INTATTR.b.trg = (uint8_t)(flags & CLIC_INTATTR_TRIG_Msk); +} + +static int nuclei_eclic_init(const struct device *dev) +{ + /* check hardware support required interrupt levels */ + __ASSERT_NO_MSG(ECLIC_INFO.b.intctlbits >= INTERRUPT_LEVEL); + + ECLIC_MTH.w = 0; + ECLIC_CFG.w = 0; + ECLIC_CFG.b.nlbits = INTERRUPT_LEVEL; + for (int i = 0; i < ECLIC_CTRL_SIZE; i++) { + ECLIC_CTRL[i] = (struct CLICCTRL) { 0 }; + } + + csr_write(mtvec, ((csr_read(mtvec) & 0xFFFFFFC0) | ECLIC_MODE_MTVEC_Msk)); + + nlbits = ECLIC_CFG.b.nlbits; + intctlbits = ECLIC_INFO.b.intctlbits; + max_prio = mask8(intctlbits - nlbits); + max_level = mask8(nlbits); + intctrl_mask = leftalign8(mask8(intctlbits), intctlbits); + + return 0; +} + +SYS_INIT(nuclei_eclic_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); diff --git a/drivers/pinctrl/Kconfig.gd32 b/drivers/pinctrl/Kconfig.gd32 index 7822033f0169e..d9bcc49d8bbda 100644 --- a/drivers/pinctrl/Kconfig.gd32 +++ b/drivers/pinctrl/Kconfig.gd32 @@ -6,7 +6,7 @@ DT_COMPAT_GIGADEVICE_GD32_PINCTRL_AFIO := gd,gd32-pinctrl-afio config PINCTRL_GD32_AF bool "GD32 AF pin controller driver" - depends on SOC_FAMILY_GD32 && GD32_HAS_AF_PINMUX + depends on GD32_HAS_AF_PINMUX default $(dt_compat_enabled,$(DT_COMPAT_GIGADEVICE_GD32_PINCTRL_AF)) help GD32 AF pin controller driver. This driver is used by series using the @@ -14,7 +14,7 @@ config PINCTRL_GD32_AF config PINCTRL_GD32_AFIO bool "GD32 AFIO pin controller driver" - depends on SOC_FAMILY_GD32 && GD32_HAS_AFIO_PINMUX + depends on GD32_HAS_AFIO_PINMUX default $(dt_compat_enabled,$(DT_COMPAT_GIGADEVICE_GD32_PINCTRL_AFIO)) help GD32 AFIO pin controller driver. This driver is used by series using the diff --git a/drivers/serial/Kconfig.gd32 b/drivers/serial/Kconfig.gd32 index 56b823ce0eb13..85b22a7fc384d 100644 --- a/drivers/serial/Kconfig.gd32 +++ b/drivers/serial/Kconfig.gd32 @@ -7,7 +7,7 @@ DT_COMPAT_GIGADEVICE_GD32_USART := gd,gd32-usart config USART_GD32 bool "GD32 serial driver" default $(dt_compat_enabled,$(DT_COMPAT_GIGADEVICE_GD32_USART)) - depends on SOC_FAMILY_GD32 + depends on (SOC_FAMILY_GD32 || SOC_SERIES_GD32VF103) select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT select USE_GD32_USART diff --git a/drivers/timer/Kconfig.riscv_machine b/drivers/timer/Kconfig.riscv_machine index 37547d3ed140a..2095d95ade2bd 100644 --- a/drivers/timer/Kconfig.riscv_machine +++ b/drivers/timer/Kconfig.riscv_machine @@ -11,3 +11,20 @@ config RISCV_MACHINE_TIMER help This module implements a kernel device driver for the generic RISCV machine timer driver. It provides the standard "system clock driver" interfaces. + +config RISCV_MACHINE_TIMER_SYSTEM_CLOCK_DIVIDER + int + default 0 + help + Specifies the division ratio of the system clock supplied to the Machine Timer. + + A clock obtained by dividing the system clock by a value of [2^N] is + supplied to the timer. Where N is this parameter's value. + When N=2, it is divided by 4, and when N=5, it is divided by 32. + Default case is N=0, this means use system clock as machine timer clock. + It is normal configuration for RISC-V machine clock. + + This parameter usually depends on the hardware configuration. + The division ratio should define in devicetree, + and it is desireble usage that references it with using a function such as + dt_node_int_prop_int from Kconfig. (Tune in the conf file is not preferable.) diff --git a/drivers/timer/riscv_machine_timer.c b/drivers/timer/riscv_machine_timer.c index 9a5b367d46677..7d63e4e19f085 100644 --- a/drivers/timer/riscv_machine_timer.c +++ b/drivers/timer/riscv_machine_timer.c @@ -9,8 +9,9 @@ #include #include -#define CYC_PER_TICK ((uint32_t)((uint64_t)sys_clock_hw_cycles_per_sec() \ - / (uint64_t)CONFIG_SYS_CLOCK_TICKS_PER_SEC)) +#define CYC_PER_TICK ((uint32_t)((uint64_t) (sys_clock_hw_cycles_per_sec() \ + >> CONFIG_RISCV_MACHINE_TIMER_SYSTEM_CLOCK_DIVIDER) \ + / (uint64_t)CONFIG_SYS_CLOCK_TICKS_PER_SEC)) #define MAX_CYC INT_MAX #define MAX_TICKS ((MAX_CYC - CYC_PER_TICK) / CYC_PER_TICK) #define MIN_DELAY 1000 @@ -135,12 +136,12 @@ uint32_t sys_clock_elapsed(void) uint32_t sys_clock_cycle_get_32(void) { - return (uint32_t)mtime(); + return (uint32_t)(mtime() << CONFIG_RISCV_MACHINE_TIMER_SYSTEM_CLOCK_DIVIDER); } uint64_t sys_clock_cycle_get_64(void) { - return mtime(); + return (mtime() << CONFIG_RISCV_MACHINE_TIMER_SYSTEM_CLOCK_DIVIDER); } static int sys_clock_driver_init(const struct device *dev) diff --git a/dts/bindings/cpu/nuclei,bumblebee.yaml b/dts/bindings/cpu/nuclei,bumblebee.yaml new file mode 100644 index 0000000000000..e5eaa74cc9651 --- /dev/null +++ b/dts/bindings/cpu/nuclei,bumblebee.yaml @@ -0,0 +1,14 @@ +# Copyright (c) 2021 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +description: Nuclei Bumblebee RISC-V Core + +compatible: "nuclei,bumblebee" + +include: cpu.yaml + +properties: + mcause-exception-mask: + type: int + required: true + description: Specify the bits to use for exception code in mcause register. diff --git a/dts/bindings/interrupt-controller/nuclei,eclic.yaml b/dts/bindings/interrupt-controller/nuclei,eclic.yaml new file mode 100644 index 0000000000000..47aee3157dfc1 --- /dev/null +++ b/dts/bindings/interrupt-controller/nuclei,eclic.yaml @@ -0,0 +1,19 @@ +# Copyright (c) 2021, Tokita, Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +description: Nuclei ECLIC interrupt controller + +compatible: "nuclei,eclic" + +include: [interrupt-controller.yaml, base.yaml] + +properties: + reg: + required: true + + "#interrupt-cells": + const: 2 + +interrupt-cells: + - irq + - priority diff --git a/dts/bindings/timer/riscv,machine-timer.yaml b/dts/bindings/timer/riscv,machine-timer.yaml new file mode 100644 index 0000000000000..149914f406b8e --- /dev/null +++ b/dts/bindings/timer/riscv,machine-timer.yaml @@ -0,0 +1,39 @@ +# Copyright (c) 2021 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +description: RISC-V Machine timer + +compatible: "nuclei,machine-timer" + +include: base.yaml + +properties: + clk-divider: + type: int + required: false + description: | + clk-divider specifies the division ratio to the CPU frequency that + clock used by machine timer. + This property supports the case that the machine timer and CPU use + different clock sources. + This configuration is used sometimes for such as low power consumption. + + For example, the CPU clock frequency is 108MHz, and the machine timer + uses 27MHz, which is the CPU clock divided by 4. + In this case, the CPU clock frequency is defined in the CPU node + as follows + + clock-frequency = <108000000>; + + This property takes exponent of the power of 2. + The relationship with the frequency division ratio is as + following equation. + + division_ratio = 2^n + n = log_2(division_ratio) + + Setting clk-divider to 2 specifies the machine timer uses the clock + that CPU clock frequency divided by (2^2=)4, or 27MHz. + + Devision ratio constants can be found in the + dt-bindings/timer/nuclei-machine-timer.h header file. diff --git a/dts/bindings/vendor-prefixes.txt b/dts/bindings/vendor-prefixes.txt index 352177db2902a..b43b2b9a99c5a 100644 --- a/dts/bindings/vendor-prefixes.txt +++ b/dts/bindings/vendor-prefixes.txt @@ -412,6 +412,7 @@ nokia Nokia nordic Nordic Semiconductor novtech NovTech, Inc. nutsboard NutsBoard +nuclei Nuclei System Technology nuvoton Nuvoton Technology Corporation nvd New Vision Display nvidia NVIDIA diff --git a/dts/riscv/gigadevice/gd32vf103.dtsi b/dts/riscv/gigadevice/gd32vf103.dtsi new file mode 100644 index 0000000000000..f9280a16bddfc --- /dev/null +++ b/dts/riscv/gigadevice/gd32vf103.dtsi @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2021 Tokita, Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu: cpu@0 { + clock-frequency = <108000000>; + mcause-exception-mask = <0x7ff>; + compatible = "nuclei,bumblebee", "riscv"; + device_type = "cpu"; + reg = <0>; + }; + }; + + sram0: memory@20000000 { + compatible = "mmio-sram"; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "gd,gd32vf103-soc", "simple-bus"; + ranges; + + mtimer: machine-timer@d1000000 { + compatible = "riscv,machine-timer"; + reg = <0xd1000000 0x1 + 0xd1000008 0x1>; + clk-divider = ; + }; + + eclic: interrupt-controller@d2000000 { + #interrupt-cells = <2>; + compatible = "nuclei,eclic"; + interrupt-controller; + reg = <0xd2000000 0x0001 + 0xd2000004 0x0004 + 0xd200000b 0x0001 + 0xd2001000 0x1000>; + label = "NUCLEI_ECLIC"; + }; + + fmc: flash-controller@40022000 { + compatible = "gd,gd32-flash-controller"; + label = "FMC"; + reg = <0x40022000 0x400>; + #address-cells = <1>; + #size-cells = <1>; + + flash0: flash@8000000 { + compatible = "soc-nv-flash"; + label = "FLASH0"; + write-block-size = <2>; + }; + }; + + usart0: serial@40013800 { + compatible = "gd,gd32-usart"; + reg = <0x40013800 0x400>; + interrupts = <56 0>; + interrupt-parent = <&eclic>; + rcu-periph-clock = <0x60e>; + status = "disabled"; + label = "UART_0"; + }; + + usart1: serial@40004400 { + compatible = "gd,gd32-usart"; + reg = <0x40004400 0x400>; + interrupts = <57 0>; + interrupt-parent = <&eclic>; + rcu-periph-clock = <0x711>; + status = "disabled"; + label = "UART_1"; + }; + + usart2: serial@40004800 { + compatible = "gd,gd32-usart"; + reg = <0x40004800 0x400>; + interrupts = <58 0>; + interrupt-parent = <&eclic>; + rcu-periph-clock = <0x712>; + status = "disabled"; + label = "UART_2"; + }; + + afio: afio@40010000 { + compatible = "gd,gd32-afio"; + reg = <0x40010000 0x400>; + rcu-periph-clock = <0x600>; + status = "okay"; + label = "AFIO"; + }; + + pinctrl: pin-controller@40010800 { + compatible = "gd,gd32-pinctrl-afio"; + reg = <0x40010800 0x1c00>; + #address-cells = <1>; + #size-cells = <1>; + status = "okay"; + label = "PINCTRL"; + + gpioa: gpio@40010800 { + compatible = "gd,gd32-gpio"; + reg = <0x40010800 0x400>; + gpio-controller; + #gpio-cells = <2>; + rcu-periph-clock = <0x602>; + status = "disabled"; + label = "GPIOA"; + }; + + gpiob: gpio@40010c00 { + compatible = "gd,gd32-gpio"; + reg = <0x40010c00 0x400>; + gpio-controller; + #gpio-cells = <2>; + rcu-periph-clock = <0x603>; + status = "disabled"; + label = "GPIOB"; + }; + + gpioc: gpio@40011000 { + compatible = "gd,gd32-gpio"; + reg = <0x40011000 0x400>; + gpio-controller; + #gpio-cells = <2>; + rcu-periph-clock = <0x604>; + status = "disabled"; + label = "GPIOC"; + }; + + gpiod: gpio@40011400 { + compatible = "gd,gd32-gpio"; + reg = <0x40011400 0x400>; + gpio-controller; + #gpio-cells = <2>; + rcu-periph-clock = <0x605>; + status = "disabled"; + label = "GPIOD"; + }; + + gpioe: gpio@40011800 { + compatible = "gd,gd32-gpio"; + reg = <0x40011800 0x400>; + gpio-controller; + #gpio-cells = <2>; + rcu-periph-clock = <0x606>; + status = "disabled"; + label = "GPIOE"; + }; + }; + }; +}; diff --git a/dts/riscv/gigadevice/gd32vf103X8.dtsi b/dts/riscv/gigadevice/gd32vf103X8.dtsi new file mode 100644 index 0000000000000..af94ad2aa5046 --- /dev/null +++ b/dts/riscv/gigadevice/gd32vf103X8.dtsi @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2021 Tokita, Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(20)>; + }; + + soc { + flash: flash-controller@40022000 { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_K(64)>; + }; + }; + }; +}; diff --git a/dts/riscv/gigadevice/gd32vf103Xb.dtsi b/dts/riscv/gigadevice/gd32vf103Xb.dtsi new file mode 100644 index 0000000000000..8f0deb2a913e4 --- /dev/null +++ b/dts/riscv/gigadevice/gd32vf103Xb.dtsi @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2021 Tokita, Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(32)>; + }; + + soc { + flash: flash-controller@40022000 { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_K(128)>; + }; + }; + }; +}; diff --git a/include/arch/riscv/arch.h b/include/arch/riscv/arch.h index d0379b614a047..302729058323e 100644 --- a/include/arch/riscv/arch.h +++ b/include/arch/riscv/arch.h @@ -291,6 +291,13 @@ void z_irq_spurious(const void *unused); Z_ISR_DECLARE(irq_p, 0, isr_p, isr_param_p); \ arch_irq_priority_set(irq_p, priority_p); \ } +#elif defined(CONFIG_NUCLEI_ECLIC) +void nuclei_eclic_irq_priority_set(unsigned int irq, unsigned int prio, unsigned int flags); +#define ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \ +{ \ + Z_ISR_DECLARE(irq_p, 0, isr_p, isr_param_p); \ + nuclei_eclic_irq_priority_set(irq_p, priority_p, flags_p); \ +} #else #define ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \ { \ diff --git a/include/drivers/pinctrl/pinctrl_soc_gd32_common.h b/include/drivers/pinctrl/pinctrl_soc_gd32_common.h new file mode 100644 index 0000000000000..9ec61d254392c --- /dev/null +++ b/include/drivers/pinctrl/pinctrl_soc_gd32_common.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2021 Teslabs Engineering S.L. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * Gigadevice SoC specific helpers for pinctrl driver + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_PINCTRL_PINCTRL_SOC_GD32_COMMON_H_ +#define ZEPHYR_INCLUDE_DRIVERS_PINCTRL_PINCTRL_SOC_GD32_COMMON_H_ + +#include +#include + +#ifdef CONFIG_PINCTRL_GD32_AF +#include +#else +#include +#endif /* CONFIG_PINCTRL_GD32_AF */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond INTERNAL_HIDDEN */ + +/** @brief Type for GD32 pin. + * + * Bits (AF model): + * - 0-12: GD32_PINMUX_AF bit field. + * - 13-25: Reserved. + * - 26-31: Pin configuration bit field (@ref GD32_PINCFG). + * + * Bits (AFIO model): + * - 0-19: GD32_PINMUX_AFIO bit field. + * - 20-25: Reserved. + * - 26-31: Pin configuration bit field (@ref GD32_PINCFG). + */ +typedef uint32_t pinctrl_soc_pin_t; + +/** + * @brief Utility macro to initialize each pin. + * + * @param node_id Node identifier. + * @param prop Property name. + * @param idx Property entry index. + */ +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + (DT_PROP_BY_IDX(node_id, prop, idx) | \ + ((GD32_PUPD_PULLUP * DT_PROP(node_id, bias_pull_up)) \ + << GD32_PUPD_POS) | \ + ((GD32_PUPD_PULLDOWN * DT_PROP(node_id, bias_pull_down)) \ + << GD32_PUPD_POS) | \ + ((GD32_OTYPE_OD * DT_PROP(node_id, drive_open_drain)) \ + << GD32_OTYPE_POS) | \ + (DT_ENUM_IDX(node_id, slew_rate) << GD32_OSPEED_POS)), + +/** + * @brief Utility macro to initialize state pins contained in a given property. + * + * @param node_id Node identifier. + * @param prop Property name describing state pins. + */ +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + {DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), \ + DT_FOREACH_PROP_ELEM, pinmux, \ + Z_PINCTRL_STATE_PIN_INIT)} + +/** @endcond */ + +/** + * @name GD32 PUPD (values match the ones in the HAL for AF model). + * @{ + */ + +/** No pull-up/down */ +#define GD32_PUPD_NONE 0U +/** Pull-up */ +#define GD32_PUPD_PULLUP 1U +/** Pull-down */ +#define GD32_PUPD_PULLDOWN 2U + +/** @} */ + +/** + * @name GD32 OTYPE (values match the ones in the HAL for AF model). + * @{ + */ + +/** Push-pull */ +#define GD32_OTYPE_PP 0U +/** Open-drain */ +#define GD32_OTYPE_OD 1U + +/** @} */ + +/** + * @name GD32 OSPEED (values match the ones in the HAL for AF model, mode minus + * one for AFIO model). + * @{ + */ + +#ifdef CONFIG_PINCTRL_GD32_AF +/** Maximum 2MHz */ +#define GD32_OSPEED_2MHZ 0U +#ifdef CONFIG_SOC_SERIES_GD32F3X0 +/** Maximum 10MHz */ +#define GD32_OSPEED_10MHZ 1U +/** Maximum 50MHz */ +#define GD32_OSPEED_50MHZ 3U +#else +/** Maximum 25MHz */ +#define GD32_OSPEED_25MHZ 1U +/** Maximum 50MHz */ +#define GD32_OSPEED_50MHZ 2U +/** Maximum 200MHz */ +#define GD32_OSPEED_200MHZ 3U +#endif /* CONFIG_SOC_SERIES_GD32F3X0 */ +#else +/** Maximum 10MHz */ +#define GD32_OSPEED_10MHZ 0U +/** Maximum 2MHz */ +#define GD32_OSPEED_2MHZ 1U +/** Maximum 50MHz */ +#define GD32_OSPEED_50MHZ 2U +/** Maximum speed */ +#define GD32_OSPEED_MAX 3U +#endif /* CONFIG_PINCTRL_GD32_AF */ + +/** @} */ + +/** + * @name GD32 pin configuration bit field mask and positions. + * @anchor GD32_PINCFG + * + * Fields: + * + * - 31..29: Pull-up/down + * - 28: Output type + * - 27..26: Output speed + * + * @{ + */ + +/** PUPD field mask. */ +#define GD32_PUPD_MSK 0x3U +/** PUPD field position. */ +#define GD32_PUPD_POS 29U +/** OTYPE field mask. */ +#define GD32_OTYPE_MSK 0x1U +/** OTYPE field position. */ +#define GD32_OTYPE_POS 28U +/** OSPEED field mask. */ +#define GD32_OSPEED_MSK 0x3U +/** OSPEED field position. */ +#define GD32_OSPEED_POS 26U + +/** @} */ + +/** + * Obtain PUPD field from pinctrl_soc_pin_t configuration. + * + * @param pincfg pinctrl_soc_pin_t bit field value. + */ +#define GD32_PUPD_GET(pincfg) \ + (((pincfg) >> GD32_PUPD_POS) & GD32_PUPD_MSK) + +/** + * Obtain OTYPE field from pinctrl_soc_pin_t configuration. + * + * @param pincfg pinctrl_soc_pin_t bit field value. + */ +#define GD32_OTYPE_GET(pincfg) \ + (((pincfg) >> GD32_OTYPE_POS) & GD32_OTYPE_MSK) + +/** + * Obtain OSPEED field from pinctrl_soc_pin_t configuration. + * + * @param pincfg pinctrl_soc_pin_t bit field value. + */ +#define GD32_OSPEED_GET(pincfg) \ + (((pincfg) >> GD32_OSPEED_POS) & GD32_OSPEED_MSK) + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_PINCTRL_PINCTRL_SOC_GD32_COMMON_H_ */ diff --git a/include/dt-bindings/timer/riscv-machine-timer.h b/include/dt-bindings/timer/riscv-machine-timer.h new file mode 100644 index 0000000000000..32808f49b8c04 --- /dev/null +++ b/include/dt-bindings/timer/riscv-machine-timer.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2021, TOKITA Hiroshi + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_TIMER_RISCV_MACHINE_TIMER_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_TIMER_RISCV_MACHINE_TIMER_H_ + +/* Clock divider values */ +#define RISCV_MACHINE_TIMER_DIVIDER_1 0 +#define RISCV_MACHINE_TIMER_DIVIDER_2 1 +#define RISCV_MACHINE_TIMER_DIVIDER_4 2 +#define RISCV_MACHINE_TIMER_DIVIDER_8 3 +#define RISCV_MACHINE_TIMER_DIVIDER_16 4 +#define RISCV_MACHINE_TIMER_DIVIDER_32 5 +#define RISCV_MACHINE_TIMER_DIVIDER_64 6 +#define RISCV_MACHINE_TIMER_DIVIDER_128 7 +#define RISCV_MACHINE_TIMER_DIVIDER_256 8 +#define RISCV_MACHINE_TIMER_DIVIDER_512 9 +#define RISCV_MACHINE_TIMER_DIVIDER_1024 10 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_TIMER_RISCV_MACHINE_TIMER_H_ */ diff --git a/modules/hal_gigadevice/CMakeLists.txt b/modules/hal_gigadevice/CMakeLists.txt index eb929e8aa7493..488da7648f9a1 100644 --- a/modules/hal_gigadevice/CMakeLists.txt +++ b/modules/hal_gigadevice/CMakeLists.txt @@ -6,7 +6,13 @@ if(CONFIG_HAS_GD32_HAL) string(TOUPPER ${CONFIG_SOC} gd32_soc_uc) set(gd32_soc_dir ${ZEPHYR_HAL_GIGADEVICE_MODULE_DIR}/${CONFIG_SOC_SERIES}) -set(gd32_cmsis_dir ${gd32_soc_dir}/cmsis/gd/${CONFIG_SOC_SERIES}) +if(CONFIG_SOC_FAMILY_GD32_ARM) + set(gd32_soc_sys_dir ${gd32_soc_dir}/cmsis/gd/${CONFIG_SOC_SERIES}) +elseif(CONFIG_SOC_SERIES_GD32VF103) + set(gd32_soc_sys_dir ${gd32_soc_dir}/riscv) + zephyr_include_directories(${gd32_soc_dir}/riscv/drivers) +endif() + set(gd32_std_dir ${gd32_soc_dir}/standard_peripheral) set(gd32_std_src_dir ${gd32_std_dir}/source) @@ -14,12 +20,22 @@ zephyr_library_named(hal_gigadevice) zephyr_compile_definitions(${gd32_soc_uc}) +# The header files of GigaDevice firmware are reference HXTAL_VALUE. +# The HXTAL_VALUE has the possibility of being referenced from any files +# via that header files. +# Therefore, we need to define HXTAL_VALUE for all compilations. +if(${CONFIG_GD32_HXTAL_8MHZ}) + zephyr_compile_definitions(HXTAL_VALUE=8000000 HXTAL_VALUE_25M=8000000) +elseif(${CONFIG_GD32_HXTAL_25MHZ}) + zephyr_compile_definitions(HXTAL_VALUE=25000000 HXTAL_VALUE_8M=25000000) +endif() + # Global includes to be used outside hal_gigadevice -zephyr_include_directories(${gd32_cmsis_dir}/include) +zephyr_include_directories(${gd32_soc_sys_dir}/include) zephyr_include_directories(${gd32_std_dir}/include) zephyr_include_directories(${ZEPHYR_HAL_GIGADEVICE_MODULE_DIR}/include) -zephyr_library_sources(${gd32_cmsis_dir}/source/system_${CONFIG_SOC_SERIES}.c) +zephyr_library_sources(${gd32_soc_sys_dir}/source/system_${CONFIG_SOC_SERIES}.c) zephyr_library_sources_ifdef(CONFIG_USE_GD32_ADC ${gd32_std_src_dir}/${CONFIG_SOC_SERIES}_adc.c) zephyr_library_sources_ifdef(CONFIG_USE_GD32_BKP ${gd32_std_src_dir}/${CONFIG_SOC_SERIES}_bkp.c) diff --git a/modules/hal_gigadevice/Kconfig b/modules/hal_gigadevice/Kconfig index 80b81926740d2..a26c03b044746 100644 --- a/modules/hal_gigadevice/Kconfig +++ b/modules/hal_gigadevice/Kconfig @@ -20,6 +20,36 @@ config HAS_GD32_HAL if HAS_GD32_HAL +choice GD32_HXTAL_FREQUENCY + prompt "High speed external oscillator clock frequency" + default GD32_HXTAL_FIRMWARE_DEFINED if !SOC_SERIES_GD32VF103 + default GD32_HXTAL_25MHZ if SOC_SERIES_GD32VF103 + help + Define value of high speed crystal oscillator (HXTAL) in Hz + This value sets the frequency of the oscillator. + +config GD32_HXTAL_FIRMWARE_DEFINED + bool "Firmware defined" + depends on !SOC_SERIES_GD32VF103 + help + Use default frequency defined in firmware for HXTAL + This is using for SoCs (e.g. gd32f4xx, gd32f3x0, etc ...) + that have default HXTAL definitions in firmware. + +config GD32_HXTAL_8MHZ + bool "8MHz" + depends on SOC_SERIES_GD32VF103 + help + Use 8MHz oscillator for HXTAL + +config GD32_HXTAL_25MHZ + bool "25MHz" + depends on SOC_SERIES_GD32VF103 + help + Use 25MHz oscillator for HXTAL + +endchoice + config USE_GD32_ADC bool help @@ -76,12 +106,6 @@ config USE_GD32_DMA help Enable GD32 Direct Memory Access controller (DMA) HAL module driver -config USE_GD32_ECLIC - bool - help - Enable GD32 Enhancement Core-Local Interrupt Controller (ECLIC) HAL - module driver - config USE_GD32_ENET bool help diff --git a/soc/arm/gigadevice/common/pinctrl_soc.h b/soc/arm/gigadevice/common/pinctrl_soc.h index 331986bc0bfc0..e552ae4d3f592 100644 --- a/soc/arm/gigadevice/common/pinctrl_soc.h +++ b/soc/arm/gigadevice/common/pinctrl_soc.h @@ -12,180 +12,6 @@ #ifndef ZEPHYR_SOC_ARM_GIGADEVICE_COMMON_PINCTRL_SOC_H_ #define ZEPHYR_SOC_ARM_GIGADEVICE_COMMON_PINCTRL_SOC_H_ -#include -#include - -#ifdef CONFIG_PINCTRL_GD32_AF -#include -#else -#include -#endif /* CONFIG_PINCTRL_GD32_AF */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** @cond INTERNAL_HIDDEN */ - -/** @brief Type for GD32 pin. - * - * Bits (AF model): - * - 0-12: GD32_PINMUX_AF bit field. - * - 13-25: Reserved. - * - 26-31: Pin configuration bit field (@ref GD32_PINCFG). - * - * Bits (AFIO model): - * - 0-19: GD32_PINMUX_AFIO bit field. - * - 20-25: Reserved. - * - 26-31: Pin configuration bit field (@ref GD32_PINCFG). - */ -typedef uint32_t pinctrl_soc_pin_t; - -/** - * @brief Utility macro to initialize each pin. - * - * @param node_id Node identifier. - * @param prop Property name. - * @param idx Property entry index. - */ -#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ - (DT_PROP_BY_IDX(node_id, prop, idx) | \ - ((GD32_PUPD_PULLUP * DT_PROP(node_id, bias_pull_up)) \ - << GD32_PUPD_POS) | \ - ((GD32_PUPD_PULLDOWN * DT_PROP(node_id, bias_pull_down)) \ - << GD32_PUPD_POS) | \ - ((GD32_OTYPE_OD * DT_PROP(node_id, drive_open_drain)) \ - << GD32_OTYPE_POS) | \ - (DT_ENUM_IDX(node_id, slew_rate) << GD32_OSPEED_POS)), - -/** - * @brief Utility macro to initialize state pins contained in a given property. - * - * @param node_id Node identifier. - * @param prop Property name describing state pins. - */ -#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ - {DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), \ - DT_FOREACH_PROP_ELEM, pinmux, \ - Z_PINCTRL_STATE_PIN_INIT)} - -/** @endcond */ - -/** - * @name GD32 PUPD (values match the ones in the HAL for AF model). - * @{ - */ - -/** No pull-up/down */ -#define GD32_PUPD_NONE 0U -/** Pull-up */ -#define GD32_PUPD_PULLUP 1U -/** Pull-down */ -#define GD32_PUPD_PULLDOWN 2U - -/** @} */ - -/** - * @name GD32 OTYPE (values match the ones in the HAL for AF model). - * @{ - */ - -/** Push-pull */ -#define GD32_OTYPE_PP 0U -/** Open-drain */ -#define GD32_OTYPE_OD 1U - -/** @} */ - -/** - * @name GD32 OSPEED (values match the ones in the HAL for AF model, mode minus - * one for AFIO model). - * @{ - */ - -#ifdef CONFIG_PINCTRL_GD32_AF -/** Maximum 2MHz */ -#define GD32_OSPEED_2MHZ 0U -#ifdef CONFIG_SOC_SERIES_GD32F3X0 -/** Maximum 10MHz */ -#define GD32_OSPEED_10MHZ 1U -/** Maximum 50MHz */ -#define GD32_OSPEED_50MHZ 3U -#else -/** Maximum 25MHz */ -#define GD32_OSPEED_25MHZ 1U -/** Maximum 50MHz */ -#define GD32_OSPEED_50MHZ 2U -/** Maximum 200MHz */ -#define GD32_OSPEED_200MHZ 3U -#endif /* CONFIG_SOC_SERIES_GD32F3X0 */ -#else -/** Maximum 10MHz */ -#define GD32_OSPEED_10MHZ 0U -/** Maximum 2MHz */ -#define GD32_OSPEED_2MHZ 1U -/** Maximum 50MHz */ -#define GD32_OSPEED_50MHZ 2U -/** Maximum speed */ -#define GD32_OSPEED_MAX 3U -#endif /* CONFIG_PINCTRL_GD32_AF */ - -/** @} */ - -/** - * @name GD32 pin configuration bit field mask and positions. - * @anchor GD32_PINCFG - * - * Fields: - * - * - 31..29: Pull-up/down - * - 28: Output type - * - 27..26: Output speed - * - * @{ - */ - -/** PUPD field mask. */ -#define GD32_PUPD_MSK 0x3U -/** PUPD field position. */ -#define GD32_PUPD_POS 29U -/** OTYPE field mask. */ -#define GD32_OTYPE_MSK 0x1U -/** OTYPE field position. */ -#define GD32_OTYPE_POS 28U -/** OSPEED field mask. */ -#define GD32_OSPEED_MSK 0x3U -/** OSPEED field position. */ -#define GD32_OSPEED_POS 26U - -/** @} */ - -/** - * Obtain PUPD field from pinctrl_soc_pin_t configuration. - * - * @param pincfg pinctrl_soc_pin_t bit field value. - */ -#define GD32_PUPD_GET(pincfg) \ - (((pincfg) >> GD32_PUPD_POS) & GD32_PUPD_MSK) - -/** - * Obtain OTYPE field from pinctrl_soc_pin_t configuration. - * - * @param pincfg pinctrl_soc_pin_t bit field value. - */ -#define GD32_OTYPE_GET(pincfg) \ - (((pincfg) >> GD32_OTYPE_POS) & GD32_OTYPE_MSK) - -/** - * Obtain OSPEED field from pinctrl_soc_pin_t configuration. - * - * @param pincfg pinctrl_soc_pin_t bit field value. - */ -#define GD32_OSPEED_GET(pincfg) \ - (((pincfg) >> GD32_OSPEED_POS) & GD32_OSPEED_MSK) - -#ifdef __cplusplus -} -#endif +#include #endif /* ZEPHYR_SOC_ARM_GIGADEVICE_COMMON_PINCTRL_SOC_H_ */ diff --git a/soc/riscv/riscv-privilege/common/nuclei/nuclei_csr.h b/soc/riscv/riscv-privilege/common/nuclei/nuclei_csr.h new file mode 100644 index 0000000000000..e245cf255f863 --- /dev/null +++ b/soc/riscv/riscv-privilege/common/nuclei/nuclei_csr.h @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * Copyright (c) 2021 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Define Nuclei specific CSR and related definitions. + * + * This header contains Nuclei specific definitions. + * Use arch/riscv/csr.h for RISC-V standard CSR and definitions. + */ + +#ifndef ZEPHYR_SOC_RISCV_RISCV_PRIVILEGE_COMMON_NUCLEI_NUCLEI_CSR_H_ +#define ZEPHYR_SOC_RISCV_RISCV_PRIVILEGE_COMMON_NUCLEI_NUCLEI_CSR_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define UCODE_OV (0x1U) + +#define WFE_WFE (0x1U) +#define TXEVT_TXEVT (0x1U) +#define SLEEPVALUE_SLEEPVALUE (0x1U) + +#define MCOUNTINHIBIT_IR BIT(2U) +#define MCOUNTINHIBIT_CY BIT(0U) + +#define MILM_CTL_ILM_BPA (((1ULL << ((__riscv_xlen) - 10U)) - 1U) << 10U) +#define MILM_CTL_ILM_RWECC BIT(3U) +#define MILM_CTL_ILM_ECC_EXCP_EN BIT(2U) +#define MILM_CTL_ILM_ECC_EN BIT(1U) +#define MILM_CTL_ILM_EN BIT(0U) + +#define MDLM_CTL_DLM_BPA (((1ULL << ((__riscv_xlen) - 10U)) - 1U) << 10U) +#define MDLM_CTL_DLM_RWECC BIT(3U) +#define MDLM_CTL_DLM_ECC_EXCP_EN BIT(2U) +#define MDLM_CTL_DLM_ECC_EN BIT(1U) +#define MDLM_CTL_DLM_EN BIT(0U) + +#define MSUBM_PTYP (0x3U << 8U) +#define MSUBM_TYP (0x3U << 6U) + +#define MDCAUSE_MDCAUSE (0x3U) + +#define MMISC_CTL_NMI_CAUSE_FFF BIT(9U) +#define MMISC_CTL_MISALIGN BIT(6U) +#define MMISC_CTL_BPu BIT(3U) + +#define MCACHE_CTL_IC_EN BIT(0U) +#define MCACHE_CTL_IC_SCPD_MOD BIT(1U) +#define MCACHE_CTL_IC_ECC_EN BIT(2U) +#define MCACHE_CTL_IC_ECC_EXCP_EN BIT(3U) +#define MCACHE_CTL_IC_RWTECC BIT(4U) +#define MCACHE_CTL_IC_RWDECC BIT(5U) +#define MCACHE_CTL_DC_EN BIT(16U) +#define MCACHE_CTL_DC_ECC_EN BIT(17U) +#define MCACHE_CTL_DC_ECC_EXCP_EN BIT(18U) +#define MCACHE_CTL_DC_RWTECC BIT(19U) +#define MCACHE_CTL_DC_RWDECC BIT(20U) + +#define MTVT2_MTVT2EN BIT(0U) +#define MTVT2_COMMON_CODE_ENTRY (((1ULL << ((__riscv_xlen) - 2U)) - 1U) << 2U) + +#define MCFG_INFO_TEE BIT(0U) +#define MCFG_INFO_ECC BIT(1U) +#define MCFG_INFO_CLIC BIT(2U) +#define MCFG_INFO_PLIC BIT(3U) +#define MCFG_INFO_FIO BIT(4U) +#define MCFG_INFO_PPI BIT(5U) +#define MCFG_INFO_NICE BIT(6U) +#define MCFG_INFO_ILM BIT(7U) +#define MCFG_INFO_DLM BIT(8U) +#define MCFG_INFO_ICACHE BIT(9U) +#define MCFG_INFO_DCACHE BIT(10U) + +#define MICFG_IC_SET (0xFU << 0U) +#define MICFG_IC_WAY (0x7U << 4U) +#define MICFG_IC_LSIZE (0x7U << 7U) +#define MICFG_IC_ECC (0x1U << 10U) +#define MICFG_ILM_SIZE (0x1FU << 16U) +#define MICFG_ILM_XONLY (0x1U << 21U) +#define MICFG_ILM_ECC (0x1U << 22U) + +#define MDCFG_DC_SET (0xFU << 0U) +#define MDCFG_DC_WAY (0x7U << 4U) +#define MDCFG_DC_LSIZE (0x7U << 7U) +#define MDCFG_DC_ECC (0x1U << 10U) +#define MDCFG_DLM_SIZE (0x1FU << 16U) +#define MDCFG_DLM_ECC (0x1U << 21U) + +#define MPPICFG_INFO_PPI_SIZE (0x1FU << 1U) +#define MPPICFG_INFO_PPI_BPA (((1ULL << ((__riscv_xlen) - 10U)) - 1U) << 10U) + +#define MFIOCFG_INFO_FIO_SIZE (0x1FU << 1) +#define MFIOCFG_INFO_FIO_BPA (((1ULL << ((__riscv_xlen) - 10U)) - 1U) << 10U) + +#define MECC_LOCK_ECC_LOCK (0x1U) + +#define MECC_CODE_CODE (0x1FFU) +#define MECC_CODE_RAMID (0x1FU << 16U) +#define MECC_CODE_SRAMID (0x1FU << 24U) + +#define CCM_SUEN_SUEN (0x1U << 0U) +#define CCM_DATA_DATA (0x7U << 0U) +#define CCM_COMMAND_COMMAND (0x1FU << 0U) + +#define FRM_RNDMODE_RNE 0x0U +#define FRM_RNDMODE_RTZ 0x1U +#define FRM_RNDMODE_RDN 0x2U +#define FRM_RNDMODE_RUP 0x3U +#define FRM_RNDMODE_RMM 0x4U +#define FRM_RNDMODE_DYN 0x7U + +#define FFLAGS_AE_NX BIT(0U) +#define FFLAGS_AE_UF BIT(1U) +#define FFLAGS_AE_OF BIT(2U) +#define FFLAGS_AE_DZ BIT(3U) +#define FFLAGS_AE_NV BIT(4U) + +#define MSTATUS_SD MSTATUS32_SD +#define SSTATUS_SD SSTATUS32_SD +#define RISCV_PGLEVEL_BITS 10 + +#define RISCV_PGSHIFT 12U +#define RISCV_PGSIZE (1U << RISCV_PGSHIFT) + +#define CSR_SPMPCFG0 0x1A0U +#define CSR_SPMPCFG1 0x1A1U +#define CSR_SPMPCFG2 0x1A2U +#define CSR_SPMPCFG3 0x1A3U +#define CSR_SPMPADDR0 0x1B0U +#define CSR_SPMPADDR1 0x1B1U +#define CSR_SPMPADDR2 0x1B2U +#define CSR_SPMPADDR3 0x1B3U +#define CSR_SPMPADDR4 0x1B4U +#define CSR_SPMPADDR5 0x1B5U +#define CSR_SPMPADDR6 0x1B6U +#define CSR_SPMPADDR7 0x1B7U +#define CSR_SPMPADDR8 0x1B8U +#define CSR_SPMPADDR9 0x1B9U +#define CSR_SPMPADDR10 0x1BAU +#define CSR_SPMPADDR11 0x1BBU +#define CSR_SPMPADDR12 0x1BCU +#define CSR_SPMPADDR13 0x1BDU +#define CSR_SPMPADDR14 0x1BEU +#define CSR_SPMPADDR15 0x1BFU + +#define CSR_JALSNXTI 0x947U +#define CSR_STVT2 0x948U +#define CSR_PUSHSCAUSE 0x949U +#define CSR_PUSHSEPC 0x94AU + +#define CSR_MTVT 0x307U +#define CSR_MNXTI 0x345U +#define CSR_MINTSTATUS 0x346U +#define CSR_MSCRATCHCSW 0x348U +#define CSR_MSCRATCHCSWL 0x349U +#define CSR_MCLICBASE 0x350U + +#define CSR_UCODE 0x801U + +#define CSR_MILM_CTL 0x7C0U +#define CSR_MDLM_CTL 0x7C1U +#define CSR_MECC_CODE 0x7C2U +#define CSR_MNVEC 0x7C3U +#define CSR_MSUBM 0x7C4U +#define CSR_MDCAUSE 0x7C9U +#define CSR_MCACHE_CTL 0x7CAU +#define CSR_MMISC_CTL 0x7D0U +#define CSR_MSAVESTATUS 0x7D6U +#define CSR_MSAVEEPC1 0x7D7U +#define CSR_MSAVECAUSE1 0x7D8U +#define CSR_MSAVEEPC2 0x7D9U +#define CSR_MSAVECAUSE2 0x7DAU +#define CSR_MSAVEDCAUSE1 0x7DBU +#define CSR_MSAVEDCAUSE2 0x7DCU +#define CSR_MTLB_CTL 0x7DDU +#define CSR_MECC_LOCK 0x7DEU +#define CSR_MFP16MODE 0x7E2U +#define CSR_LSTEPFORC 0x7E9U +#define CSR_PUSHMSUBM 0x7EBU +#define CSR_MTVT2 0x7ECU +#define CSR_JALMNXTI 0x7EDU +#define CSR_PUSHMCAUSE 0x7EEU +#define CSR_PUSHMEPC 0x7EFU +#define CSR_MPPICFG_INFO 0x7F0U +#define CSR_MFIOCFG_INFO 0x7F1U +#define CSR_MSMPCFG_INFO 0x7F7U +#define CSR_SLEEPVALUE 0x811U +#define CSR_TXEVT 0x812U +#define CSR_WFE 0x810U +#define CSR_MICFG_INFO 0xFC0U +#define CSR_MDCFG_INFO 0xFC1U +#define CSR_MCFG_INFO 0xFC2U +#define CSR_MTLBCFG_INFO 0xFC3U + +#define CSR_CCM_MBEGINADDR 0x7CBU +#define CSR_CCM_MCOMMAND 0x7CCU +#define CSR_CCM_MDATA 0x7CDU +#define CSR_CCM_SUEN 0x7CEU +#define CSR_CCM_SBEGINADDR 0x5CBU +#define CSR_CCM_SCOMMAND 0x5CCU +#define CSR_CCM_SDATA 0x5CDU +#define CSR_CCM_UBEGINADDR 0x4CBU +#define CSR_CCM_UCOMMAND 0x4CCU +#define CSR_CCM_UDATA 0x4CDU +#define CSR_CCM_FPIPE 0x4CFU + +#define CAUSE_MISALIGNED_FETCH 0x0U +#define CAUSE_FAULT_FETCH 0x1U +#define CAUSE_ILLEGAL_INSTRUCTION 0x2U +#define CAUSE_BREAKPOINT 0x3U +#define CAUSE_MISALIGNED_LOAD 0x4U +#define CAUSE_FAULT_LOAD 0x5U +#define CAUSE_MISALIGNED_STORE 0x6U +#define CAUSE_FAULT_STORE 0x7U +#define CAUSE_USER_ECALL 0x8U +#define CAUSE_SUPERVISOR_ECALL 0x9U +#define CAUSE_HYPERVISOR_ECALL 0xaU +#define CAUSE_MACHINE_ECALL 0xbU + +#define DCAUSE_FAULT_FETCH_PMP 0x1U +#define DCAUSE_FAULT_FETCH_INST 0x2U + +#define DCAUSE_FAULT_LOAD_PMP 0x1U +#define DCAUSE_FAULT_LOAD_INST 0x2U +#define DCAUSE_FAULT_LOAD_NICE 0x3U + +#define DCAUSE_FAULT_STORE_PMP 0x1U +#define DCAUSE_FAULT_STORE_INST 0x2U + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_SOC_RISCV_RISCV_PRIVILEGE_COMMON_NUCLEI_NUCLEI_CSR_H_ */ diff --git a/soc/riscv/riscv-privilege/common/soc_common.h b/soc/riscv/riscv-privilege/common/soc_common.h index 37c8d6d7d0563..0a3a875e5d80c 100644 --- a/soc/riscv/riscv-privilege/common/soc_common.h +++ b/soc/riscv/riscv-privilege/common/soc_common.h @@ -25,15 +25,14 @@ #ifdef CONFIG_64BIT /* Interrupt Mask */ #define SOC_MCAUSE_IRQ_MASK (1 << 63) -/* Exception code Mask */ -#define SOC_MCAUSE_EXP_MASK 0x7FFFFFFFFFFFFFFF #else /* Interrupt Mask */ #define SOC_MCAUSE_IRQ_MASK (1 << 31) -/* Exception code Mask */ -#define SOC_MCAUSE_EXP_MASK 0x7FFFFFFF #endif +/* Exception code Mask */ +#define SOC_MCAUSE_EXP_MASK CONFIG_RISCV_SOC_MCAUSE_EXCEPTION_MASK + /* SOC-Specific EXIT ISR command */ #define SOC_ERET mret @@ -51,6 +50,13 @@ void riscv_plic_set_priority(uint32_t irq, uint32_t priority); int riscv_plic_get_irq(void); #endif +#if defined(CONFIG_NUCLEI_ECLIC) +void nuclei_eclic_irq_enable(uint32_t irq); +void nuclei_eclic_irq_disable(uint32_t irq); +int nuclei_eclic_irq_is_enabled(uint32_t irq); +void nuclei_eclic_set_priority(uint32_t irq, uint32_t priority); +#endif + #endif /* !_ASMLANGUAGE */ #endif /* __SOC_COMMON_H_ */ diff --git a/soc/riscv/riscv-privilege/common/soc_common_irq.c b/soc/riscv/riscv-privilege/common/soc_common_irq.c index 14848094d477c..e79d01622db10 100644 --- a/soc/riscv/riscv-privilege/common/soc_common_irq.c +++ b/soc/riscv/riscv-privilege/common/soc_common_irq.c @@ -24,6 +24,10 @@ void arch_irq_enable(unsigned int irq) return; } #endif +#if defined(CONFIG_NUCLEI_ECLIC) + nuclei_eclic_irq_enable(irq); + return; +#endif /* * CSR mie register is updated using atomic instruction csrrs @@ -47,6 +51,10 @@ void arch_irq_disable(unsigned int irq) return; } #endif +#if defined(CONFIG_NUCLEI_ECLIC) + nuclei_eclic_irq_disable(irq); + return; +#endif /* * Use atomic instruction csrrc to disable device interrupt in mie CSR. @@ -67,6 +75,9 @@ void arch_irq_priority_set(unsigned int irq, unsigned int prio) riscv_plic_set_priority(irq, prio); } #endif +#if defined(CONFIG_NUCLEI_ECLIC) + nuclei_eclic_set_priority(irq, prio); +#endif return ; } @@ -83,6 +94,9 @@ int arch_irq_is_enabled(unsigned int irq) return riscv_plic_irq_is_enabled(irq); } #endif +#if defined(CONFIG_NUCLEI_ECLIC) + return nuclei_eclic_irq_is_enabled(irq); +#endif __asm__ volatile ("csrr %0, mie" : "=r" (mie)); diff --git a/soc/riscv/riscv-privilege/gd32vf103/CMakeLists.txt b/soc/riscv/riscv-privilege/gd32vf103/CMakeLists.txt new file mode 100644 index 0000000000000..a3cabd57ab1d9 --- /dev/null +++ b/soc/riscv/riscv-privilege/gd32vf103/CMakeLists.txt @@ -0,0 +1,5 @@ +# Copyright (c) 2021 Tokita, Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources(entry.S) +zephyr_sources(soc.c) diff --git a/soc/riscv/riscv-privilege/gd32vf103/Kconfig.defconfig.gd32vf103 b/soc/riscv/riscv-privilege/gd32vf103/Kconfig.defconfig.gd32vf103 new file mode 100644 index 0000000000000..b039891eb5a62 --- /dev/null +++ b/soc/riscv/riscv-privilege/gd32vf103/Kconfig.defconfig.gd32vf103 @@ -0,0 +1,46 @@ +# Copyright (c) 2021 Tokita, Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +if SOC_GD32VF103 + +config SOC + default "gd32vf103" + +config KERNEL_ENTRY + default "__nuclei_start" + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) if RISCV_MACHINE_TIMER + +config RISCV_MACHINE_TIMER_SYSTEM_CLOCK_DIVIDER + default $(dt_node_int_prop_int,/soc/machine-timer@d1000000,clk-divider) if RISCV_MACHINE_TIMER + +config RISCV_SOC_MCAUSE_EXCEPTION_MASK + default $(dt_node_int_prop_hex,/cpus/cpu@0,mcause-exception-mask) + +config RISCV_SOC_INTERRUPT_INIT + default y + +config RISCV_HAS_CPU_IDLE + default y + +config RISCV_GP + default y + +config RISCV_HAS_PLIC + default n + +config NUM_IRQS + default 87 if NUCLEI_ECLIC + default 16 if !NUCLEI_ECLIC + +config FLASH_BASE_ADDRESS + default $(dt_node_reg_addr_hex,flash0@8000000) + +config 2ND_LEVEL_INTERRUPTS + default y + +config PINCTRL + default y + +endif # GD32VF103 diff --git a/soc/riscv/riscv-privilege/gd32vf103/Kconfig.defconfig.series b/soc/riscv/riscv-privilege/gd32vf103/Kconfig.defconfig.series new file mode 100644 index 0000000000000..309b7ecc0e1f1 --- /dev/null +++ b/soc/riscv/riscv-privilege/gd32vf103/Kconfig.defconfig.series @@ -0,0 +1,11 @@ +# Copyright (c) 2021 Tokita, Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_GD32VF103 + +source "soc/riscv/riscv-privilege/gd32vf103/Kconfig.defconfig.gd32vf103*" + +config SOC_SERIES + default "gd32vf103" + +endif # SOC_SERIES_GD32VF103 diff --git a/soc/riscv/riscv-privilege/gd32vf103/Kconfig.series b/soc/riscv/riscv-privilege/gd32vf103/Kconfig.series new file mode 100644 index 0000000000000..79f4956fc4e0b --- /dev/null +++ b/soc/riscv/riscv-privilege/gd32vf103/Kconfig.series @@ -0,0 +1,20 @@ +# GD32VF103 SOC implementation + +# Copyright (c) 2021 Tokita, Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_GD32VF103 + bool "GigaDevice GD32VF103 series SoC implementation" + select RISCV + select SOC_FAMILY_RISCV_PRIVILEGE + select ATOMIC_OPERATIONS_C + select COMPRESSED_ISA + select INCLUDE_RESET_VECTOR + select BUILD_OUTPUT_HEX + select XIP + select GD32_HAS_AFIO_PINMUX + select HAS_GD32_HAL + select HAS_NUCLEI_ECLIC + + help + Enable support for GigaDevice GD32VF1 series SoC diff --git a/soc/riscv/riscv-privilege/gd32vf103/Kconfig.soc b/soc/riscv/riscv-privilege/gd32vf103/Kconfig.soc new file mode 100644 index 0000000000000..74b6298fd93bb --- /dev/null +++ b/soc/riscv/riscv-privilege/gd32vf103/Kconfig.soc @@ -0,0 +1,13 @@ +# GD32VF103 SOC configuration options + +# Copyright (c) 2021 Tokita, Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +choice + prompt "GigaDevice GD32VF103 SOC implementation" + depends on SOC_SERIES_GD32VF103 + +config SOC_GD32VF103 + bool "GD32VF103" + +endchoice diff --git a/soc/riscv/riscv-privilege/gd32vf103/entry.S b/soc/riscv/riscv-privilege/gd32vf103/entry.S new file mode 100644 index 0000000000000..71e489ed32248 --- /dev/null +++ b/soc/riscv/riscv-privilege/gd32vf103/entry.S @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2021 Tokita, Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +GTEXT(__nuclei_start) +SECTION_FUNC(vectors, __nuclei_start) + /* Disable Global Interrupt */ + csrc mstatus, MSTATUS_MIE + /* Jump to logical address first to ensure correct operation of RAM region */ + la a0, __nuclei_start + li a1, 1 + slli a1, a1, 29 + bleu a1, a0, _start0800 + srli a1, a1, 2 + bleu a1, a0, _start0800 + la a0, _start0800 + add a0, a0, a1 + jr a0 + +_start0800: + +#if defined(CONFIG_RISCV_GP) + /* Initialize global pointer */ + .option push + .option norelax + la gp, __global_pointer$ + .option pop +#endif + + .option norvc; + + /* Set the the NMI base to share with mtvec by setting CSR_MMISC_CTL */ + li t0, 0x200 + csrs CSR_MMISC_CTL, t0 + + /* Initial the CSR MTVEC for the Trap ane NMI base addr */ + la t0, trap_entry + csrw mtvec, t0 + + /* Direct Mode: All exceptions set pc to BASE. */ + csrc mtvec, 0x3 + + /* Disable performance counter */ + csrsi mcountinhibit, 0x5 + + /* Jump to __reset */ + tail __reset + +1: + j 1b + +.align 6 +trap_entry: + tail __irq_wrapper diff --git a/soc/riscv/riscv-privilege/gd32vf103/linker.ld b/soc/riscv/riscv-privilege/gd32vf103/linker.ld new file mode 100644 index 0000000000000..05a873151bbf8 --- /dev/null +++ b/soc/riscv/riscv-privilege/gd32vf103/linker.ld @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2021 Tokita, Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include diff --git a/soc/riscv/riscv-privilege/gd32vf103/pinctrl_soc.h b/soc/riscv/riscv-privilege/gd32vf103/pinctrl_soc.h new file mode 100644 index 0000000000000..5feaded106fd4 --- /dev/null +++ b/soc/riscv/riscv-privilege/gd32vf103/pinctrl_soc.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2021 Tokita, Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * Gigadevice SoC specific helpers for pinctrl driver + */ + +#ifndef ZEPHYR_SOC_RISCV_RISCV_PRIVILEGE_NUCLEI_GD32VF103_COMMON_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_RISCV_RISCV_PRIVILEGE_NUCLEI_GD32VF103_COMMON_PINCTRL_SOC_H_ + +#include + +#endif /* ZEPHYR_SOC_RISCV_RISCV_PRIVILEGE_NUCLEI_GD32VF103_COMMON_PINCTRL_SOC_H_ */ diff --git a/soc/riscv/riscv-privilege/gd32vf103/soc.c b/soc/riscv/riscv-privilege/gd32vf103/soc.c new file mode 100644 index 0000000000000..59cd511e43f17 --- /dev/null +++ b/soc/riscv/riscv-privilege/gd32vf103/soc.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021 Tokita, Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +static int gigadevice_gd32v_soc_init(const struct device *dev) +{ + uint32_t key; + + ARG_UNUSED(dev); + + key = irq_lock(); + + SystemInit(); + + irq_unlock(key); + + return 0; +} + +SYS_INIT(gigadevice_gd32v_soc_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); diff --git a/soc/riscv/riscv-privilege/gd32vf103/soc.h b/soc/riscv/riscv-privilege/gd32vf103/soc.h new file mode 100644 index 0000000000000..ff994ee2cc19f --- /dev/null +++ b/soc/riscv/riscv-privilege/gd32vf103/soc.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2021 Tokita, Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file SoC configuration macros for the GigaDevice GD32VF103 processor + */ + +#ifndef RISCV_GD32VF103_SOC_H_ +#define RISCV_GD32VF103_SOC_H_ + +#include +#include + +/* Timer configuration */ +#define RISCV_MTIME_BASE DT_REG_ADDR_BY_IDX(DT_NODELABEL(mtimer), 0) +#define RISCV_MTIMECMP_BASE DT_REG_ADDR_BY_IDX(DT_NODELABEL(mtimer), 1) + +#ifndef _ASMLANGUAGE +#include +#include +#endif /* !_ASMLANGUAGE */ + +#endif /* RISCV_GD32VF103_SOC_H */ diff --git a/tests/kernel/common/src/irq_offload.c b/tests/kernel/common/src/irq_offload.c index e389e212abe0c..431302a2cd480 100644 --- a/tests/kernel/common/src/irq_offload.c +++ b/tests/kernel/common/src/irq_offload.c @@ -121,6 +121,27 @@ __no_optimization void test_nop(void) /* do 2 nop instructions more to cost cycles */ arch_nop(); arch_nop(); +#if defined(CONFIG_RISCV_MACHINE_TIMER_SYSTEM_CLOCK_DIVIDER) + /* When the case machine timer clock uses the divided system clock, + * k_cycle_get_32() can't measure accurately how many cycles elapsed. + * + * For example, use the value as timer clock obtained by dividing + * the system clock by 4. + * In this case, measuring a duration with k_cycle_get32() has up to 3 + * (4-1) cycles systematic error. + * + * To run this test, we need to insert an appropriate of nops + * with consideration for the errors. + * 'nop' can not repeat with for loop. + * Must insert as separated statement. + * But we don't have a convenient function such as + * BOOST_PP_REPEAT in C++. + * + * At this time, Implementing a generic test is a bit difficult. + * Skipping this test in the case. + */ + ztest_test_skip(); +#endif #elif defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) || \ defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) /* do 4 nop instructions more to cost cycles */ diff --git a/tests/subsys/debug/coredump/src/main.c b/tests/subsys/debug/coredump/src/main.c index 471a6196c5eb8..812b0d61420fa 100644 --- a/tests/subsys/debug/coredump/src/main.c +++ b/tests/subsys/debug/coredump/src/main.c @@ -10,7 +10,10 @@ void func_3(uint32_t *addr) { -#if defined(CONFIG_BOARD_M2GL025_MIV) || defined(CONFIG_BOARD_HIFIVE1) +#if defined(CONFIG_BOARD_M2GL025_MIV) || \ + defined(CONFIG_BOARD_HIFIVE1) || \ + defined(CONFIG_BOARD_LONGAN_NANO) || \ + defined(CONFIG_BOARD_LONGAN_NANO_LITE) ARG_UNUSED(addr); /* Call coredump() directly so Renode doesn't pause execution */ z_arch_esf_t esf;