Copy-paste Matcha's board and chip folders into sw/matcha, along with minor path tweaks so they compile. Makefile changes will be in the next CL. Change-Id: I9efc93c87353a2feadd8fe75d9a5bd608edbaa26
diff --git a/board/Cargo.toml b/board/Cargo.toml new file mode 100644 index 0000000..414bb3c --- /dev/null +++ b/board/Cargo.toml
@@ -0,0 +1,31 @@ +[package] +name = "opentitan-matcha" +version = "0.1.0" +authors = ["Tock Project Developers <tock-dev@googlegroups.com>"] +build = "build.rs" +edition = "2018" + +[dependencies] +components = { path = "../../tock/boards/components" } +rv32i = { path = "../../tock/arch/rv32i" } +capsules = { path = "../../tock/capsules" } +kernel = { path = "../../tock/kernel" } +matcha = { path = "../chip" } +lowrisc = { path = "../../tock/chips/lowrisc" } +blob_fs = { path = "../../tock/libraries/blob_fs" } + +[features] +# OpenTitan Matcha SoC design can be synthesized or compiled for different targets. A +# target can be a specific FPGA board, an ASIC technology, or a simulation tool. +# Please see: https://docs.opentitan.org/doc/ug/getting_started/ for further +# information. +# +# OpenTitan Matcha CPU and possibly other components must be configured appropriately +# for a specific target: +# - fpga_nexysvideo: +# OpenTitan Matcha SoC design running on Nexys Video Artix-7 FPGA. +# +# - sim_verilator: +# OpenTitan Matcha SoC design simulated in Verilator. +fpga_nexysvideo = ["matcha/config_fpga_nexysvideo"] +sim_verilator = ["matcha/config_sim_verilator"]
diff --git a/board/Makefile b/board/Makefile new file mode 100644 index 0000000..41bc04d --- /dev/null +++ b/board/Makefile
@@ -0,0 +1,34 @@ +# Makefile for building the tock kernel for the OpenTitan Matcha platform + +DEFAULT_BOARD_CONFIGURATION=fpga_nexysvideo +TARGET=riscv32imc-unknown-none-elf +PLATFORM=opentitan-matcha +FLASHID=--dev-id="0403:6010" +RISC_PREFIX = riscv64-elf + + +include Makefile.common + +# Pass OpenTitan board configuration option in `BOARD_CONFIGURATION` through +# Cargo `--features`. Please see `Cargo.toml` for available options. +ifneq ($(BOARD_CONFIGURATION),) + CARGO_FLAGS += --features=$(BOARD_CONFIGURATION) +else + CARGO_FLAGS += --features=$(DEFAULT_BOARD_CONFIGURATION) +endif + +qemu: $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM).elf + $(call check_defined, OPENTITAN_BOOT_ROM) + qemu-system-riscv32 -M opentitan -kernel $^ -bios $(OPENTITAN_BOOT_ROM) -nographic -serial mon:stdio + +qemu-app: $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM).elf + $(call check_defined, OPENTITAN_BOOT_ROM) + qemu-system-riscv32 -M opentitan -kernel $^ -bios $(OPENTITAN_BOOT_ROM) -device loader,file=$(APP),addr=0x20030000 -nographic -serial mon:stdio + +flash: $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM).bin + $(OPENTITAN_TREE)/build-out/sw/host/spiflash/spiflash $(FLASHID) --input=$(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM).bin + +flash-app: $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM).elf + $(RISC_PREFIX)-objcopy --update-section .apps=$(APP) $^ $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM)-app.elf + $(RISC_PREFIX)-objcopy --output-target=binary $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM)-app.elf $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM)-app.bin + $(OPENTITAN_TREE)/build-out/sw/host/spiflash/spiflash $(FLASHID) --input=$(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM)-app.bin
diff --git a/board/Makefile.common b/board/Makefile.common new file mode 100644 index 0000000..6ace79a --- /dev/null +++ b/board/Makefile.common
@@ -0,0 +1,296 @@ +# Force the Shell to be bash as some systems have strange default shells +SHELL := bash + +# Remove built-in rules and variables +# n.b. no-op for make --version < 4.0 +MAKEFLAGS += -r +MAKEFLAGS += -R + +# The absolute path of the directory containing this `Makefile.common` file. +MAKEFILE_COMMON_PATH := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) + +# The absolute path of Tock's root directory. +# This is currently the parent directory of MAKEFILE_COMMON_PATH. +#TOCK_ROOT_DIRECTORY := $(dir $(abspath $(MAKEFILE_COMMON_PATH))) +TOCK_ROOT_DIRECTORY := /usr/local/google/home/aappleby/shodan/sw/tock/ + + +# Common defaults that specific boards can override, but likely do not need to. +TOOLCHAIN ?= llvm +CARGO ?= cargo +RUSTUP ?= rustup + +# Default location of target directory (relative to board makefile) +# passed to cargo --target_dir +TARGET_DIRECTORY ?= $(TOCK_ROOT_DIRECTORY)target/ + +# RUSTC_FLAGS allows boards to define board-specific options. +# This will hopefully move into Cargo.toml (or Cargo.toml.local) eventually. +# lld uses the page size to align program sections. It defaults to 4096 and this +# puts a gap between before the .relocate section. `zmax-page-size=512` tells +# lld the actual page size so it doesn't have to be conservative. +RUSTC_FLAGS ?= \ + -C link-arg=-Tlayout.ld \ + -C linker=rust-lld \ + -C linker-flavor=ld.lld \ + -C relocation-model=dynamic-no-pic \ + -C link-arg=-zmax-page-size=512 \ + -C link-arg=-icf=all \ + +# RISC-V-specific flags. +ifneq ($(findstring riscv32i, $(TARGET)),) + # NOTE: This flag causes kernel panics on some ARM cores. Since the + # size benefit is almost exclusively for RISC-V, we only apply it for + # those targets. + RUSTC_FLAGS += -C force-frame-pointers=no +endif + +# RUSTC_FLAGS_TOCK by default extends RUSTC_FLAGS with options +# that are global to all Tock boards. +# +# We use `remap-path-prefix` to remove user-specific filepath strings for error +# reporting from appearing in the generated binary. +RUSTC_FLAGS_TOCK ?= \ + $(RUSTC_FLAGS) \ + --remap-path-prefix=$(TOCK_ROOT_DIRECTORY)= \ + +# Disallow warnings for continuous integration builds. Disallowing them here +# ensures that warnings during testing won't prevent compilation from succeeding. +ifeq ($(CI),true) + RUSTC_FLAGS_TOCK += -D warnings +endif + +# The following flags should only be passed to the board's binary crate, but +# not to any of its dependencies (the kernel, capsules, chips, etc.). The +# dependencies wouldn't use it, but because the link path is different for each +# board, Cargo wouldn't be able to cache builds of the dependencies. +# +# Indeed, as far as Cargo is concerned, building the kernel with +# `-C link-arg=-L/tock/boards/imix` is different than building the kernel with +# `-C link-arg=-L/tock/boards/hail`, so Cargo would have to rebuild the kernel +# for each board instead of caching it per board (even if in reality the same +# kernel is built because the link-arg isn't used by the kernel). +# +# Ultimately, this should move to the Cargo.toml, for example when +# https://github.com/rust-lang/cargo/pull/7811 is merged into Cargo. +# +# The difference between `RUSTC_FLAGS_TOCK` and `RUSTC_FLAGS_FOR_BIN` is that +# the former is forwarded to all the dependencies (being passed to cargo via +# the `RUSTFLAGS` environment variable), whereas the latter is only applied to +# the final binary crate (being passed as parameter to `cargo rustc`). +RUSTC_FLAGS_FOR_BIN ?= \ + -C link-arg=-L$(abspath .) \ + +# http://stackoverflow.com/questions/10858261/abort-makefile-if-variable-not-set +# Check that given variables are set and all have non-empty values, print an +# error otherwise. +check_defined = $(strip $(foreach 1,$1,$(if $(value $1),,$(error Undefined variable "$1")))) + +# Check that we know the basics of what we are compiling for. +# `PLATFORM`: The name of the board that the kernel is being compiled for. +# `TARGET` : The Rust target architecture the kernel is being compiled for. +$(call check_defined, PLATFORM) +$(call check_defined, TARGET) + +# Location of target-specific build +TARGET_PATH := $(TARGET_DIRECTORY)$(TARGET) + +# If environment variable V is non-empty, be verbose. +ifneq ($(V),) + Q = + VERBOSE = --verbose +else + Q = @ + VERBOSE = +endif + +# Ask git what version of the Tock kernel we are compiling, so we can include +# this within the binary. If Tock is not within a git repo then we fallback to +# a set string which should be updated with every release. +export TOCK_KERNEL_VERSION := $(shell git describe --tags --always 2> /dev/null || echo "1.4+") + +# Validate that rustup is new enough. +MINIMUM_RUSTUP_VERSION := 1.11.0 +RUSTUP_VERSION := $(strip $(word 2, $(shell $(RUSTUP) --version))) +ifeq ($(shell $(TOCK_ROOT_DIRECTORY)tools/semver.sh $(RUSTUP_VERSION) \< $(MINIMUM_RUSTUP_VERSION)), true) + $(warning Required tool `$(RUSTUP)` is out-of-date.) + $(warning Running `$(RUSTUP) update` in 3 seconds (ctrl-c to cancel)) + $(shell sleep 3s) + DUMMY := $(shell $(RUSTUP) update) +endif + +# Verify that various required Rust components are installed. All of these steps +# only have to be done once per Rust version, but will take some time when +# compiling for the first time. +LLVM_TOOLS_INSTALLED := $(shell $(RUSTUP) component list | grep 'llvm-tools-preview.*(installed)' > /dev/null; echo $$?) +ifeq ($(LLVM_TOOLS_INSTALLED),1) + $(shell $(RUSTUP) component add llvm-tools-preview) +endif +ifneq ($(shell $(RUSTUP) component list | grep rust-src),rust-src (installed)) + $(shell $(RUSTUP) component add rust-src) +endif +ifneq ($(shell $(RUSTUP) target list | grep "$(TARGET) (installed)"),$(TARGET) (installed)) + $(shell $(RUSTUP) target add $(TARGET)) +endif + +# If the user is using the standard toolchain we need to get the full path. +# rustup should take care of this for us by putting in a proxy in .cargo/bin, +# but until that is setup we workaround it. +ifeq ($(TOOLCHAIN),llvm) + TOOLCHAIN = "$(shell dirname $(shell find `rustc --print sysroot` -name llvm-size))/llvm" +endif + +# Set variables of the key tools we need to compile a Tock kernel. +SIZE ?= $(TOOLCHAIN)-size +OBJCOPY ?= $(TOOLCHAIN)-objcopy +OBJDUMP ?= $(TOOLCHAIN)-objdump + +# Set additional flags to produce binary from .elf. +# * --strip-sections prevents enormous binaries when SRAM is below flash. +# * --remove-section .apps prevents the .apps section from being included in the +# kernel binary file. This section is a placeholder for optionally including +# application binaries, and only needs to exist in the .elf. By removing it, +# we prevent the kernel binary from overwriting applications. +OBJCOPY_FLAGS ?= --strip-sections -S --remove-section .apps +# This make variable allows board-specific Makefiles to pass down options to +# the Cargo build command. For example, in boards/<custom_board>/Makefile: +# `CARGO_FLAGS += --features=foo` would pass feature `foo` to the top level +# Cargo.toml. +CARGO_FLAGS ?= +# Add default flags to cargo. Boards can add additional options in CARGO_FLAGS +CARGO_FLAGS_TOCK ?= $(VERBOSE) --target=$(TARGET) --package $(PLATFORM) --target-dir=$(TARGET_DIRECTORY) $(CARGO_FLAGS) +# Set the default flags we need for objdump to get a .lst file. +OBJDUMP_FLAGS ?= --disassemble-all --source --section-headers --demangle +# Set default flags for size +SIZE_FLAGS ?= + +# Need an extra flag for OBJDUMP if we are on a thumb platform. +ifneq (,$(findstring thumb,$(TARGET))) + OBJDUMP_FLAGS += --arch-name=thumb +endif + +# Check whether the system already has a sha256sum application +# present, if not use the custom shipped one +ifeq (, $(shell sha256sum --version 2>/dev/null)) + # No system sha256sum available + SHA256SUM := $(CARGO) run --manifest-path $(TOCK_ROOT_DIRECTORY)tools/sha256sum/Cargo.toml -- 2>/dev/null +else + # Use system sha256sum + SHA256SUM := sha256sum +endif + +# Dump configuration for verbose builds +ifneq ($(V),) + $(info ) + $(info *******************************************************) + $(info TOCK KERNEL BUILD SYSTEM -- VERBOSE BUILD CONFIGURATION) + $(info *******************************************************) + $(info MAKEFILE_COMMON_PATH = $(MAKEFILE_COMMON_PATH)) + $(info TOCK_ROOT_DIRECTORY = $(TOCK_ROOT_DIRECTORY)) + $(info TARGET_DIRECTORY = $(TARGET_DIRECTORY)) + $(info ) + $(info PLATFORM = $(PLATFORM)) + $(info TARGET = $(TARGET)) + $(info TOCK_KERNEL_VERSION = $(TOCK_KERNEL_VERSION)) + $(info RUSTC_FLAGS = $(RUSTC_FLAGS)) + $(info RUSTC_FLAGS_TOCK = $(RUSTC_FLAGS_TOCK)) + $(info MAKEFLAGS = $(MAKEFLAGS)) + $(info OBJDUMP_FLAGS = $(OBJDUMP_FLAGS)) + $(info OBJCOPY_FLAGS = $(OBJCOPY_FLAGS)) + $(info CARGO_FLAGS = $(CARGO_FLAGS)) + $(info CARGO_FLAGS_TOCK = $(CARGO_FLAGS_TOCK)) + $(info SIZE_FLAGS = $(SIZE_FLAGS)) + $(info ) + $(info TOOLCHAIN = $(TOOLCHAIN)) + $(info SIZE = $(SIZE)) + $(info OBJCOPY = $(OBJCOPY)) + $(info OBJDUMP = $(OBJDUMP)) + $(info CARGO = $(CARGO)) + $(info RUSTUP = $(RUSTUP)) + $(info SHA256SUM = $(SHA256SUM)) + $(info ) + $(info cargo --version = $(shell $(CARGO) --version)) + $(info rustc --version = $(shell rustc --version)) + $(info rustup --version = $(shell $(RUSTUP) --version)) + $(info *******************************************************) + $(info ) +endif + +.PRECIOUS: %.elf +# Support rules + +# User-facing targets +.PHONY: all +all: release + +# `make check` runs the Rust compiler but does not actually output the final +# binary. This makes checking for Rust errors much faster. +.PHONY: check +check: + $(Q)$(CARGO) check $(VERBOSE) $(CARGO_FLAGS_TOCK) + + +.PHONY: clean +clean:: + $(Q)$(CARGO) clean $(VERBOSE) --target-dir=$(TARGET_DIRECTORY) + +.PHONY: release +release: $(TARGET_PATH)/release/$(PLATFORM).bin + +.PHONY: debug +debug: $(TARGET_PATH)/debug/$(PLATFORM).bin + +.PHONY: debug-lst +debug-lst: $(TARGET_PATH)/debug/$(PLATFORM).lst + +.PHONY: doc +doc: | target + @# This mess is all to work around rustdoc giving no way to return an + @# error if there are warnings. This effectively simulates that. + $(Q)RUSTDOCFLAGS='-Z unstable-options --document-hidden-items -D warnings' $(CARGO) --color=always doc $(VERBOSE) --release --package $(PLATFORM) --target-dir=$(TARGET_DIRECTORY) 2>&1 | tee /dev/tty | grep -q warning && (echo "Warnings detected during doc build" && if [[ $$CI == "true" ]]; then echo "Erroring due to CI context" && exit 33; fi) || if [ $$? -eq 33 ]; then exit 1; fi + + +.PHONY: lst +lst: $(TARGET_PATH)/release/$(PLATFORM).lst + +# Helper rule for showing the TARGET used by this board. Useful when building +# the documentation for all boards. +.PHONY: show-target +show-target: + $(info $(TARGET)) + +# Support rules + +target: + @mkdir -p $(TARGET_PATH) + +# Cargo outputs an elf file (just without a file extension) +%.elf: % + $(Q)cp $< $@ + + +%.bin: %.elf + $(Q)$(OBJCOPY) --output-target=binary $(OBJCOPY_FLAGS) $< $@ + $(Q)$(SHA256SUM) $@ + +%.lst: %.elf + $(Q)$(OBJDUMP) $(OBJDUMP_FLAGS) $< > $@ + + +$(TOCK_ROOT_DIRECTORY)tools/sha256sum/target/debug/sha256sum: + $(Q)$(CARGO) build $(VERBOSE) --manifest-path $(TOCK_ROOT_DIRECTORY)tools/sha256sum/Cargo.toml + + +# Cargo-drivers +# We want to always invoke cargo (yay nested build systems), so these need to +# be phony, which means they can't be pattern rules. + +.PHONY: $(TARGET_PATH)/release/$(PLATFORM) +$(TARGET_PATH)/release/$(PLATFORM): + $(Q)RUSTFLAGS="$(RUSTC_FLAGS_TOCK)" $(CARGO) rustc $(CARGO_FLAGS_TOCK) --bin $(PLATFORM) --release -- $(RUSTC_FLAGS_FOR_BIN) + $(Q)$(SIZE) $(SIZE_FLAGS) $@ + +.PHONY: $(TARGET_PATH)/debug/$(PLATFORM) +$(TARGET_PATH)/debug/$(PLATFORM): + $(Q)RUSTFLAGS="$(RUSTC_FLAGS_TOCK)" $(CARGO) rustc $(CARGO_FLAGS_TOCK) --bin $(PLATFORM) -- $(RUSTC_FLAGS_FOR_BIN) + $(Q)$(SIZE) $(SIZE_FLAGS) $@
diff --git a/board/README.md b/board/README.md new file mode 100644 index 0000000..551991f --- /dev/null +++ b/board/README.md
@@ -0,0 +1,4 @@ +OpenTitan Matcha RISC-V Board +================= + +This is provides board support for the Matcha config of OpenTitan. \ No newline at end of file
diff --git a/board/build.rs b/board/build.rs new file mode 100644 index 0000000..ab031c3 --- /dev/null +++ b/board/build.rs
@@ -0,0 +1,4 @@ +fn main() { + println!("cargo:rerun-if-changed=layout.ld"); + println!("cargo:rerun-if-changed=../../../tock/boards/kernel_layout.ld"); +}
diff --git a/board/kernel_layout.ld b/board/kernel_layout.ld new file mode 100644 index 0000000..d11d311 --- /dev/null +++ b/board/kernel_layout.ld
@@ -0,0 +1,337 @@ +/* + * This is the generic linker script for Tock. For most developers, it should + * be sufficient to define {ROM/PROG/RAM}_{ORIGIN/LENGTH} (6 variables, the + * start and length for each), MPU_MIN_ALIGN (the minimum alignment + * granularity supported by the MPU) and PAGE_SIZE (the size of a flash page). + * If undefined, PAGE_SIZE uses the default value of 512 bytes. + * + * -------------------------------------------------------------------------- + * + * If you wish to create your own linker script from scratch, you must define + * the following symbols: + * + * `_etext`, `_srelocate`, `_erelocate` + * The `_etext` symbol marks the end of data stored in flash that should + * stay in flash. `_srelocate` and `_erelocate` mark the address range in + * SRAM that mutable program data is copied to. + * + * Tock will copy `_erelocate` - `_srelocate` bytes of data from the + * `_etext` pointer to the `_srelocate` pointer. + * + * `_szero`, `_ezero` + * + * The `_szero` and `_ezero` symbols define the range of the BSS, SRAM that + * Tock will zero on boot. + * + * `_sapps`, `_eapps` + * + * The `_sapps` symbol marks the beginning of application memory in flash. + * The `_eapps` symbol marks the end of application memory in flash by + * pointing to next address after application flash. + * + * `_sappmem`, `_eappmem` + * + * The `_sappmem` symbol marks the beginning of application memory in RAM. + * The `_eappmem` symbol marks the end of application memory in RAM by + * pointing to next address after application RAM. + */ + +PAGE_SIZE = DEFINED(PAGE_SIZE) ? PAGE_SIZE : 512; + +SECTIONS +{ + .stack (NOLOAD) : + { + /* Kernel stack. + * + * Tock places the kernel stack at the bottom of SRAM so that the + * kernel will trigger memory fault if it exceeds its stack depth, + * rather than silently overwriting valuable data. + */ + . = ALIGN(8); + _sstack = .; + + /* For GNU LD, we can just advance the location pointer (".") here to + * reserve space for the stack. That, however, doesn't seem to work + * for LLVM LLD. The resulting ELF has a stack section that shows the + * correct size, but the next section (in our case .relocate) is not + * moved down as well, instead it sits at the same address as .stack. + * To work around this, we declare a dummy buffer and then insert it + * here in the .stack section. This sets the stack size correctly and + * places the .relocate section at the correct address. */ + KEEP(*(.stack_buffer)) + /*. = . + 0x1000;*/ /*This is the original method. */ + + . = ALIGN(8); + _estack = .; + } > ram + + + /* STATIC ELEMENTS FOR TOCK KERNEL */ + .text : + { + . = ALIGN(4); + _textstart = .; /* Symbol expected by some MS build toolchains */ + _stext = .; /* First of standard s,e (start/end) pair */ + + /* Place vector table at the beginning of ROM. + * + * The first 16 entries in the ARM vector table are defined by ARM and + * are common among all ARM chips. The remaining entries are + * chip-specific, which Tock defines in a separate .irqs section + * + * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/BABIFJFG.html + */ + KEEP(*(.vectors .vectors.*)) + KEEP(*(.irqs)) + + /* RISC-V + * There is no vector table in RISCV, so .vectors and .irqs will be + * empty. Instead, the _start function needs to be first in the binary + * for it to correctly be executed. We also need to include the trap + * handler assembly function. + * + * These are expected to just be empty on other platforms so they + * shouldn't have any effect. + */ + KEEP(*(.riscv.start)); + /* For RISC-V we need the `_start_trap` function to be 256 byte aligned, + * and that function is at the start of the .riscv.trap section. If that + * function does not exist (as for non-RISC-V platforms) then we do not + * need any unusual alignment. + * The allignment is implementation specific, so we currently use 256 to + * work with the lowRISC CPUs. + */ + . = DEFINED(_start_trap) ? ALIGN(256) : ALIGN(1); + KEEP(*(.riscv.trap_vectored)); + KEEP(*(.riscv.trap)); + + /* .text and .rodata hold most program code and immutable constants */ + /* .gnu.linkonce hold C++ elements with vague linkage + https://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html */ + *(.text .text.* .gnu.linkonce.t.*) + *(.rodata .rodata.* .gnu.linkonce.r.*) + + /* C++ exception unwinding information */ + *(.ARM.extab* .gnu.linkonce.armextab.*) + + /* glue_7 and glue_7t hold helper functions emitted by the compiler to + support interworking (linking between functions in ARM and THUMB + mode). Note that Cortex-M's do not support ARM mode, but this is left + here to save someone headache if they ever attempt to port Tock to a + Cortex-A core. */ + *(.glue_7t) *(.glue_7) + + + /* Constructor and destructor sections: + + - init/fini + Defined by ELF as sections that hold `process + initialization/termination code` + - {pre}{init/fini}_array_{start/end} + Symbols used by the C runtime for initialization / termination + - ctors/dtors + Symbols used by the C++ runtime for initialization / termination + */ + . = ALIGN(4); + KEEP(*(.init)) + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + /* End constructor/destructor */ + } > rom + + + /* ARM Exception support + * + * This contains compiler-generated support for unwinding the stack, + * consisting of key-value pairs of function addresses and information on + * how to unwind stack frames. + * https://wiki.linaro.org/KenWerner/Sandbox/libunwind?action=AttachFile&do=get&target=libunwind-LDS.pdf + * + * .ARM.exidx is sorted, so has to go in its own output section. + */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + /* (C++) Index entries for section unwinding */ + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > rom + PROVIDE_HIDDEN (__exidx_end = .); + + /* Region for on-chip kernel non-volatile storage. + * + * Align on PAGE_SIZE number of bytes. Volumes within this region are + * allocated with the storage_volume! macro in utils.rs. + */ + .storage : + { + . = ALIGN(PAGE_SIZE); + _sstorage = .; + *(.storage* storage*) + _estorage = .; + . = ALIGN(PAGE_SIZE); + } > rom + . = ALIGN(PAGE_SIZE); + + /* Mark the end of static elements */ + . = ALIGN(4); + _etext = .; + _textend = .; /* alias for _etext expected by some MS toolchains */ + + + /* Customer configuration is most often located at the end of the rom. It is + * conditional, and won't be written if not specified in the board specific + * linker file. + */ + .ccfg : { + KEEP(*(.ccfg)) + } > ccfg + + + /* Section for application binaries in flash. + * + * This section is put into the "prog" memory, which is reserved for + * applications. This section is not used for the kernel, but including it + * in the .elf file allows for concatenating application binaries with the + * kernel. + */ + .apps : + { + /* _sapps symbol used by Tock to look for first application. */ + . = ALIGN(4); + _sapps = .; + + /* Include a placeholder byte in this section so that the linker + * includes a segment for it. Otherwise the section will be empty and + * the linker will ignore it when defining the segments. + */ + BYTE(0) + } > prog + /* _eapps symbol used by tock to calculate the length of app flash */ + _eapps = _sapps + LENGTH(prog); + + + + + + + + /* Kernel data that must be relocated. This is program data that is + * expected to live in SRAM, but is initialized with a value. This data is + * physically placed into flash and is copied into SRAM by Tock. The + * symbols here will be defined with addresses in SRAM. + * + * Tock assumes the relocation section follows all static elements and will + * copy (_erelocate - _srelocate) bytes from _etext to _srelocate. + */ + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + + /* The Global Pointer is used by the RISC-V architecture to provide + * "gp-relative" addressing. The global pointer is set to the gp + * register once on boot, and the linker can then take advantage of this + * when emitting instructions by using offsets relative to this known + * value. Since RISC-V has only 12 bit immediates, this can help reduce + * code size. + * + * The standard is to set the global pointer to 0x800 past the beginning + * of the data section in RAM. This allows instructions to use 12 bit + * immediates to access the first 4KB of data memory. In theory the GP + * can be set to any value, but it should be placed near actual data for + * the compiler to actually be able to use it. + * + * Per convention, the variable _must_ be called __global_pointer$ for + * the linker to actually take advantage of it. + */ + PROVIDE(__global_pointer$ = . + 0x800); + + *(.ramfunc .ramfunc.*); + *(.sdata .sdata.* .gnu.linkonce.r.*) + *(.data .data.*); + + . = ALIGN(4); + _erelocate = .; + } > ram + + + .sram (NOLOAD) : + { + /* Kernel BSS section. Memory that is expected to be initialized to + * zero. + * + * Elements in this section do not contribute to the binary size. Tock + * initialization will write zeros to the memory between _szero and + * _ezero. + * + * Elements placed in the .bss and .COMMON sections are simply used to + * measure amount of memory to zero out. + */ + . = ALIGN(4); + _szero = .; + + /* In addition to the traditional .bss section, RISC-V splits out a "small data" section + * see: https://github.com/riscv/riscv-pk/blob/a3e4ac61d2b1ff37a22b9193b85d3b94273e80cb/pk/pk.lds#L84 + */ + *(.sbss .sbss.* .bss .bss.*); + *(COMMON) + + . = ALIGN(4); + _ezero = .; + + + + /* Application Memory. + * + * Tock uses the remainder of SRAM for application memory. + * + * Currently, Tock allocates a fixed array of application memories at + * compile-time, and that array is simply placed here. A possible + * future enhancement may allow the kernel to parcel this memory space + * dynamically, requiring changes to this section. + */ + . = ALIGN(MPU_MIN_ALIGN); + _sappmem = .; + *(.app_memory) + } > ram + _eappmem = ORIGIN(ram) + LENGTH(ram); + + /* Discard RISC-V relevant .eh_frame, we are not doing unwind on panic + so it is not needed. */ + /DISCARD/ : + { + *(.eh_frame); + } +} + +ASSERT((_etext-_stext) + (_erelocate-_srelocate) < LENGTH(rom), " +Text plus relocations exceeds the available ROM space.");
diff --git a/board/layout.ld b/board/layout.ld new file mode 100644 index 0000000..4ef628e --- /dev/null +++ b/board/layout.ld
@@ -0,0 +1,25 @@ +MEMORY +{ + /* + For debugging, use 8M rom, 8M prog, 16M ram. + */ + rom (rx) : ORIGIN = 0x20000000, LENGTH = 0x0800000 + prog (rx) : ORIGIN = 0x20800000, LENGTH = 0x0800000 + ram (!rx) : ORIGIN = 0x10000000, LENGTH = 0x1000000 +} + +MPU_MIN_ALIGN = 1K; +SECTIONS { + /* + * The flash header needs to match what the boot ROM for OpenTitan is + * expecting. At the moment, it contains only the entry point, but it + * will eventually contain the signature -- and (hopefully?!) some + * versioning information to make it slightly easier to debug when the + * boot ROM and Tock are out of sync with respect to the definition... + */ + .flash_header : { + LONG(_stext) + } > rom +} + +INCLUDE kernel_layout.ld
diff --git a/board/rust-toolchain b/board/rust-toolchain new file mode 100644 index 0000000..b18a3f3 --- /dev/null +++ b/board/rust-toolchain
@@ -0,0 +1 @@ +nightly-2020-06-03
diff --git a/board/src/io.rs b/board/src/io.rs new file mode 100644 index 0000000..2439aec --- /dev/null +++ b/board/src/io.rs
@@ -0,0 +1,50 @@ +use core::fmt::Write; +use core::panic::PanicInfo; +use core::str; +use kernel::debug; +use kernel::debug::IoWrite; +use kernel::hil::gpio; +use kernel::hil::led; + +use crate::CHIP; +use crate::PROCESSES; + +struct Writer {} + +static mut WRITER: Writer = Writer {}; + +impl Write for Writer { + fn write_str(&mut self, s: &str) -> ::core::fmt::Result { + self.write(s.as_bytes()); + Ok(()) + } +} + +impl IoWrite for Writer { + fn write(&mut self, buf: &[u8]) { + unsafe { + matcha::uart::UART0.transmit_sync(buf); + } + } +} + +/// Panic handler. +#[cfg(not(test))] +#[no_mangle] +#[panic_handler] +pub unsafe extern "C" fn panic_fmt(pi: &PanicInfo) -> ! { + // turn off the non panic leds, just in case + let first_led = &mut led::LedLow::new(&mut matcha::gpio::PORT[7]); + gpio::Pin::make_output(&matcha::gpio::PORT[7]); + + let writer = &mut WRITER; + + debug::panic( + &mut [first_led], + writer, + pi, + &rv32i::support::nop, + &PROCESSES, + &CHIP, + ) +}
diff --git a/board/src/main.rs b/board/src/main.rs new file mode 100644 index 0000000..7a82465 --- /dev/null +++ b/board/src/main.rs
@@ -0,0 +1,332 @@ +//! Board file for LowRISC OpenTitan Matcha RISC-V development platform. +//! +//! - <https://opentitan.org/> + +#![no_std] +// Disable this attribute when documenting, as a workaround for +// https://github.com/rust-lang/rust/issues/62184. +#![cfg_attr(not(doc), no_main)] +#![feature(const_in_array_repeat_expressions)] + +use capsules::debug_uart::DebugUart; +use capsules::virtual_alarm::{MuxAlarm, VirtualMuxAlarm}; +use capsules::virtual_hmac::VirtualMuxHmac; +use kernel::capabilities; +use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferredCallClientState}; +use kernel::common::registers::{ReadOnly, WriteOnly}; +use kernel::common::StaticRef; +use kernel::component::Component; +use kernel::hil; +use kernel::hil::i2c::I2CMaster; +use kernel::hil::time::Alarm; +use kernel::Chip; +use kernel::Platform; +use kernel::{create_capability, debug, static_init}; +use rv32i::csr; + +pub mod io; + +// +// Actual memory for holding the active process structures. Need an empty list +// at least. +static mut PROCESSES: [Option<&'static dyn kernel::procs::ProcessType>; 4] = + [None, None, None, None]; + +static mut CHIP: Option< + &'static matcha::chip::Matcha<VirtualMuxAlarm<'static, matcha::timer::RvTimer>>, +> = None; + +// How should the kernel respond when a process faults. +const FAULT_RESPONSE: kernel::procs::FaultResponse = kernel::procs::FaultResponse::Panic; + +/// Dummy buffer that causes the linker to reserve enough space for the stack. +/// Must be at least 16k in debug builds (@aappleby - not sure why, what's so large?) +#[no_mangle] +#[link_section = ".stack_buffer"] +pub static mut STACK_MEMORY: [u8; 0x4000] = [0; 0x4000]; + +/// A structure representing this platform that holds references to all +/// capsules for this platform. We've included an alarm and console. +struct OpenTitan { + led: &'static capsules::led::LED<'static, matcha::gpio::GpioPin<'static>>, + gpio: &'static capsules::gpio::GPIO<'static, matcha::gpio::GpioPin<'static>>, + console: &'static capsules::console::Console<'static>, + alarm: &'static capsules::alarm::AlarmDriver< + 'static, + VirtualMuxAlarm<'static, matcha::timer::RvTimer<'static>>, + >, + hmac: &'static capsules::hmac::HmacDriver< + 'static, + VirtualMuxHmac<'static, lowrisc::hmac::Hmac<'static>, [u8; 32]>, + [u8; 32], + >, + lldb: &'static capsules::low_level_debug::LowLevelDebug< + 'static, + capsules::virtual_uart::UartDevice<'static>, + >, + i2c_master: &'static capsules::i2c_master::I2CMasterDriver<lowrisc::i2c::I2c<'static>>, + debug_uart: &'static DebugUart, + storage_manager: &'static capsules::storage_manager::StorageManager, +} + +/// Mapping of integer syscalls to objects that implement syscalls. +impl Platform for OpenTitan { + fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R + where + F: FnOnce(Option<&dyn kernel::Driver>) -> R, + { + match driver_num { + capsules::led::DRIVER_NUM => f(Some(self.led)), + capsules::hmac::DRIVER_NUM => f(Some(self.hmac)), + capsules::gpio::DRIVER_NUM => f(Some(self.gpio)), + capsules::console::DRIVER_NUM => f(Some(self.console)), + capsules::alarm::DRIVER_NUM => f(Some(self.alarm)), + capsules::low_level_debug::DRIVER_NUM => f(Some(self.lldb)), + capsules::i2c_master::DRIVER_NUM => f(Some(self.i2c_master)), + capsules::debug_uart::DRIVER_NUM => f(Some(self.debug_uart)), + capsules::storage_manager::DRIVER_NUM => f(Some(self.storage_manager)), + _ => f(None), + } + } +} + +/// Reset Handler. +/// +/// This function is called from the arch crate after some very basic RISC-V +/// setup. +#[no_mangle] +pub unsafe fn reset_handler() { + // Basic setup of the platform. + rv32i::init_memory(); + // Ibex-specific handler + matcha::chip::configure_trap_handler(); + + // initialize capabilities + let process_mgmt_cap = create_capability!(capabilities::ProcessManagementCapability); + let memory_allocation_cap = create_capability!(capabilities::MemoryAllocationCapability); + + let main_loop_cap = create_capability!(capabilities::MainLoopCapability); + + let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(&PROCESSES)); + + let dynamic_deferred_call_clients = + static_init!([DynamicDeferredCallClientState; 1], Default::default()); + let dynamic_deferred_caller = static_init!( + DynamicDeferredCall, + DynamicDeferredCall::new(dynamic_deferred_call_clients) + ); + DynamicDeferredCall::set_global_instance(dynamic_deferred_caller); + + // Configure kernel debug gpios as early as possible + kernel::debug::assign_gpios( + Some(&matcha::gpio::PORT[7]), // First LED + None, + None, + ); + + // Create a shared UART channel for the console and for kernel debug. + let uart_mux = components::console::UartMuxComponent::new( + &matcha::uart::UART0, + matcha::uart::UART0_BAUDRATE, + dynamic_deferred_caller, + ) + .finalize(()); + + // LEDs + // Start with half on and half off + let led = components::led::LedsComponent::new(components::led_component_helper!( + matcha::gpio::GpioPin, + ( + &matcha::gpio::PORT[8], + kernel::hil::gpio::ActivationMode::ActiveHigh + ), + ( + &matcha::gpio::PORT[9], + kernel::hil::gpio::ActivationMode::ActiveHigh + ), + ( + &matcha::gpio::PORT[10], + kernel::hil::gpio::ActivationMode::ActiveHigh + ), + ( + &matcha::gpio::PORT[11], + kernel::hil::gpio::ActivationMode::ActiveHigh + ), + ( + &matcha::gpio::PORT[12], + kernel::hil::gpio::ActivationMode::ActiveHigh + ), + ( + &matcha::gpio::PORT[13], + kernel::hil::gpio::ActivationMode::ActiveHigh + ), + ( + &matcha::gpio::PORT[14], + kernel::hil::gpio::ActivationMode::ActiveHigh + ), + ( + &matcha::gpio::PORT[15], + kernel::hil::gpio::ActivationMode::ActiveHigh + ) + )) + .finalize(components::led_component_buf!(matcha::gpio::GpioPin)); + + let gpio = components::gpio::GpioComponent::new( + board_kernel, + components::gpio_component_helper!( + matcha::gpio::GpioPin, + 0 => &matcha::gpio::PORT[0], + 1 => &matcha::gpio::PORT[1], + 2 => &matcha::gpio::PORT[2], + 3 => &matcha::gpio::PORT[3], + 4 => &matcha::gpio::PORT[4], + 5 => &matcha::gpio::PORT[5], + 6 => &matcha::gpio::PORT[6], + 7 => &matcha::gpio::PORT[15] + ), + ) + .finalize(components::gpio_component_buf!(matcha::gpio::GpioPin)); + + let alarm = &matcha::timer::TIMER; + alarm.setup(); + + // Create a shared virtualization mux layer on top of a single hardware + // alarm. + let mux_alarm = static_init!( + MuxAlarm<'static, matcha::timer::RvTimer>, + MuxAlarm::new(alarm) + ); + hil::time::Alarm::set_alarm_client(&matcha::timer::TIMER, mux_alarm); + + // Alarm + let virtual_alarm_user = static_init!( + VirtualMuxAlarm<'static, matcha::timer::RvTimer>, + VirtualMuxAlarm::new(mux_alarm) + ); + let scheduler_timer_virtual_alarm = static_init!( + VirtualMuxAlarm<'static, matcha::timer::RvTimer>, + VirtualMuxAlarm::new(mux_alarm) + ); + let alarm = static_init!( + capsules::alarm::AlarmDriver<'static, VirtualMuxAlarm<'static, matcha::timer::RvTimer>>, + capsules::alarm::AlarmDriver::new( + virtual_alarm_user, + board_kernel.create_grant(&memory_allocation_cap) + ) + ); + hil::time::Alarm::set_alarm_client(virtual_alarm_user, alarm); + + let chip = static_init!( + matcha::chip::Matcha<VirtualMuxAlarm<'static, matcha::timer::RvTimer>>, + matcha::chip::Matcha::new(scheduler_timer_virtual_alarm) + ); + scheduler_timer_virtual_alarm.set_alarm_client(chip.scheduler_timer()); + CHIP = Some(chip); + + // Need to enable all interrupts for Tock Kernel + chip.enable_plic_interrupts(); + // enable interrupts globally + csr::CSR + .mie + .modify(csr::mie::mie::msoft::SET + csr::mie::mie::mtimer::SET + csr::mie::mie::mext::SET); + csr::CSR.mstatus.modify(csr::mstatus::mstatus::mie::SET); + + // Setup the console. + let console = components::console::ConsoleComponent::new(board_kernel, uart_mux).finalize(()); + // Create the debugger object that handles calls to `debug!()`. + components::debug_writer::DebugWriterComponent::new(uart_mux).finalize(()); + + let lldb = components::lldb::LowLevelDebugComponent::new(board_kernel, uart_mux).finalize(()); + + let hmac_data_buffer = static_init!([u8; 64], [0; 64]); + let hmac_dest_buffer = static_init!([u8; 32], [0; 32]); + + let mux_hmac = components::hmac::HmacMuxComponent::new(&matcha::hmac::HMAC).finalize( + components::hmac_mux_component_helper!(lowrisc::hmac::Hmac, [u8; 32]), + ); + + let hmac = components::hmac::HmacComponent::new( + board_kernel, + &mux_hmac, + hmac_data_buffer, + hmac_dest_buffer, + ) + .finalize(components::hmac_component_helper!( + lowrisc::hmac::Hmac, + [u8; 32] + )); + + let i2c_master = static_init!( + capsules::i2c_master::I2CMasterDriver<lowrisc::i2c::I2c<'static>>, + capsules::i2c_master::I2CMasterDriver::new( + &matcha::i2c::I2C, + &mut capsules::i2c_master::BUF, + board_kernel.create_grant(&memory_allocation_cap) + ) + ); + + matcha::i2c::I2C.set_master_client(i2c_master); + + let debug_uart = static_init!( + DebugUart, + DebugUart { + tx_busy: StaticRef::new(0x4000_0010 as *const ReadOnly<u32>), + tx_port: StaticRef::new(0x4000_0018 as *const WriteOnly<u32>), + app_data_grant: board_kernel.create_grant(&memory_allocation_cap) + } + ); + + /// These symbols are defined in the linker script. + extern "C" { + /// Beginning of the ROM region containing app images. + static _sapps: u8; + /// End of the ROM region containing app images. + static _eapps: u8; + /// Beginning of the RAM region for app memory. + static mut _sappmem: u8; + /// End of the RAM region for app memory. + static _eappmem: u8; + } + + let storage_manager = static_init!( + capsules::storage_manager::StorageManager, + capsules::storage_manager::StorageManager::new(board_kernel.create_grant(&memory_allocation_cap)) + ); + + let opentitan = OpenTitan { + gpio: gpio, + led: led, + console: console, + alarm: alarm, + hmac, + lldb: lldb, + i2c_master, + debug_uart: debug_uart, + storage_manager: storage_manager, + }; + + kernel::procs::load_processes( + board_kernel, + chip, + core::slice::from_raw_parts( + &_sapps as *const u8, + &_eapps as *const u8 as usize - &_sapps as *const u8 as usize, + ), + core::slice::from_raw_parts_mut( + &mut _sappmem as *mut u8, + &_eappmem as *const u8 as usize - &_sappmem as *const u8 as usize, + ), + &mut PROCESSES, + FAULT_RESPONSE, + &process_mgmt_cap, + ) + .unwrap_or_else(|err| { + debug!("Error loading processes!"); + debug!("{:?}", err); + }); + debug!("OpenTitan initialisation complete. Entering main loop"); + debug!("Woo Tock!"); + + let scheduler = components::sched::priority::PriorityComponent::new(board_kernel).finalize(()); + board_kernel.kernel_loop(&opentitan, chip, None, scheduler, &main_loop_cap); +}
diff --git a/chip/Cargo.toml b/chip/Cargo.toml new file mode 100644 index 0000000..b55a931 --- /dev/null +++ b/chip/Cargo.toml
@@ -0,0 +1,18 @@ +[package] +name = "matcha" +version = "0.1.0" +authors = ["Tock Project Developers <tock-dev@googlegroups.com>"] +edition = "2018" + +[features] +# Compiling this crate requires enabling one of these features, otherwise +# the default will be chosen. +config_fpga_nexysvideo = ["config_disable_default"] +config_sim_verilator = ["config_disable_default"] +config_disable_default = [] + +[dependencies] +lowrisc = { path = "../../tock/chips/lowrisc" } +rv32i = { path = "../../tock/arch/rv32i" } +kernel = { path = "../../tock/kernel" } +
diff --git a/chip/README.md b/chip/README.md new file mode 100644 index 0000000..b5b6a4c --- /dev/null +++ b/chip/README.md
@@ -0,0 +1,4 @@ +OpenTitan Matcha SoC +======================= +Matcha is the dual-hart OpenTitan system. At the center of the Matcha are two +Ibex RISC-V compliant processors. \ No newline at end of file
diff --git a/chip/src/aes.rs b/chip/src/aes.rs new file mode 100644 index 0000000..7ab4bf9 --- /dev/null +++ b/chip/src/aes.rs
@@ -0,0 +1,350 @@ +//! Support for the AES hardware block on OpenTitan +//! +//! https://docs.opentitan.org/hw/ip/aes/doc/ + +use kernel::common::cells::{OptionalCell, TakeCell}; +use kernel::common::registers::{ + register_bitfields, register_structs, ReadOnly, ReadWrite, WriteOnly, +}; +use kernel::common::StaticRef; +use kernel::debug; +use kernel::hil; +use kernel::hil::symmetric_encryption; +use kernel::hil::symmetric_encryption::{AES128_BLOCK_SIZE, AES128_KEY_SIZE}; +use kernel::ReturnCode; + +const MAX_LENGTH: usize = 128; + +register_structs! { + pub AesRegisters { + (0x00 => key0: WriteOnly<u32>), + (0x04 => key1: WriteOnly<u32>), + (0x08 => key2: WriteOnly<u32>), + (0x0c => key3: WriteOnly<u32>), + (0x10 => key4: WriteOnly<u32>), + (0x14 => key5: WriteOnly<u32>), + (0x18 => key6: WriteOnly<u32>), + (0x1c => key7: WriteOnly<u32>), + (0x20 => data_in0: WriteOnly<u32>), + (0x24 => data_in1: WriteOnly<u32>), + (0x28 => data_in2: WriteOnly<u32>), + (0x2c => data_in3: WriteOnly<u32>), + (0x30 => data_out0: ReadOnly<u32>), + (0x34 => data_out1: ReadOnly<u32>), + (0x38 => data_out2: ReadOnly<u32>), + (0x3c => data_out3: ReadOnly<u32>), + (0x40 => ctrl: ReadWrite<u32, CTRL::Register>), + (0x44 => trigger: WriteOnly<u32, TRIGGER::Register>), + (0x48 => status: ReadOnly<u32, STATUS::Register>), + (0x4c => @END), + } +} + +register_bitfields![u32, + CTRL [ + OPERATION OFFSET(0) NUMBITS(1) [ + Encrypting = 0, + Decrypting = 1 + ], + KEY_LEN OFFSET(1) NUMBITS(3) [ + Key128 = 1, + Key192 = 2, + Key256 = 4 + ], + MANUAL_OPERATION OFFSET(4) NUMBITS(1) [] + ], + TRIGGER [ + START OFFSET(0) NUMBITS(1) [], + KEY_CLEAR OFFSET(1) NUMBITS(1) [], + DATA_IN_CLEAR OFFSET(2) NUMBITS(1) [], + DATA_OUT_CLEAR OFFSET(3) NUMBITS(1) [] + ], + STATUS [ + IDLE 0, + STALL 1, + OUTPUT_VALID 2, + INPUT_READY 3 + ] +]; + +// https://docs.opentitan.org/hw/top_earlgrey/doc/ +const AES_BASE: StaticRef<AesRegisters> = + unsafe { StaticRef::new(0x41100000 as *const AesRegisters) }; + +pub struct Aes<'a> { + registers: StaticRef<AesRegisters>, + + client: OptionalCell<&'a dyn hil::symmetric_encryption::Client<'a>>, + source: TakeCell<'a, [u8]>, + dest: TakeCell<'a, [u8]>, +} + +impl<'a> Aes<'a> { + const fn new() -> Aes<'a> { + Aes { + registers: AES_BASE, + client: OptionalCell::empty(), + source: TakeCell::empty(), + dest: TakeCell::empty(), + } + } + + fn clear(&self) { + let regs = self.registers; + regs.trigger.write( + TRIGGER::KEY_CLEAR::SET + TRIGGER::DATA_IN_CLEAR::SET + TRIGGER::DATA_OUT_CLEAR::SET, + ); + } + + fn configure(&self, encrypting: bool) { + let regs = self.registers; + let e = if encrypting { + CTRL::OPERATION::Encrypting + } else { + CTRL::OPERATION::Decrypting + }; + // Set this in manual mode for the moment since automatic block mode + // does not appear to be working + + regs.ctrl + .write(e + CTRL::KEY_LEN::Key128 + CTRL::MANUAL_OPERATION::SET); + } + + fn idle(&self) -> bool { + let regs = self.registers; + regs.status.is_set(STATUS::IDLE) + } + + fn input_ready(&self) -> bool { + let regs = self.registers; + regs.status.is_set(STATUS::INPUT_READY) + } + + fn output_valid(&self) -> bool { + let regs = self.registers; + regs.status.is_set(STATUS::OUTPUT_VALID) + } + + fn trigger(&self) { + let regs = self.registers; + regs.trigger.write(TRIGGER::START::SET); + } + + fn read_block(&self, blocknum: usize) { + let regs = self.registers; + let blocknum = blocknum * AES128_BLOCK_SIZE; + + loop { + if self.output_valid() { + break; + } + } + + self.dest.map_or_else( + || { + debug!("Called read_block() with no data"); + }, + |dest| { + for i in 0..4 { + // we work off an array of u8 so we need to assemble those + // back into a u32 + let mut v = 0; + match i { + 0 => v = regs.data_out0.get(), + 1 => v = regs.data_out1.get(), + 2 => v = regs.data_out2.get(), + 3 => v = regs.data_out3.get(), + _ => {} + } + dest[blocknum + (i * 4) + 0] = (v >> 0) as u8; + dest[blocknum + (i * 4) + 1] = (v >> 8) as u8; + dest[blocknum + (i * 4) + 2] = (v >> 16) as u8; + dest[blocknum + (i * 4) + 3] = (v >> 24) as u8; + } + }, + ); + } + + fn write_block(&self, blocknum: usize) { + let regs = self.registers; + let blocknum = blocknum * AES128_BLOCK_SIZE; + + loop { + if self.input_ready() { + break; + } + } + + self.source.map_or_else( + || { + // This is the case that dest = source + self.dest.map_or_else( + || { + debug!("Called write_block() with no data"); + }, + |dest| { + for i in 0..4 { + // we work off an array of u8 so we need to + // assemble those back into a u32 + let mut v = dest[blocknum + (i * 4) + 0] as usize; + v |= (dest[blocknum + (i * 4) + 1] as usize) << 8; + v |= (dest[blocknum + (i * 4) + 2] as usize) << 16; + v |= (dest[blocknum + (i * 4) + 3] as usize) << 24; + match i { + 0 => regs.data_in0.set(v as u32), + 1 => regs.data_in1.set(v as u32), + 2 => regs.data_in2.set(v as u32), + 3 => regs.data_in3.set(v as u32), + _ => {} + } + } + }, + ) + }, + |source| { + for i in 0..4 { + // we work off an array of u8 so we need to assemble + // those back into a u32 + let mut v = source[blocknum + (i * 4) + 0] as usize; + v |= (source[blocknum + (i * 4) + 1] as usize) << 8; + v |= (source[blocknum + (i * 4) + 2] as usize) << 16; + v |= (source[blocknum + (i * 4) + 3] as usize) << 24; + match i { + 0 => regs.data_in0.set(v as u32), + 1 => regs.data_in1.set(v as u32), + 2 => regs.data_in2.set(v as u32), + 3 => regs.data_in3.set(v as u32), + _ => {} + } + } + }, + ); + } + + fn set_key(&self, key: &[u8]) -> ReturnCode { + let regs = self.registers; + + loop { + if self.idle() { + break; + } + } + + if key.len() != AES128_KEY_SIZE { + return ReturnCode::EINVAL; + } + + for i in 0..4 { + let mut k = key[i * 4 + 0] as usize; + k |= (key[i * 4 + 1] as usize) << 8; + k |= (key[i * 4 + 2] as usize) << 16; + k |= (key[i * 4 + 3] as usize) << 24; + match i { + 0 => regs.key0.set(k as u32), + 1 => regs.key1.set(k as u32), + 2 => regs.key2.set(k as u32), + 3 => regs.key3.set(k as u32), + _ => {} + } + } + + // We must write the rest of the registers as well + regs.key4.set(0); + regs.key5.set(0); + regs.key6.set(0); + regs.key7.set(0); + ReturnCode::SUCCESS + } + + fn do_crypt(&self, start_index: usize, stop_index: usize, wr_start_index: usize) { + // convert our indicies into the array into block numbers + // start and end are pointer for reading + // write is the pointer for writing + // Note that depending on whether or not we have separate source + // and dest buffers the write and read pointers may index into + // different arrays. + let start_block = start_index / AES128_BLOCK_SIZE; + let end_block = stop_index / AES128_BLOCK_SIZE; + let mut write_block = wr_start_index / AES128_BLOCK_SIZE; + for i in start_block..end_block { + self.write_block(write_block); + self.trigger(); + self.read_block(i); + write_block = write_block + 1; + } + } +} + +impl<'a> hil::symmetric_encryption::AES128<'a> for Aes<'a> { + fn enable(&self) { + self.configure(true); + } + + fn disable(&self) { + self.clear(); + } + + fn set_client(&'a self, client: &'a dyn symmetric_encryption::Client<'a>) { + self.client.set(client); + } + + fn set_iv(&self, _iv: &[u8]) -> ReturnCode { + // nothing because this is ECB + ReturnCode::SUCCESS + } + + fn start_message(&self) {} + + fn set_key(&self, key: &[u8]) -> ReturnCode { + self.set_key(key) + } + + fn crypt( + &'a self, + source: Option<&'a mut [u8]>, + dest: &'a mut [u8], + start_index: usize, + stop_index: usize, + ) -> Option<(ReturnCode, Option<&'a mut [u8]>, &'a mut [u8])> { + match stop_index.checked_sub(start_index) { + None => return Some((ReturnCode::EINVAL, source, dest)), + Some(s) => { + if s > MAX_LENGTH { + return Some((ReturnCode::EINVAL, source, dest)); + } + if s % AES128_BLOCK_SIZE != 0 { + return Some((ReturnCode::EINVAL, source, dest)); + } + } + } + self.dest.replace(dest); + // The crypt API has two cases: separate source and destination + // buffers and a single source buffer. + // If we don't have a separate source buffer, we overwrite the + // destination with the data. This means that read index and write + // index match + // If we do have a separate source buffer, we start writing from + // 0 and the read index is separate. + match source { + None => { + self.do_crypt(start_index, stop_index, start_index); + } + Some(src) => { + self.source.replace(src); + self.do_crypt(start_index, stop_index, 0); + } + } + self.client.map(|client| { + client.crypt_done(self.source.take(), self.dest.take().unwrap()); + }); + None + } +} + +pub static mut AES: Aes<'static> = Aes::new(); + +impl kernel::hil::symmetric_encryption::AES128ECB for Aes<'_> { + fn set_mode_aes128ecb(&self, encrypting: bool) { + self.configure(encrypting); + } +}
diff --git a/chip/src/chip.rs b/chip/src/chip.rs new file mode 100644 index 0000000..58a95b9 --- /dev/null +++ b/chip/src/chip.rs
@@ -0,0 +1,338 @@ +//! High-level setup and interrupt mapping for the chip. + +use core::fmt::Write; +use core::hint::unreachable_unchecked; +use kernel; +use kernel::debug; +use kernel::hil::time::Alarm; +use kernel::Chip; +use rv32i::csr::{mcause, mie::mie, mip::mip, mtvec::mtvec, CSR}; +use rv32i::syscall::SysCall; +use rv32i::PMPConfigMacro; + +use crate::chip_config::CONFIG; +use crate::gpio; +use crate::hmac; +use crate::interrupts; +use crate::plic; +use crate::pwrmgr; +use crate::timer; +use crate::uart; +use crate::usbdev; + +PMPConfigMacro!(4); + +pub struct Matcha<A: 'static + Alarm<'static>> { + userspace_kernel_boundary: SysCall, + pmp: PMP, + scheduler_timer: kernel::VirtualSchedulerTimer<A>, +} + +impl<A: 'static + Alarm<'static>> Matcha<A> { + pub unsafe fn new(alarm: &'static A) -> Self { + Self { + userspace_kernel_boundary: SysCall::new(), + pmp: PMP::new(), + scheduler_timer: kernel::VirtualSchedulerTimer::new(alarm), + } + } + + pub unsafe fn enable_plic_interrupts(&self) { + plic::disable_all(); + plic::clear_all_pending(); + plic::enable_all(); + } + + unsafe fn handle_plic_interrupts(&self) { + while let Some(interrupt) = plic::next_pending() { + match interrupt { + interrupts::UART0_TX_WATERMARK..=interrupts::UART0_RX_PARITY_ERR => { + uart::UART0.handle_interrupt() + } + int_pin @ interrupts::GPIO_PIN0..=interrupts::GPIO_PIN31 => { + let pin = &gpio::PORT[(int_pin - interrupts::GPIO_PIN0) as usize]; + pin.handle_interrupt(); + } + interrupts::HMAC_HMAC_DONE..=interrupts::HMAC_HMAC_ERR => { + hmac::HMAC.handle_interrupt() + } + interrupts::USBDEV_PKT_RECEIVED..=interrupts::USBDEV_CONNECTED => { + usbdev::USB.handle_interrupt() + } + interrupts::PWRMGRWAKEUP => { + pwrmgr::PWRMGR.handle_interrupt(); + self.check_until_true_or_interrupt( + || pwrmgr::PWRMGR.check_clock_propagation(), + None, + ); + } + _ => debug!("Pidx {}", interrupt), + } + plic::complete(interrupt); + } + } + + /// Run a function in an interruptable loop. + /// + /// The function will run until it returns true, an interrupt occurs or if + /// `max_tries` is not `None` and that limit is reached. + /// If the function returns true this call will also return true. If an + /// interrupt occurs or `max_tries` is reached this call will return false. + fn check_until_true_or_interrupt<F>(&self, f: F, max_tries: Option<usize>) -> bool + where + F: Fn() -> bool, + { + match max_tries { + Some(t) => { + for _i in 0..t { + if self.has_pending_interrupts() { + return false; + } + if f() { + return true; + } + } + } + None => { + while !self.has_pending_interrupts() { + if f() { + return true; + } + } + } + } + + false + } +} + +impl<A: 'static + Alarm<'static>> kernel::Chip for Matcha<A> { + type MPU = PMP; + type UserspaceKernelBoundary = SysCall; + type SchedulerTimer = kernel::VirtualSchedulerTimer<A>; + type WatchDog = (); + + fn mpu(&self) -> &Self::MPU { + &self.pmp + } + + fn scheduler_timer(&self) -> &Self::SchedulerTimer { + &self.scheduler_timer + } + + fn watchdog(&self) -> &Self::WatchDog { + &() + } + + fn userspace_kernel_boundary(&self) -> &SysCall { + &self.userspace_kernel_boundary + } + + fn service_pending_interrupts(&self) { + loop { + let mip = CSR.mip.extract(); + + if mip.is_set(mip::mtimer) { + unsafe { + timer::TIMER.service_interrupt(); + } + } + if mip.is_set(mip::mext) { + unsafe { + self.handle_plic_interrupts(); + } + } + + if !mip.matches_any(mip::mext::SET + mip::mtimer::SET) { + break; + } + } + + // Re-enable all MIE interrupts that we care about. Since we looped + // until we handled them all, we can re-enable all of them. + CSR.mie.modify(mie::mext::SET + mie::mtimer::SET); + } + + fn has_pending_interrupts(&self) -> bool { + let mip = CSR.mip.extract(); + mip.matches_any(mip::mext::SET + mip::mtimer::SET) + } + + fn sleep(&self) { + unsafe { + pwrmgr::PWRMGR.enable_low_power(); + self.check_until_true_or_interrupt(|| pwrmgr::PWRMGR.check_clock_propagation(), None); + rv32i::support::wfi(); + } + } + + unsafe fn atomic<F, R>(&self, f: F) -> R + where + F: FnOnce() -> R, + { + rv32i::support::atomic(f) + } + + unsafe fn print_state(&self, writer: &mut dyn Write) { + let _ = writer.write_fmt(format_args!( + "\r\n---| Matcha configuration for {} |---", + CONFIG.name + )); + rv32i::print_riscv_state(writer); + } +} + +fn handle_exception(exception: mcause::Exception) { + match exception { + mcause::Exception::UserEnvCall | mcause::Exception::SupervisorEnvCall => (), + + mcause::Exception::InstructionMisaligned + | mcause::Exception::InstructionFault + | mcause::Exception::IllegalInstruction + | mcause::Exception::Breakpoint + | mcause::Exception::LoadMisaligned + | mcause::Exception::LoadFault + | mcause::Exception::StoreMisaligned + | mcause::Exception::StoreFault + | mcause::Exception::MachineEnvCall + | mcause::Exception::InstructionPageFault + | mcause::Exception::LoadPageFault + | mcause::Exception::StorePageFault + | mcause::Exception::Unknown => { + panic!("fatal exception"); + } + } +} + +unsafe fn handle_interrupt(intr: mcause::Interrupt) { + match intr { + mcause::Interrupt::UserSoft + | mcause::Interrupt::UserTimer + | mcause::Interrupt::UserExternal => { + panic!("unexpected user-mode interrupt"); + } + mcause::Interrupt::SupervisorExternal + | mcause::Interrupt::SupervisorTimer + | mcause::Interrupt::SupervisorSoft => { + panic!("unexpected supervisor-mode interrupt"); + } + + mcause::Interrupt::MachineSoft => { + CSR.mie.modify(mie::msoft::CLEAR); + } + mcause::Interrupt::MachineTimer => { + CSR.mie.modify(mie::mtimer::CLEAR); + } + mcause::Interrupt::MachineExternal => { + CSR.mie.modify(mie::mext::CLEAR); + } + + mcause::Interrupt::Unknown => { + panic!("interrupt of unknown cause"); + } + } +} + +/// Trap handler for board/chip specific code. +/// +/// For the Ibex this gets called when an interrupt occurs while the chip is +/// in kernel mode. All we need to do is check which interrupt occurred and +/// disable it. +#[export_name = "_start_trap_rust"] +pub unsafe extern "C" fn start_trap_rust() { + match mcause::Trap::from(CSR.mcause.extract()) { + mcause::Trap::Interrupt(interrupt) => { + handle_interrupt(interrupt); + } + mcause::Trap::Exception(exception) => { + handle_exception(exception); + } + } +} + +/// Function that gets called if an interrupt occurs while an app was running. +/// mcause is passed in, and this function should correctly handle disabling the +/// interrupt that fired so that it does not trigger again. +#[export_name = "_disable_interrupt_trap_handler"] +pub unsafe extern "C" fn disable_interrupt_trap_handler(mcause_val: u32) { + match mcause::Trap::from(mcause_val) { + mcause::Trap::Interrupt(interrupt) => { + handle_interrupt(interrupt); + } + _ => { + panic!("unexpected non-interrupt\n"); + } + } +} + +pub unsafe fn configure_trap_handler() { + // The Ibex CPU does not support non-vectored trap entries. + CSR.mtvec + .write(mtvec::trap_addr.val(_start_trap_vectored as u32 >> 2) + mtvec::mode::Vectored) +} + +// Mock implementation for crate tests that does not include the section +// specifier, as the test will not use our linker script, and the host +// compilation environment may not allow the section name. +#[cfg(not(any(target_arch = "riscv32", target_os = "none")))] +pub extern "C" fn _start_trap_vectored() { + unsafe { + unreachable_unchecked(); + } +} + +#[cfg(all(target_arch = "riscv32", target_os = "none"))] +#[link_section = ".riscv.trap_vectored"] +#[export_name = "_start_trap_vectored"] +#[naked] +pub extern "C" fn _start_trap_vectored() -> ! { + unsafe { + // According to the Ibex user manual: + // [NMI] has interrupt ID 31, i.e., it has the highest priority of all + // interrupts and the core jumps to the trap-handler base address (in + // mtvec) plus 0x7C to handle the NMI. + // + // Below are 32 (non-compressed) jumps to cover the entire possible + // range of vectored traps. + #[cfg(all(target_arch = "riscv32", target_os = "none"))] + llvm_asm!(" + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + j _start_trap + " + : + : + : + : "volatile"); + unreachable_unchecked() + } +}
diff --git a/chip/src/chip_config.rs b/chip/src/chip_config.rs new file mode 100644 index 0000000..9a26ff9 --- /dev/null +++ b/chip/src/chip_config.rs
@@ -0,0 +1,46 @@ +//! Chip specific configuration. +//! +//! This file includes configuration values for different implementations and +//! uses of the same matcha chip. For example, running the chip on an FPGA +//! requires different parameters from running it in a verilog simulator. +//! Additionally, chips on different platforms can be used differently, so this +//! also permits changing values like the UART baud rate to enable better +//! debugging on platforms that can support it. +//! +//! The configuration used is selected via Cargo features specified when the +//! board is compiled. + +/// Matcha configuration based on the target device. +pub struct Config<'a> { + /// Identifier for the platform. This is useful for debugging to confirm the + /// correct configuration of the chip is being used. + pub name: &'a str, + /// The clock speed of the CPU in Hz. + pub cpu_freq: u32, + /// The clock speed of the peripherals in Hz. + pub peripheral_freq: u32, + /// The baud rate for UART. This allows for a version of the chip that can + /// support a faster baud rate to use it to help with debugging. + pub uart_baudrate: u32, +} + +/// Config for running Matcha on an FPGA. Also the default configuration. +#[cfg(any( + feature = "config_fpga_nexysvideo", + not(feature = "config_disable_default") +))] +pub const CONFIG: Config = Config { + name: "fpga_nexysvideo", + cpu_freq: 10_000_000, + peripheral_freq: 2_500_000, + uart_baudrate: 115200, +}; + +/// Config for running Matcha in a verilog simulator. +#[cfg(feature = "config_sim_verilator")] +pub const CONFIG: Config = Config { + name: "sim_verilator", + cpu_freq: 500_000, + peripheral_freq: 125_000, + uart_baudrate: 9600, +};
diff --git a/chip/src/gpio.rs b/chip/src/gpio.rs new file mode 100644 index 0000000..03adf98 --- /dev/null +++ b/chip/src/gpio.rs
@@ -0,0 +1,69 @@ +//! GPIO instantiation. + +use core::ops::{Index, IndexMut}; + +use kernel::common::StaticRef; +pub use lowrisc::gpio::GpioPin; +use lowrisc::gpio::{pins, GpioRegisters}; +use lowrisc::padctrl::PadCtrlRegisters; + +const PADCTRL_BASE: StaticRef<PadCtrlRegisters> = + unsafe { StaticRef::new(0x4046_0000 as *const PadCtrlRegisters) }; + +const GPIO0_BASE: StaticRef<GpioRegisters> = + unsafe { StaticRef::new(0x4004_0000 as *const GpioRegisters) }; + +pub struct Port<'a> { + pins: [GpioPin<'a>; 32], +} + +impl<'a> Index<usize> for Port<'a> { + type Output = GpioPin<'a>; + + fn index(&self, index: usize) -> &GpioPin<'a> { + &self.pins[index] + } +} + +impl<'a> IndexMut<usize> for Port<'a> { + fn index_mut(&mut self, index: usize) -> &mut GpioPin<'a> { + &mut self.pins[index] + } +} + +pub static mut PORT: Port = Port { + pins: [ + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin0), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin1), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin2), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin3), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin4), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin5), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin6), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin7), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin8), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin9), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin10), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin11), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin12), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin13), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin14), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin15), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin16), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin17), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin18), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin19), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin20), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin21), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin22), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin23), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin24), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin25), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin26), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin27), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin28), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin29), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin30), + GpioPin::new(GPIO0_BASE, PADCTRL_BASE, pins::pin31), + ], +};
diff --git a/chip/src/hmac.rs b/chip/src/hmac.rs new file mode 100644 index 0000000..182ed53 --- /dev/null +++ b/chip/src/hmac.rs
@@ -0,0 +1,7 @@ +use kernel::common::StaticRef; +use lowrisc::hmac::{Hmac, HmacRegisters}; + +pub static mut HMAC: Hmac = Hmac::new(HMAC0_BASE); + +const HMAC0_BASE: StaticRef<HmacRegisters> = + unsafe { StaticRef::new(0x4111_0000 as *const HmacRegisters) };
diff --git a/chip/src/i2c.rs b/chip/src/i2c.rs new file mode 100644 index 0000000..4cc7332 --- /dev/null +++ b/chip/src/i2c.rs
@@ -0,0 +1,9 @@ +use crate::chip_config::CONFIG; +use kernel::common::StaticRef; +use lowrisc::i2c::{I2c, I2cRegisters}; + +pub static mut I2C: I2c = I2c::new(I2C_BASE, (1 / CONFIG.cpu_freq) * 1000 * 1000); + +// This is a placeholder address as the I2C MMIO interface isn't avaliable yet +const I2C_BASE: StaticRef<I2cRegisters> = + unsafe { StaticRef::new(0x4008_0000 as *const I2cRegisters) };
diff --git a/chip/src/interrupts.rs b/chip/src/interrupts.rs new file mode 100644 index 0000000..d503127 --- /dev/null +++ b/chip/src/interrupts.rs
@@ -0,0 +1,210 @@ +//! Named interrupts for the Matcha chip. + +#![allow(dead_code)] + +pub const PWRMGRWAKEUP: u32 = 0x50; + +pub const NO_INTERRUPT: u32 = 0; + +pub const UART0_TX_WATERMARK: u32 = 1; +pub const UART0_RX_WATERMARK: u32 = 2; +pub const UART0_TX_EMPTY: u32 = 3; +pub const UART0_RX_OVERFLOW: u32 = 4; +pub const UART0_RX_FRAME_ERR: u32 = 5; +pub const UART0_RX_BREAK_ERR: u32 = 6; +pub const UART0_RX_TIMEOUT: u32 = 7; +pub const UART0_RX_PARITY_ERR: u32 = 8; + +pub const UART1_TX_WATERMARK: u32 = 9; +pub const UART1_RX_WATERMARK: u32 = 10; +pub const UART1_TX_EMPTY: u32 = 11; +pub const UART1_RX_OVERFLOW: u32 = 12; +pub const UART1_RX_FRAME_ERR: u32 = 13; +pub const UART1_RX_BREAK_ERR: u32 = 14; +pub const UART1_RX_TIMEOUT: u32 = 15; +pub const UART1_RX_PARITY_ERR: u32 = 16; + +pub const UART2_TX_WATERMARK: u32 = 17; +pub const UART2_RX_WATERMARK: u32 = 18; +pub const UART2_TX_EMPTY: u32 = 19; +pub const UART2_RX_OVERFLOW: u32 = 20; +pub const UART2_RX_FRAME_ERR: u32 = 21; +pub const UART2_RX_BREAK_ERR: u32 = 22; +pub const UART2_RX_TIMEOUT: u32 = 23; +pub const UART2_RX_PARITY_ERR: u32 = 24; + +pub const UART3_TX_WATERMARK: u32 = 25; +pub const UART3_RX_WATERMARK: u32 = 26; +pub const UART3_TX_EMPTY: u32 = 27; +pub const UART3_RX_OVERFLOW: u32 = 28; +pub const UART3_RX_FRAME_ERR: u32 = 29; +pub const UART3_RX_BREAK_ERR: u32 = 30; +pub const UART3_RX_TIMEOUT: u32 = 31; +pub const UART3_RX_PARITY_ERR: u32 = 32; + +pub const GPIO_PIN0: u32 = 33; +pub const GPIO_PIN1: u32 = 34; +pub const GPIO_PIN2: u32 = 35; +pub const GPIO_PIN3: u32 = 36; +pub const GPIO_PIN4: u32 = 37; +pub const GPIO_PIN5: u32 = 38; +pub const GPIO_PIN6: u32 = 39; +pub const GPIO_PIN7: u32 = 40; +pub const GPIO_PIN8: u32 = 41; +pub const GPIO_PIN9: u32 = 42; +pub const GPIO_PIN10: u32 = 43; +pub const GPIO_PIN11: u32 = 44; +pub const GPIO_PIN12: u32 = 45; +pub const GPIO_PIN13: u32 = 46; +pub const GPIO_PIN14: u32 = 47; +pub const GPIO_PIN15: u32 = 48; +pub const GPIO_PIN16: u32 = 49; +pub const GPIO_PIN17: u32 = 50; +pub const GPIO_PIN18: u32 = 51; +pub const GPIO_PIN19: u32 = 52; +pub const GPIO_PIN20: u32 = 53; +pub const GPIO_PIN21: u32 = 54; +pub const GPIO_PIN22: u32 = 55; +pub const GPIO_PIN23: u32 = 56; +pub const GPIO_PIN24: u32 = 57; +pub const GPIO_PIN25: u32 = 58; +pub const GPIO_PIN26: u32 = 59; +pub const GPIO_PIN27: u32 = 60; +pub const GPIO_PIN28: u32 = 61; +pub const GPIO_PIN29: u32 = 62; +pub const GPIO_PIN30: u32 = 63; +pub const GPIO_PIN31: u32 = 64; + +pub const SPI_DEVICE_RXF: u32 = 65; +pub const SPI_DEVICE_RXLVL: u32 = 66; +pub const SPI_DEVICE_TXLVL: u32 = 67; +pub const SPI_DEVICE_RXERR: u32 = 68; +pub const SPI_DEVICE_RXOVERFLOW: u32 = 69; +pub const SPI_DEVICE_TXUNDERFLOW: u32 = 70; + + +pub const SPI_HOST0_ERROR: u32 = 71; +pub const SPI_HOST0_SPIEVENT: u32 = 72; +pub const SPI_HOST1_ERROR: u32 = 73; +pub const SPI_HOST1_SPIEVENT: u32 = 74; + +pub const I2C0_FMT_WATERMARK: u32 = 75; +pub const I2C0_RX_WATERMARK: u32 = 76; +pub const I2C0_FMT_OVERFLOW: u32 = 77; +pub const I2C0_RX_OVERFLOW: u32 = 78; +pub const I2C0_NAK: u32 = 79; +pub const I2C0_SCL_INTERFERENCE: u32 = 80; +pub const I2C0_SDA_INTERFERENCE: u32 = 81; +pub const I2C0_STRETCH_TIMEOUT: u32 = 82; +pub const I2C0_SDA_UNSTABLE: u32 = 83; +pub const I2C0_TRANS_COMPLETE: u32 = 84; +pub const I2C0_TX_EMPTY: u32 = 85; +pub const I2C0_TX_NONEMPTY: u32 = 86; +pub const I2C0_TX_OVERFLOW: u32 = 87; +pub const I2C0_ACQ_OVERFLOW: u32 = 88; +pub const I2C0_ACK_STOP: u32 = 89; +pub const I2C0_HOST_TIMEOUT: u32 = 90; + +pub const I2C1_FMT_WATERMARK: u32 = 91; +pub const I2C1_RX_WATERMARK: u32 = 92; +pub const I2C1_FMT_OVERFLOW: u32 = 93; +pub const I2C1_RX_OVERFLOW: u32 = 94; +pub const I2C1_NAK: u32 = 95; +pub const I2C1_SCL_INTERFERENCE: u32 = 96; +pub const I2C1_SDA_INTERFERENCE: u32 = 97; +pub const I2C1_STRETCH_TIMEOUT: u32 = 98; +pub const I2C1_SDA_UNSTABLE: u32 = 99; +pub const I2C1_TRANS_COMPLETE: u32 = 100; +pub const I2C1_TX_EMPTY: u32 = 101; +pub const I2C1_TX_NONEMPTY: u32 = 102; +pub const I2C1_TX_OVERFLOW: u32 = 103; +pub const I2C1_ACQ_OVERFLOW: u32 = 104; +pub const I2C1_ACK_STOP: u32 = 105; +pub const I2C1_HOST_TIMEOUT: u32 = 106; + +pub const I2C2_FMT_WATERMARK: u32 = 107; +pub const I2C2_RX_WATERMARK: u32 = 108; +pub const I2C2_FMT_OVERFLOW: u32 = 109; +pub const I2C2_RX_OVERFLOW: u32 = 110; +pub const I2C2_NAK: u32 = 111; +pub const I2C2_SCL_INTERFERENCE: u32 = 112; +pub const I2C2_SDA_INTERFERENCE: u32 = 113; +pub const I2C2_STRETCH_TIMEOUT: u32 = 114; +pub const I2C2_SDA_UNSTABLE: u32 = 115; +pub const I2C2_TRANS_COMPLETE: u32 = 116; +pub const I2C2_TX_EMPTY: u32 = 117; +pub const I2C2_TX_NONEMPTY: u32 = 118; +pub const I2C2_TX_OVERFLOW: u32 = 119; +pub const I2C2_ACQ_OVERFLOW: u32 = 120; +pub const I2C2_ACK_STOP: u32 = 121; +pub const I2C2_HOST_TIMEOUT: u32 = 122; + +pub const PATTGEN_DONE_CH0: u32 = 123; +pub const PATTGEN_DONE_CH1: u32 = 124; + +pub const RV_TIMER_EXPIRED0_0: u32 = 125; + +pub const USBDEV_PKT_RECEIVED: u32 = 126; +pub const USBDEV_PKT_SENT: u32 = 127; +pub const USBDEV_DISCONNECTED: u32 = 128; +pub const USBDEV_HOST_LOST: u32 = 129; +pub const USBDEV_LINK_RESET: u32 = 130; +pub const USBDEV_LINK_SUSPEND: u32 = 131; +pub const USBDEV_LINK_RESUME: u32 = 132; +pub const USBDEV_AV_EMPTY: u32 = 133; +pub const USBDEV_RX_FULL: u32 = 134; +pub const USBDEV_AV_OVERFLOW: u32 = 135; +pub const USBDEV_LINK_IN_ERR: u32 = 136; +pub const USBDEV_RX_CRC_ERR: u32 = 137; +pub const USBDEV_RX_PID_ERR: u32 = 138; +pub const USBDEV_RX_BITSTUFF_ERR: u32 = 139; +pub const USBDEV_FRAME: u32 = 140; +pub const USBDEV_CONNECTED: u32 = 141; +pub const USBDEV_LINK_OUT_ERR: u32 = 142; + +pub const OTP_CTRL_OTP_OPERATION_DONE: u32 = 143; +pub const OTP_CTRL_OTP_ERR: u32 = 144; + +pub const ALERT_CLASSA: u32 = 145; +pub const ALERT_CLASSB: u32 = 146; +pub const ALERT_CLASSC: u32 = 147; +pub const ALERT_CLASSD: u32 = 148; + +pub const PWRMGR_AON_WAKEUP: u32 = 149; + +pub const ADC_CTRL_AON_DEBUG_CABLE: u32 = 150; + +pub const AON_TIMER_AON_WAKEUP_TIMER_EXPIRED: u32 = 151; +pub const AON_TIMER_AON_WATCHDOG_EXPIRED: u32 = 152; + +pub const FLASH_PROG_EMPTY: u32 = 153; +pub const FLASH_PROG_LVL: u32 = 154; +pub const FLASH_RD_FULL: u32 = 155; +pub const FLASH_RD_LVL: u32 = 156; +pub const FLASH_OP_DONE: u32 = 157; + +pub const HMAC_HMAC_DONE: u32 = 158; +pub const HMAC_FIFO_EMPTY: u32 = 159; +pub const HMAC_HMAC_ERR: u32 = 160; + +pub const KMAC_KMAC_DONE: u32 = 161; +pub const KMAC_FIFO_EMPTY: u32 = 162; +pub const KMAC_KMAC_ERR: u32 = 163; + +pub const KEYMGR_OP_DONE: u32 = 164; + +pub const CSRNG_CS_CMD_REQ_DONE: u32 = 165; +pub const CSRNG_CS_ENTROPY_REQ: u32 = 166; +pub const CSRNG_CS_HW_INST_EXC: u32 = 167; +pub const CSRNG_CS_FATAL_ERR: u32 = 168; +pub const ENTROPY_SRC_ES_ENTROPY_VALID: u32 = 169; +pub const ENTROPY_SRC_ES_HEALTH_TEST_FAILED: u32 = 170; +pub const ENTROPY_SRC_ES_FATAL_ERR: u32 = 171; + +pub const EDN0_EDN_CMD_REQ_DONE: u32 = 172; +pub const EDN0_EDN_FATAL_ERR: u32 = 173; + +pub const EDN1_EDN_CMD_REQ_DONE: u32 = 174; +pub const EDN1_EDN_FATAL_ERR: u32 = 175; + +pub const OTBN_DONE: u32 = 176; \ No newline at end of file
diff --git a/chip/src/lib.rs b/chip/src/lib.rs new file mode 100644 index 0000000..67af24d --- /dev/null +++ b/chip/src/lib.rs
@@ -0,0 +1,21 @@ +//! Drivers and chip support for Matcha. + +#![feature(llvm_asm, const_fn, naked_functions)] +#![no_std] +#![crate_name = "matcha"] +#![crate_type = "rlib"] + +mod chip_config; +mod interrupts; +mod plic_constants; + +pub mod aes; +pub mod chip; +pub mod gpio; +pub mod hmac; +pub mod i2c; +pub mod plic; +pub mod pwrmgr; +pub mod timer; +pub mod uart; +pub mod usbdev;
diff --git a/chip/src/plic.rs b/chip/src/plic.rs new file mode 100644 index 0000000..9852ce3 --- /dev/null +++ b/chip/src/plic.rs
@@ -0,0 +1,104 @@ +//! Platform Level Interrupt Control peripheral driver. + +use kernel::common::registers::{register_bitfields, register_structs, ReadOnly, ReadWrite}; +use kernel::common::StaticRef; +use crate::plic_constants::*; +//use kernel::debug; + +register_structs! { + pub PlicRegisters { + /// Interrupt Pending Register + (RV_PLIC_IP_0_REG_OFFSET => pending: [ReadOnly<u32>; RV_PLIC_IP_MULTIREG_COUNT as usize]), + /// Interrupt Source Register + (RV_PLIC_LE_0_REG_OFFSET => source: [ReadWrite<u32>; RV_PLIC_LE_MULTIREG_COUNT as usize]), + /// Interrupt Priority Registers + (RV_PLIC_PRIO0_REG_OFFSET => priority: [ReadWrite<u32, priority::Register>; RV_PLIC_PARAM_NUM_SRC as usize]), + (0x30C => _reserved0: [ReadWrite<u32>; 61]), + /// Interrupt Enable Register + (RV_PLIC_IE0_0_REG_OFFSET => enable: [ReadWrite<u32>; RV_PLIC_IE0_MULTIREG_COUNT as usize]), + /// Priority Threshold Register + (RV_PLIC_THRESHOLD0_REG_OFFSET => threshold: ReadWrite<u32, priority::Register>), + /// Claim/Complete Register + (RV_PLIC_CC0_REG_OFFSET => claim: ReadWrite<u32>), + /// MSIP Register + (RV_PLIC_MSIP0_REG_OFFSET => msip: ReadWrite<u32>), + (RV_PLIC_MSIP0_REG_OFFSET + 4 => @END), + } +} + +register_bitfields![u32, + priority [ + Priority OFFSET(0) NUMBITS(3) [] + ] +]; + +const PLIC_BASE: StaticRef<PlicRegisters> = + unsafe { StaticRef::new(0x4101_0000 as *const PlicRegisters) }; + +/// Clear all pending interrupts. +pub unsafe fn clear_all_pending() { + let _plic: &PlicRegisters = &*PLIC_BASE; +} + +/// Enable all interrupts. +pub unsafe fn enable_all() { + let plic: &PlicRegisters = &*PLIC_BASE; + + // USB hardware on current OT master branch seems to have + // interrupt bugs: running Alarms causes persistent USB + // CONNECTED interrupts that can't be masked from USBDEV and + // cause the system to hang. So enable all interrupts except + // for the USB ones. Some open PRs on OT fix this, we'll re-enable + // USB interrurupts. + // + // https://github.com/lowRISC/opentitan/issues/3388 + plic.enable[0].set(0xFFFF_FFFF); + plic.enable[1].set(0xFFFF_FFFF); + plic.enable[2].set(0xFFFF_0000); // USB are 64-79 + + // Set the max priority for each interrupt. This is not really used + // at this point. + for priority in plic.priority.iter() { + priority.write(priority::Priority.val(3)); + } + + // Accept all interrupts. + plic.threshold.write(priority::Priority.val(1)); +} + +/// Disable all interrupts. +pub unsafe fn disable_all() { + let plic: &PlicRegisters = &*PLIC_BASE; + for enable in plic.enable.iter() { + enable.set(0); + } +} + +/// Get the index (0-256) of the lowest number pending interrupt, or `None` if +/// none is pending. RISC-V PLIC has a "claim" register which makes it easy +/// to grab the highest priority pending interrupt. +pub unsafe fn next_pending() -> Option<u32> { + let plic: &PlicRegisters = &*PLIC_BASE; + + let claim = plic.claim.get(); + if claim == 0 { + None + } else { + Some(claim) + } +} + +/// Signal that an interrupt is finished being handled. In Tock, this should be +/// called from the normal main loop (not the interrupt handler). +pub unsafe fn complete(index: u32) { + let plic: &PlicRegisters = &*PLIC_BASE; + plic.claim.set(index); +} + +/// Return `true` if there are any pending interrupts in the PLIC, `false` +/// otherwise. +pub unsafe fn has_pending() -> bool { + let plic: &PlicRegisters = &*PLIC_BASE; + + plic.pending.iter().fold(0, |i, pending| pending.get() | i) != 0 +}
diff --git a/chip/src/plic_constants.rs b/chip/src/plic_constants.rs new file mode 100644 index 0000000..7498b8a --- /dev/null +++ b/chip/src/plic_constants.rs
@@ -0,0 +1,1799 @@ +// TODO(b/204322283): Remove this file in favor of auto-generated crate. +// Crate level unused is necessary as otherwise this generates 1k unused warnings. +#![allow(unused)] +// Generated register constants for RV_PLIC + +// Copyright information found in source file: +// Copyright lowRISC contributors. + +// Licensing information found in source file: +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Number of interrupt sources +pub const RV_PLIC_PARAM_NUM_SRC: u32 = 183; + +// Number of Targets (Harts) +pub const RV_PLIC_PARAM_NUM_TARGET: u32 = 2; + +// Width of priority signals +pub const RV_PLIC_PARAM_PRIO_WIDTH: u32 = 3; + +// Number of alerts +pub const RV_PLIC_PARAM_NUM_ALERTS: u32 = 1; + +// Register width +pub const RV_PLIC_PARAM_REG_WIDTH: u32 = 32; + +// Interrupt Pending (common parameters) +pub const RV_PLIC_IP_P_FIELD_WIDTH: u32 = 1; +pub const RV_PLIC_IP_P_FIELDS_PER_REG: u32 = 32; +pub const RV_PLIC_IP_MULTIREG_COUNT: u32 = 6; + +// Interrupt Pending +pub const RV_PLIC_IP_0_REG_OFFSET: usize = 0x0; +pub const RV_PLIC_IP_0_P_0_BIT: u32 = 0; +pub const RV_PLIC_IP_0_P_1_BIT: u32 = 1; +pub const RV_PLIC_IP_0_P_2_BIT: u32 = 2; +pub const RV_PLIC_IP_0_P_3_BIT: u32 = 3; +pub const RV_PLIC_IP_0_P_4_BIT: u32 = 4; +pub const RV_PLIC_IP_0_P_5_BIT: u32 = 5; +pub const RV_PLIC_IP_0_P_6_BIT: u32 = 6; +pub const RV_PLIC_IP_0_P_7_BIT: u32 = 7; +pub const RV_PLIC_IP_0_P_8_BIT: u32 = 8; +pub const RV_PLIC_IP_0_P_9_BIT: u32 = 9; +pub const RV_PLIC_IP_0_P_10_BIT: u32 = 10; +pub const RV_PLIC_IP_0_P_11_BIT: u32 = 11; +pub const RV_PLIC_IP_0_P_12_BIT: u32 = 12; +pub const RV_PLIC_IP_0_P_13_BIT: u32 = 13; +pub const RV_PLIC_IP_0_P_14_BIT: u32 = 14; +pub const RV_PLIC_IP_0_P_15_BIT: u32 = 15; +pub const RV_PLIC_IP_0_P_16_BIT: u32 = 16; +pub const RV_PLIC_IP_0_P_17_BIT: u32 = 17; +pub const RV_PLIC_IP_0_P_18_BIT: u32 = 18; +pub const RV_PLIC_IP_0_P_19_BIT: u32 = 19; +pub const RV_PLIC_IP_0_P_20_BIT: u32 = 20; +pub const RV_PLIC_IP_0_P_21_BIT: u32 = 21; +pub const RV_PLIC_IP_0_P_22_BIT: u32 = 22; +pub const RV_PLIC_IP_0_P_23_BIT: u32 = 23; +pub const RV_PLIC_IP_0_P_24_BIT: u32 = 24; +pub const RV_PLIC_IP_0_P_25_BIT: u32 = 25; +pub const RV_PLIC_IP_0_P_26_BIT: u32 = 26; +pub const RV_PLIC_IP_0_P_27_BIT: u32 = 27; +pub const RV_PLIC_IP_0_P_28_BIT: u32 = 28; +pub const RV_PLIC_IP_0_P_29_BIT: u32 = 29; +pub const RV_PLIC_IP_0_P_30_BIT: u32 = 30; +pub const RV_PLIC_IP_0_P_31_BIT: u32 = 31; + +// Interrupt Pending +pub const RV_PLIC_IP_1_REG_OFFSET: usize = 0x4; +pub const RV_PLIC_IP_1_P_32_BIT: u32 = 0; +pub const RV_PLIC_IP_1_P_33_BIT: u32 = 1; +pub const RV_PLIC_IP_1_P_34_BIT: u32 = 2; +pub const RV_PLIC_IP_1_P_35_BIT: u32 = 3; +pub const RV_PLIC_IP_1_P_36_BIT: u32 = 4; +pub const RV_PLIC_IP_1_P_37_BIT: u32 = 5; +pub const RV_PLIC_IP_1_P_38_BIT: u32 = 6; +pub const RV_PLIC_IP_1_P_39_BIT: u32 = 7; +pub const RV_PLIC_IP_1_P_40_BIT: u32 = 8; +pub const RV_PLIC_IP_1_P_41_BIT: u32 = 9; +pub const RV_PLIC_IP_1_P_42_BIT: u32 = 10; +pub const RV_PLIC_IP_1_P_43_BIT: u32 = 11; +pub const RV_PLIC_IP_1_P_44_BIT: u32 = 12; +pub const RV_PLIC_IP_1_P_45_BIT: u32 = 13; +pub const RV_PLIC_IP_1_P_46_BIT: u32 = 14; +pub const RV_PLIC_IP_1_P_47_BIT: u32 = 15; +pub const RV_PLIC_IP_1_P_48_BIT: u32 = 16; +pub const RV_PLIC_IP_1_P_49_BIT: u32 = 17; +pub const RV_PLIC_IP_1_P_50_BIT: u32 = 18; +pub const RV_PLIC_IP_1_P_51_BIT: u32 = 19; +pub const RV_PLIC_IP_1_P_52_BIT: u32 = 20; +pub const RV_PLIC_IP_1_P_53_BIT: u32 = 21; +pub const RV_PLIC_IP_1_P_54_BIT: u32 = 22; +pub const RV_PLIC_IP_1_P_55_BIT: u32 = 23; +pub const RV_PLIC_IP_1_P_56_BIT: u32 = 24; +pub const RV_PLIC_IP_1_P_57_BIT: u32 = 25; +pub const RV_PLIC_IP_1_P_58_BIT: u32 = 26; +pub const RV_PLIC_IP_1_P_59_BIT: u32 = 27; +pub const RV_PLIC_IP_1_P_60_BIT: u32 = 28; +pub const RV_PLIC_IP_1_P_61_BIT: u32 = 29; +pub const RV_PLIC_IP_1_P_62_BIT: u32 = 30; +pub const RV_PLIC_IP_1_P_63_BIT: u32 = 31; + +// Interrupt Pending +pub const RV_PLIC_IP_2_REG_OFFSET: usize = 0x8; +pub const RV_PLIC_IP_2_P_64_BIT: u32 = 0; +pub const RV_PLIC_IP_2_P_65_BIT: u32 = 1; +pub const RV_PLIC_IP_2_P_66_BIT: u32 = 2; +pub const RV_PLIC_IP_2_P_67_BIT: u32 = 3; +pub const RV_PLIC_IP_2_P_68_BIT: u32 = 4; +pub const RV_PLIC_IP_2_P_69_BIT: u32 = 5; +pub const RV_PLIC_IP_2_P_70_BIT: u32 = 6; +pub const RV_PLIC_IP_2_P_71_BIT: u32 = 7; +pub const RV_PLIC_IP_2_P_72_BIT: u32 = 8; +pub const RV_PLIC_IP_2_P_73_BIT: u32 = 9; +pub const RV_PLIC_IP_2_P_74_BIT: u32 = 10; +pub const RV_PLIC_IP_2_P_75_BIT: u32 = 11; +pub const RV_PLIC_IP_2_P_76_BIT: u32 = 12; +pub const RV_PLIC_IP_2_P_77_BIT: u32 = 13; +pub const RV_PLIC_IP_2_P_78_BIT: u32 = 14; +pub const RV_PLIC_IP_2_P_79_BIT: u32 = 15; +pub const RV_PLIC_IP_2_P_80_BIT: u32 = 16; +pub const RV_PLIC_IP_2_P_81_BIT: u32 = 17; +pub const RV_PLIC_IP_2_P_82_BIT: u32 = 18; +pub const RV_PLIC_IP_2_P_83_BIT: u32 = 19; +pub const RV_PLIC_IP_2_P_84_BIT: u32 = 20; +pub const RV_PLIC_IP_2_P_85_BIT: u32 = 21; +pub const RV_PLIC_IP_2_P_86_BIT: u32 = 22; +pub const RV_PLIC_IP_2_P_87_BIT: u32 = 23; +pub const RV_PLIC_IP_2_P_88_BIT: u32 = 24; +pub const RV_PLIC_IP_2_P_89_BIT: u32 = 25; +pub const RV_PLIC_IP_2_P_90_BIT: u32 = 26; +pub const RV_PLIC_IP_2_P_91_BIT: u32 = 27; +pub const RV_PLIC_IP_2_P_92_BIT: u32 = 28; +pub const RV_PLIC_IP_2_P_93_BIT: u32 = 29; +pub const RV_PLIC_IP_2_P_94_BIT: u32 = 30; +pub const RV_PLIC_IP_2_P_95_BIT: u32 = 31; + +// Interrupt Pending +pub const RV_PLIC_IP_3_REG_OFFSET: usize = 0xc; +pub const RV_PLIC_IP_3_P_96_BIT: u32 = 0; +pub const RV_PLIC_IP_3_P_97_BIT: u32 = 1; +pub const RV_PLIC_IP_3_P_98_BIT: u32 = 2; +pub const RV_PLIC_IP_3_P_99_BIT: u32 = 3; +pub const RV_PLIC_IP_3_P_100_BIT: u32 = 4; +pub const RV_PLIC_IP_3_P_101_BIT: u32 = 5; +pub const RV_PLIC_IP_3_P_102_BIT: u32 = 6; +pub const RV_PLIC_IP_3_P_103_BIT: u32 = 7; +pub const RV_PLIC_IP_3_P_104_BIT: u32 = 8; +pub const RV_PLIC_IP_3_P_105_BIT: u32 = 9; +pub const RV_PLIC_IP_3_P_106_BIT: u32 = 10; +pub const RV_PLIC_IP_3_P_107_BIT: u32 = 11; +pub const RV_PLIC_IP_3_P_108_BIT: u32 = 12; +pub const RV_PLIC_IP_3_P_109_BIT: u32 = 13; +pub const RV_PLIC_IP_3_P_110_BIT: u32 = 14; +pub const RV_PLIC_IP_3_P_111_BIT: u32 = 15; +pub const RV_PLIC_IP_3_P_112_BIT: u32 = 16; +pub const RV_PLIC_IP_3_P_113_BIT: u32 = 17; +pub const RV_PLIC_IP_3_P_114_BIT: u32 = 18; +pub const RV_PLIC_IP_3_P_115_BIT: u32 = 19; +pub const RV_PLIC_IP_3_P_116_BIT: u32 = 20; +pub const RV_PLIC_IP_3_P_117_BIT: u32 = 21; +pub const RV_PLIC_IP_3_P_118_BIT: u32 = 22; +pub const RV_PLIC_IP_3_P_119_BIT: u32 = 23; +pub const RV_PLIC_IP_3_P_120_BIT: u32 = 24; +pub const RV_PLIC_IP_3_P_121_BIT: u32 = 25; +pub const RV_PLIC_IP_3_P_122_BIT: u32 = 26; +pub const RV_PLIC_IP_3_P_123_BIT: u32 = 27; +pub const RV_PLIC_IP_3_P_124_BIT: u32 = 28; +pub const RV_PLIC_IP_3_P_125_BIT: u32 = 29; +pub const RV_PLIC_IP_3_P_126_BIT: u32 = 30; +pub const RV_PLIC_IP_3_P_127_BIT: u32 = 31; + +// Interrupt Pending +pub const RV_PLIC_IP_4_REG_OFFSET: usize = 0x10; +pub const RV_PLIC_IP_4_P_128_BIT: u32 = 0; +pub const RV_PLIC_IP_4_P_129_BIT: u32 = 1; +pub const RV_PLIC_IP_4_P_130_BIT: u32 = 2; +pub const RV_PLIC_IP_4_P_131_BIT: u32 = 3; +pub const RV_PLIC_IP_4_P_132_BIT: u32 = 4; +pub const RV_PLIC_IP_4_P_133_BIT: u32 = 5; +pub const RV_PLIC_IP_4_P_134_BIT: u32 = 6; +pub const RV_PLIC_IP_4_P_135_BIT: u32 = 7; +pub const RV_PLIC_IP_4_P_136_BIT: u32 = 8; +pub const RV_PLIC_IP_4_P_137_BIT: u32 = 9; +pub const RV_PLIC_IP_4_P_138_BIT: u32 = 10; +pub const RV_PLIC_IP_4_P_139_BIT: u32 = 11; +pub const RV_PLIC_IP_4_P_140_BIT: u32 = 12; +pub const RV_PLIC_IP_4_P_141_BIT: u32 = 13; +pub const RV_PLIC_IP_4_P_142_BIT: u32 = 14; +pub const RV_PLIC_IP_4_P_143_BIT: u32 = 15; +pub const RV_PLIC_IP_4_P_144_BIT: u32 = 16; +pub const RV_PLIC_IP_4_P_145_BIT: u32 = 17; +pub const RV_PLIC_IP_4_P_146_BIT: u32 = 18; +pub const RV_PLIC_IP_4_P_147_BIT: u32 = 19; +pub const RV_PLIC_IP_4_P_148_BIT: u32 = 20; +pub const RV_PLIC_IP_4_P_149_BIT: u32 = 21; +pub const RV_PLIC_IP_4_P_150_BIT: u32 = 22; +pub const RV_PLIC_IP_4_P_151_BIT: u32 = 23; +pub const RV_PLIC_IP_4_P_152_BIT: u32 = 24; +pub const RV_PLIC_IP_4_P_153_BIT: u32 = 25; +pub const RV_PLIC_IP_4_P_154_BIT: u32 = 26; +pub const RV_PLIC_IP_4_P_155_BIT: u32 = 27; +pub const RV_PLIC_IP_4_P_156_BIT: u32 = 28; +pub const RV_PLIC_IP_4_P_157_BIT: u32 = 29; +pub const RV_PLIC_IP_4_P_158_BIT: u32 = 30; +pub const RV_PLIC_IP_4_P_159_BIT: u32 = 31; + +// Interrupt Pending +pub const RV_PLIC_IP_5_REG_OFFSET: usize = 0x14; +pub const RV_PLIC_IP_5_P_160_BIT: u32 = 0; +pub const RV_PLIC_IP_5_P_161_BIT: u32 = 1; +pub const RV_PLIC_IP_5_P_162_BIT: u32 = 2; +pub const RV_PLIC_IP_5_P_163_BIT: u32 = 3; +pub const RV_PLIC_IP_5_P_164_BIT: u32 = 4; +pub const RV_PLIC_IP_5_P_165_BIT: u32 = 5; +pub const RV_PLIC_IP_5_P_166_BIT: u32 = 6; +pub const RV_PLIC_IP_5_P_167_BIT: u32 = 7; +pub const RV_PLIC_IP_5_P_168_BIT: u32 = 8; +pub const RV_PLIC_IP_5_P_169_BIT: u32 = 9; +pub const RV_PLIC_IP_5_P_170_BIT: u32 = 10; +pub const RV_PLIC_IP_5_P_171_BIT: u32 = 11; +pub const RV_PLIC_IP_5_P_172_BIT: u32 = 12; +pub const RV_PLIC_IP_5_P_173_BIT: u32 = 13; +pub const RV_PLIC_IP_5_P_174_BIT: u32 = 14; +pub const RV_PLIC_IP_5_P_175_BIT: u32 = 15; +pub const RV_PLIC_IP_5_P_176_BIT: u32 = 16; +pub const RV_PLIC_IP_5_P_177_BIT: u32 = 17; +pub const RV_PLIC_IP_5_P_178_BIT: u32 = 18; +pub const RV_PLIC_IP_5_P_179_BIT: u32 = 19; +pub const RV_PLIC_IP_5_P_180_BIT: u32 = 20; +pub const RV_PLIC_IP_5_P_181_BIT: u32 = 21; +pub const RV_PLIC_IP_5_P_182_BIT: u32 = 22; + +// Interrupt Source mode. 0: Level, 1: Edge-triggered (common parameters) +pub const RV_PLIC_LE_LE_FIELD_WIDTH: u32 = 1; +pub const RV_PLIC_LE_LE_FIELDS_PER_REG: u32 = 32; +pub const RV_PLIC_LE_MULTIREG_COUNT: u32 = 6; + +// Interrupt Source mode. 0: Level, 1: Edge-triggered +pub const RV_PLIC_LE_0_REG_OFFSET: usize = 0x18; +pub const RV_PLIC_LE_0_LE_0_BIT: u32 = 0; +pub const RV_PLIC_LE_0_LE_1_BIT: u32 = 1; +pub const RV_PLIC_LE_0_LE_2_BIT: u32 = 2; +pub const RV_PLIC_LE_0_LE_3_BIT: u32 = 3; +pub const RV_PLIC_LE_0_LE_4_BIT: u32 = 4; +pub const RV_PLIC_LE_0_LE_5_BIT: u32 = 5; +pub const RV_PLIC_LE_0_LE_6_BIT: u32 = 6; +pub const RV_PLIC_LE_0_LE_7_BIT: u32 = 7; +pub const RV_PLIC_LE_0_LE_8_BIT: u32 = 8; +pub const RV_PLIC_LE_0_LE_9_BIT: u32 = 9; +pub const RV_PLIC_LE_0_LE_10_BIT: u32 = 10; +pub const RV_PLIC_LE_0_LE_11_BIT: u32 = 11; +pub const RV_PLIC_LE_0_LE_12_BIT: u32 = 12; +pub const RV_PLIC_LE_0_LE_13_BIT: u32 = 13; +pub const RV_PLIC_LE_0_LE_14_BIT: u32 = 14; +pub const RV_PLIC_LE_0_LE_15_BIT: u32 = 15; +pub const RV_PLIC_LE_0_LE_16_BIT: u32 = 16; +pub const RV_PLIC_LE_0_LE_17_BIT: u32 = 17; +pub const RV_PLIC_LE_0_LE_18_BIT: u32 = 18; +pub const RV_PLIC_LE_0_LE_19_BIT: u32 = 19; +pub const RV_PLIC_LE_0_LE_20_BIT: u32 = 20; +pub const RV_PLIC_LE_0_LE_21_BIT: u32 = 21; +pub const RV_PLIC_LE_0_LE_22_BIT: u32 = 22; +pub const RV_PLIC_LE_0_LE_23_BIT: u32 = 23; +pub const RV_PLIC_LE_0_LE_24_BIT: u32 = 24; +pub const RV_PLIC_LE_0_LE_25_BIT: u32 = 25; +pub const RV_PLIC_LE_0_LE_26_BIT: u32 = 26; +pub const RV_PLIC_LE_0_LE_27_BIT: u32 = 27; +pub const RV_PLIC_LE_0_LE_28_BIT: u32 = 28; +pub const RV_PLIC_LE_0_LE_29_BIT: u32 = 29; +pub const RV_PLIC_LE_0_LE_30_BIT: u32 = 30; +pub const RV_PLIC_LE_0_LE_31_BIT: u32 = 31; + +// Interrupt Source mode. 0: Level, 1: Edge-triggered +pub const RV_PLIC_LE_1_REG_OFFSET: usize = 0x1c; +pub const RV_PLIC_LE_1_LE_32_BIT: u32 = 0; +pub const RV_PLIC_LE_1_LE_33_BIT: u32 = 1; +pub const RV_PLIC_LE_1_LE_34_BIT: u32 = 2; +pub const RV_PLIC_LE_1_LE_35_BIT: u32 = 3; +pub const RV_PLIC_LE_1_LE_36_BIT: u32 = 4; +pub const RV_PLIC_LE_1_LE_37_BIT: u32 = 5; +pub const RV_PLIC_LE_1_LE_38_BIT: u32 = 6; +pub const RV_PLIC_LE_1_LE_39_BIT: u32 = 7; +pub const RV_PLIC_LE_1_LE_40_BIT: u32 = 8; +pub const RV_PLIC_LE_1_LE_41_BIT: u32 = 9; +pub const RV_PLIC_LE_1_LE_42_BIT: u32 = 10; +pub const RV_PLIC_LE_1_LE_43_BIT: u32 = 11; +pub const RV_PLIC_LE_1_LE_44_BIT: u32 = 12; +pub const RV_PLIC_LE_1_LE_45_BIT: u32 = 13; +pub const RV_PLIC_LE_1_LE_46_BIT: u32 = 14; +pub const RV_PLIC_LE_1_LE_47_BIT: u32 = 15; +pub const RV_PLIC_LE_1_LE_48_BIT: u32 = 16; +pub const RV_PLIC_LE_1_LE_49_BIT: u32 = 17; +pub const RV_PLIC_LE_1_LE_50_BIT: u32 = 18; +pub const RV_PLIC_LE_1_LE_51_BIT: u32 = 19; +pub const RV_PLIC_LE_1_LE_52_BIT: u32 = 20; +pub const RV_PLIC_LE_1_LE_53_BIT: u32 = 21; +pub const RV_PLIC_LE_1_LE_54_BIT: u32 = 22; +pub const RV_PLIC_LE_1_LE_55_BIT: u32 = 23; +pub const RV_PLIC_LE_1_LE_56_BIT: u32 = 24; +pub const RV_PLIC_LE_1_LE_57_BIT: u32 = 25; +pub const RV_PLIC_LE_1_LE_58_BIT: u32 = 26; +pub const RV_PLIC_LE_1_LE_59_BIT: u32 = 27; +pub const RV_PLIC_LE_1_LE_60_BIT: u32 = 28; +pub const RV_PLIC_LE_1_LE_61_BIT: u32 = 29; +pub const RV_PLIC_LE_1_LE_62_BIT: u32 = 30; +pub const RV_PLIC_LE_1_LE_63_BIT: u32 = 31; + +// Interrupt Source mode. 0: Level, 1: Edge-triggered +pub const RV_PLIC_LE_2_REG_OFFSET: usize = 0x20; +pub const RV_PLIC_LE_2_LE_64_BIT: u32 = 0; +pub const RV_PLIC_LE_2_LE_65_BIT: u32 = 1; +pub const RV_PLIC_LE_2_LE_66_BIT: u32 = 2; +pub const RV_PLIC_LE_2_LE_67_BIT: u32 = 3; +pub const RV_PLIC_LE_2_LE_68_BIT: u32 = 4; +pub const RV_PLIC_LE_2_LE_69_BIT: u32 = 5; +pub const RV_PLIC_LE_2_LE_70_BIT: u32 = 6; +pub const RV_PLIC_LE_2_LE_71_BIT: u32 = 7; +pub const RV_PLIC_LE_2_LE_72_BIT: u32 = 8; +pub const RV_PLIC_LE_2_LE_73_BIT: u32 = 9; +pub const RV_PLIC_LE_2_LE_74_BIT: u32 = 10; +pub const RV_PLIC_LE_2_LE_75_BIT: u32 = 11; +pub const RV_PLIC_LE_2_LE_76_BIT: u32 = 12; +pub const RV_PLIC_LE_2_LE_77_BIT: u32 = 13; +pub const RV_PLIC_LE_2_LE_78_BIT: u32 = 14; +pub const RV_PLIC_LE_2_LE_79_BIT: u32 = 15; +pub const RV_PLIC_LE_2_LE_80_BIT: u32 = 16; +pub const RV_PLIC_LE_2_LE_81_BIT: u32 = 17; +pub const RV_PLIC_LE_2_LE_82_BIT: u32 = 18; +pub const RV_PLIC_LE_2_LE_83_BIT: u32 = 19; +pub const RV_PLIC_LE_2_LE_84_BIT: u32 = 20; +pub const RV_PLIC_LE_2_LE_85_BIT: u32 = 21; +pub const RV_PLIC_LE_2_LE_86_BIT: u32 = 22; +pub const RV_PLIC_LE_2_LE_87_BIT: u32 = 23; +pub const RV_PLIC_LE_2_LE_88_BIT: u32 = 24; +pub const RV_PLIC_LE_2_LE_89_BIT: u32 = 25; +pub const RV_PLIC_LE_2_LE_90_BIT: u32 = 26; +pub const RV_PLIC_LE_2_LE_91_BIT: u32 = 27; +pub const RV_PLIC_LE_2_LE_92_BIT: u32 = 28; +pub const RV_PLIC_LE_2_LE_93_BIT: u32 = 29; +pub const RV_PLIC_LE_2_LE_94_BIT: u32 = 30; +pub const RV_PLIC_LE_2_LE_95_BIT: u32 = 31; + +// Interrupt Source mode. 0: Level, 1: Edge-triggered +pub const RV_PLIC_LE_3_REG_OFFSET: usize = 0x24; +pub const RV_PLIC_LE_3_LE_96_BIT: u32 = 0; +pub const RV_PLIC_LE_3_LE_97_BIT: u32 = 1; +pub const RV_PLIC_LE_3_LE_98_BIT: u32 = 2; +pub const RV_PLIC_LE_3_LE_99_BIT: u32 = 3; +pub const RV_PLIC_LE_3_LE_100_BIT: u32 = 4; +pub const RV_PLIC_LE_3_LE_101_BIT: u32 = 5; +pub const RV_PLIC_LE_3_LE_102_BIT: u32 = 6; +pub const RV_PLIC_LE_3_LE_103_BIT: u32 = 7; +pub const RV_PLIC_LE_3_LE_104_BIT: u32 = 8; +pub const RV_PLIC_LE_3_LE_105_BIT: u32 = 9; +pub const RV_PLIC_LE_3_LE_106_BIT: u32 = 10; +pub const RV_PLIC_LE_3_LE_107_BIT: u32 = 11; +pub const RV_PLIC_LE_3_LE_108_BIT: u32 = 12; +pub const RV_PLIC_LE_3_LE_109_BIT: u32 = 13; +pub const RV_PLIC_LE_3_LE_110_BIT: u32 = 14; +pub const RV_PLIC_LE_3_LE_111_BIT: u32 = 15; +pub const RV_PLIC_LE_3_LE_112_BIT: u32 = 16; +pub const RV_PLIC_LE_3_LE_113_BIT: u32 = 17; +pub const RV_PLIC_LE_3_LE_114_BIT: u32 = 18; +pub const RV_PLIC_LE_3_LE_115_BIT: u32 = 19; +pub const RV_PLIC_LE_3_LE_116_BIT: u32 = 20; +pub const RV_PLIC_LE_3_LE_117_BIT: u32 = 21; +pub const RV_PLIC_LE_3_LE_118_BIT: u32 = 22; +pub const RV_PLIC_LE_3_LE_119_BIT: u32 = 23; +pub const RV_PLIC_LE_3_LE_120_BIT: u32 = 24; +pub const RV_PLIC_LE_3_LE_121_BIT: u32 = 25; +pub const RV_PLIC_LE_3_LE_122_BIT: u32 = 26; +pub const RV_PLIC_LE_3_LE_123_BIT: u32 = 27; +pub const RV_PLIC_LE_3_LE_124_BIT: u32 = 28; +pub const RV_PLIC_LE_3_LE_125_BIT: u32 = 29; +pub const RV_PLIC_LE_3_LE_126_BIT: u32 = 30; +pub const RV_PLIC_LE_3_LE_127_BIT: u32 = 31; + +// Interrupt Source mode. 0: Level, 1: Edge-triggered +pub const RV_PLIC_LE_4_REG_OFFSET: usize = 0x28; +pub const RV_PLIC_LE_4_LE_128_BIT: u32 = 0; +pub const RV_PLIC_LE_4_LE_129_BIT: u32 = 1; +pub const RV_PLIC_LE_4_LE_130_BIT: u32 = 2; +pub const RV_PLIC_LE_4_LE_131_BIT: u32 = 3; +pub const RV_PLIC_LE_4_LE_132_BIT: u32 = 4; +pub const RV_PLIC_LE_4_LE_133_BIT: u32 = 5; +pub const RV_PLIC_LE_4_LE_134_BIT: u32 = 6; +pub const RV_PLIC_LE_4_LE_135_BIT: u32 = 7; +pub const RV_PLIC_LE_4_LE_136_BIT: u32 = 8; +pub const RV_PLIC_LE_4_LE_137_BIT: u32 = 9; +pub const RV_PLIC_LE_4_LE_138_BIT: u32 = 10; +pub const RV_PLIC_LE_4_LE_139_BIT: u32 = 11; +pub const RV_PLIC_LE_4_LE_140_BIT: u32 = 12; +pub const RV_PLIC_LE_4_LE_141_BIT: u32 = 13; +pub const RV_PLIC_LE_4_LE_142_BIT: u32 = 14; +pub const RV_PLIC_LE_4_LE_143_BIT: u32 = 15; +pub const RV_PLIC_LE_4_LE_144_BIT: u32 = 16; +pub const RV_PLIC_LE_4_LE_145_BIT: u32 = 17; +pub const RV_PLIC_LE_4_LE_146_BIT: u32 = 18; +pub const RV_PLIC_LE_4_LE_147_BIT: u32 = 19; +pub const RV_PLIC_LE_4_LE_148_BIT: u32 = 20; +pub const RV_PLIC_LE_4_LE_149_BIT: u32 = 21; +pub const RV_PLIC_LE_4_LE_150_BIT: u32 = 22; +pub const RV_PLIC_LE_4_LE_151_BIT: u32 = 23; +pub const RV_PLIC_LE_4_LE_152_BIT: u32 = 24; +pub const RV_PLIC_LE_4_LE_153_BIT: u32 = 25; +pub const RV_PLIC_LE_4_LE_154_BIT: u32 = 26; +pub const RV_PLIC_LE_4_LE_155_BIT: u32 = 27; +pub const RV_PLIC_LE_4_LE_156_BIT: u32 = 28; +pub const RV_PLIC_LE_4_LE_157_BIT: u32 = 29; +pub const RV_PLIC_LE_4_LE_158_BIT: u32 = 30; +pub const RV_PLIC_LE_4_LE_159_BIT: u32 = 31; + +// Interrupt Source mode. 0: Level, 1: Edge-triggered +pub const RV_PLIC_LE_5_REG_OFFSET: usize = 0x2c; +pub const RV_PLIC_LE_5_LE_160_BIT: u32 = 0; +pub const RV_PLIC_LE_5_LE_161_BIT: u32 = 1; +pub const RV_PLIC_LE_5_LE_162_BIT: u32 = 2; +pub const RV_PLIC_LE_5_LE_163_BIT: u32 = 3; +pub const RV_PLIC_LE_5_LE_164_BIT: u32 = 4; +pub const RV_PLIC_LE_5_LE_165_BIT: u32 = 5; +pub const RV_PLIC_LE_5_LE_166_BIT: u32 = 6; +pub const RV_PLIC_LE_5_LE_167_BIT: u32 = 7; +pub const RV_PLIC_LE_5_LE_168_BIT: u32 = 8; +pub const RV_PLIC_LE_5_LE_169_BIT: u32 = 9; +pub const RV_PLIC_LE_5_LE_170_BIT: u32 = 10; +pub const RV_PLIC_LE_5_LE_171_BIT: u32 = 11; +pub const RV_PLIC_LE_5_LE_172_BIT: u32 = 12; +pub const RV_PLIC_LE_5_LE_173_BIT: u32 = 13; +pub const RV_PLIC_LE_5_LE_174_BIT: u32 = 14; +pub const RV_PLIC_LE_5_LE_175_BIT: u32 = 15; +pub const RV_PLIC_LE_5_LE_176_BIT: u32 = 16; +pub const RV_PLIC_LE_5_LE_177_BIT: u32 = 17; +pub const RV_PLIC_LE_5_LE_178_BIT: u32 = 18; +pub const RV_PLIC_LE_5_LE_179_BIT: u32 = 19; +pub const RV_PLIC_LE_5_LE_180_BIT: u32 = 20; +pub const RV_PLIC_LE_5_LE_181_BIT: u32 = 21; +pub const RV_PLIC_LE_5_LE_182_BIT: u32 = 22; + +// Interrupt Source 0 Priority +pub const RV_PLIC_PRIO0_REG_OFFSET: usize = 0x30; +pub const RV_PLIC_PRIO0_PRIO0_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO0_PRIO0_OFFSET: usize = 0; + +// Interrupt Source 1 Priority +pub const RV_PLIC_PRIO1_REG_OFFSET: usize = 0x34; +pub const RV_PLIC_PRIO1_PRIO1_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO1_PRIO1_OFFSET: usize = 0; + +// Interrupt Source 2 Priority +pub const RV_PLIC_PRIO2_REG_OFFSET: usize = 0x38; +pub const RV_PLIC_PRIO2_PRIO2_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO2_PRIO2_OFFSET: usize = 0; + +// Interrupt Source 3 Priority +pub const RV_PLIC_PRIO3_REG_OFFSET: usize = 0x3c; +pub const RV_PLIC_PRIO3_PRIO3_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO3_PRIO3_OFFSET: usize = 0; + +// Interrupt Source 4 Priority +pub const RV_PLIC_PRIO4_REG_OFFSET: usize = 0x40; +pub const RV_PLIC_PRIO4_PRIO4_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO4_PRIO4_OFFSET: usize = 0; + +// Interrupt Source 5 Priority +pub const RV_PLIC_PRIO5_REG_OFFSET: usize = 0x44; +pub const RV_PLIC_PRIO5_PRIO5_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO5_PRIO5_OFFSET: usize = 0; + +// Interrupt Source 6 Priority +pub const RV_PLIC_PRIO6_REG_OFFSET: usize = 0x48; +pub const RV_PLIC_PRIO6_PRIO6_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO6_PRIO6_OFFSET: usize = 0; + +// Interrupt Source 7 Priority +pub const RV_PLIC_PRIO7_REG_OFFSET: usize = 0x4c; +pub const RV_PLIC_PRIO7_PRIO7_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO7_PRIO7_OFFSET: usize = 0; + +// Interrupt Source 8 Priority +pub const RV_PLIC_PRIO8_REG_OFFSET: usize = 0x50; +pub const RV_PLIC_PRIO8_PRIO8_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO8_PRIO8_OFFSET: usize = 0; + +// Interrupt Source 9 Priority +pub const RV_PLIC_PRIO9_REG_OFFSET: usize = 0x54; +pub const RV_PLIC_PRIO9_PRIO9_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO9_PRIO9_OFFSET: usize = 0; + +// Interrupt Source 10 Priority +pub const RV_PLIC_PRIO10_REG_OFFSET: usize = 0x58; +pub const RV_PLIC_PRIO10_PRIO10_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO10_PRIO10_OFFSET: usize = 0; + +// Interrupt Source 11 Priority +pub const RV_PLIC_PRIO11_REG_OFFSET: usize = 0x5c; +pub const RV_PLIC_PRIO11_PRIO11_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO11_PRIO11_OFFSET: usize = 0; + +// Interrupt Source 12 Priority +pub const RV_PLIC_PRIO12_REG_OFFSET: usize = 0x60; +pub const RV_PLIC_PRIO12_PRIO12_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO12_PRIO12_OFFSET: usize = 0; + +// Interrupt Source 13 Priority +pub const RV_PLIC_PRIO13_REG_OFFSET: usize = 0x64; +pub const RV_PLIC_PRIO13_PRIO13_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO13_PRIO13_OFFSET: usize = 0; + +// Interrupt Source 14 Priority +pub const RV_PLIC_PRIO14_REG_OFFSET: usize = 0x68; +pub const RV_PLIC_PRIO14_PRIO14_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO14_PRIO14_OFFSET: usize = 0; + +// Interrupt Source 15 Priority +pub const RV_PLIC_PRIO15_REG_OFFSET: usize = 0x6c; +pub const RV_PLIC_PRIO15_PRIO15_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO15_PRIO15_OFFSET: usize = 0; + +// Interrupt Source 16 Priority +pub const RV_PLIC_PRIO16_REG_OFFSET: usize = 0x70; +pub const RV_PLIC_PRIO16_PRIO16_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO16_PRIO16_OFFSET: usize = 0; + +// Interrupt Source 17 Priority +pub const RV_PLIC_PRIO17_REG_OFFSET: usize = 0x74; +pub const RV_PLIC_PRIO17_PRIO17_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO17_PRIO17_OFFSET: usize = 0; + +// Interrupt Source 18 Priority +pub const RV_PLIC_PRIO18_REG_OFFSET: usize = 0x78; +pub const RV_PLIC_PRIO18_PRIO18_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO18_PRIO18_OFFSET: usize = 0; + +// Interrupt Source 19 Priority +pub const RV_PLIC_PRIO19_REG_OFFSET: usize = 0x7c; +pub const RV_PLIC_PRIO19_PRIO19_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO19_PRIO19_OFFSET: usize = 0; + +// Interrupt Source 20 Priority +pub const RV_PLIC_PRIO20_REG_OFFSET: usize = 0x80; +pub const RV_PLIC_PRIO20_PRIO20_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO20_PRIO20_OFFSET: usize = 0; + +// Interrupt Source 21 Priority +pub const RV_PLIC_PRIO21_REG_OFFSET: usize = 0x84; +pub const RV_PLIC_PRIO21_PRIO21_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO21_PRIO21_OFFSET: usize = 0; + +// Interrupt Source 22 Priority +pub const RV_PLIC_PRIO22_REG_OFFSET: usize = 0x88; +pub const RV_PLIC_PRIO22_PRIO22_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO22_PRIO22_OFFSET: usize = 0; + +// Interrupt Source 23 Priority +pub const RV_PLIC_PRIO23_REG_OFFSET: usize = 0x8c; +pub const RV_PLIC_PRIO23_PRIO23_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO23_PRIO23_OFFSET: usize = 0; + +// Interrupt Source 24 Priority +pub const RV_PLIC_PRIO24_REG_OFFSET: usize = 0x90; +pub const RV_PLIC_PRIO24_PRIO24_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO24_PRIO24_OFFSET: usize = 0; + +// Interrupt Source 25 Priority +pub const RV_PLIC_PRIO25_REG_OFFSET: usize = 0x94; +pub const RV_PLIC_PRIO25_PRIO25_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO25_PRIO25_OFFSET: usize = 0; + +// Interrupt Source 26 Priority +pub const RV_PLIC_PRIO26_REG_OFFSET: usize = 0x98; +pub const RV_PLIC_PRIO26_PRIO26_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO26_PRIO26_OFFSET: usize = 0; + +// Interrupt Source 27 Priority +pub const RV_PLIC_PRIO27_REG_OFFSET: usize = 0x9c; +pub const RV_PLIC_PRIO27_PRIO27_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO27_PRIO27_OFFSET: usize = 0; + +// Interrupt Source 28 Priority +pub const RV_PLIC_PRIO28_REG_OFFSET: usize = 0xa0; +pub const RV_PLIC_PRIO28_PRIO28_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO28_PRIO28_OFFSET: usize = 0; + +// Interrupt Source 29 Priority +pub const RV_PLIC_PRIO29_REG_OFFSET: usize = 0xa4; +pub const RV_PLIC_PRIO29_PRIO29_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO29_PRIO29_OFFSET: usize = 0; + +// Interrupt Source 30 Priority +pub const RV_PLIC_PRIO30_REG_OFFSET: usize = 0xa8; +pub const RV_PLIC_PRIO30_PRIO30_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO30_PRIO30_OFFSET: usize = 0; + +// Interrupt Source 31 Priority +pub const RV_PLIC_PRIO31_REG_OFFSET: usize = 0xac; +pub const RV_PLIC_PRIO31_PRIO31_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO31_PRIO31_OFFSET: usize = 0; + +// Interrupt Source 32 Priority +pub const RV_PLIC_PRIO32_REG_OFFSET: usize = 0xb0; +pub const RV_PLIC_PRIO32_PRIO32_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO32_PRIO32_OFFSET: usize = 0; + +// Interrupt Source 33 Priority +pub const RV_PLIC_PRIO33_REG_OFFSET: usize = 0xb4; +pub const RV_PLIC_PRIO33_PRIO33_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO33_PRIO33_OFFSET: usize = 0; + +// Interrupt Source 34 Priority +pub const RV_PLIC_PRIO34_REG_OFFSET: usize = 0xb8; +pub const RV_PLIC_PRIO34_PRIO34_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO34_PRIO34_OFFSET: usize = 0; + +// Interrupt Source 35 Priority +pub const RV_PLIC_PRIO35_REG_OFFSET: usize = 0xbc; +pub const RV_PLIC_PRIO35_PRIO35_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO35_PRIO35_OFFSET: usize = 0; + +// Interrupt Source 36 Priority +pub const RV_PLIC_PRIO36_REG_OFFSET: usize = 0xc0; +pub const RV_PLIC_PRIO36_PRIO36_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO36_PRIO36_OFFSET: usize = 0; + +// Interrupt Source 37 Priority +pub const RV_PLIC_PRIO37_REG_OFFSET: usize = 0xc4; +pub const RV_PLIC_PRIO37_PRIO37_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO37_PRIO37_OFFSET: usize = 0; + +// Interrupt Source 38 Priority +pub const RV_PLIC_PRIO38_REG_OFFSET: usize = 0xc8; +pub const RV_PLIC_PRIO38_PRIO38_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO38_PRIO38_OFFSET: usize = 0; + +// Interrupt Source 39 Priority +pub const RV_PLIC_PRIO39_REG_OFFSET: usize = 0xcc; +pub const RV_PLIC_PRIO39_PRIO39_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO39_PRIO39_OFFSET: usize = 0; + +// Interrupt Source 40 Priority +pub const RV_PLIC_PRIO40_REG_OFFSET: usize = 0xd0; +pub const RV_PLIC_PRIO40_PRIO40_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO40_PRIO40_OFFSET: usize = 0; + +// Interrupt Source 41 Priority +pub const RV_PLIC_PRIO41_REG_OFFSET: usize = 0xd4; +pub const RV_PLIC_PRIO41_PRIO41_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO41_PRIO41_OFFSET: usize = 0; + +// Interrupt Source 42 Priority +pub const RV_PLIC_PRIO42_REG_OFFSET: usize = 0xd8; +pub const RV_PLIC_PRIO42_PRIO42_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO42_PRIO42_OFFSET: usize = 0; + +// Interrupt Source 43 Priority +pub const RV_PLIC_PRIO43_REG_OFFSET: usize = 0xdc; +pub const RV_PLIC_PRIO43_PRIO43_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO43_PRIO43_OFFSET: usize = 0; + +// Interrupt Source 44 Priority +pub const RV_PLIC_PRIO44_REG_OFFSET: usize = 0xe0; +pub const RV_PLIC_PRIO44_PRIO44_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO44_PRIO44_OFFSET: usize = 0; + +// Interrupt Source 45 Priority +pub const RV_PLIC_PRIO45_REG_OFFSET: usize = 0xe4; +pub const RV_PLIC_PRIO45_PRIO45_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO45_PRIO45_OFFSET: usize = 0; + +// Interrupt Source 46 Priority +pub const RV_PLIC_PRIO46_REG_OFFSET: usize = 0xe8; +pub const RV_PLIC_PRIO46_PRIO46_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO46_PRIO46_OFFSET: usize = 0; + +// Interrupt Source 47 Priority +pub const RV_PLIC_PRIO47_REG_OFFSET: usize = 0xec; +pub const RV_PLIC_PRIO47_PRIO47_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO47_PRIO47_OFFSET: usize = 0; + +// Interrupt Source 48 Priority +pub const RV_PLIC_PRIO48_REG_OFFSET: usize = 0xf0; +pub const RV_PLIC_PRIO48_PRIO48_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO48_PRIO48_OFFSET: usize = 0; + +// Interrupt Source 49 Priority +pub const RV_PLIC_PRIO49_REG_OFFSET: usize = 0xf4; +pub const RV_PLIC_PRIO49_PRIO49_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO49_PRIO49_OFFSET: usize = 0; + +// Interrupt Source 50 Priority +pub const RV_PLIC_PRIO50_REG_OFFSET: usize = 0xf8; +pub const RV_PLIC_PRIO50_PRIO50_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO50_PRIO50_OFFSET: usize = 0; + +// Interrupt Source 51 Priority +pub const RV_PLIC_PRIO51_REG_OFFSET: usize = 0xfc; +pub const RV_PLIC_PRIO51_PRIO51_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO51_PRIO51_OFFSET: usize = 0; + +// Interrupt Source 52 Priority +pub const RV_PLIC_PRIO52_REG_OFFSET: usize = 0x100; +pub const RV_PLIC_PRIO52_PRIO52_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO52_PRIO52_OFFSET: usize = 0; + +// Interrupt Source 53 Priority +pub const RV_PLIC_PRIO53_REG_OFFSET: usize = 0x104; +pub const RV_PLIC_PRIO53_PRIO53_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO53_PRIO53_OFFSET: usize = 0; + +// Interrupt Source 54 Priority +pub const RV_PLIC_PRIO54_REG_OFFSET: usize = 0x108; +pub const RV_PLIC_PRIO54_PRIO54_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO54_PRIO54_OFFSET: usize = 0; + +// Interrupt Source 55 Priority +pub const RV_PLIC_PRIO55_REG_OFFSET: usize = 0x10c; +pub const RV_PLIC_PRIO55_PRIO55_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO55_PRIO55_OFFSET: usize = 0; + +// Interrupt Source 56 Priority +pub const RV_PLIC_PRIO56_REG_OFFSET: usize = 0x110; +pub const RV_PLIC_PRIO56_PRIO56_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO56_PRIO56_OFFSET: usize = 0; + +// Interrupt Source 57 Priority +pub const RV_PLIC_PRIO57_REG_OFFSET: usize = 0x114; +pub const RV_PLIC_PRIO57_PRIO57_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO57_PRIO57_OFFSET: usize = 0; + +// Interrupt Source 58 Priority +pub const RV_PLIC_PRIO58_REG_OFFSET: usize = 0x118; +pub const RV_PLIC_PRIO58_PRIO58_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO58_PRIO58_OFFSET: usize = 0; + +// Interrupt Source 59 Priority +pub const RV_PLIC_PRIO59_REG_OFFSET: usize = 0x11c; +pub const RV_PLIC_PRIO59_PRIO59_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO59_PRIO59_OFFSET: usize = 0; + +// Interrupt Source 60 Priority +pub const RV_PLIC_PRIO60_REG_OFFSET: usize = 0x120; +pub const RV_PLIC_PRIO60_PRIO60_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO60_PRIO60_OFFSET: usize = 0; + +// Interrupt Source 61 Priority +pub const RV_PLIC_PRIO61_REG_OFFSET: usize = 0x124; +pub const RV_PLIC_PRIO61_PRIO61_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO61_PRIO61_OFFSET: usize = 0; + +// Interrupt Source 62 Priority +pub const RV_PLIC_PRIO62_REG_OFFSET: usize = 0x128; +pub const RV_PLIC_PRIO62_PRIO62_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO62_PRIO62_OFFSET: usize = 0; + +// Interrupt Source 63 Priority +pub const RV_PLIC_PRIO63_REG_OFFSET: usize = 0x12c; +pub const RV_PLIC_PRIO63_PRIO63_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO63_PRIO63_OFFSET: usize = 0; + +// Interrupt Source 64 Priority +pub const RV_PLIC_PRIO64_REG_OFFSET: usize = 0x130; +pub const RV_PLIC_PRIO64_PRIO64_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO64_PRIO64_OFFSET: usize = 0; + +// Interrupt Source 65 Priority +pub const RV_PLIC_PRIO65_REG_OFFSET: usize = 0x134; +pub const RV_PLIC_PRIO65_PRIO65_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO65_PRIO65_OFFSET: usize = 0; + +// Interrupt Source 66 Priority +pub const RV_PLIC_PRIO66_REG_OFFSET: usize = 0x138; +pub const RV_PLIC_PRIO66_PRIO66_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO66_PRIO66_OFFSET: usize = 0; + +// Interrupt Source 67 Priority +pub const RV_PLIC_PRIO67_REG_OFFSET: usize = 0x13c; +pub const RV_PLIC_PRIO67_PRIO67_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO67_PRIO67_OFFSET: usize = 0; + +// Interrupt Source 68 Priority +pub const RV_PLIC_PRIO68_REG_OFFSET: usize = 0x140; +pub const RV_PLIC_PRIO68_PRIO68_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO68_PRIO68_OFFSET: usize = 0; + +// Interrupt Source 69 Priority +pub const RV_PLIC_PRIO69_REG_OFFSET: usize = 0x144; +pub const RV_PLIC_PRIO69_PRIO69_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO69_PRIO69_OFFSET: usize = 0; + +// Interrupt Source 70 Priority +pub const RV_PLIC_PRIO70_REG_OFFSET: usize = 0x148; +pub const RV_PLIC_PRIO70_PRIO70_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO70_PRIO70_OFFSET: usize = 0; + +// Interrupt Source 71 Priority +pub const RV_PLIC_PRIO71_REG_OFFSET: usize = 0x14c; +pub const RV_PLIC_PRIO71_PRIO71_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO71_PRIO71_OFFSET: usize = 0; + +// Interrupt Source 72 Priority +pub const RV_PLIC_PRIO72_REG_OFFSET: usize = 0x150; +pub const RV_PLIC_PRIO72_PRIO72_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO72_PRIO72_OFFSET: usize = 0; + +// Interrupt Source 73 Priority +pub const RV_PLIC_PRIO73_REG_OFFSET: usize = 0x154; +pub const RV_PLIC_PRIO73_PRIO73_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO73_PRIO73_OFFSET: usize = 0; + +// Interrupt Source 74 Priority +pub const RV_PLIC_PRIO74_REG_OFFSET: usize = 0x158; +pub const RV_PLIC_PRIO74_PRIO74_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO74_PRIO74_OFFSET: usize = 0; + +// Interrupt Source 75 Priority +pub const RV_PLIC_PRIO75_REG_OFFSET: usize = 0x15c; +pub const RV_PLIC_PRIO75_PRIO75_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO75_PRIO75_OFFSET: usize = 0; + +// Interrupt Source 76 Priority +pub const RV_PLIC_PRIO76_REG_OFFSET: usize = 0x160; +pub const RV_PLIC_PRIO76_PRIO76_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO76_PRIO76_OFFSET: usize = 0; + +// Interrupt Source 77 Priority +pub const RV_PLIC_PRIO77_REG_OFFSET: usize = 0x164; +pub const RV_PLIC_PRIO77_PRIO77_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO77_PRIO77_OFFSET: usize = 0; + +// Interrupt Source 78 Priority +pub const RV_PLIC_PRIO78_REG_OFFSET: usize = 0x168; +pub const RV_PLIC_PRIO78_PRIO78_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO78_PRIO78_OFFSET: usize = 0; + +// Interrupt Source 79 Priority +pub const RV_PLIC_PRIO79_REG_OFFSET: usize = 0x16c; +pub const RV_PLIC_PRIO79_PRIO79_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO79_PRIO79_OFFSET: usize = 0; + +// Interrupt Source 80 Priority +pub const RV_PLIC_PRIO80_REG_OFFSET: usize = 0x170; +pub const RV_PLIC_PRIO80_PRIO80_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO80_PRIO80_OFFSET: usize = 0; + +// Interrupt Source 81 Priority +pub const RV_PLIC_PRIO81_REG_OFFSET: usize = 0x174; +pub const RV_PLIC_PRIO81_PRIO81_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO81_PRIO81_OFFSET: usize = 0; + +// Interrupt Source 82 Priority +pub const RV_PLIC_PRIO82_REG_OFFSET: usize = 0x178; +pub const RV_PLIC_PRIO82_PRIO82_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO82_PRIO82_OFFSET: usize = 0; + +// Interrupt Source 83 Priority +pub const RV_PLIC_PRIO83_REG_OFFSET: usize = 0x17c; +pub const RV_PLIC_PRIO83_PRIO83_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO83_PRIO83_OFFSET: usize = 0; + +// Interrupt Source 84 Priority +pub const RV_PLIC_PRIO84_REG_OFFSET: usize = 0x180; +pub const RV_PLIC_PRIO84_PRIO84_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO84_PRIO84_OFFSET: usize = 0; + +// Interrupt Source 85 Priority +pub const RV_PLIC_PRIO85_REG_OFFSET: usize = 0x184; +pub const RV_PLIC_PRIO85_PRIO85_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO85_PRIO85_OFFSET: usize = 0; + +// Interrupt Source 86 Priority +pub const RV_PLIC_PRIO86_REG_OFFSET: usize = 0x188; +pub const RV_PLIC_PRIO86_PRIO86_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO86_PRIO86_OFFSET: usize = 0; + +// Interrupt Source 87 Priority +pub const RV_PLIC_PRIO87_REG_OFFSET: usize = 0x18c; +pub const RV_PLIC_PRIO87_PRIO87_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO87_PRIO87_OFFSET: usize = 0; + +// Interrupt Source 88 Priority +pub const RV_PLIC_PRIO88_REG_OFFSET: usize = 0x190; +pub const RV_PLIC_PRIO88_PRIO88_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO88_PRIO88_OFFSET: usize = 0; + +// Interrupt Source 89 Priority +pub const RV_PLIC_PRIO89_REG_OFFSET: usize = 0x194; +pub const RV_PLIC_PRIO89_PRIO89_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO89_PRIO89_OFFSET: usize = 0; + +// Interrupt Source 90 Priority +pub const RV_PLIC_PRIO90_REG_OFFSET: usize = 0x198; +pub const RV_PLIC_PRIO90_PRIO90_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO90_PRIO90_OFFSET: usize = 0; + +// Interrupt Source 91 Priority +pub const RV_PLIC_PRIO91_REG_OFFSET: usize = 0x19c; +pub const RV_PLIC_PRIO91_PRIO91_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO91_PRIO91_OFFSET: usize = 0; + +// Interrupt Source 92 Priority +pub const RV_PLIC_PRIO92_REG_OFFSET: usize = 0x1a0; +pub const RV_PLIC_PRIO92_PRIO92_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO92_PRIO92_OFFSET: usize = 0; + +// Interrupt Source 93 Priority +pub const RV_PLIC_PRIO93_REG_OFFSET: usize = 0x1a4; +pub const RV_PLIC_PRIO93_PRIO93_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO93_PRIO93_OFFSET: usize = 0; + +// Interrupt Source 94 Priority +pub const RV_PLIC_PRIO94_REG_OFFSET: usize = 0x1a8; +pub const RV_PLIC_PRIO94_PRIO94_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO94_PRIO94_OFFSET: usize = 0; + +// Interrupt Source 95 Priority +pub const RV_PLIC_PRIO95_REG_OFFSET: usize = 0x1ac; +pub const RV_PLIC_PRIO95_PRIO95_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO95_PRIO95_OFFSET: usize = 0; + +// Interrupt Source 96 Priority +pub const RV_PLIC_PRIO96_REG_OFFSET: usize = 0x1b0; +pub const RV_PLIC_PRIO96_PRIO96_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO96_PRIO96_OFFSET: usize = 0; + +// Interrupt Source 97 Priority +pub const RV_PLIC_PRIO97_REG_OFFSET: usize = 0x1b4; +pub const RV_PLIC_PRIO97_PRIO97_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO97_PRIO97_OFFSET: usize = 0; + +// Interrupt Source 98 Priority +pub const RV_PLIC_PRIO98_REG_OFFSET: usize = 0x1b8; +pub const RV_PLIC_PRIO98_PRIO98_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO98_PRIO98_OFFSET: usize = 0; + +// Interrupt Source 99 Priority +pub const RV_PLIC_PRIO99_REG_OFFSET: usize = 0x1bc; +pub const RV_PLIC_PRIO99_PRIO99_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO99_PRIO99_OFFSET: usize = 0; + +// Interrupt Source 100 Priority +pub const RV_PLIC_PRIO100_REG_OFFSET: usize = 0x1c0; +pub const RV_PLIC_PRIO100_PRIO100_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO100_PRIO100_OFFSET: usize = 0; + +// Interrupt Source 101 Priority +pub const RV_PLIC_PRIO101_REG_OFFSET: usize = 0x1c4; +pub const RV_PLIC_PRIO101_PRIO101_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO101_PRIO101_OFFSET: usize = 0; + +// Interrupt Source 102 Priority +pub const RV_PLIC_PRIO102_REG_OFFSET: usize = 0x1c8; +pub const RV_PLIC_PRIO102_PRIO102_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO102_PRIO102_OFFSET: usize = 0; + +// Interrupt Source 103 Priority +pub const RV_PLIC_PRIO103_REG_OFFSET: usize = 0x1cc; +pub const RV_PLIC_PRIO103_PRIO103_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO103_PRIO103_OFFSET: usize = 0; + +// Interrupt Source 104 Priority +pub const RV_PLIC_PRIO104_REG_OFFSET: usize = 0x1d0; +pub const RV_PLIC_PRIO104_PRIO104_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO104_PRIO104_OFFSET: usize = 0; + +// Interrupt Source 105 Priority +pub const RV_PLIC_PRIO105_REG_OFFSET: usize = 0x1d4; +pub const RV_PLIC_PRIO105_PRIO105_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO105_PRIO105_OFFSET: usize = 0; + +// Interrupt Source 106 Priority +pub const RV_PLIC_PRIO106_REG_OFFSET: usize = 0x1d8; +pub const RV_PLIC_PRIO106_PRIO106_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO106_PRIO106_OFFSET: usize = 0; + +// Interrupt Source 107 Priority +pub const RV_PLIC_PRIO107_REG_OFFSET: usize = 0x1dc; +pub const RV_PLIC_PRIO107_PRIO107_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO107_PRIO107_OFFSET: usize = 0; + +// Interrupt Source 108 Priority +pub const RV_PLIC_PRIO108_REG_OFFSET: usize = 0x1e0; +pub const RV_PLIC_PRIO108_PRIO108_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO108_PRIO108_OFFSET: usize = 0; + +// Interrupt Source 109 Priority +pub const RV_PLIC_PRIO109_REG_OFFSET: usize = 0x1e4; +pub const RV_PLIC_PRIO109_PRIO109_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO109_PRIO109_OFFSET: usize = 0; + +// Interrupt Source 110 Priority +pub const RV_PLIC_PRIO110_REG_OFFSET: usize = 0x1e8; +pub const RV_PLIC_PRIO110_PRIO110_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO110_PRIO110_OFFSET: usize = 0; + +// Interrupt Source 111 Priority +pub const RV_PLIC_PRIO111_REG_OFFSET: usize = 0x1ec; +pub const RV_PLIC_PRIO111_PRIO111_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO111_PRIO111_OFFSET: usize = 0; + +// Interrupt Source 112 Priority +pub const RV_PLIC_PRIO112_REG_OFFSET: usize = 0x1f0; +pub const RV_PLIC_PRIO112_PRIO112_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO112_PRIO112_OFFSET: usize = 0; + +// Interrupt Source 113 Priority +pub const RV_PLIC_PRIO113_REG_OFFSET: usize = 0x1f4; +pub const RV_PLIC_PRIO113_PRIO113_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO113_PRIO113_OFFSET: usize = 0; + +// Interrupt Source 114 Priority +pub const RV_PLIC_PRIO114_REG_OFFSET: usize = 0x1f8; +pub const RV_PLIC_PRIO114_PRIO114_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO114_PRIO114_OFFSET: usize = 0; + +// Interrupt Source 115 Priority +pub const RV_PLIC_PRIO115_REG_OFFSET: usize = 0x1fc; +pub const RV_PLIC_PRIO115_PRIO115_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO115_PRIO115_OFFSET: usize = 0; + +// Interrupt Source 116 Priority +pub const RV_PLIC_PRIO116_REG_OFFSET: usize = 0x200; +pub const RV_PLIC_PRIO116_PRIO116_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO116_PRIO116_OFFSET: usize = 0; + +// Interrupt Source 117 Priority +pub const RV_PLIC_PRIO117_REG_OFFSET: usize = 0x204; +pub const RV_PLIC_PRIO117_PRIO117_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO117_PRIO117_OFFSET: usize = 0; + +// Interrupt Source 118 Priority +pub const RV_PLIC_PRIO118_REG_OFFSET: usize = 0x208; +pub const RV_PLIC_PRIO118_PRIO118_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO118_PRIO118_OFFSET: usize = 0; + +// Interrupt Source 119 Priority +pub const RV_PLIC_PRIO119_REG_OFFSET: usize = 0x20c; +pub const RV_PLIC_PRIO119_PRIO119_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO119_PRIO119_OFFSET: usize = 0; + +// Interrupt Source 120 Priority +pub const RV_PLIC_PRIO120_REG_OFFSET: usize = 0x210; +pub const RV_PLIC_PRIO120_PRIO120_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO120_PRIO120_OFFSET: usize = 0; + +// Interrupt Source 121 Priority +pub const RV_PLIC_PRIO121_REG_OFFSET: usize = 0x214; +pub const RV_PLIC_PRIO121_PRIO121_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO121_PRIO121_OFFSET: usize = 0; + +// Interrupt Source 122 Priority +pub const RV_PLIC_PRIO122_REG_OFFSET: usize = 0x218; +pub const RV_PLIC_PRIO122_PRIO122_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO122_PRIO122_OFFSET: usize = 0; + +// Interrupt Source 123 Priority +pub const RV_PLIC_PRIO123_REG_OFFSET: usize = 0x21c; +pub const RV_PLIC_PRIO123_PRIO123_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO123_PRIO123_OFFSET: usize = 0; + +// Interrupt Source 124 Priority +pub const RV_PLIC_PRIO124_REG_OFFSET: usize = 0x220; +pub const RV_PLIC_PRIO124_PRIO124_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO124_PRIO124_OFFSET: usize = 0; + +// Interrupt Source 125 Priority +pub const RV_PLIC_PRIO125_REG_OFFSET: usize = 0x224; +pub const RV_PLIC_PRIO125_PRIO125_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO125_PRIO125_OFFSET: usize = 0; + +// Interrupt Source 126 Priority +pub const RV_PLIC_PRIO126_REG_OFFSET: usize = 0x228; +pub const RV_PLIC_PRIO126_PRIO126_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO126_PRIO126_OFFSET: usize = 0; + +// Interrupt Source 127 Priority +pub const RV_PLIC_PRIO127_REG_OFFSET: usize = 0x22c; +pub const RV_PLIC_PRIO127_PRIO127_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO127_PRIO127_OFFSET: usize = 0; + +// Interrupt Source 128 Priority +pub const RV_PLIC_PRIO128_REG_OFFSET: usize = 0x230; +pub const RV_PLIC_PRIO128_PRIO128_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO128_PRIO128_OFFSET: usize = 0; + +// Interrupt Source 129 Priority +pub const RV_PLIC_PRIO129_REG_OFFSET: usize = 0x234; +pub const RV_PLIC_PRIO129_PRIO129_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO129_PRIO129_OFFSET: usize = 0; + +// Interrupt Source 130 Priority +pub const RV_PLIC_PRIO130_REG_OFFSET: usize = 0x238; +pub const RV_PLIC_PRIO130_PRIO130_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO130_PRIO130_OFFSET: usize = 0; + +// Interrupt Source 131 Priority +pub const RV_PLIC_PRIO131_REG_OFFSET: usize = 0x23c; +pub const RV_PLIC_PRIO131_PRIO131_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO131_PRIO131_OFFSET: usize = 0; + +// Interrupt Source 132 Priority +pub const RV_PLIC_PRIO132_REG_OFFSET: usize = 0x240; +pub const RV_PLIC_PRIO132_PRIO132_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO132_PRIO132_OFFSET: usize = 0; + +// Interrupt Source 133 Priority +pub const RV_PLIC_PRIO133_REG_OFFSET: usize = 0x244; +pub const RV_PLIC_PRIO133_PRIO133_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO133_PRIO133_OFFSET: usize = 0; + +// Interrupt Source 134 Priority +pub const RV_PLIC_PRIO134_REG_OFFSET: usize = 0x248; +pub const RV_PLIC_PRIO134_PRIO134_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO134_PRIO134_OFFSET: usize = 0; + +// Interrupt Source 135 Priority +pub const RV_PLIC_PRIO135_REG_OFFSET: usize = 0x24c; +pub const RV_PLIC_PRIO135_PRIO135_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO135_PRIO135_OFFSET: usize = 0; + +// Interrupt Source 136 Priority +pub const RV_PLIC_PRIO136_REG_OFFSET: usize = 0x250; +pub const RV_PLIC_PRIO136_PRIO136_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO136_PRIO136_OFFSET: usize = 0; + +// Interrupt Source 137 Priority +pub const RV_PLIC_PRIO137_REG_OFFSET: usize = 0x254; +pub const RV_PLIC_PRIO137_PRIO137_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO137_PRIO137_OFFSET: usize = 0; + +// Interrupt Source 138 Priority +pub const RV_PLIC_PRIO138_REG_OFFSET: usize = 0x258; +pub const RV_PLIC_PRIO138_PRIO138_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO138_PRIO138_OFFSET: usize = 0; + +// Interrupt Source 139 Priority +pub const RV_PLIC_PRIO139_REG_OFFSET: usize = 0x25c; +pub const RV_PLIC_PRIO139_PRIO139_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO139_PRIO139_OFFSET: usize = 0; + +// Interrupt Source 140 Priority +pub const RV_PLIC_PRIO140_REG_OFFSET: usize = 0x260; +pub const RV_PLIC_PRIO140_PRIO140_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO140_PRIO140_OFFSET: usize = 0; + +// Interrupt Source 141 Priority +pub const RV_PLIC_PRIO141_REG_OFFSET: usize = 0x264; +pub const RV_PLIC_PRIO141_PRIO141_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO141_PRIO141_OFFSET: usize = 0; + +// Interrupt Source 142 Priority +pub const RV_PLIC_PRIO142_REG_OFFSET: usize = 0x268; +pub const RV_PLIC_PRIO142_PRIO142_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO142_PRIO142_OFFSET: usize = 0; + +// Interrupt Source 143 Priority +pub const RV_PLIC_PRIO143_REG_OFFSET: usize = 0x26c; +pub const RV_PLIC_PRIO143_PRIO143_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO143_PRIO143_OFFSET: usize = 0; + +// Interrupt Source 144 Priority +pub const RV_PLIC_PRIO144_REG_OFFSET: usize = 0x270; +pub const RV_PLIC_PRIO144_PRIO144_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO144_PRIO144_OFFSET: usize = 0; + +// Interrupt Source 145 Priority +pub const RV_PLIC_PRIO145_REG_OFFSET: usize = 0x274; +pub const RV_PLIC_PRIO145_PRIO145_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO145_PRIO145_OFFSET: usize = 0; + +// Interrupt Source 146 Priority +pub const RV_PLIC_PRIO146_REG_OFFSET: usize = 0x278; +pub const RV_PLIC_PRIO146_PRIO146_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO146_PRIO146_OFFSET: usize = 0; + +// Interrupt Source 147 Priority +pub const RV_PLIC_PRIO147_REG_OFFSET: usize = 0x27c; +pub const RV_PLIC_PRIO147_PRIO147_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO147_PRIO147_OFFSET: usize = 0; + +// Interrupt Source 148 Priority +pub const RV_PLIC_PRIO148_REG_OFFSET: usize = 0x280; +pub const RV_PLIC_PRIO148_PRIO148_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO148_PRIO148_OFFSET: usize = 0; + +// Interrupt Source 149 Priority +pub const RV_PLIC_PRIO149_REG_OFFSET: usize = 0x284; +pub const RV_PLIC_PRIO149_PRIO149_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO149_PRIO149_OFFSET: usize = 0; + +// Interrupt Source 150 Priority +pub const RV_PLIC_PRIO150_REG_OFFSET: usize = 0x288; +pub const RV_PLIC_PRIO150_PRIO150_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO150_PRIO150_OFFSET: usize = 0; + +// Interrupt Source 151 Priority +pub const RV_PLIC_PRIO151_REG_OFFSET: usize = 0x28c; +pub const RV_PLIC_PRIO151_PRIO151_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO151_PRIO151_OFFSET: usize = 0; + +// Interrupt Source 152 Priority +pub const RV_PLIC_PRIO152_REG_OFFSET: usize = 0x290; +pub const RV_PLIC_PRIO152_PRIO152_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO152_PRIO152_OFFSET: usize = 0; + +// Interrupt Source 153 Priority +pub const RV_PLIC_PRIO153_REG_OFFSET: usize = 0x294; +pub const RV_PLIC_PRIO153_PRIO153_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO153_PRIO153_OFFSET: usize = 0; + +// Interrupt Source 154 Priority +pub const RV_PLIC_PRIO154_REG_OFFSET: usize = 0x298; +pub const RV_PLIC_PRIO154_PRIO154_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO154_PRIO154_OFFSET: usize = 0; + +// Interrupt Source 155 Priority +pub const RV_PLIC_PRIO155_REG_OFFSET: usize = 0x29c; +pub const RV_PLIC_PRIO155_PRIO155_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO155_PRIO155_OFFSET: usize = 0; + +// Interrupt Source 156 Priority +pub const RV_PLIC_PRIO156_REG_OFFSET: usize = 0x2a0; +pub const RV_PLIC_PRIO156_PRIO156_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO156_PRIO156_OFFSET: usize = 0; + +// Interrupt Source 157 Priority +pub const RV_PLIC_PRIO157_REG_OFFSET: usize = 0x2a4; +pub const RV_PLIC_PRIO157_PRIO157_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO157_PRIO157_OFFSET: usize = 0; + +// Interrupt Source 158 Priority +pub const RV_PLIC_PRIO158_REG_OFFSET: usize = 0x2a8; +pub const RV_PLIC_PRIO158_PRIO158_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO158_PRIO158_OFFSET: usize = 0; + +// Interrupt Source 159 Priority +pub const RV_PLIC_PRIO159_REG_OFFSET: usize = 0x2ac; +pub const RV_PLIC_PRIO159_PRIO159_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO159_PRIO159_OFFSET: usize = 0; + +// Interrupt Source 160 Priority +pub const RV_PLIC_PRIO160_REG_OFFSET: usize = 0x2b0; +pub const RV_PLIC_PRIO160_PRIO160_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO160_PRIO160_OFFSET: usize = 0; + +// Interrupt Source 161 Priority +pub const RV_PLIC_PRIO161_REG_OFFSET: usize = 0x2b4; +pub const RV_PLIC_PRIO161_PRIO161_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO161_PRIO161_OFFSET: usize = 0; + +// Interrupt Source 162 Priority +pub const RV_PLIC_PRIO162_REG_OFFSET: usize = 0x2b8; +pub const RV_PLIC_PRIO162_PRIO162_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO162_PRIO162_OFFSET: usize = 0; + +// Interrupt Source 163 Priority +pub const RV_PLIC_PRIO163_REG_OFFSET: usize = 0x2bc; +pub const RV_PLIC_PRIO163_PRIO163_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO163_PRIO163_OFFSET: usize = 0; + +// Interrupt Source 164 Priority +pub const RV_PLIC_PRIO164_REG_OFFSET: usize = 0x2c0; +pub const RV_PLIC_PRIO164_PRIO164_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO164_PRIO164_OFFSET: usize = 0; + +// Interrupt Source 165 Priority +pub const RV_PLIC_PRIO165_REG_OFFSET: usize = 0x2c4; +pub const RV_PLIC_PRIO165_PRIO165_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO165_PRIO165_OFFSET: usize = 0; + +// Interrupt Source 166 Priority +pub const RV_PLIC_PRIO166_REG_OFFSET: usize = 0x2c8; +pub const RV_PLIC_PRIO166_PRIO166_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO166_PRIO166_OFFSET: usize = 0; + +// Interrupt Source 167 Priority +pub const RV_PLIC_PRIO167_REG_OFFSET: usize = 0x2cc; +pub const RV_PLIC_PRIO167_PRIO167_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO167_PRIO167_OFFSET: usize = 0; + +// Interrupt Source 168 Priority +pub const RV_PLIC_PRIO168_REG_OFFSET: usize = 0x2d0; +pub const RV_PLIC_PRIO168_PRIO168_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO168_PRIO168_OFFSET: usize = 0; + +// Interrupt Source 169 Priority +pub const RV_PLIC_PRIO169_REG_OFFSET: usize = 0x2d4; +pub const RV_PLIC_PRIO169_PRIO169_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO169_PRIO169_OFFSET: usize = 0; + +// Interrupt Source 170 Priority +pub const RV_PLIC_PRIO170_REG_OFFSET: usize = 0x2d8; +pub const RV_PLIC_PRIO170_PRIO170_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO170_PRIO170_OFFSET: usize = 0; + +// Interrupt Source 171 Priority +pub const RV_PLIC_PRIO171_REG_OFFSET: usize = 0x2dc; +pub const RV_PLIC_PRIO171_PRIO171_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO171_PRIO171_OFFSET: usize = 0; + +// Interrupt Source 172 Priority +pub const RV_PLIC_PRIO172_REG_OFFSET: usize = 0x2e0; +pub const RV_PLIC_PRIO172_PRIO172_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO172_PRIO172_OFFSET: usize = 0; + +// Interrupt Source 173 Priority +pub const RV_PLIC_PRIO173_REG_OFFSET: usize = 0x2e4; +pub const RV_PLIC_PRIO173_PRIO173_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO173_PRIO173_OFFSET: usize = 0; + +// Interrupt Source 174 Priority +pub const RV_PLIC_PRIO174_REG_OFFSET: usize = 0x2e8; +pub const RV_PLIC_PRIO174_PRIO174_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO174_PRIO174_OFFSET: usize = 0; + +// Interrupt Source 175 Priority +pub const RV_PLIC_PRIO175_REG_OFFSET: usize = 0x2ec; +pub const RV_PLIC_PRIO175_PRIO175_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO175_PRIO175_OFFSET: usize = 0; + +// Interrupt Source 176 Priority +pub const RV_PLIC_PRIO176_REG_OFFSET: usize = 0x2f0; +pub const RV_PLIC_PRIO176_PRIO176_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO176_PRIO176_OFFSET: usize = 0; + +// Interrupt Source 177 Priority +pub const RV_PLIC_PRIO177_REG_OFFSET: usize = 0x2f4; +pub const RV_PLIC_PRIO177_PRIO177_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO177_PRIO177_OFFSET: usize = 0; + +// Interrupt Source 178 Priority +pub const RV_PLIC_PRIO178_REG_OFFSET: usize = 0x2f8; +pub const RV_PLIC_PRIO178_PRIO178_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO178_PRIO178_OFFSET: usize = 0; + +// Interrupt Source 179 Priority +pub const RV_PLIC_PRIO179_REG_OFFSET: usize = 0x2fc; +pub const RV_PLIC_PRIO179_PRIO179_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO179_PRIO179_OFFSET: usize = 0; + +// Interrupt Source 180 Priority +pub const RV_PLIC_PRIO180_REG_OFFSET: usize = 0x300; +pub const RV_PLIC_PRIO180_PRIO180_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO180_PRIO180_OFFSET: usize = 0; + +// Interrupt Source 181 Priority +pub const RV_PLIC_PRIO181_REG_OFFSET: usize = 0x304; +pub const RV_PLIC_PRIO181_PRIO181_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO181_PRIO181_OFFSET: usize = 0; + +// Interrupt Source 182 Priority +pub const RV_PLIC_PRIO182_REG_OFFSET: usize = 0x308; +pub const RV_PLIC_PRIO182_PRIO182_MASK: u32 = 0x7; +pub const RV_PLIC_PRIO182_PRIO182_OFFSET: usize = 0; + +// Interrupt Enable for Target 0 (common parameters) +pub const RV_PLIC_IE0_E_FIELD_WIDTH: u32 = 1; +pub const RV_PLIC_IE0_E_FIELDS_PER_REG: u32 = 32; +pub const RV_PLIC_IE0_MULTIREG_COUNT: u32 = 6; + +// Interrupt Enable for Target 0 +pub const RV_PLIC_IE0_0_REG_OFFSET: usize = 0x400; +pub const RV_PLIC_IE0_0_E_0_BIT: u32 = 0; +pub const RV_PLIC_IE0_0_E_1_BIT: u32 = 1; +pub const RV_PLIC_IE0_0_E_2_BIT: u32 = 2; +pub const RV_PLIC_IE0_0_E_3_BIT: u32 = 3; +pub const RV_PLIC_IE0_0_E_4_BIT: u32 = 4; +pub const RV_PLIC_IE0_0_E_5_BIT: u32 = 5; +pub const RV_PLIC_IE0_0_E_6_BIT: u32 = 6; +pub const RV_PLIC_IE0_0_E_7_BIT: u32 = 7; +pub const RV_PLIC_IE0_0_E_8_BIT: u32 = 8; +pub const RV_PLIC_IE0_0_E_9_BIT: u32 = 9; +pub const RV_PLIC_IE0_0_E_10_BIT: u32 = 10; +pub const RV_PLIC_IE0_0_E_11_BIT: u32 = 11; +pub const RV_PLIC_IE0_0_E_12_BIT: u32 = 12; +pub const RV_PLIC_IE0_0_E_13_BIT: u32 = 13; +pub const RV_PLIC_IE0_0_E_14_BIT: u32 = 14; +pub const RV_PLIC_IE0_0_E_15_BIT: u32 = 15; +pub const RV_PLIC_IE0_0_E_16_BIT: u32 = 16; +pub const RV_PLIC_IE0_0_E_17_BIT: u32 = 17; +pub const RV_PLIC_IE0_0_E_18_BIT: u32 = 18; +pub const RV_PLIC_IE0_0_E_19_BIT: u32 = 19; +pub const RV_PLIC_IE0_0_E_20_BIT: u32 = 20; +pub const RV_PLIC_IE0_0_E_21_BIT: u32 = 21; +pub const RV_PLIC_IE0_0_E_22_BIT: u32 = 22; +pub const RV_PLIC_IE0_0_E_23_BIT: u32 = 23; +pub const RV_PLIC_IE0_0_E_24_BIT: u32 = 24; +pub const RV_PLIC_IE0_0_E_25_BIT: u32 = 25; +pub const RV_PLIC_IE0_0_E_26_BIT: u32 = 26; +pub const RV_PLIC_IE0_0_E_27_BIT: u32 = 27; +pub const RV_PLIC_IE0_0_E_28_BIT: u32 = 28; +pub const RV_PLIC_IE0_0_E_29_BIT: u32 = 29; +pub const RV_PLIC_IE0_0_E_30_BIT: u32 = 30; +pub const RV_PLIC_IE0_0_E_31_BIT: u32 = 31; + +// Interrupt Enable for Target 0 +pub const RV_PLIC_IE0_1_REG_OFFSET: usize = 0x404; +pub const RV_PLIC_IE0_1_E_32_BIT: u32 = 0; +pub const RV_PLIC_IE0_1_E_33_BIT: u32 = 1; +pub const RV_PLIC_IE0_1_E_34_BIT: u32 = 2; +pub const RV_PLIC_IE0_1_E_35_BIT: u32 = 3; +pub const RV_PLIC_IE0_1_E_36_BIT: u32 = 4; +pub const RV_PLIC_IE0_1_E_37_BIT: u32 = 5; +pub const RV_PLIC_IE0_1_E_38_BIT: u32 = 6; +pub const RV_PLIC_IE0_1_E_39_BIT: u32 = 7; +pub const RV_PLIC_IE0_1_E_40_BIT: u32 = 8; +pub const RV_PLIC_IE0_1_E_41_BIT: u32 = 9; +pub const RV_PLIC_IE0_1_E_42_BIT: u32 = 10; +pub const RV_PLIC_IE0_1_E_43_BIT: u32 = 11; +pub const RV_PLIC_IE0_1_E_44_BIT: u32 = 12; +pub const RV_PLIC_IE0_1_E_45_BIT: u32 = 13; +pub const RV_PLIC_IE0_1_E_46_BIT: u32 = 14; +pub const RV_PLIC_IE0_1_E_47_BIT: u32 = 15; +pub const RV_PLIC_IE0_1_E_48_BIT: u32 = 16; +pub const RV_PLIC_IE0_1_E_49_BIT: u32 = 17; +pub const RV_PLIC_IE0_1_E_50_BIT: u32 = 18; +pub const RV_PLIC_IE0_1_E_51_BIT: u32 = 19; +pub const RV_PLIC_IE0_1_E_52_BIT: u32 = 20; +pub const RV_PLIC_IE0_1_E_53_BIT: u32 = 21; +pub const RV_PLIC_IE0_1_E_54_BIT: u32 = 22; +pub const RV_PLIC_IE0_1_E_55_BIT: u32 = 23; +pub const RV_PLIC_IE0_1_E_56_BIT: u32 = 24; +pub const RV_PLIC_IE0_1_E_57_BIT: u32 = 25; +pub const RV_PLIC_IE0_1_E_58_BIT: u32 = 26; +pub const RV_PLIC_IE0_1_E_59_BIT: u32 = 27; +pub const RV_PLIC_IE0_1_E_60_BIT: u32 = 28; +pub const RV_PLIC_IE0_1_E_61_BIT: u32 = 29; +pub const RV_PLIC_IE0_1_E_62_BIT: u32 = 30; +pub const RV_PLIC_IE0_1_E_63_BIT: u32 = 31; + +// Interrupt Enable for Target 0 +pub const RV_PLIC_IE0_2_REG_OFFSET: usize = 0x408; +pub const RV_PLIC_IE0_2_E_64_BIT: u32 = 0; +pub const RV_PLIC_IE0_2_E_65_BIT: u32 = 1; +pub const RV_PLIC_IE0_2_E_66_BIT: u32 = 2; +pub const RV_PLIC_IE0_2_E_67_BIT: u32 = 3; +pub const RV_PLIC_IE0_2_E_68_BIT: u32 = 4; +pub const RV_PLIC_IE0_2_E_69_BIT: u32 = 5; +pub const RV_PLIC_IE0_2_E_70_BIT: u32 = 6; +pub const RV_PLIC_IE0_2_E_71_BIT: u32 = 7; +pub const RV_PLIC_IE0_2_E_72_BIT: u32 = 8; +pub const RV_PLIC_IE0_2_E_73_BIT: u32 = 9; +pub const RV_PLIC_IE0_2_E_74_BIT: u32 = 10; +pub const RV_PLIC_IE0_2_E_75_BIT: u32 = 11; +pub const RV_PLIC_IE0_2_E_76_BIT: u32 = 12; +pub const RV_PLIC_IE0_2_E_77_BIT: u32 = 13; +pub const RV_PLIC_IE0_2_E_78_BIT: u32 = 14; +pub const RV_PLIC_IE0_2_E_79_BIT: u32 = 15; +pub const RV_PLIC_IE0_2_E_80_BIT: u32 = 16; +pub const RV_PLIC_IE0_2_E_81_BIT: u32 = 17; +pub const RV_PLIC_IE0_2_E_82_BIT: u32 = 18; +pub const RV_PLIC_IE0_2_E_83_BIT: u32 = 19; +pub const RV_PLIC_IE0_2_E_84_BIT: u32 = 20; +pub const RV_PLIC_IE0_2_E_85_BIT: u32 = 21; +pub const RV_PLIC_IE0_2_E_86_BIT: u32 = 22; +pub const RV_PLIC_IE0_2_E_87_BIT: u32 = 23; +pub const RV_PLIC_IE0_2_E_88_BIT: u32 = 24; +pub const RV_PLIC_IE0_2_E_89_BIT: u32 = 25; +pub const RV_PLIC_IE0_2_E_90_BIT: u32 = 26; +pub const RV_PLIC_IE0_2_E_91_BIT: u32 = 27; +pub const RV_PLIC_IE0_2_E_92_BIT: u32 = 28; +pub const RV_PLIC_IE0_2_E_93_BIT: u32 = 29; +pub const RV_PLIC_IE0_2_E_94_BIT: u32 = 30; +pub const RV_PLIC_IE0_2_E_95_BIT: u32 = 31; + +// Interrupt Enable for Target 0 +pub const RV_PLIC_IE0_3_REG_OFFSET: usize = 0x40c; +pub const RV_PLIC_IE0_3_E_96_BIT: u32 = 0; +pub const RV_PLIC_IE0_3_E_97_BIT: u32 = 1; +pub const RV_PLIC_IE0_3_E_98_BIT: u32 = 2; +pub const RV_PLIC_IE0_3_E_99_BIT: u32 = 3; +pub const RV_PLIC_IE0_3_E_100_BIT: u32 = 4; +pub const RV_PLIC_IE0_3_E_101_BIT: u32 = 5; +pub const RV_PLIC_IE0_3_E_102_BIT: u32 = 6; +pub const RV_PLIC_IE0_3_E_103_BIT: u32 = 7; +pub const RV_PLIC_IE0_3_E_104_BIT: u32 = 8; +pub const RV_PLIC_IE0_3_E_105_BIT: u32 = 9; +pub const RV_PLIC_IE0_3_E_106_BIT: u32 = 10; +pub const RV_PLIC_IE0_3_E_107_BIT: u32 = 11; +pub const RV_PLIC_IE0_3_E_108_BIT: u32 = 12; +pub const RV_PLIC_IE0_3_E_109_BIT: u32 = 13; +pub const RV_PLIC_IE0_3_E_110_BIT: u32 = 14; +pub const RV_PLIC_IE0_3_E_111_BIT: u32 = 15; +pub const RV_PLIC_IE0_3_E_112_BIT: u32 = 16; +pub const RV_PLIC_IE0_3_E_113_BIT: u32 = 17; +pub const RV_PLIC_IE0_3_E_114_BIT: u32 = 18; +pub const RV_PLIC_IE0_3_E_115_BIT: u32 = 19; +pub const RV_PLIC_IE0_3_E_116_BIT: u32 = 20; +pub const RV_PLIC_IE0_3_E_117_BIT: u32 = 21; +pub const RV_PLIC_IE0_3_E_118_BIT: u32 = 22; +pub const RV_PLIC_IE0_3_E_119_BIT: u32 = 23; +pub const RV_PLIC_IE0_3_E_120_BIT: u32 = 24; +pub const RV_PLIC_IE0_3_E_121_BIT: u32 = 25; +pub const RV_PLIC_IE0_3_E_122_BIT: u32 = 26; +pub const RV_PLIC_IE0_3_E_123_BIT: u32 = 27; +pub const RV_PLIC_IE0_3_E_124_BIT: u32 = 28; +pub const RV_PLIC_IE0_3_E_125_BIT: u32 = 29; +pub const RV_PLIC_IE0_3_E_126_BIT: u32 = 30; +pub const RV_PLIC_IE0_3_E_127_BIT: u32 = 31; + +// Interrupt Enable for Target 0 +pub const RV_PLIC_IE0_4_REG_OFFSET: usize = 0x410; +pub const RV_PLIC_IE0_4_E_128_BIT: u32 = 0; +pub const RV_PLIC_IE0_4_E_129_BIT: u32 = 1; +pub const RV_PLIC_IE0_4_E_130_BIT: u32 = 2; +pub const RV_PLIC_IE0_4_E_131_BIT: u32 = 3; +pub const RV_PLIC_IE0_4_E_132_BIT: u32 = 4; +pub const RV_PLIC_IE0_4_E_133_BIT: u32 = 5; +pub const RV_PLIC_IE0_4_E_134_BIT: u32 = 6; +pub const RV_PLIC_IE0_4_E_135_BIT: u32 = 7; +pub const RV_PLIC_IE0_4_E_136_BIT: u32 = 8; +pub const RV_PLIC_IE0_4_E_137_BIT: u32 = 9; +pub const RV_PLIC_IE0_4_E_138_BIT: u32 = 10; +pub const RV_PLIC_IE0_4_E_139_BIT: u32 = 11; +pub const RV_PLIC_IE0_4_E_140_BIT: u32 = 12; +pub const RV_PLIC_IE0_4_E_141_BIT: u32 = 13; +pub const RV_PLIC_IE0_4_E_142_BIT: u32 = 14; +pub const RV_PLIC_IE0_4_E_143_BIT: u32 = 15; +pub const RV_PLIC_IE0_4_E_144_BIT: u32 = 16; +pub const RV_PLIC_IE0_4_E_145_BIT: u32 = 17; +pub const RV_PLIC_IE0_4_E_146_BIT: u32 = 18; +pub const RV_PLIC_IE0_4_E_147_BIT: u32 = 19; +pub const RV_PLIC_IE0_4_E_148_BIT: u32 = 20; +pub const RV_PLIC_IE0_4_E_149_BIT: u32 = 21; +pub const RV_PLIC_IE0_4_E_150_BIT: u32 = 22; +pub const RV_PLIC_IE0_4_E_151_BIT: u32 = 23; +pub const RV_PLIC_IE0_4_E_152_BIT: u32 = 24; +pub const RV_PLIC_IE0_4_E_153_BIT: u32 = 25; +pub const RV_PLIC_IE0_4_E_154_BIT: u32 = 26; +pub const RV_PLIC_IE0_4_E_155_BIT: u32 = 27; +pub const RV_PLIC_IE0_4_E_156_BIT: u32 = 28; +pub const RV_PLIC_IE0_4_E_157_BIT: u32 = 29; +pub const RV_PLIC_IE0_4_E_158_BIT: u32 = 30; +pub const RV_PLIC_IE0_4_E_159_BIT: u32 = 31; + +// Interrupt Enable for Target 0 +pub const RV_PLIC_IE0_5_REG_OFFSET: usize = 0x414; +pub const RV_PLIC_IE0_5_E_160_BIT: u32 = 0; +pub const RV_PLIC_IE0_5_E_161_BIT: u32 = 1; +pub const RV_PLIC_IE0_5_E_162_BIT: u32 = 2; +pub const RV_PLIC_IE0_5_E_163_BIT: u32 = 3; +pub const RV_PLIC_IE0_5_E_164_BIT: u32 = 4; +pub const RV_PLIC_IE0_5_E_165_BIT: u32 = 5; +pub const RV_PLIC_IE0_5_E_166_BIT: u32 = 6; +pub const RV_PLIC_IE0_5_E_167_BIT: u32 = 7; +pub const RV_PLIC_IE0_5_E_168_BIT: u32 = 8; +pub const RV_PLIC_IE0_5_E_169_BIT: u32 = 9; +pub const RV_PLIC_IE0_5_E_170_BIT: u32 = 10; +pub const RV_PLIC_IE0_5_E_171_BIT: u32 = 11; +pub const RV_PLIC_IE0_5_E_172_BIT: u32 = 12; +pub const RV_PLIC_IE0_5_E_173_BIT: u32 = 13; +pub const RV_PLIC_IE0_5_E_174_BIT: u32 = 14; +pub const RV_PLIC_IE0_5_E_175_BIT: u32 = 15; +pub const RV_PLIC_IE0_5_E_176_BIT: u32 = 16; +pub const RV_PLIC_IE0_5_E_177_BIT: u32 = 17; +pub const RV_PLIC_IE0_5_E_178_BIT: u32 = 18; +pub const RV_PLIC_IE0_5_E_179_BIT: u32 = 19; +pub const RV_PLIC_IE0_5_E_180_BIT: u32 = 20; +pub const RV_PLIC_IE0_5_E_181_BIT: u32 = 21; +pub const RV_PLIC_IE0_5_E_182_BIT: u32 = 22; + +// Threshold of priority for Target 0 +pub const RV_PLIC_THRESHOLD0_REG_OFFSET: usize = 0x418; +pub const RV_PLIC_THRESHOLD0_THRESHOLD0_MASK: u32 = 0x7; +pub const RV_PLIC_THRESHOLD0_THRESHOLD0_OFFSET: usize = 0; + +// Claim interrupt by read, complete interrupt by write for Target 0. +pub const RV_PLIC_CC0_REG_OFFSET: usize = 0x41c; +pub const RV_PLIC_CC0_CC0_MASK: u32 = 0xff; +pub const RV_PLIC_CC0_CC0_OFFSET: usize = 0; + +// msip for Hart 0. +pub const RV_PLIC_MSIP0_REG_OFFSET: usize = 0x420; +pub const RV_PLIC_MSIP0_MSIP0_BIT: u32 = 0; + +// Interrupt Enable for Target 1 (common parameters) +pub const RV_PLIC_IE1_E_FIELD_WIDTH: u32 = 1; +pub const RV_PLIC_IE1_E_FIELDS_PER_REG: u32 = 32; +pub const RV_PLIC_IE1_MULTIREG_COUNT: u32 = 6; + +// Interrupt Enable for Target 1 +pub const RV_PLIC_IE1_0_REG_OFFSET: usize = 0x500; +pub const RV_PLIC_IE1_0_E_0_BIT: u32 = 0; +pub const RV_PLIC_IE1_0_E_1_BIT: u32 = 1; +pub const RV_PLIC_IE1_0_E_2_BIT: u32 = 2; +pub const RV_PLIC_IE1_0_E_3_BIT: u32 = 3; +pub const RV_PLIC_IE1_0_E_4_BIT: u32 = 4; +pub const RV_PLIC_IE1_0_E_5_BIT: u32 = 5; +pub const RV_PLIC_IE1_0_E_6_BIT: u32 = 6; +pub const RV_PLIC_IE1_0_E_7_BIT: u32 = 7; +pub const RV_PLIC_IE1_0_E_8_BIT: u32 = 8; +pub const RV_PLIC_IE1_0_E_9_BIT: u32 = 9; +pub const RV_PLIC_IE1_0_E_10_BIT: u32 = 10; +pub const RV_PLIC_IE1_0_E_11_BIT: u32 = 11; +pub const RV_PLIC_IE1_0_E_12_BIT: u32 = 12; +pub const RV_PLIC_IE1_0_E_13_BIT: u32 = 13; +pub const RV_PLIC_IE1_0_E_14_BIT: u32 = 14; +pub const RV_PLIC_IE1_0_E_15_BIT: u32 = 15; +pub const RV_PLIC_IE1_0_E_16_BIT: u32 = 16; +pub const RV_PLIC_IE1_0_E_17_BIT: u32 = 17; +pub const RV_PLIC_IE1_0_E_18_BIT: u32 = 18; +pub const RV_PLIC_IE1_0_E_19_BIT: u32 = 19; +pub const RV_PLIC_IE1_0_E_20_BIT: u32 = 20; +pub const RV_PLIC_IE1_0_E_21_BIT: u32 = 21; +pub const RV_PLIC_IE1_0_E_22_BIT: u32 = 22; +pub const RV_PLIC_IE1_0_E_23_BIT: u32 = 23; +pub const RV_PLIC_IE1_0_E_24_BIT: u32 = 24; +pub const RV_PLIC_IE1_0_E_25_BIT: u32 = 25; +pub const RV_PLIC_IE1_0_E_26_BIT: u32 = 26; +pub const RV_PLIC_IE1_0_E_27_BIT: u32 = 27; +pub const RV_PLIC_IE1_0_E_28_BIT: u32 = 28; +pub const RV_PLIC_IE1_0_E_29_BIT: u32 = 29; +pub const RV_PLIC_IE1_0_E_30_BIT: u32 = 30; +pub const RV_PLIC_IE1_0_E_31_BIT: u32 = 31; + +// Interrupt Enable for Target 1 +pub const RV_PLIC_IE1_1_REG_OFFSET: usize = 0x504; +pub const RV_PLIC_IE1_1_E_32_BIT: u32 = 0; +pub const RV_PLIC_IE1_1_E_33_BIT: u32 = 1; +pub const RV_PLIC_IE1_1_E_34_BIT: u32 = 2; +pub const RV_PLIC_IE1_1_E_35_BIT: u32 = 3; +pub const RV_PLIC_IE1_1_E_36_BIT: u32 = 4; +pub const RV_PLIC_IE1_1_E_37_BIT: u32 = 5; +pub const RV_PLIC_IE1_1_E_38_BIT: u32 = 6; +pub const RV_PLIC_IE1_1_E_39_BIT: u32 = 7; +pub const RV_PLIC_IE1_1_E_40_BIT: u32 = 8; +pub const RV_PLIC_IE1_1_E_41_BIT: u32 = 9; +pub const RV_PLIC_IE1_1_E_42_BIT: u32 = 10; +pub const RV_PLIC_IE1_1_E_43_BIT: u32 = 11; +pub const RV_PLIC_IE1_1_E_44_BIT: u32 = 12; +pub const RV_PLIC_IE1_1_E_45_BIT: u32 = 13; +pub const RV_PLIC_IE1_1_E_46_BIT: u32 = 14; +pub const RV_PLIC_IE1_1_E_47_BIT: u32 = 15; +pub const RV_PLIC_IE1_1_E_48_BIT: u32 = 16; +pub const RV_PLIC_IE1_1_E_49_BIT: u32 = 17; +pub const RV_PLIC_IE1_1_E_50_BIT: u32 = 18; +pub const RV_PLIC_IE1_1_E_51_BIT: u32 = 19; +pub const RV_PLIC_IE1_1_E_52_BIT: u32 = 20; +pub const RV_PLIC_IE1_1_E_53_BIT: u32 = 21; +pub const RV_PLIC_IE1_1_E_54_BIT: u32 = 22; +pub const RV_PLIC_IE1_1_E_55_BIT: u32 = 23; +pub const RV_PLIC_IE1_1_E_56_BIT: u32 = 24; +pub const RV_PLIC_IE1_1_E_57_BIT: u32 = 25; +pub const RV_PLIC_IE1_1_E_58_BIT: u32 = 26; +pub const RV_PLIC_IE1_1_E_59_BIT: u32 = 27; +pub const RV_PLIC_IE1_1_E_60_BIT: u32 = 28; +pub const RV_PLIC_IE1_1_E_61_BIT: u32 = 29; +pub const RV_PLIC_IE1_1_E_62_BIT: u32 = 30; +pub const RV_PLIC_IE1_1_E_63_BIT: u32 = 31; + +// Interrupt Enable for Target 1 +pub const RV_PLIC_IE1_2_REG_OFFSET: usize = 0x508; +pub const RV_PLIC_IE1_2_E_64_BIT: u32 = 0; +pub const RV_PLIC_IE1_2_E_65_BIT: u32 = 1; +pub const RV_PLIC_IE1_2_E_66_BIT: u32 = 2; +pub const RV_PLIC_IE1_2_E_67_BIT: u32 = 3; +pub const RV_PLIC_IE1_2_E_68_BIT: u32 = 4; +pub const RV_PLIC_IE1_2_E_69_BIT: u32 = 5; +pub const RV_PLIC_IE1_2_E_70_BIT: u32 = 6; +pub const RV_PLIC_IE1_2_E_71_BIT: u32 = 7; +pub const RV_PLIC_IE1_2_E_72_BIT: u32 = 8; +pub const RV_PLIC_IE1_2_E_73_BIT: u32 = 9; +pub const RV_PLIC_IE1_2_E_74_BIT: u32 = 10; +pub const RV_PLIC_IE1_2_E_75_BIT: u32 = 11; +pub const RV_PLIC_IE1_2_E_76_BIT: u32 = 12; +pub const RV_PLIC_IE1_2_E_77_BIT: u32 = 13; +pub const RV_PLIC_IE1_2_E_78_BIT: u32 = 14; +pub const RV_PLIC_IE1_2_E_79_BIT: u32 = 15; +pub const RV_PLIC_IE1_2_E_80_BIT: u32 = 16; +pub const RV_PLIC_IE1_2_E_81_BIT: u32 = 17; +pub const RV_PLIC_IE1_2_E_82_BIT: u32 = 18; +pub const RV_PLIC_IE1_2_E_83_BIT: u32 = 19; +pub const RV_PLIC_IE1_2_E_84_BIT: u32 = 20; +pub const RV_PLIC_IE1_2_E_85_BIT: u32 = 21; +pub const RV_PLIC_IE1_2_E_86_BIT: u32 = 22; +pub const RV_PLIC_IE1_2_E_87_BIT: u32 = 23; +pub const RV_PLIC_IE1_2_E_88_BIT: u32 = 24; +pub const RV_PLIC_IE1_2_E_89_BIT: u32 = 25; +pub const RV_PLIC_IE1_2_E_90_BIT: u32 = 26; +pub const RV_PLIC_IE1_2_E_91_BIT: u32 = 27; +pub const RV_PLIC_IE1_2_E_92_BIT: u32 = 28; +pub const RV_PLIC_IE1_2_E_93_BIT: u32 = 29; +pub const RV_PLIC_IE1_2_E_94_BIT: u32 = 30; +pub const RV_PLIC_IE1_2_E_95_BIT: u32 = 31; + +// Interrupt Enable for Target 1 +pub const RV_PLIC_IE1_3_REG_OFFSET: usize = 0x50c; +pub const RV_PLIC_IE1_3_E_96_BIT: u32 = 0; +pub const RV_PLIC_IE1_3_E_97_BIT: u32 = 1; +pub const RV_PLIC_IE1_3_E_98_BIT: u32 = 2; +pub const RV_PLIC_IE1_3_E_99_BIT: u32 = 3; +pub const RV_PLIC_IE1_3_E_100_BIT: u32 = 4; +pub const RV_PLIC_IE1_3_E_101_BIT: u32 = 5; +pub const RV_PLIC_IE1_3_E_102_BIT: u32 = 6; +pub const RV_PLIC_IE1_3_E_103_BIT: u32 = 7; +pub const RV_PLIC_IE1_3_E_104_BIT: u32 = 8; +pub const RV_PLIC_IE1_3_E_105_BIT: u32 = 9; +pub const RV_PLIC_IE1_3_E_106_BIT: u32 = 10; +pub const RV_PLIC_IE1_3_E_107_BIT: u32 = 11; +pub const RV_PLIC_IE1_3_E_108_BIT: u32 = 12; +pub const RV_PLIC_IE1_3_E_109_BIT: u32 = 13; +pub const RV_PLIC_IE1_3_E_110_BIT: u32 = 14; +pub const RV_PLIC_IE1_3_E_111_BIT: u32 = 15; +pub const RV_PLIC_IE1_3_E_112_BIT: u32 = 16; +pub const RV_PLIC_IE1_3_E_113_BIT: u32 = 17; +pub const RV_PLIC_IE1_3_E_114_BIT: u32 = 18; +pub const RV_PLIC_IE1_3_E_115_BIT: u32 = 19; +pub const RV_PLIC_IE1_3_E_116_BIT: u32 = 20; +pub const RV_PLIC_IE1_3_E_117_BIT: u32 = 21; +pub const RV_PLIC_IE1_3_E_118_BIT: u32 = 22; +pub const RV_PLIC_IE1_3_E_119_BIT: u32 = 23; +pub const RV_PLIC_IE1_3_E_120_BIT: u32 = 24; +pub const RV_PLIC_IE1_3_E_121_BIT: u32 = 25; +pub const RV_PLIC_IE1_3_E_122_BIT: u32 = 26; +pub const RV_PLIC_IE1_3_E_123_BIT: u32 = 27; +pub const RV_PLIC_IE1_3_E_124_BIT: u32 = 28; +pub const RV_PLIC_IE1_3_E_125_BIT: u32 = 29; +pub const RV_PLIC_IE1_3_E_126_BIT: u32 = 30; +pub const RV_PLIC_IE1_3_E_127_BIT: u32 = 31; + +// Interrupt Enable for Target 1 +pub const RV_PLIC_IE1_4_REG_OFFSET: usize = 0x510; +pub const RV_PLIC_IE1_4_E_128_BIT: u32 = 0; +pub const RV_PLIC_IE1_4_E_129_BIT: u32 = 1; +pub const RV_PLIC_IE1_4_E_130_BIT: u32 = 2; +pub const RV_PLIC_IE1_4_E_131_BIT: u32 = 3; +pub const RV_PLIC_IE1_4_E_132_BIT: u32 = 4; +pub const RV_PLIC_IE1_4_E_133_BIT: u32 = 5; +pub const RV_PLIC_IE1_4_E_134_BIT: u32 = 6; +pub const RV_PLIC_IE1_4_E_135_BIT: u32 = 7; +pub const RV_PLIC_IE1_4_E_136_BIT: u32 = 8; +pub const RV_PLIC_IE1_4_E_137_BIT: u32 = 9; +pub const RV_PLIC_IE1_4_E_138_BIT: u32 = 10; +pub const RV_PLIC_IE1_4_E_139_BIT: u32 = 11; +pub const RV_PLIC_IE1_4_E_140_BIT: u32 = 12; +pub const RV_PLIC_IE1_4_E_141_BIT: u32 = 13; +pub const RV_PLIC_IE1_4_E_142_BIT: u32 = 14; +pub const RV_PLIC_IE1_4_E_143_BIT: u32 = 15; +pub const RV_PLIC_IE1_4_E_144_BIT: u32 = 16; +pub const RV_PLIC_IE1_4_E_145_BIT: u32 = 17; +pub const RV_PLIC_IE1_4_E_146_BIT: u32 = 18; +pub const RV_PLIC_IE1_4_E_147_BIT: u32 = 19; +pub const RV_PLIC_IE1_4_E_148_BIT: u32 = 20; +pub const RV_PLIC_IE1_4_E_149_BIT: u32 = 21; +pub const RV_PLIC_IE1_4_E_150_BIT: u32 = 22; +pub const RV_PLIC_IE1_4_E_151_BIT: u32 = 23; +pub const RV_PLIC_IE1_4_E_152_BIT: u32 = 24; +pub const RV_PLIC_IE1_4_E_153_BIT: u32 = 25; +pub const RV_PLIC_IE1_4_E_154_BIT: u32 = 26; +pub const RV_PLIC_IE1_4_E_155_BIT: u32 = 27; +pub const RV_PLIC_IE1_4_E_156_BIT: u32 = 28; +pub const RV_PLIC_IE1_4_E_157_BIT: u32 = 29; +pub const RV_PLIC_IE1_4_E_158_BIT: u32 = 30; +pub const RV_PLIC_IE1_4_E_159_BIT: u32 = 31; + +// Interrupt Enable for Target 1 +pub const RV_PLIC_IE1_5_REG_OFFSET: usize = 0x514; +pub const RV_PLIC_IE1_5_E_160_BIT: u32 = 0; +pub const RV_PLIC_IE1_5_E_161_BIT: u32 = 1; +pub const RV_PLIC_IE1_5_E_162_BIT: u32 = 2; +pub const RV_PLIC_IE1_5_E_163_BIT: u32 = 3; +pub const RV_PLIC_IE1_5_E_164_BIT: u32 = 4; +pub const RV_PLIC_IE1_5_E_165_BIT: u32 = 5; +pub const RV_PLIC_IE1_5_E_166_BIT: u32 = 6; +pub const RV_PLIC_IE1_5_E_167_BIT: u32 = 7; +pub const RV_PLIC_IE1_5_E_168_BIT: u32 = 8; +pub const RV_PLIC_IE1_5_E_169_BIT: u32 = 9; +pub const RV_PLIC_IE1_5_E_170_BIT: u32 = 10; +pub const RV_PLIC_IE1_5_E_171_BIT: u32 = 11; +pub const RV_PLIC_IE1_5_E_172_BIT: u32 = 12; +pub const RV_PLIC_IE1_5_E_173_BIT: u32 = 13; +pub const RV_PLIC_IE1_5_E_174_BIT: u32 = 14; +pub const RV_PLIC_IE1_5_E_175_BIT: u32 = 15; +pub const RV_PLIC_IE1_5_E_176_BIT: u32 = 16; +pub const RV_PLIC_IE1_5_E_177_BIT: u32 = 17; +pub const RV_PLIC_IE1_5_E_178_BIT: u32 = 18; +pub const RV_PLIC_IE1_5_E_179_BIT: u32 = 19; +pub const RV_PLIC_IE1_5_E_180_BIT: u32 = 20; +pub const RV_PLIC_IE1_5_E_181_BIT: u32 = 21; +pub const RV_PLIC_IE1_5_E_182_BIT: u32 = 22; + +// Threshold of priority for Target 1 +pub const RV_PLIC_THRESHOLD1_REG_OFFSET: usize = 0x518; +pub const RV_PLIC_THRESHOLD1_THRESHOLD1_MASK: u32 = 0x7; +pub const RV_PLIC_THRESHOLD1_THRESHOLD1_OFFSET: usize = 0; + +// Claim interrupt by read, complete interrupt by write for Target 1. +pub const RV_PLIC_CC1_REG_OFFSET: usize = 0x51c; +pub const RV_PLIC_CC1_CC1_MASK: u32 = 0xff; +pub const RV_PLIC_CC1_CC1_OFFSET: usize = 0; + +// msip for Hart 1. +pub const RV_PLIC_MSIP1_REG_OFFSET: usize = 0x520; +pub const RV_PLIC_MSIP1_MSIP1_BIT: u32 = 0; + +// Alert Test Register. +pub const RV_PLIC_ALERT_TEST_REG_OFFSET: usize = 0x600; +pub const RV_PLIC_ALERT_TEST_FATAL_FAULT_BIT: u32 = 0; + +// End generated register constants for RV_PLIC \ No newline at end of file
diff --git a/chip/src/pwrmgr.rs b/chip/src/pwrmgr.rs new file mode 100644 index 0000000..23db221 --- /dev/null +++ b/chip/src/pwrmgr.rs
@@ -0,0 +1,7 @@ +use kernel::common::StaticRef; +use lowrisc::pwrmgr::{PwrMgr, PwrMgrRegisters}; + +pub static mut PWRMGR: PwrMgr = PwrMgr::new(PWRMGR_BASE); + +const PWRMGR_BASE: StaticRef<PwrMgrRegisters> = + unsafe { StaticRef::new(0x4040_0000 as *const PwrMgrRegisters) };
diff --git a/chip/src/timer.rs b/chip/src/timer.rs new file mode 100644 index 0000000..3c2e09e --- /dev/null +++ b/chip/src/timer.rs
@@ -0,0 +1,198 @@ +//! Timer driver. + +use crate::chip_config::CONFIG; +use kernel::common::cells::OptionalCell; +use kernel::common::registers::{register_bitfields, register_structs, ReadWrite, WriteOnly}; +use kernel::common::StaticRef; +use kernel::hil::time; +use kernel::hil::time::{Ticks, Ticks64, Time}; +use kernel::ReturnCode; + +const PRESCALE: u16 = ((CONFIG.cpu_freq / 10_000) - 1) as u16; // 10Khz + +/// 10KHz `Frequency` +#[derive(Debug)] +pub struct Freq10KHz; +impl time::Frequency for Freq10KHz { + fn frequency() -> u32 { + 10_000 + } +} + +register_structs! { + pub TimerRegisters { + (0x000 => ctrl: ReadWrite<u32, ctrl::Register>), + + (0x004 => _reserved), + + (0x100 => config: ReadWrite<u32, config::Register>), + + (0x104 => value_low: ReadWrite<u32>), + (0x108 => value_high: ReadWrite<u32>), + + (0x10c => compare_low: ReadWrite<u32>), + (0x110 => compare_high: ReadWrite<u32>), + + (0x114 => intr_enable: ReadWrite<u32, intr::Register>), + (0x118 => intr_state: ReadWrite<u32, intr::Register>), + (0x11c => intr_test: WriteOnly<u32, intr::Register>), + (0x120 => @END), + } +} + +register_bitfields![u32, + ctrl [ + enable OFFSET(0) NUMBITS(1) [] + ], + config [ + prescale OFFSET(0) NUMBITS(12) [], + step OFFSET(16) NUMBITS(8) [] + ], + intr [ + timer0 OFFSET(0) NUMBITS(1) [] + ] +]; + +pub struct RvTimer<'a> { + registers: StaticRef<TimerRegisters>, + alarm_client: OptionalCell<&'a dyn time::AlarmClient>, + overflow_client: OptionalCell<&'a dyn time::OverflowClient>, +} + +impl<'a> RvTimer<'a> { + const fn new(base: StaticRef<TimerRegisters>) -> RvTimer<'a> { + RvTimer { + registers: base, + alarm_client: OptionalCell::empty(), + overflow_client: OptionalCell::empty(), + } + } + + pub fn setup(&self) { + let regs = self.registers; + // Set proper prescaler and the like + regs.config + .write(config::prescale.val(PRESCALE as u32) + config::step.val(1u32)); + regs.compare_high.set(0); + regs.value_low.set(0xFFFF_0000); + regs.intr_enable.write(intr::timer0::CLEAR); + regs.ctrl.write(ctrl::enable::SET); + } + + pub fn service_interrupt(&self) { + let regs = self.registers; + regs.intr_enable.write(intr::timer0::CLEAR); + regs.intr_state.write(intr::timer0::SET); + self.alarm_client.map(|client| { + client.alarm(); + }); + } +} + +impl time::Time for RvTimer<'_> { + type Frequency = Freq10KHz; + type Ticks = Ticks64; + + fn now(&self) -> Ticks64 { + // RISC-V has a 64-bit counter but you can only read 32 bits + // at once, which creates a race condition if the lower register + // wraps between the reads. So the recommended approach is to read + // low, read high, read low, and if the second low is lower, re-read + // high. -pal 8/6/20 + let first_low: u32 = self.registers.value_low.get(); + let mut high: u32 = self.registers.value_high.get(); + let second_low: u32 = self.registers.value_low.get(); + if second_low < first_low { + // Wraparound + high = self.registers.value_high.get(); + } + Ticks64::from(((high as u64) << 32) | second_low as u64) + } +} + +impl<'a> time::Counter<'a> for RvTimer<'a> { + fn set_overflow_client(&'a self, client: &'a dyn time::OverflowClient) { + self.overflow_client.set(client); + } + + fn start(&self) -> ReturnCode { + ReturnCode::SUCCESS + } + + fn stop(&self) -> ReturnCode { + // RISCV counter can't be stopped... + ReturnCode::EBUSY + } + + fn reset(&self) -> ReturnCode { + // RISCV counter can't be reset + ReturnCode::FAIL + } + + fn is_running(&self) -> bool { + true + } +} + +impl<'a> time::Alarm<'a> for RvTimer<'a> { + fn set_alarm_client(&self, client: &'a dyn time::AlarmClient) { + self.alarm_client.set(client); + } + + fn set_alarm(&self, reference: Self::Ticks, dt: Self::Ticks) { + // This does not handle the 64-bit wraparound case. + // Because mtimer fires if the counter is >= the compare, + // handling wraparound requires setting compare to the + // maximum value, issuing a callback on the overflow client + // if there is one, spinning until it wraps around to 0, then + // setting the compare to the correct value. + let regs = self.registers; + let now = self.now(); + let mut expire = reference.wrapping_add(dt); + + if !now.within_range(reference, expire) { + expire = now; + } + + let val = expire.into_u64(); + let high = (val >> 32) as u32; + let low = (val & 0xffffffff) as u32; + + // Recommended approach for setting the two compare registers + // (RISC-V Privileged Architectures 3.1.15) -pal 8/6/20 + regs.compare_low.set(0xffffffff); + regs.compare_high.set(high); + regs.compare_low.set(low); + //debug!("TIMER: set to {}", expire.into_u64()); + self.registers.intr_enable.write(intr::timer0::SET); + } + + fn get_alarm(&self) -> Self::Ticks { + let mut val: u64 = (self.registers.compare_high.get() as u64) << 32; + val |= self.registers.compare_low.get() as u64; + Ticks64::from(val) + } + + fn disarm(&self) -> ReturnCode { + // You clear the RISCV mtime interrupt by writing to the compare + // registers. Since the only way to do so is to set a new alarm, + // and this is also the only way to re-enable the interrupt, disabling + // the interrupt is sufficient. Calling set_alarm will clear the + // pending interrupt before re-enabling. -pal 8/6/20 + self.registers.intr_enable.write(intr::timer0::CLEAR); + ReturnCode::SUCCESS + } + + fn is_armed(&self) -> bool { + self.registers.intr_enable.is_set(intr::timer0) + } + + fn minimum_dt(&self) -> Self::Ticks { + Self::Ticks::from(1 as u64) + } +} + +const TIMER_BASE: StaticRef<TimerRegisters> = + unsafe { StaticRef::new(0x4010_0000 as *const TimerRegisters) }; + +pub static mut TIMER: RvTimer = RvTimer::new(TIMER_BASE);
diff --git a/chip/src/uart.rs b/chip/src/uart.rs new file mode 100644 index 0000000..63d9b72 --- /dev/null +++ b/chip/src/uart.rs
@@ -0,0 +1,10 @@ +use crate::chip_config::CONFIG; +use kernel::common::StaticRef; +use lowrisc::uart::{Uart, UartRegisters}; + +pub const UART0_BAUDRATE: u32 = CONFIG.uart_baudrate; + +pub static mut UART0: Uart = Uart::new(UART0_BASE, CONFIG.peripheral_freq); + +const UART0_BASE: StaticRef<UartRegisters> = + unsafe { StaticRef::new(0x4000_0000 as *const UartRegisters) };
diff --git a/chip/src/usbdev.rs b/chip/src/usbdev.rs new file mode 100644 index 0000000..aa70c29 --- /dev/null +++ b/chip/src/usbdev.rs
@@ -0,0 +1,7 @@ +use kernel::common::StaticRef; +use lowrisc::usbdev::{Usb, UsbRegisters}; + +pub static mut USB: Usb = Usb::new(USB0_BASE); + +const USB0_BASE: StaticRef<UsbRegisters> = + unsafe { StaticRef::new(0x4011_0000 as *const UsbRegisters) };