Merge "Move the matcha root app to sw/matcha/app"
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) };