soc: riscv: privilege: add neorv32 processor suppport

Add support for the open-source NEORV32 RISC-V compatible processor
system (SoC).

Signed-off-by: Henrik Brix Andersen <henrik@brixandersen.dk>
This commit is contained in:
Henrik Brix Andersen 2021-08-14 23:52:35 +02:00 committed by Christopher Friedt
commit a281dbfb6d
11 changed files with 364 additions and 0 deletions

View file

@ -0,0 +1,8 @@
# Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
# SPDX-License-Identifier: Apache-2.0
description: NEORV32 RISC-V CPU
compatible: "neorv32-cpu"
include: cpu.yaml

67
dts/riscv/neorv32.dtsi Normal file
View file

@ -0,0 +1,67 @@
/*
* Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
*
* SPDX-License-Identifier: Apache-2.0
*/
/dts-v1/;
#include <skeleton.dtsi>
/ {
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu0: cpu@0 {
compatible = "neorv32-cpu";
reg = <0>;
device_type = "cpu";
intc: interrupt-controller {
compatible = "riscv,cpu-intc";
interrupt-controller;
#address-cells = <1>;
#interrupt-cells = <1>;
firq: firq {
interrupt-map-mask = <0x0 0xffffffff>;
interrupt-map = <
0 0 &intc 0 16
0 1 &intc 0 17
0 2 &intc 0 18
0 3 &intc 0 19
0 4 &intc 0 20
0 5 &intc 0 21
0 6 &intc 0 22
0 7 &intc 0 23
0 8 &intc 0 24
0 9 &intc 0 25
0 10 &intc 0 26
0 11 &intc 0 27
0 12 &intc 0 28
0 13 &intc 0 29
0 14 &intc 0 30
0 15 &intc 0 31
>;
#interrupt-cells = <1>;
};
};
};
};
soc {
compatible = "simple-bus";
interrupt-parent = <&firq>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
sysinfo: syscon@ffffffe0 {
compatible = "neorv-sysinfo", "syscon";
status = "okay";
reg = <0xffffffe0 32>;
label = "SYSINFO";
};
};
};

View file

@ -0,0 +1,8 @@
# Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
# SPDX-License-Identifier: Apache-2.0
zephyr_sources(
reset.S
soc_irq.S
soc.c
)

View file

@ -0,0 +1,24 @@
# Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
# SPDX-License-Identifier: Apache-2.0
if SOC_SERIES_NEORV32
config SOC_SERIES
default "neorv32"
config SYS_CLOCK_HW_CYCLES_PER_SEC
default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) if RISCV_MACHINE_TIMER
config NUM_IRQS
default 32
config RISCV_HAS_CPU_IDLE
default y
config RISCV_GP
default y
config SYSCON
default y
endif # SOC_SERIES_NEORV32

View file

@ -0,0 +1,21 @@
# Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
# SPDX-License-Identifier: Apache-2.0
config SOC_SERIES_NEORV32
bool "NEORV32 Processor"
select RISCV
select SOC_FAMILY_RISCV_PRIVILEGE
help
Enable support for the NEORV32 Processor (SoC).
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)

View file

@ -0,0 +1,32 @@
# Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
# SPDX-License-Identifier: Apache-2.0
choice
prompt "NEORV32 Version"
depends on SOC_SERIES_NEORV32
config SOC_NEORV32_V1_6_1
bool "v1.6.1"
# NEORV32 RISC-V ISA A extension implements only LR/SC, not AMO
select ATOMIC_OPERATIONS_C
endchoice
if SOC_SERIES_NEORV32
config SOC_NEORV32_VERSION
hex
default 0x01060100 if SOC_NEORV32_V1_6_1
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 COMPRESSED_ISA
help
Enable this if the NEORV32 CPU implementation supports the RISC-V ISA
"C" extension (Compressed Instructions).
endif # SOC_SERIES_NEORV32

View file

@ -0,0 +1,23 @@
/*
* Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <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 <arch/riscv/common/linker.ld>

View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <toolchain.h>
/* exports */
GTEXT(__reset)
/* imports */
GTEXT(__initialize)
SECTION_FUNC(reset, __reset)
/* Zerorize zero register */
lui x0, 0
/* Disable insterrupts */
csrw mstatus, x0
csrw mie, x0
#ifdef CONFIG_USERSPACE
/* Disable counter access outside M-mode */
csrw mcounteren, x0
#endif /* CONFIG_USERSPACE */
/* Allow mcycle and minstret counters to increment */
li x11, ~5
csrw mcountinhibit, x11
/* Zerorize counters */
csrw mcycle, x0
csrw mcycleh, x0
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

@ -0,0 +1,17 @@
/*
* Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <irq.h>
#include <soc.h>
#if defined(CONFIG_RISCV_SOC_INTERRUPT_INIT)
void soc_interrupt_init(void)
{
(void)irq_lock();
__asm__ volatile ("csrwi mie, 0\n");
}
#endif

View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef RISCV_NEORV32_SOC_H
#define RISCV_NEORV32_SOC_H
#include <soc_common.h>
#include <devicetree.h>
/* Machine System Timer (MTIME) registers */
#define RISCV_MTIME_BASE 0xffffff90U
#define RISCV_MTIMECMP_BASE 0xffffff98U
/* System information (SYSINFO) register offsets */
#define NEORV32_SYSINFO_CLK 0x00U
#define NEORV32_SYSINFO_CPU 0x04U
#define NEORV32_SYSINFO_FEATURES 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) 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)
#endif /* RISCV_NEORV32_SOC_H */

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <toolchain.h>
GTEXT(__soc_handle_irq)
/*
* SOC-specific function to handle pending IRQ number generating the interrupt.
* Exception number is given as parameter via register a0.
*/
SECTION_FUNC(exception.other, __soc_handle_irq)
/*
* The 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 */
jalr x0, ra