soc: neorv32: update to support NEORV32 v1.11.1

Update the NEORV32 SoC, peripheral drivers, and board to support NEORV32
v1.11.1. Notable changes include:

- Optional RISC-V ISA Kconfigs are now selected on the board level.
- Peripheral registers are now automatically reset in hardware, no need for
  software initialization code.
- The NEORV32 GPIO controller now supports 32 pins, not 64. Interrupt
  support will be submitted in a separate PR.
- Default board configuration has 64k RAM and is clocked at 18 MHz.

Signed-off-by: Henrik Brix Andersen <henrik@brixandersen.dk>
This commit is contained in:
Henrik Brix Andersen 2025-02-26 16:11:03 +00:00 committed by Benjamin Cabé
commit 63c24d9d34
20 changed files with 340 additions and 409 deletions

View file

@ -1,4 +1,4 @@
# Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
# Copyright (c) 2021,2025 Henrik Brix Andersen <henrik@brixandersen.dk>
# SPDX-License-Identifier: Apache-2.0
if((CONFIG_BOARD_NEORV32) AND (CONFIG_BUILD_OUTPUT_BIN))
@ -18,7 +18,7 @@ if((CONFIG_BOARD_NEORV32) AND (CONFIG_BUILD_OUTPUT_BIN))
set_property(GLOBAL APPEND PROPERTY extra_post_build_commands
COMMAND ${IMAGE_GEN}
ARGS -app_img
ARGS -app_vhd
${CONFIG_KERNEL_BIN_NAME}.bin
${CONFIG_KERNEL_BIN_NAME}.vhd
${PROJECT_BINARY_DIR}

View file

@ -0,0 +1,7 @@
# Copyright (c) 2021,2025 Henrik Brix Andersen <henrik@brixandersen.dk>
# SPDX-License-Identifier: Apache-2.0
config BOARD_NEORV32
select RISCV_ISA_RV32I
select RISCV_ISA_EXT_M
select ATOMIC_OPERATIONS_C

View file

@ -13,7 +13,7 @@ For more information about the NEORV32, see the following websites:
- `The NEORV32 RISC-V Processor Datasheet`_
- `The NEORV32 RISC-V Processor User Guide`_
The currently supported version is 1.8.6.
The currently supported version is NEORV32 v1.11.1.
Supported Features
==================
@ -27,7 +27,7 @@ using :ref:`devicetree overlays <use-dt-overlays>`.
System Clock
============
The default board configuration assumes a system clock of 100 MHz. The clock
The default board configuration assumes a system clock of 18 MHz. The clock
frequency can be overridden by changing the ``clock-frequency`` property of the
``cpu0`` devicetree node.
@ -37,9 +37,10 @@ CPU
The default board configuration assumes the NEORV32 CPU implementation has the
following RISC-V ISA extensions enabled:
- C (Compresses Instructions)
- I (Base Integer Instruction Set, 32-bit)
- M (Integer Multiplication and Division)
- Zicsr (Control and Status Register (CSR) Instructions)
- Zicsr (Control and Status Register (CSR) Instructions, always enabled)
- Zifencei (Instruction-fetch fence, always enabled)
Internal Instruction Memory
===========================
@ -52,7 +53,7 @@ instruction memory can be overridden by changing the ``reg`` property of the
Internal Data Memory
====================
The default board configuration assumes the NEORV32 SoC implementation has a 32k
The default board configuration assumes the NEORV32 SoC implementation has a 64k
byte internal data memory (DMEM). The size of the data memory can be overridden
by changing the ``reg`` property of the ``dmem`` devicetree node.
@ -115,21 +116,21 @@ implementation with the On-Chip Debugger (OCD) and bootloader enabled.
The default board configuration uses an :ref:`openocd-debug-host-tools`
configuration similar to the example provided by the NEORV32 project. Other
JTAGs can be used by providing further arguments when building. Here is an
example for using the Flyswatter JTAG:
JTAGs can be used by providing further arguments when flashing. Here is an
example for using the Flyswatter JTAG @ 2 kHz:
.. zephyr-app-commands::
:zephyr-app: samples/hello_world
:board: neorv32
:goals: flash
:gen-args: -DBOARD_RUNNER_ARGS_openocd="--config;interface/ftdi/flyswatter.cfg;--config;neorv32.cfg;--cmd-pre-init;'adapter speed 2000'"
:flash-args: --config interface/ftdi/flyswatter.cfg --config neorv32.cfg --cmd-pre-init 'adapter speed 2000'
After flashing, you should see message similar to the following in the terminal:
.. code-block:: console
*** Booting Zephyr OS build zephyr-vn.n.nn ***
Hello World! neorv32
Hello World! neorv32/neorv32
Note, however, that the application was not persisted in flash memory by the
above steps. It was merely written to internal block RAM in the FPGA. It will
@ -176,7 +177,7 @@ similar to the following in the terminal:
.. code-block:: console
*** Booting Zephyr OS build zephyr-vn.n.nn ***
Hello World! neorv32
Hello World! neorv32/neorv32
.. _The NEORV32 RISC-V Processor GitHub:
https://github.com/stnolting/neorv32

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
* Copyright (c) 2021,2025 Henrik Brix Andersen <henrik@brixandersen.dk>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -29,25 +29,9 @@
zephyr,uart-pipe = &uart0;
};
soc {
imem: memory@0 {
compatible = "soc-nv-flash", "mmio-sram";
reg = <0x0 DT_SIZE_K(64)>;
};
bootrom: memory@ffff0000 {
compatible = "soc-nv-flash", "mmio-sram";
reg = <0xffff0000 DT_SIZE_K(4)>;
};
dmem: memory@80000000 {
compatible = "mmio-sram";
reg = <0x80000000 DT_SIZE_K(32)>;
};
};
leds {
compatible = "gpio-leds";
led0: led0 {
gpios = <&gpio 0 GPIO_ACTIVE_HIGH>;
label = "LED_0";
@ -71,7 +55,30 @@
};
&cpu0 {
clock-frequency = <DT_FREQ_M(100)>;
riscv,isa = "rv32im_zicsr_zifencei";
clock-frequency = <DT_FREQ_M(18)>;
};
&bootrom {
status = "okay";
};
&imem {
status = "okay";
reg = <0x0 DT_SIZE_K(64)>;
};
&dmem {
status = "okay";
reg = <0x80000000 DT_SIZE_K(64)>;
};
&clint {
status = "okay";
};
&mtimer {
status = "okay";
};
&uart0 {
@ -79,10 +86,6 @@
current-speed = <19200>;
};
&gpio_lo {
status = "okay";
};
&gpio_hi {
&gpio {
status = "okay";
};

View file

@ -5,7 +5,7 @@ arch: riscv
toolchain:
- cross-compile
- zephyr
ram: 32
ram: 64
flash: 64
supported:
- gpio

View file

@ -1,7 +1,6 @@
# Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
# Copyright (c) 2021,2025 Henrik Brix Andersen <henrik@brixandersen.dk>
# SPDX-License-Identifier: Apache-2.0
CONFIG_SOC_NEORV32_ISA_C=y
CONFIG_SERIAL=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
* Copyright (c) 2021,2025 Henrik Brix Andersen <henrik@brixandersen.dk>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -17,10 +17,19 @@
LOG_MODULE_REGISTER(neorv32_trng, CONFIG_ENTROPY_LOG_LEVEL);
/* TRNG CTRL register bits */
#define NEORV32_TRNG_CTRL_DATA_MASK BIT_MASK(8)
#define NEORV32_TRNG_CTRL_EN BIT(30)
#define NEORV32_TRNG_CTRL_VALID BIT(31)
/* Register offsets */
#define NEORV32_TRNG_CTRL 0x00
#define NEORV32_TRNG_DATA 0x04
/* CTRL register bits */
#define NEORV32_TRNG_CTRL_EN BIT(0)
#define NEORV32_TRNG_CTRL_FIFO_CLR BIT(1)
#define NEORV32_TRNG_CTRL_FIFO_DEPTH GENMASK(5, 2)
#define NEORV32_TRNG_CTRL_SIM_MODE BIT(6)
#define NEORV32_TRNG_CTRL_AVAIL BIT(7)
/* DATA register bits */
#define NEORV32_TRNG_DATA_MASK GENMASK(7, 0)
struct neorv32_trng_config {
const struct device *syscon;
@ -31,14 +40,21 @@ static inline uint32_t neorv32_trng_read_ctrl(const struct device *dev)
{
const struct neorv32_trng_config *config = dev->config;
return sys_read32(config->base);
return sys_read32(config->base + NEORV32_TRNG_CTRL);
}
static inline void neorv32_trng_write_ctrl(const struct device *dev, uint32_t ctrl)
{
const struct neorv32_trng_config *config = dev->config;
sys_write32(ctrl, config->base);
sys_write32(ctrl, config->base + NEORV32_TRNG_CTRL);
}
static inline uint8_t neorv32_trng_read_data(const struct device *dev)
{
const struct neorv32_trng_config *config = dev->config;
return sys_read32(config->base + NEORV32_TRNG_DATA) & NEORV32_TRNG_DATA_MASK;
}
static int neorv32_trng_get_entropy(const struct device *dev, uint8_t *buffer, uint16_t len)
@ -48,8 +64,8 @@ static int neorv32_trng_get_entropy(const struct device *dev, uint8_t *buffer, u
while (len > 0) {
ctrl = neorv32_trng_read_ctrl(dev);
if ((ctrl & NEORV32_TRNG_CTRL_VALID) != 0) {
*buffer++ = ctrl & NEORV32_TRNG_CTRL_DATA_MASK;
if ((ctrl & NEORV32_TRNG_CTRL_AVAIL) != 0) {
*buffer++ = neorv32_trng_read_data(dev);
len--;
}
}
@ -65,8 +81,8 @@ static int neorv32_trng_get_entropy_isr(const struct device *dev, uint8_t *buffe
if ((flags & ENTROPY_BUSYWAIT) == 0) {
ctrl = neorv32_trng_read_ctrl(dev);
if ((ctrl & NEORV32_TRNG_CTRL_VALID) != 0) {
*buffer = ctrl & NEORV32_TRNG_CTRL_DATA_MASK;
if ((ctrl & NEORV32_TRNG_CTRL_AVAIL) != 0) {
*buffer = neorv32_trng_read_data(dev);
return 1;
}
@ -93,13 +109,13 @@ static int neorv32_trng_init(const struct device *dev)
return -EINVAL;
}
err = syscon_read_reg(config->syscon, NEORV32_SYSINFO_FEATURES, &features);
err = syscon_read_reg(config->syscon, NEORV32_SYSINFO_SOC, &features);
if (err < 0) {
LOG_ERR("failed to determine implemented features (err %d)", err);
return err;
}
if ((features & NEORV32_SYSINFO_FEATURES_IO_TRNG) == 0) {
if ((features & NEORV32_SYSINFO_SOC_IO_TRNG) == 0) {
LOG_ERR("neorv32 trng not supported");
return -ENODEV;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
* Copyright (c) 2021,2025 Henrik Brix Andersen <henrik@brixandersen.dk>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -20,6 +20,10 @@ LOG_MODULE_REGISTER(gpio_neorv32, CONFIG_GPIO_LOG_LEVEL);
#include <zephyr/drivers/gpio/gpio_utils.h>
/* Register offsets */
#define NEORV32_GPIO_PORT_IN 0x00
#define NEORV32_GPIO_PORT_OUT 0x04
/* Maximum number of GPIOs supported */
#define MAX_GPIOS 32
@ -27,8 +31,7 @@ struct neorv32_gpio_config {
/* gpio_driver_config needs to be first */
struct gpio_driver_config common;
const struct device *syscon;
mm_reg_t input;
mm_reg_t output;
mm_reg_t base;
};
struct neorv32_gpio_data {
@ -42,14 +45,14 @@ static inline uint32_t neorv32_gpio_read(const struct device *dev)
{
const struct neorv32_gpio_config *config = dev->config;
return sys_read32(config->input);
return sys_read32(config->base + NEORV32_GPIO_PORT_IN);
}
static inline void neorv32_gpio_write(const struct device *dev, uint32_t val)
{
const struct neorv32_gpio_config *config = dev->config;
sys_write32(val, config->output);
sys_write32(val, config->base + NEORV32_GPIO_PORT_OUT);
}
static int neorv32_gpio_pin_configure(const struct device *dev, gpio_pin_t pin,
@ -179,13 +182,13 @@ static int neorv32_gpio_init(const struct device *dev)
return -EINVAL;
}
err = syscon_read_reg(config->syscon, NEORV32_SYSINFO_FEATURES, &features);
err = syscon_read_reg(config->syscon, NEORV32_SYSINFO_SOC, &features);
if (err < 0) {
LOG_ERR("failed to determine implemented features (err %d)", err);
return -EIO;
}
if ((features & NEORV32_SYSINFO_FEATURES_IO_GPIO) == 0) {
if ((features & NEORV32_SYSINFO_SOC_IO_GPIO) == 0) {
LOG_ERR("neorv32 gpio not supported");
return -ENODEV;
}
@ -216,8 +219,7 @@ static DEVICE_API(gpio, neorv32_gpio_driver_api) = {
.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n) \
}, \
.syscon = DEVICE_DT_GET(DT_INST_PHANDLE(n, syscon)), \
.input = DT_INST_REG_ADDR_BY_NAME(n, input), \
.output = DT_INST_REG_ADDR_BY_NAME(n, output), \
.base = DT_INST_REG_ADDR(n), \
}; \
\
DEVICE_DT_INST_DEFINE(n, \

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
* Copyright (c) 2021,2025 Henrik Brix Andersen <henrik@brixandersen.dk>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -9,59 +9,63 @@
#include <zephyr/device.h>
#include <zephyr/drivers/syscon.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/pm/device.h>
#include <zephyr/sys/sys_io.h>
#include <zephyr/logging/log.h>
#include <zephyr/irq.h>
#include <zephyr/logging/log.h>
#include <zephyr/pm/device.h>
#include <zephyr/spinlock.h>
#include <zephyr/sys/sys_io.h>
#include <soc.h>
LOG_MODULE_REGISTER(uart_neorv32, CONFIG_UART_LOG_LEVEL);
/* NEORV32 UART registers offsets */
#define NEORV32_UART_CTRL_OFFSET 0x00
#define NEORV32_UART_DATA_OFFSET 0x04
#define NEORV32_UART_CTRL 0x00
#define NEORV32_UART_DATA 0x04
/* UART_CTRL register bits */
/* NEORV32 UART CTRL register bits */
#define NEORV32_UART_CTRL_EN BIT(0)
#define NEORV32_UART_CTRL_SIM_MODE BIT(1)
#define NEORV32_UART_CTRL_HWFC_EN BIT(2)
#define NEORV32_UART_CTRL_PRSC_POS 3U
#define NEORV32_UART_CTRL_PRSC_MASK BIT_MASK(3)
#define NEORV32_UART_CTRL_BAUD_POS 6U
#define NEORV32_UART_CTRL_BAUD_MASK BIT_MASK(10)
#define NEORV32_UART_CTRL_PRSC GENMASK(5, 3)
#define NEORV32_UART_CTRL_BAUD GENMASK(15, 6)
#define NEORV32_UART_CTRL_RX_NEMPTY BIT(16)
#define NEORV32_UART_CTRL_RX_HALF BIT(17)
#define NEORV32_UART_CTRL_RX_FULL BIT(18)
#define NEORV32_UART_CTRL_TX_NEMPTY BIT(19)
#define NEORV32_UART_CTRL_TX_HALF BIT(20)
#define NEORV32_UART_CTRL_TX_EMPTY BIT(19)
#define NEORV32_UART_CTRL_TX_NHALF BIT(20)
#define NEORV32_UART_CTRL_TX_FULL BIT(21)
#define NEORV32_UART_CTRL_IRQ_RX_NEMPTY BIT(22)
#define NEORV32_UART_CTRL_IRQ_RX_HALF BIT(23)
#define NEORV32_UART_CTRL_IRQ_RX_FULL BIT(24)
#define NEORV32_UART_CTRL_IRQ_TX_EMPTY BIT(25)
#define NEORV32_UART_CTRL_IRQ_TX_NHALF BIT(26)
#define NEORV32_UART_CTRL_UART_CTRL_RX_CLR BIT(28)
#define NEORV32_UART_CTRL_UART_CTRL_TX_CLR BIT(29)
#define NEORV32_UART_CTRL_RX_OVER BIT(30)
#define NEORV32_UART_CTRL_TX_BUSY BIT(31)
/* NEORV32 UART DATA register bits */
#define NEORV32_UART_DATA_RTX GENMASK(7, 0)
#define NEORV32_UART_DATA_RX_FIFO_SIZE GENMASK(11, 8)
#define NEORV32_UART_DATA_TX_FIFO_SIZE GENMASK(15, 12)
struct neorv32_uart_config {
const struct device *syscon;
uint32_t feature_mask;
mm_reg_t base;
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
void (*irq_config_func)(const struct device *dev);
unsigned int tx_irq;
unsigned int rx_irq;
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
};
struct neorv32_uart_data {
struct uart_config uart_cfg;
uint32_t last_data;
struct k_spinlock lock;
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
struct k_timer timer;
uart_irq_callback_user_data_t callback;
void *callback_data;
uint32_t last_ctrl;
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
};
@ -69,44 +73,37 @@ static inline uint32_t neorv32_uart_read_ctrl(const struct device *dev)
{
const struct neorv32_uart_config *config = dev->config;
return sys_read32(config->base + NEORV32_UART_CTRL_OFFSET);
return sys_read32(config->base + NEORV32_UART_CTRL);
}
static inline void neorv32_uart_write_ctrl(const struct device *dev, uint32_t ctrl)
{
const struct neorv32_uart_config *config = dev->config;
sys_write32(ctrl, config->base + NEORV32_UART_CTRL_OFFSET);
sys_write32(ctrl, config->base + NEORV32_UART_CTRL);
}
static inline uint32_t neorv32_uart_read_data(const struct device *dev)
{
const struct neorv32_uart_config *config = dev->config;
struct neorv32_uart_data *data = dev->data;
uint32_t reg;
/* Cache status bits as they are cleared upon read */
reg = sys_read32(config->base + NEORV32_UART_DATA_OFFSET);
data->last_data = reg;
return reg;
return sys_read32(config->base + NEORV32_UART_DATA);
}
static inline void neorv32_uart_write_data(const struct device *dev, uint32_t data)
{
const struct neorv32_uart_config *config = dev->config;
sys_write32(data, config->base + NEORV32_UART_DATA_OFFSET);
sys_write32(data, config->base + NEORV32_UART_DATA);
}
static int neorv32_uart_poll_in(const struct device *dev, unsigned char *c)
{
uint32_t data;
uint32_t ctrl;
data = neorv32_uart_read_data(dev);
if ((data & NEORV32_UART_CTRL_RX_NEMPTY) != 0) {
*c = data & BIT_MASK(8);
ctrl = neorv32_uart_read_ctrl(dev);
if ((ctrl & NEORV32_UART_CTRL_RX_NEMPTY) != 0U) {
*c = neorv32_uart_read_data(dev) & NEORV32_UART_DATA_RTX;
return 0;
}
@ -115,7 +112,7 @@ static int neorv32_uart_poll_in(const struct device *dev, unsigned char *c)
static void neorv32_uart_poll_out(const struct device *dev, unsigned char c)
{
while ((neorv32_uart_read_ctrl(dev) & NEORV32_UART_CTRL_TX_BUSY) != 0) {
while ((neorv32_uart_read_ctrl(dev) & NEORV32_UART_CTRL_TX_FULL) != 0U) {
}
neorv32_uart_write_data(dev, c);
@ -123,11 +120,15 @@ static void neorv32_uart_poll_out(const struct device *dev, unsigned char c)
static int neorv32_uart_configure(const struct device *dev, const struct uart_config *cfg)
{
const uint16_t baudxx_max = FIELD_GET(NEORV32_UART_CTRL_BAUD, NEORV32_UART_CTRL_BAUD);
const uint8_t prscx_max = FIELD_GET(NEORV32_UART_CTRL_PRSC, NEORV32_UART_CTRL_PRSC);
const struct neorv32_uart_config *config = dev->config;
struct neorv32_uart_data *data = dev->data;
uint32_t ctrl = NEORV32_UART_CTRL_EN;
k_spinlock_key_t key;
uint16_t baudxx = 0;
uint8_t prscx = 0;
uint32_t ctrl;
bool hwfc_en;
uint32_t clk;
int err;
@ -143,20 +144,17 @@ static int neorv32_uart_configure(const struct device *dev, const struct uart_co
return -ENOTSUP;
}
switch (cfg->parity) {
case UART_CFG_PARITY_NONE:
break;
default:
LOG_ERR("unsupported parity mode %d", cfg->parity);
if (cfg->parity != UART_CFG_PARITY_NONE) {
LOG_ERR("hardware only supports parity mode none");
return -ENOTSUP;
}
switch (cfg->flow_ctrl) {
case UART_CFG_FLOW_CTRL_NONE:
ctrl |= 0;
hwfc_en = false;
break;
case UART_CFG_FLOW_CTRL_RTS_CTS:
ctrl |= NEORV32_UART_CTRL_HWFC_EN;
hwfc_en = true;
break;
default:
LOG_ERR("unsupported flow control mode %d", cfg->flow_ctrl);
@ -179,7 +177,7 @@ static int neorv32_uart_configure(const struct device *dev, const struct uart_co
* clock / 2.
*/
baudxx = clk / (2 * cfg->baudrate);
while (baudxx >= NEORV32_UART_CTRL_BAUD_MASK) {
while (baudxx >= baudxx_max) {
if ((prscx == 2) || (prscx == 4)) {
baudxx >>= 3;
} else {
@ -189,16 +187,30 @@ static int neorv32_uart_configure(const struct device *dev, const struct uart_co
prscx++;
}
if (prscx > NEORV32_UART_CTRL_PRSC_MASK) {
if (prscx > prscx_max) {
LOG_ERR("unsupported baud rate %d", cfg->baudrate);
return -ENOTSUP;
}
ctrl |= (baudxx - 1) << NEORV32_UART_CTRL_BAUD_POS;
ctrl |= prscx << NEORV32_UART_CTRL_PRSC_POS;
key = k_spin_lock(&data->lock);
ctrl = neorv32_uart_read_ctrl(dev);
ctrl |= NEORV32_UART_CTRL_EN;
if (hwfc_en) {
ctrl |= NEORV32_UART_CTRL_HWFC_EN;
} else {
ctrl &= ~NEORV32_UART_CTRL_HWFC_EN;
}
ctrl &= ~(NEORV32_UART_CTRL_BAUD | NEORV32_UART_CTRL_PRSC);
ctrl |= FIELD_PREP(NEORV32_UART_CTRL_BAUD, baudxx - 1U) |
FIELD_PREP(NEORV32_UART_CTRL_PRSC, prscx);
data->uart_cfg = *cfg;
neorv32_uart_write_ctrl(dev, ctrl);
data->uart_cfg = *cfg;
k_spin_unlock(&data->lock, key);
return 0;
}
@ -215,28 +227,25 @@ static int neorv32_uart_config_get(const struct device *dev, struct uart_config
}
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
static int neorv32_uart_fifo_fill(const struct device *dev, const uint8_t *tx_data, int len)
static int neorv32_uart_fifo_fill(const struct device *dev, const uint8_t *tx_data, int size)
{
uint32_t ctrl;
int count = 0;
if (len <= 0) {
if (size <= 0) {
return 0;
}
__ASSERT_NO_MSG(tx_data != NULL);
ctrl = neorv32_uart_read_ctrl(dev);
if ((ctrl & NEORV32_UART_CTRL_TX_BUSY) == 0) {
neorv32_uart_write_data(dev, *tx_data);
return 1;
while (count < size && (neorv32_uart_read_ctrl(dev) & NEORV32_UART_CTRL_TX_FULL) == 0U) {
neorv32_uart_write_data(dev, tx_data[count++]);
}
return 0;
return count;
}
static int neorv32_uart_fifo_read(const struct device *dev, uint8_t *rx_data, const int size)
{
struct neorv32_uart_data *data = dev->data;
int count = 0;
if (size <= 0) {
@ -245,104 +254,100 @@ static int neorv32_uart_fifo_read(const struct device *dev, uint8_t *rx_data, co
__ASSERT_NO_MSG(rx_data != NULL);
while ((data->last_data & NEORV32_UART_CTRL_RX_NEMPTY) != 0) {
rx_data[count++] = data->last_data & BIT_MASK(8);
data->last_data &= ~(NEORV32_UART_CTRL_RX_NEMPTY);
if (count >= size) {
break;
}
(void)neorv32_uart_read_data(dev);
while (count < size && (neorv32_uart_read_ctrl(dev) & NEORV32_UART_CTRL_RX_NEMPTY) != 0U) {
rx_data[count++] = neorv32_uart_read_data(dev) & NEORV32_UART_DATA_RTX;
}
return count;
}
static void neorv32_uart_tx_soft_isr(struct k_timer *timer)
{
const struct device *dev = k_timer_user_data_get(timer);
struct neorv32_uart_data *data = dev->data;
uart_irq_callback_user_data_t callback = data->callback;
if (callback) {
callback(dev, data->callback_data);
}
}
static void neorv32_uart_irq_tx_enable(const struct device *dev)
{
const struct neorv32_uart_config *config = dev->config;
struct neorv32_uart_data *data = dev->data;
k_spinlock_key_t key;
uint32_t ctrl;
irq_enable(config->tx_irq);
key = k_spin_lock(&data->lock);
ctrl = neorv32_uart_read_ctrl(dev);
if ((ctrl & NEORV32_UART_CTRL_TX_BUSY) == 0) {
/*
* TX done event already generated an edge interrupt. Generate a
* soft interrupt and have it call the callback function in
* timer isr context.
*/
k_timer_start(&data->timer, K_NO_WAIT, K_NO_WAIT);
}
ctrl |= NEORV32_UART_CTRL_IRQ_TX_EMPTY;
neorv32_uart_write_ctrl(dev, ctrl);
k_spin_unlock(&data->lock, key);
}
static void neorv32_uart_irq_tx_disable(const struct device *dev)
{
const struct neorv32_uart_config *config = dev->config;
struct neorv32_uart_data *data = dev->data;
k_spinlock_key_t key;
uint32_t ctrl;
irq_disable(config->tx_irq);
key = k_spin_lock(&data->lock);
ctrl = neorv32_uart_read_ctrl(dev);
ctrl &= ~NEORV32_UART_CTRL_IRQ_TX_EMPTY;
neorv32_uart_write_ctrl(dev, ctrl);
k_spin_unlock(&data->lock, key);
}
static int neorv32_uart_irq_tx_ready(const struct device *dev)
{
const struct neorv32_uart_config *config = dev->config;
uint32_t ctrl;
struct neorv32_uart_data *data = dev->data;
if (!irq_is_enabled(config->tx_irq)) {
if ((data->last_ctrl & NEORV32_UART_CTRL_IRQ_TX_EMPTY) == 0U) {
return 0;
}
ctrl = neorv32_uart_read_ctrl(dev);
return (ctrl & NEORV32_UART_CTRL_TX_BUSY) == 0;
return (data->last_ctrl & NEORV32_UART_CTRL_TX_FULL) == 0U;
}
static void neorv32_uart_irq_rx_enable(const struct device *dev)
{
const struct neorv32_uart_config *config = dev->config;
struct neorv32_uart_data *data = dev->data;
k_spinlock_key_t key;
uint32_t ctrl;
irq_enable(config->rx_irq);
key = k_spin_lock(&data->lock);
ctrl = neorv32_uart_read_ctrl(dev);
ctrl |= NEORV32_UART_CTRL_IRQ_RX_NEMPTY;
neorv32_uart_write_ctrl(dev, ctrl);
k_spin_unlock(&data->lock, key);
}
static void neorv32_uart_irq_rx_disable(const struct device *dev)
{
const struct neorv32_uart_config *config = dev->config;
struct neorv32_uart_data *data = dev->data;
k_spinlock_key_t key;
uint32_t ctrl;
irq_disable(config->rx_irq);
key = k_spin_lock(&data->lock);
ctrl = neorv32_uart_read_ctrl(dev);
ctrl &= ~NEORV32_UART_CTRL_IRQ_RX_NEMPTY;
neorv32_uart_write_ctrl(dev, ctrl);
k_spin_unlock(&data->lock, key);
}
static int neorv32_uart_irq_tx_complete(const struct device *dev)
{
uint32_t ctrl;
struct neorv32_uart_data *data = dev->data;
ctrl = neorv32_uart_read_ctrl(dev);
return (ctrl & NEORV32_UART_CTRL_TX_BUSY) == 0;
return (data->last_ctrl & NEORV32_UART_CTRL_TX_BUSY) == 0U;
}
static int neorv32_uart_irq_rx_ready(const struct device *dev)
{
const struct neorv32_uart_config *config = dev->config;
struct neorv32_uart_data *data = dev->data;
if (!irq_is_enabled(config->rx_irq)) {
if ((data->last_ctrl & NEORV32_UART_CTRL_IRQ_RX_NEMPTY) == 0U) {
return 0;
}
return (data->last_data & NEORV32_UART_CTRL_RX_NEMPTY) != 0;
return (data->last_ctrl & NEORV32_UART_CTRL_RX_NEMPTY) != 0U;
}
static int neorv32_uart_irq_is_pending(const struct device *dev)
@ -353,12 +358,14 @@ static int neorv32_uart_irq_is_pending(const struct device *dev)
static int neorv32_uart_irq_update(const struct device *dev)
{
const struct neorv32_uart_config *config = dev->config;
struct neorv32_uart_data *data = dev->data;
if (irq_is_enabled(config->rx_irq)) {
/* Cache data for use by rx_ready() and fifo_read() */
(void)neorv32_uart_read_data(dev);
}
/* Cache the CTRL register for use in the following functions:
* - neorv32_uart_irq_tx_complete()
* - neorv32_uart_irq_tx_ready()
* - neorv32_uart_irq_rx_ready()
*/
data->last_ctrl = neorv32_uart_read_ctrl(dev);
return 1;
}
@ -395,7 +402,7 @@ static int neorv32_uart_init(const struct device *dev)
return -EINVAL;
}
err = syscon_read_reg(config->syscon, NEORV32_SYSINFO_FEATURES, &features);
err = syscon_read_reg(config->syscon, NEORV32_SYSINFO_SOC, &features);
if (err < 0) {
LOG_ERR("failed to determine implemented features (err %d)", err);
return -EIO;
@ -407,9 +414,6 @@ static int neorv32_uart_init(const struct device *dev)
}
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
k_timer_init(&data->timer, &neorv32_uart_tx_soft_isr, NULL);
k_timer_user_data_set(&data->timer, (void *)dev);
config->irq_config_func(dev);
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
@ -420,7 +424,12 @@ static int neorv32_uart_init(const struct device *dev)
static int neorv32_uart_pm_action(const struct device *dev,
enum pm_device_action action)
{
uint32_t ctrl = neorv32_uart_read_ctrl(dev);
struct neorv32_uart_data *data = dev->data;
k_spinlock_key_t key;
uint32_t ctrl;
key = k_spin_lock(&data->lock);
ctrl = neorv32_uart_read_ctrl(dev);
switch (action) {
case PM_DEVICE_ACTION_SUSPEND:
@ -434,6 +443,7 @@ static int neorv32_uart_pm_action(const struct device *dev,
}
neorv32_uart_write_ctrl(dev, ctrl);
k_spin_unlock(&data->lock, key);
return 0;
}
@ -470,16 +480,16 @@ static DEVICE_API(uart, neorv32_uart_driver_api) = {
DT_IRQ_BY_NAME(node_id, tx, priority), \
neorv32_uart_isr, \
DEVICE_DT_GET(node_id), 0); \
irq_enable(DT_IRQ_BY_NAME(node_id, tx, irq)); \
\
IRQ_CONNECT(DT_IRQ_BY_NAME(node_id, rx, irq), \
DT_IRQ_BY_NAME(node_id, rx, priority), \
neorv32_uart_isr, \
DEVICE_DT_GET(node_id), 0); \
irq_enable(DT_IRQ_BY_NAME(node_id, rx, irq)); \
}
#define NEORV32_UART_CONFIG_INIT(node_id, n) \
.irq_config_func = neorv32_uart_config_func_##n, \
.tx_irq = DT_IRQ_BY_NAME(node_id, tx, irq), \
.rx_irq = DT_IRQ_BY_NAME(node_id, rx, irq),
.irq_config_func = neorv32_uart_config_func_##n,
#else
#define NEORV32_UART_CONFIG_FUNC(node_id, n)
#define NEORV32_UART_CONFIG_INIT(node_id, n)
@ -502,7 +512,7 @@ static DEVICE_API(uart, neorv32_uart_driver_api) = {
\
static const struct neorv32_uart_config neorv32_uart_##n##_config = { \
.syscon = DEVICE_DT_GET(DT_PHANDLE(node_id, syscon)), \
.feature_mask = NEORV32_SYSINFO_FEATURES_IO_UART##n, \
.feature_mask = NEORV32_SYSINFO_SOC_IO_UART##n, \
.base = DT_REG_ADDR(node_id), \
NEORV32_UART_CONFIG_INIT(node_id, n) \
}; \

View file

@ -8,9 +8,6 @@ properties:
reg:
required: true
reg-names:
required: true
syscon:
type: phandle
required: true

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
* Copyright (c) 2021,2025 Henrik Brix Andersen <henrik@brixandersen.dk>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -20,7 +20,6 @@
cpu0: cpu@0 {
compatible = "neorv32-cpu", "riscv";
riscv,isa = "rv32imc_zicsr";
reg = <0>;
device_type = "cpu";
@ -64,77 +63,76 @@
#size-cells = <1>;
ranges;
mtimer: timer@ffffff90 {
imem: memory@0 {
compatible = "soc-nv-flash", "mmio-sram";
status = "disabled";
};
dmem: memory@80000000 {
compatible = "mmio-sram";
status = "disabled";
};
bootrom: rom@ffe00000 {
compatible = "neorv32-bootrom", "mmio-sram";
status = "disabled";
reg = <0xffe00000 0x10000>;
};
clint: clint@fff40000 {
compatible = "neorv32-clint", "sifive,clint0";
status = "disabled";
reg = <0xfff40000 0x10000>;
interrupts-extended = <&intc 3>;
};
mtimer: timer@fff4bff8 {
compatible = "riscv,machine-timer";
reg = <0xffffff90 0x8 0xffffff98 0x8>;
status = "disabled";
reg = <0xfff4bff8 0x8 0xfff44000 0x8>;
reg-names = "mtime", "mtimecmp";
interrupts-extended = <&intc 7>;
};
uart0: serial@ffffffa0 {
uart0: serial@fff50000 {
compatible = "neorv32-uart";
status = "disabled";
reg = <0xffffffa0 8>;
reg = <0xfff50000 0x10000>;
interrupts = <2>, <3>;
interrupt-names = "RX", "TX";
syscon = <&sysinfo>;
};
trng: rng@ffffffb8 {
compatible = "neorv32-trng";
status = "disabled";
reg = <0xffffffb8 4>;
syscon = <&sysinfo>;
};
gpio: gpio {
compatible = "simple-bus";
gpio-map-mask = <0xffffffe0 0xffffffc0>;
gpio-map-pass-thru = <0x1f 0x3f>;
gpio-map = <
0x00 0x0 &gpio_lo 0x0 0x0
0x20 0x0 &gpio_hi 0x0 0x0
>;
#gpio-cells = <2>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
gpio_lo: gpio@ffffffc0 {
compatible = "neorv32-gpio";
status = "disabled";
reg = <0xffffffc0 4 0xffffffc8 4>;
reg-names = "input", "output";
gpio-controller;
ngpios = <32>;
syscon = <&sysinfo>;
#gpio-cells = <2>;
};
gpio_hi: gpio@ffffffc4 {
compatible = "neorv32-gpio";
status = "disabled";
reg = <0xffffffc4 4 0xffffffcc 4>;
reg-names = "input", "output";
gpio-controller;
ngpios = <32>;
syscon = <&sysinfo>;
#gpio-cells = <2>;
};
};
uart1: serial@ffffffd0 {
uart1: serial@fff60000 {
compatible = "neorv32-uart";
status = "disabled";
reg = <0xffffffd0 8>;
reg = <0xfff60000 0x10000>;
interrupts = <4>, <5>;
interrupt-names = "RX", "TX";
syscon = <&sysinfo>;
};
sysinfo: syscon@ffffffe0 {
trng: rng@fffa0000 {
compatible = "neorv32-trng";
status = "disabled";
reg = <0xfffa0000 0x10000>;
syscon = <&sysinfo>;
};
gpio: gpio@fffc0000 {
compatible = "neorv32-gpio";
status = "disabled";
reg = <0xfffc0000 0x10000>;
syscon = <&sysinfo>;
gpio-controller;
ngpios = <32>;
#gpio-cells = <2>;
};
sysinfo: syscon@fffe0000 {
compatible = "neorv-sysinfo", "syscon";
status = "okay";
reg = <0xffffffe0 32>;
reg = <0xfffe0000 0x10000>;
};
};
};

View file

@ -7,4 +7,4 @@ zephyr_sources(
soc.c
)
set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "")
set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "")

View file

@ -3,31 +3,20 @@
config SOC_NEORV32
select RISCV
select RISCV_ISA_RV32I
select RISCV_ISA_EXT_M
select RISCV_ISA_EXT_ZICSR
select RISCV_ISA_EXT_ZIFENCEI
select RISCV_PRIVILEGED
select RISCV_SOC_HAS_GP_RELATIVE_ADDRESSING
# NEORV32 RISC-V ISA A extension implements only LR/SC, not AMO
select ATOMIC_OPERATIONS_C
select RISCV_ISA_EXT_ZICSR
select RISCV_ISA_EXT_ZIFENCEI
imply XIP
if SOC_NEORV32
config SOC_NEORV32_VERSION
hex
default 0x01080600
default 0x01110100
help
The targeted NEORV32 version as BCD-coded number. The format is
identical to that of the NEORV32 Machine implementation ID (mimpid)
register.
config SOC_NEORV32_ISA_C
bool "RISC-V ISA Extension \"C\""
select RISCV_ISA_EXT_C
help
Enable this if the NEORV32 CPU implementation supports the RISC-V ISA
"C" extension (Compressed Instructions).
endif # SOC_NEORV32

View file

@ -1,4 +1,4 @@
# Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
# Copyright (c) 2021,2025 Henrik Brix Andersen <henrik@brixandersen.dk>
# SPDX-License-Identifier: Apache-2.0
if SOC_NEORV32
@ -12,12 +12,4 @@ config NUM_IRQS
config SYSCON
default y
config SERIAL_INIT_PRIORITY
default 55
depends on SERIAL
config ENTROPY_INIT_PRIORITY
default 55
depends on ENTROPY_GENERATOR
endif # SOC_NEORV32

View file

@ -8,15 +8,9 @@ config SOC_NEORV32
The NEORV32 CPU implementation must have the following RISC-V ISA
extensions enabled in order to support Zephyr:
- M (Integer Multiplication and Division)
- Zicsr (Control and Status Register (CSR) Instructions)
The following NEORV32 CPU ISA extensions are not currently supported
by Zephyr and can safely be disabled:
- A (Atomic Instructions)
- E (Embedded, only 16 integer registers)
- Zbb (Basic Bit Manipulation)
- Zfinx (Floating Point in Integer Registers)
- Zicsr (always enabled)
- Zifencei (always enabled)
- Zicntr
config SOC
default "neorv32" if SOC_NEORV32

View file

@ -1,23 +0,0 @@
/*
* Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/linker/linker-tool.h>
MEMORY
{
IO (rw) : ORIGIN = 0xFFFFFE00, LENGTH = 512
}
SECTIONS
{
SECTION_PROLOGUE(io, (NOLOAD),)
{
PROVIDE(__io_start = ORIGIN(IO));
PROVIDE(__io_end = ORIGIN(IO) + LENGTH(IO));
} GROUP_LINK_IN(IO)
}
#include <zephyr/arch/riscv/common/linker.ld>

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
* Copyright (c) 2021,2025 Henrik Brix Andersen <henrik@brixandersen.dk>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -13,9 +13,6 @@ GTEXT(__reset)
GTEXT(__initialize)
SECTION_FUNC(reset, __reset)
/* Zerorize zero register */
lui x0, 0
/* Disable interrupts */
csrw mstatus, x0
csrw mie, x0
@ -26,7 +23,7 @@ SECTION_FUNC(reset, __reset)
#endif /* CONFIG_USERSPACE */
/* Allow mcycle and minstret counters to increment */
li x11, ~2
li x11, ~5
csrw mcountinhibit, x11
/* Zerorize counters */
@ -35,39 +32,5 @@ SECTION_FUNC(reset, __reset)
csrw minstret, x0
csrw minstreth, x0
/*
* Simplify dummy machine trap code by not having to decode
* instruction width.
*/
.option push
.option norvc
/*
* Temporarily setup a dummy machine trap vector to catch (and ignore)
* Store Access faults due to unimplemented peripherals.
*/
csrr x6, mtvec
la x7, __dummy_trap_handler
csrw mtvec, x7
/* Attempt to zerorize all IO peripheral registers */
la x8, __io_start
la x9, __io_end
1: sw x0, 0(x8)
addi x8, x8, 4
bne x8, x9, 1b
/* Restore previous machine trap vector */
csrw mtvec, x6
.option pop
/* Jump to __initialize */
call __initialize
.balign 4
SECTION_FUNC(reset, __dummy_trap_handler)
csrr x5, mepc
addi x5, x5, 4
csrw mepc, x5
mret

View file

@ -1,56 +1,60 @@
/*
* Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
* Copyright (c) 2021,2025 Henrik Brix Andersen <henrik@brixandersen.dk>
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef RISCV_NEORV32_SOC_H
#define RISCV_NEORV32_SOC_H
#ifndef _NEORV32_SOC_H
#define _NEORV32_SOC_H
/* System information (SYSINFO) register offsets */
#define NEORV32_SYSINFO_CLK 0x00U
#define NEORV32_SYSINFO_CPU 0x04U
#define NEORV32_SYSINFO_FEATURES 0x08U
#define NEORV32_SYSINFO_MISC 0x04U
#define NEORV32_SYSINFO_SOC 0x08U
#define NEORV32_SYSINFO_CACHE 0x0cU
#define NEORV32_SYSINFO_ISPACE_BASE 0xf0U
#define NEORV32_SYSINFO_IMEM_SIZE 0xf4U
#define NEORV32_SYSINFO_DSPACE_BASE 0xf8U
#define NEORV32_SYSINFO_DMEM_SIZE 0xfcU
/* System information (SYSINFO) CPU register bits */
#define NEORV32_SYSINFO_CPU_ZICSR BIT(0)
#define NEORV32_SYSINFO_CPU_ZIFENCEI BIT(1)
#define NEORV32_SYSINFO_CPU_ZMMUL BIT(2)
#define NEORV32_SYSINFO_CPU_ZBB BIT(3)
#define NEORV32_SYSINFO_CPU_ZFINX BIT(5)
#define NEORV32_SYSINFO_CPU_ZXSCNT BIT(6)
#define NEORV32_SYSINFO_CPU_ZXNOCNT BIT(7)
#define NEORV32_SYSINFO_CPU_PMP BIT(8)
#define NEORV32_SYSINFO_CPU_HPM BIT(9)
#define NEORV32_SYSINFO_CPU_DEBUGMODE BIT(10)
#define NEORV32_SYSINFO_CPU_FASTMUL BIT(30)
#define NEORV32_SYSINFO_CPU_FASTSHIFT BIT(31)
/* System information (SYSINFO) MISC register bits */
#define NEORV32_SYSINFO_MISC_IMEM GENMASK(7, 0)
#define NEORV32_SYSINFO_MISC_DMEM GENMASK(15, 8)
#define NEORV32_SYSINFO_MISC_HART GENMASK(23, 16)
#define NEORV32_SYSINFO_MISC_BOOT GENMASK(31, 24)
/* System information (SYSINFO) FEATURES register bits */
#define NEORV32_SYSINFO_FEATURES_BOOTLOADER BIT(0)
#define NEORV32_SYSINFO_FEATURES_MEM_EXT BIT(1)
#define NEORV32_SYSINFO_FEATURES_MEM_INT_IMEM BIT(2)
#define NEORV32_SYSINFO_FEATURES_MEM_INT_DMEM BIT(3)
#define NEORV32_SYSINFO_FEATURES_MEM_EXT_ENDIAN BIT(4)
#define NEORV32_SYSINFO_FEATURES_ICACHE BIT(5)
#define NEORV32_SYSINFO_FEATURES_OCD BIT(14)
#define NEORV32_SYSINFO_FEATURES_HW_RESET BIT(15)
#define NEORV32_SYSINFO_FEATURES_IO_GPIO BIT(16)
#define NEORV32_SYSINFO_FEATURES_IO_MTIME BIT(17)
#define NEORV32_SYSINFO_FEATURES_IO_UART0 BIT(18)
#define NEORV32_SYSINFO_FEATURES_IO_SPI BIT(19)
#define NEORV32_SYSINFO_FEATURES_IO_TWI BIT(20)
#define NEORV32_SYSINFO_FEATURES_IO_PWM BIT(21)
#define NEORV32_SYSINFO_FEATURES_IO_WDT BIT(22)
#define NEORV32_SYSINFO_FEATURES_IO_CFS BIT(23)
#define NEORV32_SYSINFO_FEATURES_IO_TRNG BIT(24)
#define NEORV32_SYSINFO_FEATURES_IO_SLINK BIT(25)
#define NEORV32_SYSINFO_FEATURES_IO_UART1 BIT(26)
#define NEORV32_SYSINFO_FEATURES_IO_NEOLED BIT(27)
/* System information (SYSINFO) SOC register bits */
#define NEORV32_SYSINFO_SOC_BOOTLOADER BIT(0)
#define NEORV32_SYSINFO_SOC_XBUS BIT(1)
#define NEORV32_SYSINFO_SOC_MEM_INT_IMEM BIT(2)
#define NEORV32_SYSINFO_SOC_MEM_INT_DMEM BIT(3)
#define NEORV32_SYSINFO_SOC_OCD BIT(4)
#define NEORV32_SYSINFO_SOC_ICACHE BIT(5)
#define NEORV32_SYSINFO_SOC_DCACHE BIT(6)
#define NEORV32_SYSINFO_SOC_XBUS_CACHE BIT(8)
#define NEORV32_SYSINFO_SOC_OCD_AUTH BIT(11)
#define NEORV32_SYSINFO_SOC_IMEM_ROM BIT(12)
#define NEORV32_SYSINFO_SOC_IO_TWD BIT(13)
#define NEORV32_SYSINFO_SOC_IO_DMA BIT(14)
#define NEORV32_SYSINFO_SOC_IO_GPIO BIT(15)
#define NEORV32_SYSINFO_SOC_IO_CLINT BIT(16)
#define NEORV32_SYSINFO_SOC_IO_UART0 BIT(17)
#define NEORV32_SYSINFO_SOC_IO_SPI BIT(18)
#define NEORV32_SYSINFO_SOC_IO_TWI BIT(19)
#define NEORV32_SYSINFO_SOC_IO_PWM BIT(20)
#define NEORV32_SYSINFO_SOC_IO_WDT BIT(21)
#define NEORV32_SYSINFO_SOC_IO_CFS BIT(22)
#define NEORV32_SYSINFO_SOC_IO_TRNG BIT(23)
#define NEORV32_SYSINFO_SOC_IO_SDI BIT(24)
#define NEORV32_SYSINFO_SOC_IO_UART1 BIT(25)
#define NEORV32_SYSINFO_SOC_IO_NEOLED BIT(26)
#define NEORV32_SYSINFO_SOC_IO_GPTMR BIT(28)
#define NEORV32_SYSINFO_SOC_IO_SLINK BIT(29)
#define NEORV32_SYSINFO_SOC_IO_ONEWIRE BIT(30)
#define NEORV32_SYSINFO_SOC_IO_CRC BIT(31)
#endif /* RISCV_NEORV32_SOC_H */
/* System information (SYSINFO) CACHE register bits */
#define NEORV32_SYSINFO_CACHE_INST_BLOCK_SIZE GENMASK(3, 0)
#define NEORV32_SYSINFO_CACHE_INST_NUM_BLOCKS GENMASK(7, 4)
#define NEORV32_SYSINFO_CACHE_DATA_BLOCK_SIZE GENMASK(11, 8)
#define NEORV32_SYSINFO_CACHE_DATA_NUM_BLOCKS GENMASK(15, 12)
#define NEORV32_SYSINFO_CACHE_XBUS_BLOCK_SIZE GENMASK(27, 24)
#define NEORV32_SYSINFO_CACHE_XBUS_NUM_BLOCKS GENMASK(31, 28)
#endif /* _NEORV32_SOC_H */

View file

@ -13,16 +13,4 @@ GTEXT(__soc_handle_irq)
* Exception number is given as parameter via register a0.
*/
SECTION_FUNC(exception.other, __soc_handle_irq)
/*
* The MIP CSR on the NEORV32 is read-only and can thus not be used for
* clearing a pending IRQ. Instead we disable the IRQ in the MIE CSR and
* re-enable it (if it was enabled when clearing).
*/
li t1, 1
sll t0, t1, a0
csrrc t2, mie, t0
and t1, t2, t0
csrrs t2, mie, t1
/* Return */
ret

View file

@ -1,9 +0,0 @@
/*
* Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
*
* SPDX-License-Identifier: Apache-2.0
*/
&trng {
status = "okay";
};