From cc687eaf4b41a00bdf975bc727e65ecbf42040f1 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Mon, 11 Apr 2022 09:22:28 +0200 Subject: [PATCH] initial commit --- .cproject | 145 ++ .gitignore | 13 + .gitmodules | 12 + .gitpod.Dockerfile | 31 + .gitpod.yml | 20 + .project | 59 + .pydevproject | 5 + .vscode/c_cpp_properties.json | 17 + .vscode/launch.json | 55 + .vscode/settings.json | 6 + .vscode/tasks.json | 65 + CMakeLists.txt | 142 ++ LICENSE | 201 +++ Modulefile | 16 + README.md | 126 ++ contrib/TGC_C_cycles.json | 724 +++++++++ contrib/eclipse_launch/FW-Debug.launch | 13 + contrib/eclipse_launch/TGC-VP-FW-Debug.launch | 51 + .../eclipse_launch/TGC-VP-GDBServer.launch | 34 + contrib/eclipse_launch/TGC-VP.launch | 34 + fw/.gitignore | 1 + fw/bsp/drivers/clic/clic_driver.c | 163 ++ fw/bsp/drivers/clic/clic_driver.h | 44 + fw/bsp/drivers/fe300prci/fe300prci_driver.c | 252 ++++ fw/bsp/drivers/fe300prci/fe300prci_driver.h | 79 + fw/bsp/drivers/plic/plic_driver.c | 127 ++ fw/bsp/drivers/plic/plic_driver.h | 51 + fw/bsp/env/common-clang.mk | 72 + fw/bsp/env/common-gcc.mk | 68 + fw/bsp/env/encoding.h | 1313 +++++++++++++++++ fw/bsp/env/entry.S | 97 ++ fw/bsp/env/start.S | 90 ++ fw/bsp/env/tgfs-vp/dhrystone.lds | 157 ++ fw/bsp/env/tgfs-vp/flash.lds | 161 ++ fw/bsp/env/tgfs-vp/init.c | 238 +++ fw/bsp/env/tgfs-vp/openocd.cfg | 34 + fw/bsp/env/tgfs-vp/platform.h | 133 ++ fw/bsp/env/tgfs-vp/settings.mk | 3 + fw/bsp/env/ventry.S | 288 ++++ fw/bsp/include/platform/bits.h | 36 + fw/bsp/include/platform/const.h | 18 + fw/bsp/include/platform/devices/aon.h | 88 ++ fw/bsp/include/platform/devices/clic.h | 30 + fw/bsp/include/platform/devices/clint.h | 14 + fw/bsp/include/platform/devices/gpio.h | 24 + fw/bsp/include/platform/devices/otp.h | 23 + fw/bsp/include/platform/devices/plic.h | 31 + fw/bsp/include/platform/devices/prci.h | 56 + fw/bsp/include/platform/devices/pwm.h | 37 + fw/bsp/include/platform/devices/spi.h | 80 + fw/bsp/include/platform/devices/uart.h | 27 + fw/bsp/include/platform/sections.h | 17 + fw/bsp/include/platform/smp.h | 65 + fw/bsp/libwrap/libwrap.mk | 57 + fw/bsp/libwrap/misc/write_hex.c | 19 + fw/bsp/libwrap/stdlib/malloc.c | 17 + fw/bsp/libwrap/sys/_exit.c | 17 + fw/bsp/libwrap/sys/close.c | 11 + fw/bsp/libwrap/sys/execve.c | 11 + fw/bsp/libwrap/sys/fork.c | 9 + fw/bsp/libwrap/sys/fstat.c | 18 + fw/bsp/libwrap/sys/getpid.c | 8 + fw/bsp/libwrap/sys/isatty.c | 13 + fw/bsp/libwrap/sys/kill.c | 11 + fw/bsp/libwrap/sys/link.c | 11 + fw/bsp/libwrap/sys/lseek.c | 16 + fw/bsp/libwrap/sys/open.c | 11 + fw/bsp/libwrap/sys/openat.c | 11 + fw/bsp/libwrap/sys/printf.c | 271 ++++ fw/bsp/libwrap/sys/puts.c | 28 + fw/bsp/libwrap/sys/read.c | 32 + fw/bsp/libwrap/sys/sbrk.c | 18 + fw/bsp/libwrap/sys/stat.c | 12 + fw/bsp/libwrap/sys/stub.h | 10 + fw/bsp/libwrap/sys/times.c | 12 + fw/bsp/libwrap/sys/unlink.c | 11 + fw/bsp/libwrap/sys/wait.c | 9 + fw/bsp/libwrap/sys/weak_under_alias.h | 7 + fw/bsp/libwrap/sys/write.c | 31 + fw/hello-world/.gitignore | 3 + fw/hello-world/Makefile | 18 + fw/hello-world/hello.c | 26 + fw/hello-world/prebuilt/hello.elf | Bin 0 -> 29716 bytes pysysc/.gitignore | 1 + pysysc/gitpod_install.sh | 11 + pysysc/modules.py | 66 + pysysc/tgc-vp-toplevel.py | 66 + scc | 1 + src/CLIParser.cpp | 100 ++ src/CLIParser.h | 36 + src/CMakeLists.txt | 26 + src/sc_main.cpp | 116 ++ src/tgc_vp/gen/platform_mmap.h | 26 + src/tgc_vp/platform.rdl | 25 + src/tgc_vp/rst_gen.h | 27 + src/tgc_vp/system.cpp | 136 ++ src/tgc_vp/system.h | 81 + src/tgc_vp/tb.cpp | 22 + src/tgc_vp/tb.h | 29 + tgc-iss/dbt-rise-core | 1 + tgc-iss/dbt-rise-tgc | 1 + tgc-iss/generate.sh | 25 + vpvper | 1 + 103 files changed, 7211 insertions(+) create mode 100644 .cproject create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 .gitpod.Dockerfile create mode 100644 .gitpod.yml create mode 100644 .project create mode 100644 .pydevproject create mode 100644 .vscode/c_cpp_properties.json create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 .vscode/tasks.json create mode 100644 CMakeLists.txt create mode 100644 LICENSE create mode 100644 Modulefile create mode 100644 README.md create mode 100644 contrib/TGC_C_cycles.json create mode 100644 contrib/eclipse_launch/FW-Debug.launch create mode 100644 contrib/eclipse_launch/TGC-VP-FW-Debug.launch create mode 100644 contrib/eclipse_launch/TGC-VP-GDBServer.launch create mode 100644 contrib/eclipse_launch/TGC-VP.launch create mode 100644 fw/.gitignore create mode 100644 fw/bsp/drivers/clic/clic_driver.c create mode 100644 fw/bsp/drivers/clic/clic_driver.h create mode 100644 fw/bsp/drivers/fe300prci/fe300prci_driver.c create mode 100644 fw/bsp/drivers/fe300prci/fe300prci_driver.h create mode 100644 fw/bsp/drivers/plic/plic_driver.c create mode 100644 fw/bsp/drivers/plic/plic_driver.h create mode 100644 fw/bsp/env/common-clang.mk create mode 100644 fw/bsp/env/common-gcc.mk create mode 100644 fw/bsp/env/encoding.h create mode 100644 fw/bsp/env/entry.S create mode 100644 fw/bsp/env/start.S create mode 100644 fw/bsp/env/tgfs-vp/dhrystone.lds create mode 100644 fw/bsp/env/tgfs-vp/flash.lds create mode 100644 fw/bsp/env/tgfs-vp/init.c create mode 100644 fw/bsp/env/tgfs-vp/openocd.cfg create mode 100644 fw/bsp/env/tgfs-vp/platform.h create mode 100644 fw/bsp/env/tgfs-vp/settings.mk create mode 100644 fw/bsp/env/ventry.S create mode 100644 fw/bsp/include/platform/bits.h create mode 100644 fw/bsp/include/platform/const.h create mode 100644 fw/bsp/include/platform/devices/aon.h create mode 100644 fw/bsp/include/platform/devices/clic.h create mode 100644 fw/bsp/include/platform/devices/clint.h create mode 100644 fw/bsp/include/platform/devices/gpio.h create mode 100644 fw/bsp/include/platform/devices/otp.h create mode 100644 fw/bsp/include/platform/devices/plic.h create mode 100644 fw/bsp/include/platform/devices/prci.h create mode 100644 fw/bsp/include/platform/devices/pwm.h create mode 100644 fw/bsp/include/platform/devices/spi.h create mode 100644 fw/bsp/include/platform/devices/uart.h create mode 100644 fw/bsp/include/platform/sections.h create mode 100644 fw/bsp/include/platform/smp.h create mode 100644 fw/bsp/libwrap/libwrap.mk create mode 100644 fw/bsp/libwrap/misc/write_hex.c create mode 100644 fw/bsp/libwrap/stdlib/malloc.c create mode 100644 fw/bsp/libwrap/sys/_exit.c create mode 100644 fw/bsp/libwrap/sys/close.c create mode 100644 fw/bsp/libwrap/sys/execve.c create mode 100644 fw/bsp/libwrap/sys/fork.c create mode 100644 fw/bsp/libwrap/sys/fstat.c create mode 100644 fw/bsp/libwrap/sys/getpid.c create mode 100644 fw/bsp/libwrap/sys/isatty.c create mode 100644 fw/bsp/libwrap/sys/kill.c create mode 100644 fw/bsp/libwrap/sys/link.c create mode 100644 fw/bsp/libwrap/sys/lseek.c create mode 100644 fw/bsp/libwrap/sys/open.c create mode 100644 fw/bsp/libwrap/sys/openat.c create mode 100644 fw/bsp/libwrap/sys/printf.c create mode 100644 fw/bsp/libwrap/sys/puts.c create mode 100644 fw/bsp/libwrap/sys/read.c create mode 100644 fw/bsp/libwrap/sys/sbrk.c create mode 100644 fw/bsp/libwrap/sys/stat.c create mode 100644 fw/bsp/libwrap/sys/stub.h create mode 100644 fw/bsp/libwrap/sys/times.c create mode 100644 fw/bsp/libwrap/sys/unlink.c create mode 100644 fw/bsp/libwrap/sys/wait.c create mode 100644 fw/bsp/libwrap/sys/weak_under_alias.h create mode 100644 fw/bsp/libwrap/sys/write.c create mode 100644 fw/hello-world/.gitignore create mode 100644 fw/hello-world/Makefile create mode 100644 fw/hello-world/hello.c create mode 100755 fw/hello-world/prebuilt/hello.elf create mode 100644 pysysc/.gitignore create mode 100755 pysysc/gitpod_install.sh create mode 100644 pysysc/modules.py create mode 100755 pysysc/tgc-vp-toplevel.py create mode 160000 scc create mode 100644 src/CLIParser.cpp create mode 100644 src/CLIParser.h create mode 100644 src/CMakeLists.txt create mode 100644 src/sc_main.cpp create mode 100644 src/tgc_vp/gen/platform_mmap.h create mode 100644 src/tgc_vp/platform.rdl create mode 100644 src/tgc_vp/rst_gen.h create mode 100644 src/tgc_vp/system.cpp create mode 100644 src/tgc_vp/system.h create mode 100644 src/tgc_vp/tb.cpp create mode 100644 src/tgc_vp/tb.h create mode 160000 tgc-iss/dbt-rise-core create mode 160000 tgc-iss/dbt-rise-tgc create mode 100644 tgc-iss/generate.sh create mode 160000 vpvper diff --git a/.cproject b/.cproject new file mode 100644 index 0000000..7d8ff25 --- /dev/null +++ b/.cproject @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CMAKE_BUILD_TOOL + + fw-hello-world + true + true + true + + + gmake + -C ../../fw/fir + clean all + true + false + true + + + gmake + -C ../../fw/fir VARIANT=ISAX + clean all + true + false + true + + + + \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1c4ca24 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +/build/ +/plugins/ +/.settings/ +*.o +*.a +*.lib +/*.txlog +/*.vcd +/.vs +/out +/coverage.info +/output.txt +/output.trc diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..ddd97f0 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,12 @@ +[submodule "scc"] + path = scc + url = https://github.com/VP-Vibes/SystemC-Components.git +[submodule "vpvper"] + path = vpvper + url = https://github.com/VP-Vibes/VPV-Peripherals.git +[submodule "tgc-iss/dbt-rise-core"] + path = tgc-iss/dbt-rise-core + url = https://github.com/Minres/DBT-RISE-Core.git +[submodule "tgc-iss/dbt-rise-tgc"] + path = tgc-iss/dbt-rise-tgc + url = https://git.minres.com/DBT-RISE/DBT-RISE-TGC.git diff --git a/.gitpod.Dockerfile b/.gitpod.Dockerfile new file mode 100644 index 0000000..4b3e5a1 --- /dev/null +++ b/.gitpod.Dockerfile @@ -0,0 +1,31 @@ +FROM gitpod/workspace-full:latest + + +# Make a working folder and set the necessary environment variables. +ENV RISCV /opt/riscv +RUN sudo mkdir -p $RISCV +RUN sudo touch $RISCV/install.stamp + +# Add the GNU utils bin folder to the path. +ENV PATH $RISCV/bin:$PATH +MAINTAINER eyck@minres.com + +USER root +RUN apt-get install gnupg software-properties-common wget -y +RUN wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | apt-key add - +RUN apt-add-repository 'deb https://apt.kitware.com/ubuntu/ focal main' + +# Obtain the RISCV-tools repo which consists of a number of submodules +# so make sure we get those too. +WORKDIR /opt/riscv +RUN apt-get update && \ + apt-get install -y autoconf automake autotools-dev curl python3 python3-pip python3-venv libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev cmake gdb && \ + apt-get clean && rm -rf /var/lib/apt/lists/* +RUN git clone --recursive https://github.com/riscv/riscv-gnu-toolchain && \ + cd riscv-gnu-toolchain && \ + ./configure --prefix=/opt/riscv --without-system-zlib --enable-multilib --with-arch=rv32gc --with-abi=ilp32d && \ + make -j newlib && \ + cd .. && \ + rm -rf riscv-gnu-toolchain +RUN apt-get update && apt install default-jdk -y +USER gitpod diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 0000000..6dc3178 --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,20 @@ +--- +# Commands to start on workspace startup +image: stanka/gitpod-riscv-tools:latest +# file: .gitpod.Dockerfile +tasks: + - env: + CONAN_USER_HOME: "/workspace/conan" + init: | + python3 -m venv /workspace/venv + python3 -m pip install --upgrade pip + source /workspace/venv/bin/activate + pip install conan + command: | + source /workspace/venv/bin/activate + cmake -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON + cmake --build build +vscode: + extensions: + - ms-python.python + - webfreak.debug diff --git a/.project b/.project new file mode 100644 index 0000000..2f8fe8f --- /dev/null +++ b/.project @@ -0,0 +1,59 @@ + + + TGC-VP + + + + + + org.python.pydev.PyDevBuilder + + + + + org.eclipse.xtext.ui.shared.xtextBuilder + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + org.eclipse.xtext.ui.shared.xtextNature + org.python.pydev.pythonNature + + + + 0 + + 22 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.o + + + + 0 + + 22 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.a + + + + diff --git a/.pydevproject b/.pydevproject new file mode 100644 index 0000000..2b04565 --- /dev/null +++ b/.pydevproject @@ -0,0 +1,5 @@ + + + Default + python interpreter + diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..1211532 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,17 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [], + "compilerPath": "/usr/bin/gcc", + "cStandard": "gnu17", + "cppStandard": "gnu++14", + "intelliSenseMode": "linux-gcc-x64", + "configurationProvider": "ms-vscode.cmake-tools" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..68a1a1f --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,55 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "gdb", + "request": "attach", + "name": "Attach-to-gdbserver", + "executable": "./fw/hello-world/hello", + "target": ":10000", + "remote": true, + "cwd": "${workspaceRoot}", + "valuesFormatting": "prettyPrinters", + "gdbpath": "/opt/riscv/bin/riscv32-unknown-elf-gdb", + "debugger_args": [], + "presentation": { + "hidden": true, + "group": "FW Debug", + "order": 2 + } + }, + { + "type": "gdb", + "request": "launch", + "name": "Launch-VP-with-gdbserver", + "cwd": "${workspaceRoot}", + "valuesFormatting": "parseText", + "target": "./build/src/tgc-vp", + "arguments": "-f fw/hello-world/hello -g 10000", + "presentation": { + "hidden": true, + "group": "FW Debug", + "order": 1 + } + }, + { + "type": "gdb", + "request": "launch", + "name": "VP-Debug", + "cwd": "${workspaceRoot}", + "valuesFormatting": "parseText", + "target": "./build/src/tgc-vp", + "printCalls": false, + "arguments": "-f fw/hello-world/hello" + }, + ], + "compounds": [ + { + "name": "FW-Debug", + "configurations": ["Launch-VP-with-gdbserver", "Attach-to-gdbserver"] + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..4cfbe19 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "files.associations": { + "platform.h": "c" + }, + "debug.allowBreakpointsEverywhere": true +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..26c587c --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,65 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "CMake-and-make", + "type": "shell", + "command": "source /workspace/venv/bin/activate && cmake -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON && cmake --build build", + "problemMatcher": [], + "presentation": { + "echo": true, + "reveal": "always", + "focus": true, + "panel": "dedicated", + "showReuseMessage": false, + "clear": true + }, + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "Build-FW", + "type": "shell", + "command": "cd fw/hello-world/ && make", + "problemMatcher": [], + "presentation": { + "echo": true, + "reveal": "always", + "focus": true, + "panel": "dedicated", + "showReuseMessage": false, + "clear": true + } + }, + { + "label": "Execute-VP", + "type": "shell", + "command": "build/src/tgc-vp -f fw/hello-world/hello -p pctrace=contrib/TGC_C_cycles.json", + "problemMatcher": [], + "presentation": { + "echo": true, + "reveal": "always", + "focus": true, + "panel": "dedicated", + "showReuseMessage": false, + "clear": true + } + }, + { + "label": "VP-GDB-Server", + "type": "shell", + "command": "build/src/tgc-vp -f fw/hello-world/hello -g 10000", + "problemMatcher": [], + "presentation": { + "echo": true, + "reveal": "always", + "focus": true, + "panel": "dedicated", + "showReuseMessage": false, + "clear": true + }, + } + ] +} diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..828e1f6 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,142 @@ +cmake_minimum_required(VERSION 3.16) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/scc/cmake) + +include(ConanInline) + +project(ecosystem-vp LANGUAGES C CXX VERSION 1.0.0) + +option(ENABLE_SCV "Enable the use of SCV" ON) +option(LIBS_ONLY "Just build the shared libraries needed to build the VP" OFF) +option(NO_FW_BUILD "Disable the automatic rebuild of firmware running on the VP" OFF) +option(EN_EXT_DEBUG "Enable extended debug output at runtime" OFF) +option(ENABLE_COVERAGE "Enable code coverage" OFF) +option(ENABLE_SANITIZER "Enable address sanitizer" OFF) +option(ENABLE_CLANGTIDY "Enable static analysis with clang-tidy." OFF) + +set(SCC_LIB_ONLY ON) +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_POSITION_INDEPENDENT_CODE ON) +include(CheckCXXCompilerFlag) +include(GNUInstallDirs) + +# add address sanitizer +if(ENABLE_SANITIZER) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address") +endif() +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + add_compile_options(/vmg /wd26812) # suppress Warnung C26812: "enum class" gegenüber "enum" (Enum.3) bevorzugen +endif() +set(CONAN_BOOST_OPTIONS +boost:header_only=False +boost:without_contract=True +boost:without_fiber=True +boost:without_graph=True +boost:without_graph_parallel=True +boost:without_iostreams=True +boost:without_json=True +boost:without_locale=True +boost:without_log=True +boost:without_math=True +boost:without_mpi=True +boost:without_nowide=True +boost:without_python=True +boost:without_random=True +boost:without_regex=True +boost:without_stacktrace=True +boost:without_test=True +boost:without_timer=True +boost:without_type_erasure=True +boost:without_wave=True +) +if (UNIX) + list(APPEND CONAN_BOOST_OPTIONS boost:fPIC=True boost:shared=True) +endif (UNIX) + +set(CONAN_PACKAGE_LIST fmt/8.0.1 zlib/1.2.11 boost/1.75.0 gsl-lite/0.37.0 elfio/3.8) + +if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + list(APPEND CONAN_BOOST_OPTIONS boost:fPIC=True lua:compile_as_cpp=False) + list(APPEND CONAN_PACKAGE_LIST tcc/0.9.27 seasocks/1.4.4 lua/5.4.3) +endif() +set(CONAN_PACKAGE_OPTIONS fmt:header_only=True ${CONAN_BOOST_OPTIONS}) +if(NOT USE_CWR_SYSTEMC AND NOT USE_NCSC_SYSTEMC AND NOT DEFINED ENV{SYSTEMC_HOME}) + set(CONAN_PACKAGE_LIST ${CONAN_PACKAGE_LIST} systemc/2.3.3 systemc-cci/1.0.0) + set(CONAN_PACKAGE_OPTIONS ${CONAN_PACKAGE_OPTIONS} systemc:shared=True systemc-cci:shared=True systemc:disable_virtual_bind=False) +endif() + +conan_check() +conan_add_remote(NAME minres URL https://artifactory.minres.com/artifactory/api/conan/oss) +conan_cmake_configure(REQUIRES ${CONAN_PACKAGE_LIST} + GENERATORS cmake_find_package + OPTIONS ${CONAN_PACKAGE_OPTIONS} + ) +conan_cmake_autodetect(settings) +conan_install() +# needed when using CentOS devenv-7 or -8 and boost does not build because of missing GLIBCXX version +#conan_install(BUILD b2 missing) +find_package(tcc) +find_package(elfio) +find_package(fmt) +find_package(gsl-lite) +set(Boost_NO_BOOST_CMAKE ON) # Don't do a find_package in config mode before searching for a regular boost install. +#set(Boost_NO_SYSTEM_PATHS ON) +#set(Boost_USE_STATIC_LIBS OFF) +#set(Boost_USE_MULTITHREADED ON) +#set(Boost_USE_STATIC_RUNTIME OFF) + + +find_package(Boost REQUIRED COMPONENTS program_options QUIET) + +set(CLANG_FORMAT_EXCLUDE_PATTERNS "scc") +find_package(ClangFormat) + +if(ENABLE_COVERAGE) + include(CodeCoverage) + append_coverage_compiler_flags() + set(COVERAGE_EXCLUDES "${tgfs_verif_SOURCE_DIR}/scc/*" "${tgfs_verif_SOURCE_DIR}/build/*" "$ENV{HOME}/.conan/*" "/opt/*") +endif() + +if(ENABLE_CLANGTIDY) + find_program(CLANG_TIDY_EXE NAMES "clang-tidy") + if (CLANG_TIDY_EXE) + message(STATUS "clang-tidy found: ${CLANG_TIDY_EXE}") + set(CLANG_TIDY_CHECKS + "-*,modernize-*,-modernize-use-trailing-return-type,clang-analyzer-*,concurrency-*,cppcoreguidelines-*,boost-*,bugprone-*,performance-*,portability-*,readability-*") + #set(CLANG_TIDY_CHECKS "*") + set(CMAKE_CXX_CLANG_TIDY + ${CLANG_TIDY_EXE}; + -header-filter=${tgfs_verif_SOURCE_DIR}; + -checks=${CLANG_TIDY_CHECKS};) + else() + message(AUTHOR_WARNING "clang-tidy not found!") + set(CMAKE_CXX_CLANG_TIDY "" CACHE STRING "" FORCE) # delete it + endif() +endif () + +add_subdirectory(scc) +add_subdirectory(tgc-iss/dbt-rise-core) +add_subdirectory(tgc-iss/dbt-rise-tgc) +if(NOT USE_CWR_SYSTEMC) + add_subdirectory(vpvper) +endif() +if(NOT LIBS_ONLY) + add_subdirectory(src) +endif() +if(IS_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/plugins) + add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/plugins) +endif() +if(NOT NO_FW_BUILD) + add_custom_target(fw-hello-world ALL COMMAND make -C fw/hello-world + USES_TERMINAL WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) +endif() + +# CTest is a testing tool that can be used to test your project. + enable_testing() + add_test(NAME tgc-vp-hello-world + #WORKING_DIRECTORY ${ecosystem-vp_DIR}/bin + COMMAND tgc-vp -f ${CMAKE_CURRENT_LIST_DIR}/fw/hello-world/prebuilt/hello.elf) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Modulefile b/Modulefile new file mode 100644 index 0000000..67fc848 --- /dev/null +++ b/Modulefile @@ -0,0 +1,16 @@ +#%Module###################################################################### +## +## Project Module +## +proc ModulesHelp { } { + puts stderr "\tThe TGC verification project Module\n" + puts stderr "\tThis module loads PATHs and variables for running TGC verification." +} + +set distro [exec /usr/bin/lsb_release -i -s] +if { $distro == "CentOS" && ![info exists ::env(PROJECT)] && ![info exists ::env(PCP_DIR)] } { + puts stderr "Don't forget to execute 'scl enable devtoolset-7 llvm-toolset-7 bash'" +} + +module load tools/gcc-riscv32/9.2.0 +module load tools/cmake diff --git a/README.md b/README.md new file mode 100644 index 0000000..325fddc --- /dev/null +++ b/README.md @@ -0,0 +1,126 @@ +# TGC-VP +The Scale4Edge ecosystem VP using VP-VIBES peripherals. + +This VP is based in MINRES TGC series cores and uses CoreDSL to generate the concrete ISS +of a particular ISA + extensions. The generator approach makes it very flexible and adaptable. +Since the CoreDSL description is used to generate RTL as well as verification artifacts it +provides a comprehensive and consistent solution to develop processor cores. + +## Ultra Quick start + +Using gitpod you can run the VP in the cloud. Just visit [Gitpod.io](https://www.gitpod.io/#https://github.com/Minres/TGC-VP/tree/develop) +and follow the instructions. After the build finished you can run + +``` + +build/src/tgc-vp -f fw/hello-world/prebuilt/hello.elf + +``` + +or use ctest: + +``` + +cd build +ctest + +``` + + +You will see on console the prints of the hello world firmware at fw/hello-world/hello.c + +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/Minres/TGC-VP) + +## Quick start + +* you need to have a C++14 capable compiler, make, python, and cmake installed + +* install conan.io (see also http://docs.conan.io/en/latest/installation.html): + + ``` + + pip3 install --user conan + + ``` + + It is advised to use conan version 1.36 or newer. In case of an older version please run + + ```sh + + pip3 install --user --upgrade conan + + ``` + + Installing conan for the first time you need to create a profile: + + ``` + + conan profile create default --detect + + ``` + +* checkout source from git + + ```sh + + git clone --recursive -b develop https://github.com/Minres/TGC-VP.git + + ``` + +* start an out-of-source build: + + ``` + + cd TGC-VP + mkdir build + cd build + cmake .. + make -j tgc-vp + + ``` + +* run the VP with pre-built firmware + + ``` + + ctest + + ``` + + or + + ``` + + src/tgc-vp -f ../fw/hello-world/prebuild/hello.elf + + ``` + +To rebuild the firmware you need to install a RISC-V toolchain like https://github.com/riscv/riscv-tools. + +# Windows/Visual Studio build + +TGC-VP supports VS2019/MSVC 16 and has been tested only with this version + +## Prerequisites + +You need to have to following installed: + +* Visual Studio 2019 (community edition is sufficient) with C/C++ support +* Python 3.6 or newer +* SystemC 2.3.3 and SystemC-CCI 1.0.0. Both should be installed into the same location and the + environment variable SYSTEMC_HOME should point to it +* Conan (https://conan.io/) version 1.36 or newer. If python is installed this can be installed using pip + (see above in [Quick start](#quick-start)) + +## build step + +Create a project at the location of the git workarea. This can be done + +``` + +devenv + +``` + +The build steps are as described in the VS documentation for CMake based projects. + diff --git a/contrib/TGC_C_cycles.json b/contrib/TGC_C_cycles.json new file mode 100644 index 0000000..61bc4ee --- /dev/null +++ b/contrib/TGC_C_cycles.json @@ -0,0 +1,724 @@ +{ + "TGC_C" : [ + { + "name" : "LUI", + "size" : 32, + "encoding": "0b00000000000000000000000000110111", + "mask": "0b00000000000000000000000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "AUIPC", + "size" : 32, + "encoding": "0b00000000000000000000000000010111", + "mask": "0b00000000000000000000000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "JAL", + "size" : 32, + "encoding": "0b00000000000000000000000001101111", + "mask": "0b00000000000000000000000001111111", + "branch": true, + "delay" : 2 + }, + { + "name" : "JALR", + "size" : 32, + "encoding": "0b00000000000000000000000001100111", + "mask": "0b00000000000000000111000001111111", + "branch": true, + "delay" : 2 + }, + { + "name" : "BEQ", + "size" : 32, + "encoding": "0b00000000000000000000000001100011", + "mask": "0b00000000000000000111000001111111", + "branch": true, + "delay" : [2,1] + }, + { + "name" : "BNE", + "size" : 32, + "encoding": "0b00000000000000000001000001100011", + "mask": "0b00000000000000000111000001111111", + "branch": true, + "delay" : [2,1] + }, + { + "name" : "BLT", + "size" : 32, + "encoding": "0b00000000000000000100000001100011", + "mask": "0b00000000000000000111000001111111", + "branch": true, + "delay" : [2,1] + }, + { + "name" : "BGE", + "size" : 32, + "encoding": "0b00000000000000000101000001100011", + "mask": "0b00000000000000000111000001111111", + "branch": true, + "delay" : [2,1] + }, + { + "name" : "BLTU", + "size" : 32, + "encoding": "0b00000000000000000110000001100011", + "mask": "0b00000000000000000111000001111111", + "branch": true, + "delay" : [2,1] + }, + { + "name" : "BGEU", + "size" : 32, + "encoding": "0b00000000000000000111000001100011", + "mask": "0b00000000000000000111000001111111", + "branch": true, + "delay" : [2,1] + }, + { + "name" : "LB", + "size" : 32, + "encoding": "0b00000000000000000000000000000011", + "mask": "0b00000000000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "LH", + "size" : 32, + "encoding": "0b00000000000000000001000000000011", + "mask": "0b00000000000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "LW", + "size" : 32, + "encoding": "0b00000000000000000010000000000011", + "mask": "0b00000000000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "LBU", + "size" : 32, + "encoding": "0b00000000000000000100000000000011", + "mask": "0b00000000000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "LHU", + "size" : 32, + "encoding": "0b00000000000000000101000000000011", + "mask": "0b00000000000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "SB", + "size" : 32, + "encoding": "0b00000000000000000000000000100011", + "mask": "0b00000000000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "SH", + "size" : 32, + "encoding": "0b00000000000000000001000000100011", + "mask": "0b00000000000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "SW", + "size" : 32, + "encoding": "0b00000000000000000010000000100011", + "mask": "0b00000000000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "ADDI", + "size" : 32, + "encoding": "0b00000000000000000000000000010011", + "mask": "0b00000000000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "SLTI", + "size" : 32, + "encoding": "0b00000000000000000010000000010011", + "mask": "0b00000000000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "SLTIU", + "size" : 32, + "encoding": "0b00000000000000000011000000010011", + "mask": "0b00000000000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "XORI", + "size" : 32, + "encoding": "0b00000000000000000100000000010011", + "mask": "0b00000000000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "ORI", + "size" : 32, + "encoding": "0b00000000000000000110000000010011", + "mask": "0b00000000000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "ANDI", + "size" : 32, + "encoding": "0b00000000000000000111000000010011", + "mask": "0b00000000000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "SLLI", + "size" : 32, + "encoding": "0b00000000000000000001000000010011", + "mask": "0b11111110000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "SRLI", + "size" : 32, + "encoding": "0b00000000000000000101000000010011", + "mask": "0b11111110000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "SRAI", + "size" : 32, + "encoding": "0b01000000000000000101000000010011", + "mask": "0b11111110000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "ADD", + "size" : 32, + "encoding": "0b00000000000000000000000000110011", + "mask": "0b11111110000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "SUB", + "size" : 32, + "encoding": "0b01000000000000000000000000110011", + "mask": "0b11111110000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "SLL", + "size" : 32, + "encoding": "0b00000000000000000001000000110011", + "mask": "0b11111110000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "SLT", + "size" : 32, + "encoding": "0b00000000000000000010000000110011", + "mask": "0b11111110000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "SLTU", + "size" : 32, + "encoding": "0b00000000000000000011000000110011", + "mask": "0b11111110000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "XOR", + "size" : 32, + "encoding": "0b00000000000000000100000000110011", + "mask": "0b11111110000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "SRL", + "size" : 32, + "encoding": "0b00000000000000000101000000110011", + "mask": "0b11111110000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "SRA", + "size" : 32, + "encoding": "0b01000000000000000101000000110011", + "mask": "0b11111110000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "OR", + "size" : 32, + "encoding": "0b00000000000000000110000000110011", + "mask": "0b11111110000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "AND", + "size" : 32, + "encoding": "0b00000000000000000111000000110011", + "mask": "0b11111110000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "FENCE", + "size" : 32, + "encoding": "0b00000000000000000000000000001111", + "mask": "0b00000000000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "ECALL", + "size" : 32, + "encoding": "0b00000000000000000000000001110011", + "mask": "0b11111111111111111111111111111111", + "branch": true, + "delay" : 2 + }, + { + "name" : "EBREAK", + "size" : 32, + "encoding": "0b00000000000100000000000001110011", + "mask": "0b11111111111111111111111111111111", + "branch": true, + "delay" : 2 + }, + { + "name" : "URET", + "size" : 32, + "encoding": "0b00000000001000000000000001110011", + "mask": "0b11111111111111111111111111111111", + "branch": true, + "delay" : 2 + }, + { + "name" : "SRET", + "size" : 32, + "encoding": "0b00010000001000000000000001110011", + "mask": "0b11111111111111111111111111111111", + "branch": true, + "delay" : 2 + }, + { + "name" : "MRET", + "size" : 32, + "encoding": "0b00110000001000000000000001110011", + "mask": "0b11111111111111111111111111111111", + "branch": true, + "delay" : 2 + }, + { + "name" : "WFI", + "size" : 32, + "encoding": "0b00010000010100000000000001110011", + "mask": "0b11111111111111111111111111111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "DRET", + "size" : 32, + "encoding": "0b01111011001000000000000001110011", + "mask": "0b11111111111111111111111111111111", + "branch": true, + "delay" : 2 + }, + { + "name" : "CSRRW", + "size" : 32, + "encoding": "0b00000000000000000001000001110011", + "mask": "0b00000000000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "CSRRS", + "size" : 32, + "encoding": "0b00000000000000000010000001110011", + "mask": "0b00000000000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "CSRRC", + "size" : 32, + "encoding": "0b00000000000000000011000001110011", + "mask": "0b00000000000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "CSRRWI", + "size" : 32, + "encoding": "0b00000000000000000101000001110011", + "mask": "0b00000000000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "CSRRSI", + "size" : 32, + "encoding": "0b00000000000000000110000001110011", + "mask": "0b00000000000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "CSRRCI", + "size" : 32, + "encoding": "0b00000000000000000111000001110011", + "mask": "0b00000000000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "FENCE_I", + "size" : 32, + "encoding": "0b00000000000000000001000000001111", + "mask": "0b00000000000000000111000001111111", + "branch": false, + "delay" : 2 + }, + { + "name" : "MUL", + "size" : 32, + "encoding": "0b00000010000000000000000000110011", + "mask": "0b11111110000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "MULH", + "size" : 32, + "encoding": "0b00000010000000000001000000110011", + "mask": "0b11111110000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "MULHSU", + "size" : 32, + "encoding": "0b00000010000000000010000000110011", + "mask": "0b11111110000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "MULHU", + "size" : 32, + "encoding": "0b00000010000000000011000000110011", + "mask": "0b11111110000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "DIV", + "size" : 32, + "encoding": "0b00000010000000000100000000110011", + "mask": "0b11111110000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "DIVU", + "size" : 32, + "encoding": "0b00000010000000000101000000110011", + "mask": "0b11111110000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "REM", + "size" : 32, + "encoding": "0b00000010000000000110000000110011", + "mask": "0b11111110000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "REMU", + "size" : 32, + "encoding": "0b00000010000000000111000000110011", + "mask": "0b11111110000000000111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "CADDI4SPN", + "size" : 16, + "encoding": "0b0000000000000000", + "mask": "0b1110000000000011", + "branch": false, + "delay" : 1 + }, + { + "name" : "CLW", + "size" : 16, + "encoding": "0b0100000000000000", + "mask": "0b1110000000000011", + "branch": false, + "delay" : 1 + }, + { + "name" : "CSW", + "size" : 16, + "encoding": "0b1100000000000000", + "mask": "0b1110000000000011", + "branch": false, + "delay" : 1 + }, + { + "name" : "CADDI", + "size" : 16, + "encoding": "0b0000000000000001", + "mask": "0b1110000000000011", + "branch": false, + "delay" : 1 + }, + { + "name" : "CNOP", + "size" : 16, + "encoding": "0b0000000000000001", + "mask": "0b1110111110000011", + "branch": false, + "delay" : 1 + }, + { + "name" : "CJAL", + "size" : 16, + "encoding": "0b0010000000000001", + "mask": "0b1110000000000011", + "branch": true, + "delay" : 2 + }, + { + "name" : "CLI", + "size" : 16, + "encoding": "0b0100000000000001", + "mask": "0b1110000000000011", + "branch": false, + "delay" : 1 + }, + { + "name" : "CLUI", + "size" : 16, + "encoding": "0b0110000000000001", + "mask": "0b1110000000000011", + "branch": false, + "delay" : 1 + }, + { + "name" : "CADDI16SP", + "size" : 16, + "encoding": "0b0110000100000001", + "mask": "0b1110111110000011", + "branch": false, + "delay" : 1 + }, + { + "name" : "__reserved_clui", + "size" : 16, + "encoding": "0b0110000000000001", + "mask": "0b1111000001111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "CSRLI", + "size" : 16, + "encoding": "0b1000000000000001", + "mask": "0b1111110000000011", + "branch": false, + "delay" : 1 + }, + { + "name" : "CSRAI", + "size" : 16, + "encoding": "0b1000010000000001", + "mask": "0b1111110000000011", + "branch": false, + "delay" : 1 + }, + { + "name" : "CANDI", + "size" : 16, + "encoding": "0b1000100000000001", + "mask": "0b1110110000000011", + "branch": false, + "delay" : 1 + }, + { + "name" : "CSUB", + "size" : 16, + "encoding": "0b1000110000000001", + "mask": "0b1111110001100011", + "branch": false, + "delay" : 1 + }, + { + "name" : "CXOR", + "size" : 16, + "encoding": "0b1000110000100001", + "mask": "0b1111110001100011", + "branch": false, + "delay" : 1 + }, + { + "name" : "COR", + "size" : 16, + "encoding": "0b1000110001000001", + "mask": "0b1111110001100011", + "branch": false, + "delay" : 1 + }, + { + "name" : "CAND", + "size" : 16, + "encoding": "0b1000110001100001", + "mask": "0b1111110001100011", + "branch": false, + "delay" : 1 + }, + { + "name" : "CJ", + "size" : 16, + "encoding": "0b1010000000000001", + "mask": "0b1110000000000011", + "branch": true, + "delay" : 2 + }, + { + "name" : "CBEQZ", + "size" : 16, + "encoding": "0b1100000000000001", + "mask": "0b1110000000000011", + "branch": true, + "delay" : [2,1] + }, + { + "name" : "CBNEZ", + "size" : 16, + "encoding": "0b1110000000000001", + "mask": "0b1110000000000011", + "branch": true, + "delay" : [2,1] + }, + { + "name" : "CSLLI", + "size" : 16, + "encoding": "0b0000000000000010", + "mask": "0b1111000000000011", + "branch": false, + "delay" : 1 + }, + { + "name" : "CLWSP", + "size" : 16, + "encoding": "0b0100000000000010", + "mask": "0b1110000000000011", + "branch": false, + "delay" : 1 + }, + { + "name" : "CMV", + "size" : 16, + "encoding": "0b1000000000000010", + "mask": "0b1111000000000011", + "branch": false, + "delay" : 1 + }, + { + "name" : "CJR", + "size" : 16, + "encoding": "0b1000000000000010", + "mask": "0b1111000001111111", + "branch": true, + "delay" : 2 + }, + { + "name" : "__reserved_cmv", + "size" : 16, + "encoding": "0b1000000000000010", + "mask": "0b1111111111111111", + "branch": false, + "delay" : 1 + }, + { + "name" : "CADD", + "size" : 16, + "encoding": "0b1001000000000010", + "mask": "0b1111000000000011", + "branch": false, + "delay" : 1 + }, + { + "name" : "CJALR", + "size" : 16, + "encoding": "0b1001000000000010", + "mask": "0b1111000001111111", + "branch": true, + "delay" : 2 + }, + { + "name" : "CEBREAK", + "size" : 16, + "encoding": "0b1001000000000010", + "mask": "0b1111111111111111", + "branch": true, + "delay" : 2 + }, + { + "name" : "CSWSP", + "size" : 16, + "encoding": "0b1100000000000010", + "mask": "0b1110000000000011", + "branch": false, + "delay" : 1 + }, + { + "name" : "DII", + "size" : 16, + "encoding": "0b0000000000000000", + "mask": "0b1111111111111111", + "branch": false, + "delay" : 1 + } + ] +} \ No newline at end of file diff --git a/contrib/eclipse_launch/FW-Debug.launch b/contrib/eclipse_launch/FW-Debug.launch new file mode 100644 index 0000000..2889448 --- /dev/null +++ b/contrib/eclipse_launch/FW-Debug.launch @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/contrib/eclipse_launch/TGC-VP-FW-Debug.launch b/contrib/eclipse_launch/TGC-VP-FW-Debug.launch new file mode 100644 index 0000000..b1170d3 --- /dev/null +++ b/contrib/eclipse_launch/TGC-VP-FW-Debug.launch @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contrib/eclipse_launch/TGC-VP-GDBServer.launch b/contrib/eclipse_launch/TGC-VP-GDBServer.launch new file mode 100644 index 0000000..e92ffa7 --- /dev/null +++ b/contrib/eclipse_launch/TGC-VP-GDBServer.launch @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contrib/eclipse_launch/TGC-VP.launch b/contrib/eclipse_launch/TGC-VP.launch new file mode 100644 index 0000000..56a52c7 --- /dev/null +++ b/contrib/eclipse_launch/TGC-VP.launch @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fw/.gitignore b/fw/.gitignore new file mode 100644 index 0000000..0e8815f --- /dev/null +++ b/fw/.gitignore @@ -0,0 +1 @@ +/fir diff --git a/fw/bsp/drivers/clic/clic_driver.c b/fw/bsp/drivers/clic/clic_driver.c new file mode 100644 index 0000000..22a2cd4 --- /dev/null +++ b/fw/bsp/drivers/clic/clic_driver.c @@ -0,0 +1,163 @@ +// See LICENSE for license details. + +#include "clic/clic_driver.h" +#include "platform.h" +#include "encoding.h" +#include +#include "../../include/platform/devices/clic.h" + + +void volatile_memzero(uint8_t * base, unsigned int size) { + volatile uint8_t * ptr; + for (ptr = base; ptr < (base + size); ptr++){ + *ptr = 0; + } +} + +// Note that there are no assertions or bounds checking on these +// parameter values. +void clic_init ( + clic_instance_t * this_clic, + uintptr_t hart_addr, + interrupt_function_ptr_t* vect_table, + interrupt_function_ptr_t default_handler, + uint32_t num_irq, + uint32_t num_config_bits + ) +{ + this_clic->hart_addr= hart_addr; + this_clic->vect_table= vect_table; + this_clic->num_config_bits= num_config_bits; + + //initialize vector table + for(int i=0;i++;ivect_table[i] = default_handler; + } + + //set base vectors + write_csr(mtvt, vect_table); + + + //clear all interrupt enables and pending + volatile_memzero((uint8_t*)(this_clic->hart_addr+CLIC_INTIE), num_irq); + volatile_memzero((uint8_t*)(this_clic->hart_addr+CLIC_INTIP), num_irq); + + //clear nlbits and nvbits; all interrupts trap to level 15 + *(volatile uint8_t*)(this_clic->hart_addr+CLIC_CFG)=0; + +} + +void clic_install_handler (clic_instance_t * this_clic, uint32_t source, interrupt_function_ptr_t handler) { + this_clic->vect_table[source] = handler; +} + +void clic_enable_interrupt (clic_instance_t * this_clic, uint32_t source) { + *(volatile uint8_t*)(this_clic->hart_addr+CLIC_INTIE+source) = 1; +} + +void clic_disable_interrupt (clic_instance_t * this_clic, uint32_t source){ + *(volatile uint8_t*)(this_clic->hart_addr+CLIC_INTIE+source) = 0; +} + +void clic_set_pending(clic_instance_t * this_clic, uint32_t source){ + *(volatile uint8_t*)(this_clic->hart_addr+CLIC_INTIP+source) = 1; +} + +void clic_clear_pending(clic_instance_t * this_clic, uint32_t source){ + *(volatile uint8_t*)(this_clic->hart_addr+CLIC_INTIP+source) = 0; +} + +void clic_set_intcfg (clic_instance_t * this_clic, uint32_t source, uint32_t intcfg){ + *(volatile uint8_t*)(this_clic->hart_addr+CLIC_INTCFG+source) = intcfg; +} + +uint8_t clic_get_intcfg (clic_instance_t * this_clic, uint32_t source){ + return *(volatile uint8_t*)(this_clic->hart_addr+CLIC_INTCFG+source); +} + +void clic_set_cliccfg (clic_instance_t * this_clic, uint32_t cfg){ + *(volatile uint8_t*)(this_clic->hart_addr+CLIC_CFG) = cfg; +} + +uint8_t clic_get_cliccfg (clic_instance_t * this_clic){ + return *(volatile uint8_t*)(this_clic->hart_addr+CLIC_CFG); +} + +//sets an interrupt level based encoding of nmbits, nlbits +uint8_t clic_set_int_level( clic_instance_t * this_clic, uint32_t source, uint8_t level) { + //extract nlbits + uint8_t nlbits = clic_get_cliccfg(this_clic); + nlbits = (nlbits >>1) & 0x7; + + //shift level right to mask off unused bits + level = level>>((this_clic->num_config_bits)-nlbits); //plus this_clic->nmbits which is always 0 for now. + //shift level into correct bit position + level = level << (8-this_clic->num_config_bits) + (this_clic->num_config_bits - nlbits); + + //write to clicintcfg + uint8_t current_intcfg = clic_get_intcfg(this_clic, source); + clic_set_intcfg(this_clic, source, (current_intcfg | level)); + + return level; +} + +//gets an interrupt level based encoding of nmbits, nlbits +uint8_t clic_get_int_level( clic_instance_t * this_clic, uint32_t source) { + uint8_t level; + level = clic_get_intcfg(this_clic, source); + + //extract nlbits + uint8_t nlbits = clic_get_cliccfg(this_clic); + nlbits = (nlbits >>1) & 0x7; + + //shift level + level = level >> (8-(this_clic->num_config_bits)); + + //shift level right to mask off priority bits + level = level>>(this_clic->num_config_bits-nlbits); //this_clic->nmbits which is always 0 for now. + + return level; +} + +//sets an interrupt priority based encoding of nmbits, nlbits +uint8_t clic_set_int_priority( clic_instance_t * this_clic, uint32_t source, uint8_t priority) { + //priority bits = num_config_bits - nlbits + //extract nlbits + uint8_t nlbits = clic_get_cliccfg(this_clic); + nlbits = (nlbits >>1) & 0x7; + + uint8_t priority_bits = this_clic->num_config_bits-nlbits; + if(priority_bits = 0) { + //no bits to set + return 0; + } + //mask off unused bits + priority = priority >> (8-priority_bits); + //shift into the correct bit position + priority = priority << (8-(this_clic->num_config_bits)); + + //write to clicintcfg + uint8_t current_intcfg = clic_get_intcfg(this_clic, source); + clic_set_intcfg(this_clic, source, (current_intcfg | priority)); + return current_intcfg; +} + +//gets an interrupt priority based encoding of nmbits, nlbits +uint8_t clic_get_int_priority( clic_instance_t * this_clic, uint32_t source) { + uint8_t priority; + priority = clic_get_intcfg(this_clic, source); + + //extract nlbits + uint8_t nlbits = clic_get_cliccfg(this_clic); + nlbits = (nlbits >>1) & 0x7; + + //shift left to mask off level bits + priority = priority << nlbits; + + //shift priority + priority = priority >> (8-((this_clic->num_config_bits)+nlbits)); + + return priority; +} + + diff --git a/fw/bsp/drivers/clic/clic_driver.h b/fw/bsp/drivers/clic/clic_driver.h new file mode 100644 index 0000000..27c34c2 --- /dev/null +++ b/fw/bsp/drivers/clic/clic_driver.h @@ -0,0 +1,44 @@ +// See LICENSE file for licence details + +#ifndef PLIC_DRIVER_H +#define PLIC_DRIVER_H + + +__BEGIN_DECLS + +#include "platform.h" + +typedef void (*interrupt_function_ptr_t) (void); + +typedef struct __clic_instance_t +{ + uintptr_t hart_addr; + interrupt_function_ptr_t* vect_table; + uint32_t num_config_bits; + uint32_t num_sources; +} clic_instance_t; + +// Note that there are no assertions or bounds checking on these +// parameter values. +void clic_init (clic_instance_t * this_clic, uintptr_t hart_addr, interrupt_function_ptr_t* vect_table, interrupt_function_ptr_t default_handler, uint32_t num_irq,uint32_t num_config_bits); +void clic_install_handler (clic_instance_t * this_clic, uint32_t source, interrupt_function_ptr_t handler); +void clic_enable_interrupt (clic_instance_t * this_clic, uint32_t source); +void clic_disable_interrupt (clic_instance_t * this_clic, uint32_t source); +void clic_set_pending(clic_instance_t * this_clic, uint32_t source); +void clic_clear_pending(clic_instance_t * this_clic, uint32_t source); +void clic_set_intcfg (clic_instance_t * this_clic, uint32_t source, uint32_t intcfg); +uint8_t clic_get_intcfg (clic_instance_t * this_clic, uint32_t source); +void clic_set_cliccfg (clic_instance_t * this_clic, uint32_t cfg); +uint8_t clic_get_cliccfg (clic_instance_t * this_clic); +//sets an interrupt level based encoding of nmbits, nlbits +uint8_t clic_set_int_level( clic_instance_t * this_clic, uint32_t source, uint8_t level); +//get an interrupt level based encoding of nmbits, nlbits +uint8_t clic_get_int_level( clic_instance_t * this_clic, uint32_t source); +//sets an interrupt priority based encoding of nmbits, nlbits +uint8_t clic_set_int_priority( clic_instance_t * this_clic, uint32_t source, uint8_t priority); +//sets an interrupt priority based encoding of nmbits, nlbits +uint8_t clic_get_int_priority( clic_instance_t * this_clic, uint32_t source); + +__END_DECLS + +#endif diff --git a/fw/bsp/drivers/fe300prci/fe300prci_driver.c b/fw/bsp/drivers/fe300prci/fe300prci_driver.c new file mode 100644 index 0000000..8eeaafc --- /dev/null +++ b/fw/bsp/drivers/fe300prci/fe300prci_driver.c @@ -0,0 +1,252 @@ +// See LICENSE file for license details + +#include "platform.h" + +#ifdef PRCI_CTRL_ADDR +#include "fe300prci/fe300prci_driver.h" +#include + +#define rdmcycle(x) { \ + uint32_t lo, hi, hi2; \ + __asm__ __volatile__ ("1:\n\t" \ + "csrr %0, mcycleh\n\t" \ + "csrr %1, mcycle\n\t" \ + "csrr %2, mcycleh\n\t" \ + "bne %0, %2, 1b\n\t" \ + : "=r" (hi), "=r" (lo), "=r" (hi2)) ; \ + *(x) = lo | ((uint64_t) hi << 32); \ + } + +uint32_t PRCI_measure_mcycle_freq(uint32_t mtime_ticks, uint32_t mtime_freq) +{ + + uint32_t start_mtime = CLINT_REG(CLINT_MTIME); + uint32_t end_mtime = start_mtime + mtime_ticks + 1; + + // Make sure we won't get rollover. + while (end_mtime < start_mtime){ + start_mtime = CLINT_REG(CLINT_MTIME); + end_mtime = start_mtime + mtime_ticks + 1; + } + + // Don't start measuring until mtime edge. + uint32_t tmp = start_mtime; + do { + start_mtime = CLINT_REG(CLINT_MTIME); + } while (start_mtime == tmp); + + uint64_t start_mcycle; + rdmcycle(&start_mcycle); + + while (CLINT_REG(CLINT_MTIME) < end_mtime) ; + + uint64_t end_mcycle; + rdmcycle(&end_mcycle); + uint32_t difference = (uint32_t) (end_mcycle - start_mcycle); + + uint64_t freq = ((uint64_t) difference * mtime_freq) / mtime_ticks; + return (uint32_t) freq & 0xFFFFFFFF; + +} + + +void PRCI_use_hfrosc(int div, int trim) +{ + // Make sure the HFROSC is running at its default setting + // It is OK to change this even if we are running off of it. + + PRCI_REG(PRCI_HFROSCCFG) = (ROSC_DIV(div) | ROSC_TRIM(trim) | ROSC_EN(1)); + + while ((PRCI_REG(PRCI_HFROSCCFG) & ROSC_RDY(1)) == 0); + + PRCI_REG(PRCI_PLLCFG) &= ~PLL_SEL(1); +} + +void PRCI_use_pll(int refsel, int bypass, + int r, int f, int q, int finaldiv, + int hfroscdiv, int hfrosctrim) +{ + // Ensure that we aren't running off the PLL before we mess with it. + if (PRCI_REG(PRCI_PLLCFG) & PLL_SEL(1)) { + // Make sure the HFROSC is running at its default setting + PRCI_use_hfrosc(4, 16); + } + + // Set PLL Source to be HFXOSC if desired. + uint32_t config_value = 0; + + config_value |= PLL_REFSEL(refsel); + + if (bypass) { + // Bypass + config_value |= PLL_BYPASS(1); + + PRCI_REG(PRCI_PLLCFG) = config_value; + + // If we don't have an HFXTAL, this doesn't really matter. + // Set our Final output divide to divide-by-1: + PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV_BY_1(1) | PLL_FINAL_DIV(0)); + } else { + + // To overclock, use the hfrosc + if (hfrosctrim >= 0 && hfroscdiv >= 0) { + PRCI_use_hfrosc(hfroscdiv, hfrosctrim); + } + + // Set DIV Settings for PLL + + // (Legal values of f_REF are 6-48MHz) + + // Set DIVR to divide-by-2 to get 8MHz frequency + // (legal values of f_R are 6-12 MHz) + + config_value |= PLL_BYPASS(1); + config_value |= PLL_R(r); + + // Set DIVF to get 512Mhz frequncy + // There is an implied multiply-by-2, 16Mhz. + // So need to write 32-1 + // (legal values of f_F are 384-768 MHz) + config_value |= PLL_F(f); + + // Set DIVQ to divide-by-2 to get 256 MHz frequency + // (legal values of f_Q are 50-400Mhz) + config_value |= PLL_Q(q); + + // Set our Final output divide to divide-by-1: + if (finaldiv == 1){ + PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV_BY_1(1) | PLL_FINAL_DIV(0)); + } else { + PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV(finaldiv-1)); + } + + PRCI_REG(PRCI_PLLCFG) = config_value; + + // Un-Bypass the PLL. + PRCI_REG(PRCI_PLLCFG) &= ~PLL_BYPASS(1); + + // Wait for PLL Lock + // Note that the Lock signal can be glitchy. + // Need to wait 100 us + // RTC is running at 32kHz. + // So wait 4 ticks of RTC. + uint32_t now = CLINT_REG(CLINT_MTIME); + while (CLINT_REG(CLINT_MTIME) - now < 4) ; + + // Now it is safe to check for PLL Lock + while ((PRCI_REG(PRCI_PLLCFG) & PLL_LOCK(1)) == 0); + + } + + // Switch over to PLL Clock source + PRCI_REG(PRCI_PLLCFG) |= PLL_SEL(1); + + // If we're running off HFXOSC, turn off the HFROSC to + // save power. + if (refsel) { + PRCI_REG(PRCI_HFROSCCFG) &= ~ROSC_EN(1); + } + +} + +void PRCI_use_default_clocks() +{ + // Turn off the LFROSC + AON_REG(AON_LFROSC) &= ~ROSC_EN(1); + + // Use HFROSC + PRCI_use_hfrosc(4, 16); +} + +void PRCI_use_hfxosc(uint32_t finaldiv) +{ + + PRCI_use_pll(1, // Use HFXTAL + 1, // Bypass = 1 + 0, // PLL settings don't matter + 0, // PLL settings don't matter + 0, // PLL settings don't matter + finaldiv, + -1, + -1); +} + +// This is a generic function, which +// doesn't span the entire range of HFROSC settings. +// It only adjusts the trim, which can span a hundred MHz or so. +// This function does not check the legality of the PLL settings +// at all, and it is quite possible to configure invalid PLL settings +// this way. +// It returns the actual measured CPU frequency. + +uint32_t PRCI_set_hfrosctrim_for_f_cpu(uint32_t f_cpu, PRCI_freq_target target ) +{ + + uint32_t hfrosctrim = 0; + uint32_t hfroscdiv = 4; + uint32_t prev_trim = 0; + + // In this function we use PLL settings which + // will give us a 32x multiplier from the output + // of the HFROSC source to the output of the + // PLL. We first measure our HFROSC to get the + // right trim, then finally use it as the PLL source. + // We should really check here that the f_cpu + // requested is something in the limit of the PLL. For + // now that is up to the user. + + // This will undershoot for frequencies not divisible by 16. + uint32_t desired_hfrosc_freq = (f_cpu/ 16); + + PRCI_use_hfrosc(hfroscdiv, hfrosctrim); + + // Ignore the first run (for icache reasons) + uint32_t cpu_freq = PRCI_measure_mcycle_freq(3000, RTC_FREQ); + + cpu_freq = PRCI_measure_mcycle_freq(3000, RTC_FREQ); + uint32_t prev_freq = cpu_freq; + + while ((cpu_freq < desired_hfrosc_freq) && (hfrosctrim < 0x1F)){ + prev_trim = hfrosctrim; + prev_freq = cpu_freq; + hfrosctrim ++; + PRCI_use_hfrosc(hfroscdiv, hfrosctrim); + cpu_freq = PRCI_measure_mcycle_freq(3000, RTC_FREQ); + } + + // We couldn't go low enough + if (prev_freq > desired_hfrosc_freq){ + PRCI_use_pll(0, 0, 1, 31, 1, 1, hfroscdiv, prev_trim); + cpu_freq = PRCI_measure_mcycle_freq(1000, RTC_FREQ); + return cpu_freq; + } + + // We couldn't go high enough + if (cpu_freq < desired_hfrosc_freq){ + PRCI_use_pll(0, 0, 1, 31, 1, 1, hfroscdiv, prev_trim); + cpu_freq = PRCI_measure_mcycle_freq(1000, RTC_FREQ); + return cpu_freq; + } + + // Check for over/undershoot + switch(target) { + case(PRCI_FREQ_CLOSEST): + if ((desired_hfrosc_freq - prev_freq) < (cpu_freq - desired_hfrosc_freq)) { + PRCI_use_pll(0, 0, 1, 31, 1, 1, hfroscdiv, prev_trim); + } else { + PRCI_use_pll(0, 0, 1, 31, 1, 1, hfroscdiv, hfrosctrim); + } + break; + case(PRCI_FREQ_UNDERSHOOT): + PRCI_use_pll(0, 0, 1, 31, 1, 1, hfroscdiv, prev_trim); + break; + default: + PRCI_use_pll(0, 0, 1, 31, 1, 1, hfroscdiv, hfrosctrim); + } + + cpu_freq = PRCI_measure_mcycle_freq(1000, RTC_FREQ); + return cpu_freq; + +} + +#endif diff --git a/fw/bsp/drivers/fe300prci/fe300prci_driver.h b/fw/bsp/drivers/fe300prci/fe300prci_driver.h new file mode 100644 index 0000000..7100f46 --- /dev/null +++ b/fw/bsp/drivers/fe300prci/fe300prci_driver.h @@ -0,0 +1,79 @@ +// See LICENSE file for license details + +#ifndef _FE300PRCI_DRIVER_H_ +#define _FE300PRCI_DRIVER_H_ + +__BEGIN_DECLS + +#include + +typedef enum prci_freq_target { + + PRCI_FREQ_OVERSHOOT, + PRCI_FREQ_CLOSEST, + PRCI_FREQ_UNDERSHOOT + +} PRCI_freq_target; + +/* Measure and return the approximate frequency of the + * CPU, as given by measuring the mcycle counter against + * the mtime ticks. + */ +uint32_t PRCI_measure_mcycle_freq(uint32_t mtime_ticks, uint32_t mtime_freq); + +/* Safely switch over to the HFROSC using the given div + * and trim settings. + */ +void PRCI_use_hfrosc(int div, int trim); + +/* Safely switch over to the 16MHz HFXOSC, + * applying the finaldiv clock divider (1 is the lowest + * legal value). + */ +void PRCI_use_hfxosc(uint32_t finaldiv); + +/* Safely switch over to the PLL using the given + * settings. + * + * Note that not all combinations of the inputs are actually + * legal, and this function does not check for their + * legality ("safely" means that this function won't turn off + * or glitch the clock the CPU is actually running off, but + * doesn't protect against you making it too fast or slow.) + */ + +void PRCI_use_pll(int refsel, int bypass, + int r, int f, int q, int finaldiv, + int hfroscdiv, int hfrosctrim); + +/* Use the default clocks configured at reset. + * This is ~16Mhz HFROSC and turns off the LFROSC + * (on the current FE310 Dev Platforms, an external LFROSC is + * used as it is more power efficient). + */ +void PRCI_use_default_clocks(); + +/* This routine will adjust the HFROSC trim + * while using HFROSC as the clock source, + * measure the resulting frequency, then + * use it as the PLL clock source, + * in an attempt to get over, under, or close to the + * requested frequency. It returns the actual measured + * frequency. + * + * Note that the requested frequency must be within the + * range supported by the PLL so not all values are + * achievable with this function, and not all + * are guaranteed to actually work. The PLL + * is rated higher than the hardware. + * + * There is no check on the desired f_cpu frequency, it + * is up to the user to specify something reasonable. + */ + +uint32_t PRCI_set_hfrosctrim_for_f_cpu(uint32_t f_cpu, PRCI_freq_target target); + +__END_DECLS + +#endif + diff --git a/fw/bsp/drivers/plic/plic_driver.c b/fw/bsp/drivers/plic/plic_driver.c new file mode 100644 index 0000000..ec7084c --- /dev/null +++ b/fw/bsp/drivers/plic/plic_driver.c @@ -0,0 +1,127 @@ +// See LICENSE for license details. + +#include "plic/plic_driver.h" +#include "platform.h" +#include "encoding.h" +#include +#include "../../include/platform/devices/plic.h" + + +// Note that there are no assertions or bounds checking on these +// parameter values. + +void volatile_memzero(uint8_t * base, unsigned int size) +{ + volatile uint8_t * ptr; + for (ptr = base; ptr < (base + size); ptr++){ + *ptr = 0; + } +} + +void PLIC_init ( + plic_instance_t * this_plic, + uintptr_t base_addr, + uint32_t num_sources, + uint32_t num_priorities + ) +{ + + this_plic->base_addr = base_addr; + this_plic->num_sources = num_sources; + this_plic->num_priorities = num_priorities; + + // Disable all interrupts (don't assume that these registers are reset). + unsigned long hart_id = read_csr(mhartid); + volatile_memzero((uint8_t*) (this_plic->base_addr + + PLIC_ENABLE_OFFSET + + (hart_id << PLIC_ENABLE_SHIFT_PER_TARGET)), + (num_sources + 8) / 8); + + // Set all priorities to 0 (equal priority -- don't assume that these are reset). + volatile_memzero ((uint8_t *)(this_plic->base_addr + + PLIC_PRIORITY_OFFSET), + (num_sources + 1) << PLIC_PRIORITY_SHIFT_PER_SOURCE); + + // Set the threshold to 0. + volatile plic_threshold* threshold = (plic_threshold*) + (this_plic->base_addr + + PLIC_THRESHOLD_OFFSET + + (hart_id << PLIC_THRESHOLD_SHIFT_PER_TARGET)); + + *threshold = 0; + +} + +void PLIC_set_threshold (plic_instance_t * this_plic, + plic_threshold threshold){ + + unsigned long hart_id = read_csr(mhartid); + volatile plic_threshold* threshold_ptr = (plic_threshold*) (this_plic->base_addr + + PLIC_THRESHOLD_OFFSET + + (hart_id << PLIC_THRESHOLD_SHIFT_PER_TARGET)); + + *threshold_ptr = threshold; + +} + + +void PLIC_enable_interrupt (plic_instance_t * this_plic, plic_source source){ + + unsigned long hart_id = read_csr(mhartid); + volatile uint8_t * current_ptr = (volatile uint8_t *)(this_plic->base_addr + + PLIC_ENABLE_OFFSET + + (hart_id << PLIC_ENABLE_SHIFT_PER_TARGET) + + (source >> 3)); + uint8_t current = *current_ptr; + current = current | ( 1 << (source & 0x7)); + *current_ptr = current; + +} + +void PLIC_disable_interrupt (plic_instance_t * this_plic, plic_source source){ + + unsigned long hart_id = read_csr(mhartid); + volatile uint8_t * current_ptr = (volatile uint8_t *) (this_plic->base_addr + + PLIC_ENABLE_OFFSET + + (hart_id << PLIC_ENABLE_SHIFT_PER_TARGET) + + (source >> 3)); + uint8_t current = *current_ptr; + current = current & ~(( 1 << (source & 0x7))); + *current_ptr = current; + +} + +void PLIC_set_priority (plic_instance_t * this_plic, plic_source source, plic_priority priority){ + + if (this_plic->num_priorities > 0) { + volatile plic_priority * priority_ptr = (volatile plic_priority *) + (this_plic->base_addr + + PLIC_PRIORITY_OFFSET + + (source << PLIC_PRIORITY_SHIFT_PER_SOURCE)); + *priority_ptr = priority; + } +} + +plic_source PLIC_claim_interrupt(plic_instance_t * this_plic){ + + unsigned long hart_id = read_csr(mhartid); + + volatile plic_source * claim_addr = (volatile plic_source * ) + (this_plic->base_addr + + PLIC_CLAIM_OFFSET + + (hart_id << PLIC_CLAIM_SHIFT_PER_TARGET)); + + return *claim_addr; + +} + +void PLIC_complete_interrupt(plic_instance_t * this_plic, plic_source source){ + + unsigned long hart_id = read_csr(mhartid); + volatile plic_source * claim_addr = (volatile plic_source *) (this_plic->base_addr + + PLIC_CLAIM_OFFSET + + (hart_id << PLIC_CLAIM_SHIFT_PER_TARGET)); + *claim_addr = source; + +} + diff --git a/fw/bsp/drivers/plic/plic_driver.h b/fw/bsp/drivers/plic/plic_driver.h new file mode 100644 index 0000000..e7d609b --- /dev/null +++ b/fw/bsp/drivers/plic/plic_driver.h @@ -0,0 +1,51 @@ +// See LICENSE file for licence details + +#ifndef PLIC_DRIVER_H +#define PLIC_DRIVER_H + + +__BEGIN_DECLS + +#include "platform.h" + +typedef struct __plic_instance_t +{ + uintptr_t base_addr; + + uint32_t num_sources; + uint32_t num_priorities; + +} plic_instance_t; + +typedef uint32_t plic_source; +typedef uint32_t plic_priority; +typedef uint32_t plic_threshold; + +void PLIC_init ( + plic_instance_t * this_plic, + uintptr_t base_addr, + uint32_t num_sources, + uint32_t num_priorities + ); + +void PLIC_set_threshold (plic_instance_t * this_plic, + plic_threshold threshold); + +void PLIC_enable_interrupt (plic_instance_t * this_plic, + plic_source source); + +void PLIC_disable_interrupt (plic_instance_t * this_plic, + plic_source source); + +void PLIC_set_priority (plic_instance_t * this_plic, + plic_source source, + plic_priority priority); + +plic_source PLIC_claim_interrupt(plic_instance_t * this_plic); + +void PLIC_complete_interrupt(plic_instance_t * this_plic, + plic_source source); + +__END_DECLS + +#endif diff --git a/fw/bsp/env/common-clang.mk b/fw/bsp/env/common-clang.mk new file mode 100644 index 0000000..0131143 --- /dev/null +++ b/fw/bsp/env/common-clang.mk @@ -0,0 +1,72 @@ +# See LICENSE for license details. + +ifndef _SIFIVE_MK_COMMON +_SIFIVE_MK_COMMON := # defined + +.PHONY: all +all: $(TARGET) + +include $(BSP_BASE)/libwrap/libwrap.mk + +ENV_DIR = $(BSP_BASE)/env +PLATFORM_DIR = $(ENV_DIR)/$(BOARD) + +ASM_SRCS += $(ENV_DIR)/start.S +ASM_SRCS += $(ENV_DIR)/entry.S +C_SRCS += $(PLATFORM_DIR)/init.c + +LINKER_SCRIPT := $(PLATFORM_DIR)/$(LINK_TARGET).lds + +INCLUDES += -I$(BSP_BASE)/include +INCLUDES += -I$(BSP_BASE)/drivers/ +INCLUDES += -I$(ENV_DIR) +INCLUDES += -I$(PLATFORM_DIR) + +TOOL_DIR ?= $(BSP_BASE)/../toolchain/bin/ + +LDFLAGS += -T $(LINKER_SCRIPT) -nostartfiles +LDFLAGS += -L$(ENV_DIR) --specs=nano.specs + +ASM_OBJS := $(ASM_SRCS:.S=.o) +C_OBJS := $(C_SRCS:.c=.o) +CXX_OBJS := $(CXX_SRCS:.cpp=.o) + +LINK_OBJS += $(ASM_OBJS) $(C_OBJS) $(CXX_OBJS) +LINK_DEPS += $(LINKER_SCRIPT) + +CLEAN_OBJS += $(TARGET) $(LINK_OBJS) + +CFLAGS += -march=$(RISCV_ARCH) +CFLAGS += -mabi=$(RISCV_ABI) +CFLAGS += -mcmodel=medany + +TRIPLET?=riscv64-unknown-elf +CXX=$(LLVM_TOOL_DIR)clang++ --target=$(TRIPLET) -isystem $(TOOL_DIR)/../$(TRIPLET)/include +CC=$(LLVM_TOOL_DIR)clang --target=$(TRIPLET) -isystem $(TOOL_DIR)/../$(TRIPLET)/include +LD=$(TOOL_DIR)$(TRIPLET)-gcc +AR=$(TOOL_DIR)$(TRIPLET)-ar +OBJDUMP := $(TOOL_DIR)/$(TRIPLET)-objdump + + +$(TARGET): $(LINK_OBJS) $(LINK_DEPS) + $(LD) $(LINK_OBJS) $(LDFLAGS) $(LIBWRAP) -o $@ + $(OBJDUMP) -d -S $(TARGET) > $(TARGET).dis + +$(ASM_OBJS): %.o: %.S $(HEADERS) + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $< + +$(C_OBJS): %.o: %.c $(HEADERS) + $(CC) $(CFLAGS) $(INCLUDES) -include sys/cdefs.h -c -o $@ $< + +$(CXX_OBJS): %.o: %.cpp $(HEADERS) + $(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) -include sys/cdefs.h -c -o $@ $< + +.PHONY: clean +clean: + rm -f $(TARGET) $(LINK_OBJS) + +.PHONY: clean-all +clean-all: + rm -f $(CLEAN_OBJS) $(LIBWRAP) + +endif # _SIFIVE_MK_COMMON diff --git a/fw/bsp/env/common-gcc.mk b/fw/bsp/env/common-gcc.mk new file mode 100644 index 0000000..72e8453 --- /dev/null +++ b/fw/bsp/env/common-gcc.mk @@ -0,0 +1,68 @@ +# See LICENSE for license details. + +ifndef _SIFIVE_MK_COMMON +_SIFIVE_MK_COMMON := # defined + +.PHONY: all +all: $(TARGET) + +include $(BSP_BASE)/libwrap/libwrap.mk + +ENV_DIR = $(BSP_BASE)/env +PLATFORM_DIR = $(ENV_DIR)/$(BOARD) + +ASM_SRCS += $(ENV_DIR)/start.S +ASM_SRCS += $(ENV_DIR)/entry.S +C_SRCS += $(PLATFORM_DIR)/init.c + +LINKER_SCRIPT := $(PLATFORM_DIR)/$(LINK_TARGET).lds + +INCLUDES += -I$(BSP_BASE)/include +INCLUDES += -I$(BSP_BASE)/drivers/ +INCLUDES += -I$(ENV_DIR) +INCLUDES += -I$(PLATFORM_DIR) + +TOOL_DIR ?= $(BSP_BASE)/../toolchain/bin/ + +LDFLAGS += -T $(LINKER_SCRIPT) -nostartfiles -Wl,-Map,firmware.map +LDFLAGS += -L$(ENV_DIR) --specs=nano.specs + +ASM_OBJS := $(ASM_SRCS:.S=.o) +C_OBJS := $(C_SRCS:.c=.o) +CXX_OBJS := $(CXX_SRCS:.cpp=.o) + +LINK_OBJS += $(ASM_OBJS) $(C_OBJS) $(CXX_OBJS) +LINK_DEPS += $(LINKER_SCRIPT) + +CLEAN_OBJS += $(TARGET) $(LINK_OBJS) + +CFLAGS += -march=$(RISCV_ARCH) +CFLAGS += -mabi=$(RISCV_ABI) +CFLAGS += -mcmodel=medany + +TRIPLET?=riscv64-unknown-elf +CXX=$(TOOL_DIR)$(TRIPLET)-c++ +CC=$(TOOL_DIR)$(TRIPLET)-gcc +LD=$(TOOL_DIR)$(TRIPLET)-gcc +AR=$(TOOL_DIR)$(TRIPLET)-ar +OBJDUMP := $(TOOL_DIR)/$(TRIPLET)-objdump + + +$(TARGET): $(LINK_OBJS) $(LINK_DEPS) + $(LD) $(LINK_OBJS) $(LDFLAGS) $(LIBWRAP) -o $@ + $(OBJDUMP) -d -S $(TARGET) > $(TARGET).dis + +$(ASM_OBJS): %.o: %.S $(HEADERS) + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $< + +$(C_OBJS): %.o: %.c $(HEADERS) + $(CC) $(CFLAGS) $(INCLUDES) -include sys/cdefs.h -c -o $@ $< + +$(CXX_OBJS): %.o: %.cpp $(HEADERS) + $(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) -include sys/cdefs.h -c -o $@ $< + +.PHONY: clean +clean: + rm -f $(CLEAN_OBJS) $(LIBWRAP) + +endif # _SIFIVE_MK_COMMON diff --git a/fw/bsp/env/encoding.h b/fw/bsp/env/encoding.h new file mode 100644 index 0000000..35e0f9f --- /dev/null +++ b/fw/bsp/env/encoding.h @@ -0,0 +1,1313 @@ +// See LICENSE for license details. + +#ifndef RISCV_CSR_ENCODING_H +#define RISCV_CSR_ENCODING_H + +#define MSTATUS_UIE 0x00000001 +#define MSTATUS_SIE 0x00000002 +#define MSTATUS_HIE 0x00000004 +#define MSTATUS_MIE 0x00000008 +#define MSTATUS_UPIE 0x00000010 +#define MSTATUS_SPIE 0x00000020 +#define MSTATUS_HPIE 0x00000040 +#define MSTATUS_MPIE 0x00000080 +#define MSTATUS_SPP 0x00000100 +#define MSTATUS_HPP 0x00000600 +#define MSTATUS_MPP 0x00001800 +#define MSTATUS_FS 0x00006000 +#define MSTATUS_XS 0x00018000 +#define MSTATUS_MPRV 0x00020000 +#define MSTATUS_PUM 0x00040000 +#define MSTATUS_MXR 0x00080000 +#define MSTATUS_VM 0x1F000000 +#define MSTATUS32_SD 0x80000000 +#define MSTATUS64_SD 0x8000000000000000 + +#define SSTATUS_UIE 0x00000001 +#define SSTATUS_SIE 0x00000002 +#define SSTATUS_UPIE 0x00000010 +#define SSTATUS_SPIE 0x00000020 +#define SSTATUS_SPP 0x00000100 +#define SSTATUS_FS 0x00006000 +#define SSTATUS_XS 0x00018000 +#define SSTATUS_PUM 0x00040000 +#define SSTATUS32_SD 0x80000000 +#define SSTATUS64_SD 0x8000000000000000 + +#define DCSR_XDEBUGVER (3U<<30) +#define DCSR_NDRESET (1<<29) +#define DCSR_FULLRESET (1<<28) +#define DCSR_EBREAKM (1<<15) +#define DCSR_EBREAKH (1<<14) +#define DCSR_EBREAKS (1<<13) +#define DCSR_EBREAKU (1<<12) +#define DCSR_STOPCYCLE (1<<10) +#define DCSR_STOPTIME (1<<9) +#define DCSR_CAUSE (7<<6) +#define DCSR_DEBUGINT (1<<5) +#define DCSR_HALT (1<<3) +#define DCSR_STEP (1<<2) +#define DCSR_PRV (3<<0) + +#define DCSR_CAUSE_NONE 0 +#define DCSR_CAUSE_SWBP 1 +#define DCSR_CAUSE_HWBP 2 +#define DCSR_CAUSE_DEBUGINT 3 +#define DCSR_CAUSE_STEP 4 +#define DCSR_CAUSE_HALT 5 + +#define MCONTROL_TYPE(xlen) (0xfULL<<((xlen)-4)) +#define MCONTROL_DMODE(xlen) (1ULL<<((xlen)-5)) +#define MCONTROL_MASKMAX(xlen) (0x3fULL<<((xlen)-11)) + +#define MCONTROL_SELECT (1<<19) +#define MCONTROL_TIMING (1<<18) +#define MCONTROL_ACTION (0x3f<<12) +#define MCONTROL_CHAIN (1<<11) +#define MCONTROL_MATCH (0xf<<7) +#define MCONTROL_M (1<<6) +#define MCONTROL_H (1<<5) +#define MCONTROL_S (1<<4) +#define MCONTROL_U (1<<3) +#define MCONTROL_EXECUTE (1<<2) +#define MCONTROL_STORE (1<<1) +#define MCONTROL_LOAD (1<<0) + +#define MCONTROL_TYPE_NONE 0 +#define MCONTROL_TYPE_MATCH 2 + +#define MCONTROL_ACTION_DEBUG_EXCEPTION 0 +#define MCONTROL_ACTION_DEBUG_MODE 1 +#define MCONTROL_ACTION_TRACE_START 2 +#define MCONTROL_ACTION_TRACE_STOP 3 +#define MCONTROL_ACTION_TRACE_EMIT 4 + +#define MCONTROL_MATCH_EQUAL 0 +#define MCONTROL_MATCH_NAPOT 1 +#define MCONTROL_MATCH_GE 2 +#define MCONTROL_MATCH_LT 3 +#define MCONTROL_MATCH_MASK_LOW 4 +#define MCONTROL_MATCH_MASK_HIGH 5 + +#define MIP_SSIP (1 << IRQ_S_SOFT) +#define MIP_HSIP (1 << IRQ_H_SOFT) +#define MIP_MSIP (1 << IRQ_M_SOFT) +#define MIP_STIP (1 << IRQ_S_TIMER) +#define MIP_HTIP (1 << IRQ_H_TIMER) +#define MIP_MTIP (1 << IRQ_M_TIMER) +#define MIP_SEIP (1 << IRQ_S_EXT) +#define MIP_HEIP (1 << IRQ_H_EXT) +#define MIP_MEIP (1 << IRQ_M_EXT) + +#define SIP_SSIP MIP_SSIP +#define SIP_STIP MIP_STIP + +#define PRV_U 0 +#define PRV_S 1 +#define PRV_H 2 +#define PRV_M 3 + +#define VM_MBARE 0 +#define VM_MBB 1 +#define VM_MBBID 2 +#define VM_SV32 8 +#define VM_SV39 9 +#define VM_SV48 10 + +#define IRQ_S_SOFT 1 +#define IRQ_H_SOFT 2 +#define IRQ_M_SOFT 3 +#define IRQ_S_TIMER 5 +#define IRQ_H_TIMER 6 +#define IRQ_M_TIMER 7 +#define IRQ_S_EXT 9 +#define IRQ_H_EXT 10 +#define IRQ_M_EXT 11 +#define IRQ_COP 12 +#define IRQ_HOST 13 + +#define DEFAULT_RSTVEC 0x00001000 +#define DEFAULT_NMIVEC 0x00001004 +#define DEFAULT_MTVEC 0x00001010 +#define CONFIG_STRING_ADDR 0x0000100C +#define EXT_IO_BASE 0x40000000 +#define DRAM_BASE 0x80000000 + +// page table entry (PTE) fields +#define PTE_V 0x001 // Valid +#define PTE_R 0x002 // Read +#define PTE_W 0x004 // Write +#define PTE_X 0x008 // Execute +#define PTE_U 0x010 // User +#define PTE_G 0x020 // Global +#define PTE_A 0x040 // Accessed +#define PTE_D 0x080 // Dirty +#define PTE_SOFT 0x300 // Reserved for Software + +#define PTE_PPN_SHIFT 10 + +#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V) + +#ifdef __riscv + +#ifdef __riscv64 +# define MSTATUS_SD MSTATUS64_SD +# define SSTATUS_SD SSTATUS64_SD +# define RISCV_PGLEVEL_BITS 9 +#else +# define MSTATUS_SD MSTATUS32_SD +# define SSTATUS_SD SSTATUS32_SD +# define RISCV_PGLEVEL_BITS 10 +#endif +#define RISCV_PGSHIFT 12 +#define RISCV_PGSIZE (1 << RISCV_PGSHIFT) + +#ifndef __ASSEMBLER__ + +#ifdef __GNUC__ + +#define read_csr(reg) ({ unsigned long __tmp; \ + asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \ + __tmp; }) + +#define write_csr(reg, val) ({ \ + if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ + asm volatile ("csrw " #reg ", %0" :: "i"(val)); \ + else \ + asm volatile ("csrw " #reg ", %0" :: "r"(val)); }) + +#define swap_csr(reg, val) ({ unsigned long __tmp; \ + if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ + asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "i"(val)); \ + else \ + asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "r"(val)); \ + __tmp; }) + +#define set_csr(reg, bit) ({ unsigned long __tmp; \ + if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ + asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \ + else \ + asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \ + __tmp; }) + +#define clear_csr(reg, bit) ({ unsigned long __tmp; \ + if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ + asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \ + else \ + asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \ + __tmp; }) + +#define rdtime() read_csr(time) +#define rdcycle() read_csr(cycle) +#define rdinstret() read_csr(instret) + +#endif + +#endif + +#endif + +#endif +/* Automatically generated by parse-opcodes */ +#ifndef RISCV_ENCODING_H +#define RISCV_ENCODING_H +#define MATCH_BEQ 0x63 +#define MASK_BEQ 0x707f +#define MATCH_BNE 0x1063 +#define MASK_BNE 0x707f +#define MATCH_BLT 0x4063 +#define MASK_BLT 0x707f +#define MATCH_BGE 0x5063 +#define MASK_BGE 0x707f +#define MATCH_BLTU 0x6063 +#define MASK_BLTU 0x707f +#define MATCH_BGEU 0x7063 +#define MASK_BGEU 0x707f +#define MATCH_JALR 0x67 +#define MASK_JALR 0x707f +#define MATCH_JAL 0x6f +#define MASK_JAL 0x7f +#define MATCH_LUI 0x37 +#define MASK_LUI 0x7f +#define MATCH_AUIPC 0x17 +#define MASK_AUIPC 0x7f +#define MATCH_ADDI 0x13 +#define MASK_ADDI 0x707f +#define MATCH_SLLI 0x1013 +#define MASK_SLLI 0xfc00707f +#define MATCH_SLTI 0x2013 +#define MASK_SLTI 0x707f +#define MATCH_SLTIU 0x3013 +#define MASK_SLTIU 0x707f +#define MATCH_XORI 0x4013 +#define MASK_XORI 0x707f +#define MATCH_SRLI 0x5013 +#define MASK_SRLI 0xfc00707f +#define MATCH_SRAI 0x40005013 +#define MASK_SRAI 0xfc00707f +#define MATCH_ORI 0x6013 +#define MASK_ORI 0x707f +#define MATCH_ANDI 0x7013 +#define MASK_ANDI 0x707f +#define MATCH_ADD 0x33 +#define MASK_ADD 0xfe00707f +#define MATCH_SUB 0x40000033 +#define MASK_SUB 0xfe00707f +#define MATCH_SLL 0x1033 +#define MASK_SLL 0xfe00707f +#define MATCH_SLT 0x2033 +#define MASK_SLT 0xfe00707f +#define MATCH_SLTU 0x3033 +#define MASK_SLTU 0xfe00707f +#define MATCH_XOR 0x4033 +#define MASK_XOR 0xfe00707f +#define MATCH_SRL 0x5033 +#define MASK_SRL 0xfe00707f +#define MATCH_SRA 0x40005033 +#define MASK_SRA 0xfe00707f +#define MATCH_OR 0x6033 +#define MASK_OR 0xfe00707f +#define MATCH_AND 0x7033 +#define MASK_AND 0xfe00707f +#define MATCH_ADDIW 0x1b +#define MASK_ADDIW 0x707f +#define MATCH_SLLIW 0x101b +#define MASK_SLLIW 0xfe00707f +#define MATCH_SRLIW 0x501b +#define MASK_SRLIW 0xfe00707f +#define MATCH_SRAIW 0x4000501b +#define MASK_SRAIW 0xfe00707f +#define MATCH_ADDW 0x3b +#define MASK_ADDW 0xfe00707f +#define MATCH_SUBW 0x4000003b +#define MASK_SUBW 0xfe00707f +#define MATCH_SLLW 0x103b +#define MASK_SLLW 0xfe00707f +#define MATCH_SRLW 0x503b +#define MASK_SRLW 0xfe00707f +#define MATCH_SRAW 0x4000503b +#define MASK_SRAW 0xfe00707f +#define MATCH_LB 0x3 +#define MASK_LB 0x707f +#define MATCH_LH 0x1003 +#define MASK_LH 0x707f +#define MATCH_LW 0x2003 +#define MASK_LW 0x707f +#define MATCH_LD 0x3003 +#define MASK_LD 0x707f +#define MATCH_LBU 0x4003 +#define MASK_LBU 0x707f +#define MATCH_LHU 0x5003 +#define MASK_LHU 0x707f +#define MATCH_LWU 0x6003 +#define MASK_LWU 0x707f +#define MATCH_SB 0x23 +#define MASK_SB 0x707f +#define MATCH_SH 0x1023 +#define MASK_SH 0x707f +#define MATCH_SW 0x2023 +#define MASK_SW 0x707f +#define MATCH_SD 0x3023 +#define MASK_SD 0x707f +#define MATCH_FENCE 0xf +#define MASK_FENCE 0x707f +#define MATCH_FENCE_I 0x100f +#define MASK_FENCE_I 0x707f +#define MATCH_MUL 0x2000033 +#define MASK_MUL 0xfe00707f +#define MATCH_MULH 0x2001033 +#define MASK_MULH 0xfe00707f +#define MATCH_MULHSU 0x2002033 +#define MASK_MULHSU 0xfe00707f +#define MATCH_MULHU 0x2003033 +#define MASK_MULHU 0xfe00707f +#define MATCH_DIV 0x2004033 +#define MASK_DIV 0xfe00707f +#define MATCH_DIVU 0x2005033 +#define MASK_DIVU 0xfe00707f +#define MATCH_REM 0x2006033 +#define MASK_REM 0xfe00707f +#define MATCH_REMU 0x2007033 +#define MASK_REMU 0xfe00707f +#define MATCH_MULW 0x200003b +#define MASK_MULW 0xfe00707f +#define MATCH_DIVW 0x200403b +#define MASK_DIVW 0xfe00707f +#define MATCH_DIVUW 0x200503b +#define MASK_DIVUW 0xfe00707f +#define MATCH_REMW 0x200603b +#define MASK_REMW 0xfe00707f +#define MATCH_REMUW 0x200703b +#define MASK_REMUW 0xfe00707f +#define MATCH_AMOADD_W 0x202f +#define MASK_AMOADD_W 0xf800707f +#define MATCH_AMOXOR_W 0x2000202f +#define MASK_AMOXOR_W 0xf800707f +#define MATCH_AMOOR_W 0x4000202f +#define MASK_AMOOR_W 0xf800707f +#define MATCH_AMOAND_W 0x6000202f +#define MASK_AMOAND_W 0xf800707f +#define MATCH_AMOMIN_W 0x8000202f +#define MASK_AMOMIN_W 0xf800707f +#define MATCH_AMOMAX_W 0xa000202f +#define MASK_AMOMAX_W 0xf800707f +#define MATCH_AMOMINU_W 0xc000202f +#define MASK_AMOMINU_W 0xf800707f +#define MATCH_AMOMAXU_W 0xe000202f +#define MASK_AMOMAXU_W 0xf800707f +#define MATCH_AMOSWAP_W 0x800202f +#define MASK_AMOSWAP_W 0xf800707f +#define MATCH_LR_W 0x1000202f +#define MASK_LR_W 0xf9f0707f +#define MATCH_SC_W 0x1800202f +#define MASK_SC_W 0xf800707f +#define MATCH_AMOADD_D 0x302f +#define MASK_AMOADD_D 0xf800707f +#define MATCH_AMOXOR_D 0x2000302f +#define MASK_AMOXOR_D 0xf800707f +#define MATCH_AMOOR_D 0x4000302f +#define MASK_AMOOR_D 0xf800707f +#define MATCH_AMOAND_D 0x6000302f +#define MASK_AMOAND_D 0xf800707f +#define MATCH_AMOMIN_D 0x8000302f +#define MASK_AMOMIN_D 0xf800707f +#define MATCH_AMOMAX_D 0xa000302f +#define MASK_AMOMAX_D 0xf800707f +#define MATCH_AMOMINU_D 0xc000302f +#define MASK_AMOMINU_D 0xf800707f +#define MATCH_AMOMAXU_D 0xe000302f +#define MASK_AMOMAXU_D 0xf800707f +#define MATCH_AMOSWAP_D 0x800302f +#define MASK_AMOSWAP_D 0xf800707f +#define MATCH_LR_D 0x1000302f +#define MASK_LR_D 0xf9f0707f +#define MATCH_SC_D 0x1800302f +#define MASK_SC_D 0xf800707f +#define MATCH_ECALL 0x73 +#define MASK_ECALL 0xffffffff +#define MATCH_EBREAK 0x100073 +#define MASK_EBREAK 0xffffffff +#define MATCH_URET 0x200073 +#define MASK_URET 0xffffffff +#define MATCH_SRET 0x10200073 +#define MASK_SRET 0xffffffff +#define MATCH_HRET 0x20200073 +#define MASK_HRET 0xffffffff +#define MATCH_MRET 0x30200073 +#define MASK_MRET 0xffffffff +#define MATCH_DRET 0x7b200073 +#define MASK_DRET 0xffffffff +#define MATCH_SFENCE_VM 0x10400073 +#define MASK_SFENCE_VM 0xfff07fff +#define MATCH_WFI 0x10500073 +#define MASK_WFI 0xffffffff +#define MATCH_CSRRW 0x1073 +#define MASK_CSRRW 0x707f +#define MATCH_CSRRS 0x2073 +#define MASK_CSRRS 0x707f +#define MATCH_CSRRC 0x3073 +#define MASK_CSRRC 0x707f +#define MATCH_CSRRWI 0x5073 +#define MASK_CSRRWI 0x707f +#define MATCH_CSRRSI 0x6073 +#define MASK_CSRRSI 0x707f +#define MATCH_CSRRCI 0x7073 +#define MASK_CSRRCI 0x707f +#define MATCH_FADD_S 0x53 +#define MASK_FADD_S 0xfe00007f +#define MATCH_FSUB_S 0x8000053 +#define MASK_FSUB_S 0xfe00007f +#define MATCH_FMUL_S 0x10000053 +#define MASK_FMUL_S 0xfe00007f +#define MATCH_FDIV_S 0x18000053 +#define MASK_FDIV_S 0xfe00007f +#define MATCH_FSGNJ_S 0x20000053 +#define MASK_FSGNJ_S 0xfe00707f +#define MATCH_FSGNJN_S 0x20001053 +#define MASK_FSGNJN_S 0xfe00707f +#define MATCH_FSGNJX_S 0x20002053 +#define MASK_FSGNJX_S 0xfe00707f +#define MATCH_FMIN_S 0x28000053 +#define MASK_FMIN_S 0xfe00707f +#define MATCH_FMAX_S 0x28001053 +#define MASK_FMAX_S 0xfe00707f +#define MATCH_FSQRT_S 0x58000053 +#define MASK_FSQRT_S 0xfff0007f +#define MATCH_FADD_D 0x2000053 +#define MASK_FADD_D 0xfe00007f +#define MATCH_FSUB_D 0xa000053 +#define MASK_FSUB_D 0xfe00007f +#define MATCH_FMUL_D 0x12000053 +#define MASK_FMUL_D 0xfe00007f +#define MATCH_FDIV_D 0x1a000053 +#define MASK_FDIV_D 0xfe00007f +#define MATCH_FSGNJ_D 0x22000053 +#define MASK_FSGNJ_D 0xfe00707f +#define MATCH_FSGNJN_D 0x22001053 +#define MASK_FSGNJN_D 0xfe00707f +#define MATCH_FSGNJX_D 0x22002053 +#define MASK_FSGNJX_D 0xfe00707f +#define MATCH_FMIN_D 0x2a000053 +#define MASK_FMIN_D 0xfe00707f +#define MATCH_FMAX_D 0x2a001053 +#define MASK_FMAX_D 0xfe00707f +#define MATCH_FCVT_S_D 0x40100053 +#define MASK_FCVT_S_D 0xfff0007f +#define MATCH_FCVT_D_S 0x42000053 +#define MASK_FCVT_D_S 0xfff0007f +#define MATCH_FSQRT_D 0x5a000053 +#define MASK_FSQRT_D 0xfff0007f +#define MATCH_FLE_S 0xa0000053 +#define MASK_FLE_S 0xfe00707f +#define MATCH_FLT_S 0xa0001053 +#define MASK_FLT_S 0xfe00707f +#define MATCH_FEQ_S 0xa0002053 +#define MASK_FEQ_S 0xfe00707f +#define MATCH_FLE_D 0xa2000053 +#define MASK_FLE_D 0xfe00707f +#define MATCH_FLT_D 0xa2001053 +#define MASK_FLT_D 0xfe00707f +#define MATCH_FEQ_D 0xa2002053 +#define MASK_FEQ_D 0xfe00707f +#define MATCH_FCVT_W_S 0xc0000053 +#define MASK_FCVT_W_S 0xfff0007f +#define MATCH_FCVT_WU_S 0xc0100053 +#define MASK_FCVT_WU_S 0xfff0007f +#define MATCH_FCVT_L_S 0xc0200053 +#define MASK_FCVT_L_S 0xfff0007f +#define MATCH_FCVT_LU_S 0xc0300053 +#define MASK_FCVT_LU_S 0xfff0007f +#define MATCH_FMV_X_S 0xe0000053 +#define MASK_FMV_X_S 0xfff0707f +#define MATCH_FCLASS_S 0xe0001053 +#define MASK_FCLASS_S 0xfff0707f +#define MATCH_FCVT_W_D 0xc2000053 +#define MASK_FCVT_W_D 0xfff0007f +#define MATCH_FCVT_WU_D 0xc2100053 +#define MASK_FCVT_WU_D 0xfff0007f +#define MATCH_FCVT_L_D 0xc2200053 +#define MASK_FCVT_L_D 0xfff0007f +#define MATCH_FCVT_LU_D 0xc2300053 +#define MASK_FCVT_LU_D 0xfff0007f +#define MATCH_FMV_X_D 0xe2000053 +#define MASK_FMV_X_D 0xfff0707f +#define MATCH_FCLASS_D 0xe2001053 +#define MASK_FCLASS_D 0xfff0707f +#define MATCH_FCVT_S_W 0xd0000053 +#define MASK_FCVT_S_W 0xfff0007f +#define MATCH_FCVT_S_WU 0xd0100053 +#define MASK_FCVT_S_WU 0xfff0007f +#define MATCH_FCVT_S_L 0xd0200053 +#define MASK_FCVT_S_L 0xfff0007f +#define MATCH_FCVT_S_LU 0xd0300053 +#define MASK_FCVT_S_LU 0xfff0007f +#define MATCH_FMV_S_X 0xf0000053 +#define MASK_FMV_S_X 0xfff0707f +#define MATCH_FCVT_D_W 0xd2000053 +#define MASK_FCVT_D_W 0xfff0007f +#define MATCH_FCVT_D_WU 0xd2100053 +#define MASK_FCVT_D_WU 0xfff0007f +#define MATCH_FCVT_D_L 0xd2200053 +#define MASK_FCVT_D_L 0xfff0007f +#define MATCH_FCVT_D_LU 0xd2300053 +#define MASK_FCVT_D_LU 0xfff0007f +#define MATCH_FMV_D_X 0xf2000053 +#define MASK_FMV_D_X 0xfff0707f +#define MATCH_FLW 0x2007 +#define MASK_FLW 0x707f +#define MATCH_FLD 0x3007 +#define MASK_FLD 0x707f +#define MATCH_FSW 0x2027 +#define MASK_FSW 0x707f +#define MATCH_FSD 0x3027 +#define MASK_FSD 0x707f +#define MATCH_FMADD_S 0x43 +#define MASK_FMADD_S 0x600007f +#define MATCH_FMSUB_S 0x47 +#define MASK_FMSUB_S 0x600007f +#define MATCH_FNMSUB_S 0x4b +#define MASK_FNMSUB_S 0x600007f +#define MATCH_FNMADD_S 0x4f +#define MASK_FNMADD_S 0x600007f +#define MATCH_FMADD_D 0x2000043 +#define MASK_FMADD_D 0x600007f +#define MATCH_FMSUB_D 0x2000047 +#define MASK_FMSUB_D 0x600007f +#define MATCH_FNMSUB_D 0x200004b +#define MASK_FNMSUB_D 0x600007f +#define MATCH_FNMADD_D 0x200004f +#define MASK_FNMADD_D 0x600007f +#define MATCH_C_NOP 0x1 +#define MASK_C_NOP 0xffff +#define MATCH_C_ADDI16SP 0x6101 +#define MASK_C_ADDI16SP 0xef83 +#define MATCH_C_JR 0x8002 +#define MASK_C_JR 0xf07f +#define MATCH_C_JALR 0x9002 +#define MASK_C_JALR 0xf07f +#define MATCH_C_EBREAK 0x9002 +#define MASK_C_EBREAK 0xffff +#define MATCH_C_LD 0x6000 +#define MASK_C_LD 0xe003 +#define MATCH_C_SD 0xe000 +#define MASK_C_SD 0xe003 +#define MATCH_C_ADDIW 0x2001 +#define MASK_C_ADDIW 0xe003 +#define MATCH_C_LDSP 0x6002 +#define MASK_C_LDSP 0xe003 +#define MATCH_C_SDSP 0xe002 +#define MASK_C_SDSP 0xe003 +#define MATCH_C_ADDI4SPN 0x0 +#define MASK_C_ADDI4SPN 0xe003 +#define MATCH_C_FLD 0x2000 +#define MASK_C_FLD 0xe003 +#define MATCH_C_LW 0x4000 +#define MASK_C_LW 0xe003 +#define MATCH_C_FLW 0x6000 +#define MASK_C_FLW 0xe003 +#define MATCH_C_FSD 0xa000 +#define MASK_C_FSD 0xe003 +#define MATCH_C_SW 0xc000 +#define MASK_C_SW 0xe003 +#define MATCH_C_FSW 0xe000 +#define MASK_C_FSW 0xe003 +#define MATCH_C_ADDI 0x1 +#define MASK_C_ADDI 0xe003 +#define MATCH_C_JAL 0x2001 +#define MASK_C_JAL 0xe003 +#define MATCH_C_LI 0x4001 +#define MASK_C_LI 0xe003 +#define MATCH_C_LUI 0x6001 +#define MASK_C_LUI 0xe003 +#define MATCH_C_SRLI 0x8001 +#define MASK_C_SRLI 0xec03 +#define MATCH_C_SRAI 0x8401 +#define MASK_C_SRAI 0xec03 +#define MATCH_C_ANDI 0x8801 +#define MASK_C_ANDI 0xec03 +#define MATCH_C_SUB 0x8c01 +#define MASK_C_SUB 0xfc63 +#define MATCH_C_XOR 0x8c21 +#define MASK_C_XOR 0xfc63 +#define MATCH_C_OR 0x8c41 +#define MASK_C_OR 0xfc63 +#define MATCH_C_AND 0x8c61 +#define MASK_C_AND 0xfc63 +#define MATCH_C_SUBW 0x9c01 +#define MASK_C_SUBW 0xfc63 +#define MATCH_C_ADDW 0x9c21 +#define MASK_C_ADDW 0xfc63 +#define MATCH_C_J 0xa001 +#define MASK_C_J 0xe003 +#define MATCH_C_BEQZ 0xc001 +#define MASK_C_BEQZ 0xe003 +#define MATCH_C_BNEZ 0xe001 +#define MASK_C_BNEZ 0xe003 +#define MATCH_C_SLLI 0x2 +#define MASK_C_SLLI 0xe003 +#define MATCH_C_FLDSP 0x2002 +#define MASK_C_FLDSP 0xe003 +#define MATCH_C_LWSP 0x4002 +#define MASK_C_LWSP 0xe003 +#define MATCH_C_FLWSP 0x6002 +#define MASK_C_FLWSP 0xe003 +#define MATCH_C_MV 0x8002 +#define MASK_C_MV 0xf003 +#define MATCH_C_ADD 0x9002 +#define MASK_C_ADD 0xf003 +#define MATCH_C_FSDSP 0xa002 +#define MASK_C_FSDSP 0xe003 +#define MATCH_C_SWSP 0xc002 +#define MASK_C_SWSP 0xe003 +#define MATCH_C_FSWSP 0xe002 +#define MASK_C_FSWSP 0xe003 +#define MATCH_CUSTOM0 0xb +#define MASK_CUSTOM0 0x707f +#define MATCH_CUSTOM0_RS1 0x200b +#define MASK_CUSTOM0_RS1 0x707f +#define MATCH_CUSTOM0_RS1_RS2 0x300b +#define MASK_CUSTOM0_RS1_RS2 0x707f +#define MATCH_CUSTOM0_RD 0x400b +#define MASK_CUSTOM0_RD 0x707f +#define MATCH_CUSTOM0_RD_RS1 0x600b +#define MASK_CUSTOM0_RD_RS1 0x707f +#define MATCH_CUSTOM0_RD_RS1_RS2 0x700b +#define MASK_CUSTOM0_RD_RS1_RS2 0x707f +#define MATCH_CUSTOM1 0x2b +#define MASK_CUSTOM1 0x707f +#define MATCH_CUSTOM1_RS1 0x202b +#define MASK_CUSTOM1_RS1 0x707f +#define MATCH_CUSTOM1_RS1_RS2 0x302b +#define MASK_CUSTOM1_RS1_RS2 0x707f +#define MATCH_CUSTOM1_RD 0x402b +#define MASK_CUSTOM1_RD 0x707f +#define MATCH_CUSTOM1_RD_RS1 0x602b +#define MASK_CUSTOM1_RD_RS1 0x707f +#define MATCH_CUSTOM1_RD_RS1_RS2 0x702b +#define MASK_CUSTOM1_RD_RS1_RS2 0x707f +#define MATCH_CUSTOM2 0x5b +#define MASK_CUSTOM2 0x707f +#define MATCH_CUSTOM2_RS1 0x205b +#define MASK_CUSTOM2_RS1 0x707f +#define MATCH_CUSTOM2_RS1_RS2 0x305b +#define MASK_CUSTOM2_RS1_RS2 0x707f +#define MATCH_CUSTOM2_RD 0x405b +#define MASK_CUSTOM2_RD 0x707f +#define MATCH_CUSTOM2_RD_RS1 0x605b +#define MASK_CUSTOM2_RD_RS1 0x707f +#define MATCH_CUSTOM2_RD_RS1_RS2 0x705b +#define MASK_CUSTOM2_RD_RS1_RS2 0x707f +#define MATCH_CUSTOM3 0x7b +#define MASK_CUSTOM3 0x707f +#define MATCH_CUSTOM3_RS1 0x207b +#define MASK_CUSTOM3_RS1 0x707f +#define MATCH_CUSTOM3_RS1_RS2 0x307b +#define MASK_CUSTOM3_RS1_RS2 0x707f +#define MATCH_CUSTOM3_RD 0x407b +#define MASK_CUSTOM3_RD 0x707f +#define MATCH_CUSTOM3_RD_RS1 0x607b +#define MASK_CUSTOM3_RD_RS1 0x707f +#define MATCH_CUSTOM3_RD_RS1_RS2 0x707b +#define MASK_CUSTOM3_RD_RS1_RS2 0x707f +#define CSR_FFLAGS 0x1 +#define CSR_FRM 0x2 +#define CSR_FCSR 0x3 +#define CSR_CYCLE 0xc00 +#define CSR_TIME 0xc01 +#define CSR_INSTRET 0xc02 +#define CSR_HPMCOUNTER3 0xc03 +#define CSR_HPMCOUNTER4 0xc04 +#define CSR_HPMCOUNTER5 0xc05 +#define CSR_HPMCOUNTER6 0xc06 +#define CSR_HPMCOUNTER7 0xc07 +#define CSR_HPMCOUNTER8 0xc08 +#define CSR_HPMCOUNTER9 0xc09 +#define CSR_HPMCOUNTER10 0xc0a +#define CSR_HPMCOUNTER11 0xc0b +#define CSR_HPMCOUNTER12 0xc0c +#define CSR_HPMCOUNTER13 0xc0d +#define CSR_HPMCOUNTER14 0xc0e +#define CSR_HPMCOUNTER15 0xc0f +#define CSR_HPMCOUNTER16 0xc10 +#define CSR_HPMCOUNTER17 0xc11 +#define CSR_HPMCOUNTER18 0xc12 +#define CSR_HPMCOUNTER19 0xc13 +#define CSR_HPMCOUNTER20 0xc14 +#define CSR_HPMCOUNTER21 0xc15 +#define CSR_HPMCOUNTER22 0xc16 +#define CSR_HPMCOUNTER23 0xc17 +#define CSR_HPMCOUNTER24 0xc18 +#define CSR_HPMCOUNTER25 0xc19 +#define CSR_HPMCOUNTER26 0xc1a +#define CSR_HPMCOUNTER27 0xc1b +#define CSR_HPMCOUNTER28 0xc1c +#define CSR_HPMCOUNTER29 0xc1d +#define CSR_HPMCOUNTER30 0xc1e +#define CSR_HPMCOUNTER31 0xc1f +#define CSR_SSTATUS 0x100 +#define CSR_SIE 0x104 +#define CSR_STVEC 0x105 +#define CSR_SSCRATCH 0x140 +#define CSR_SEPC 0x141 +#define CSR_SCAUSE 0x142 +#define CSR_SBADADDR 0x143 +#define CSR_SIP 0x144 +#define CSR_SPTBR 0x180 +#define CSR_MSTATUS 0x300 +#define CSR_MISA 0x301 +#define CSR_MEDELEG 0x302 +#define CSR_MIDELEG 0x303 +#define CSR_MIE 0x304 +#define CSR_MTVEC 0x305 +#define CSR_MSCRATCH 0x340 +#define CSR_MEPC 0x341 +#define CSR_MCAUSE 0x342 +#define CSR_MBADADDR 0x343 +#define CSR_MIP 0x344 +#define CSR_TSELECT 0x7a0 +#define CSR_TDATA1 0x7a1 +#define CSR_TDATA2 0x7a2 +#define CSR_TDATA3 0x7a3 +#define CSR_DCSR 0x7b0 +#define CSR_DPC 0x7b1 +#define CSR_DSCRATCH 0x7b2 +#define CSR_MCYCLE 0xb00 +#define CSR_MINSTRET 0xb02 +#define CSR_MHPMCOUNTER3 0xb03 +#define CSR_MHPMCOUNTER4 0xb04 +#define CSR_MHPMCOUNTER5 0xb05 +#define CSR_MHPMCOUNTER6 0xb06 +#define CSR_MHPMCOUNTER7 0xb07 +#define CSR_MHPMCOUNTER8 0xb08 +#define CSR_MHPMCOUNTER9 0xb09 +#define CSR_MHPMCOUNTER10 0xb0a +#define CSR_MHPMCOUNTER11 0xb0b +#define CSR_MHPMCOUNTER12 0xb0c +#define CSR_MHPMCOUNTER13 0xb0d +#define CSR_MHPMCOUNTER14 0xb0e +#define CSR_MHPMCOUNTER15 0xb0f +#define CSR_MHPMCOUNTER16 0xb10 +#define CSR_MHPMCOUNTER17 0xb11 +#define CSR_MHPMCOUNTER18 0xb12 +#define CSR_MHPMCOUNTER19 0xb13 +#define CSR_MHPMCOUNTER20 0xb14 +#define CSR_MHPMCOUNTER21 0xb15 +#define CSR_MHPMCOUNTER22 0xb16 +#define CSR_MHPMCOUNTER23 0xb17 +#define CSR_MHPMCOUNTER24 0xb18 +#define CSR_MHPMCOUNTER25 0xb19 +#define CSR_MHPMCOUNTER26 0xb1a +#define CSR_MHPMCOUNTER27 0xb1b +#define CSR_MHPMCOUNTER28 0xb1c +#define CSR_MHPMCOUNTER29 0xb1d +#define CSR_MHPMCOUNTER30 0xb1e +#define CSR_MHPMCOUNTER31 0xb1f +#define CSR_MUCOUNTEREN 0x320 +#define CSR_MSCOUNTEREN 0x321 +#define CSR_MHPMEVENT3 0x323 +#define CSR_MHPMEVENT4 0x324 +#define CSR_MHPMEVENT5 0x325 +#define CSR_MHPMEVENT6 0x326 +#define CSR_MHPMEVENT7 0x327 +#define CSR_MHPMEVENT8 0x328 +#define CSR_MHPMEVENT9 0x329 +#define CSR_MHPMEVENT10 0x32a +#define CSR_MHPMEVENT11 0x32b +#define CSR_MHPMEVENT12 0x32c +#define CSR_MHPMEVENT13 0x32d +#define CSR_MHPMEVENT14 0x32e +#define CSR_MHPMEVENT15 0x32f +#define CSR_MHPMEVENT16 0x330 +#define CSR_MHPMEVENT17 0x331 +#define CSR_MHPMEVENT18 0x332 +#define CSR_MHPMEVENT19 0x333 +#define CSR_MHPMEVENT20 0x334 +#define CSR_MHPMEVENT21 0x335 +#define CSR_MHPMEVENT22 0x336 +#define CSR_MHPMEVENT23 0x337 +#define CSR_MHPMEVENT24 0x338 +#define CSR_MHPMEVENT25 0x339 +#define CSR_MHPMEVENT26 0x33a +#define CSR_MHPMEVENT27 0x33b +#define CSR_MHPMEVENT28 0x33c +#define CSR_MHPMEVENT29 0x33d +#define CSR_MHPMEVENT30 0x33e +#define CSR_MHPMEVENT31 0x33f +#define CSR_MVENDORID 0xf11 +#define CSR_MARCHID 0xf12 +#define CSR_MIMPID 0xf13 +#define CSR_MHARTID 0xf14 +#define CSR_CYCLEH 0xc80 +#define CSR_TIMEH 0xc81 +#define CSR_INSTRETH 0xc82 +#define CSR_HPMCOUNTER3H 0xc83 +#define CSR_HPMCOUNTER4H 0xc84 +#define CSR_HPMCOUNTER5H 0xc85 +#define CSR_HPMCOUNTER6H 0xc86 +#define CSR_HPMCOUNTER7H 0xc87 +#define CSR_HPMCOUNTER8H 0xc88 +#define CSR_HPMCOUNTER9H 0xc89 +#define CSR_HPMCOUNTER10H 0xc8a +#define CSR_HPMCOUNTER11H 0xc8b +#define CSR_HPMCOUNTER12H 0xc8c +#define CSR_HPMCOUNTER13H 0xc8d +#define CSR_HPMCOUNTER14H 0xc8e +#define CSR_HPMCOUNTER15H 0xc8f +#define CSR_HPMCOUNTER16H 0xc90 +#define CSR_HPMCOUNTER17H 0xc91 +#define CSR_HPMCOUNTER18H 0xc92 +#define CSR_HPMCOUNTER19H 0xc93 +#define CSR_HPMCOUNTER20H 0xc94 +#define CSR_HPMCOUNTER21H 0xc95 +#define CSR_HPMCOUNTER22H 0xc96 +#define CSR_HPMCOUNTER23H 0xc97 +#define CSR_HPMCOUNTER24H 0xc98 +#define CSR_HPMCOUNTER25H 0xc99 +#define CSR_HPMCOUNTER26H 0xc9a +#define CSR_HPMCOUNTER27H 0xc9b +#define CSR_HPMCOUNTER28H 0xc9c +#define CSR_HPMCOUNTER29H 0xc9d +#define CSR_HPMCOUNTER30H 0xc9e +#define CSR_HPMCOUNTER31H 0xc9f +#define CSR_MCYCLEH 0xb80 +#define CSR_MINSTRETH 0xb82 +#define CSR_MHPMCOUNTER3H 0xb83 +#define CSR_MHPMCOUNTER4H 0xb84 +#define CSR_MHPMCOUNTER5H 0xb85 +#define CSR_MHPMCOUNTER6H 0xb86 +#define CSR_MHPMCOUNTER7H 0xb87 +#define CSR_MHPMCOUNTER8H 0xb88 +#define CSR_MHPMCOUNTER9H 0xb89 +#define CSR_MHPMCOUNTER10H 0xb8a +#define CSR_MHPMCOUNTER11H 0xb8b +#define CSR_MHPMCOUNTER12H 0xb8c +#define CSR_MHPMCOUNTER13H 0xb8d +#define CSR_MHPMCOUNTER14H 0xb8e +#define CSR_MHPMCOUNTER15H 0xb8f +#define CSR_MHPMCOUNTER16H 0xb90 +#define CSR_MHPMCOUNTER17H 0xb91 +#define CSR_MHPMCOUNTER18H 0xb92 +#define CSR_MHPMCOUNTER19H 0xb93 +#define CSR_MHPMCOUNTER20H 0xb94 +#define CSR_MHPMCOUNTER21H 0xb95 +#define CSR_MHPMCOUNTER22H 0xb96 +#define CSR_MHPMCOUNTER23H 0xb97 +#define CSR_MHPMCOUNTER24H 0xb98 +#define CSR_MHPMCOUNTER25H 0xb99 +#define CSR_MHPMCOUNTER26H 0xb9a +#define CSR_MHPMCOUNTER27H 0xb9b +#define CSR_MHPMCOUNTER28H 0xb9c +#define CSR_MHPMCOUNTER29H 0xb9d +#define CSR_MHPMCOUNTER30H 0xb9e +#define CSR_MHPMCOUNTER31H 0xb9f +#define CAUSE_MISALIGNED_FETCH 0x0 +#define CAUSE_FAULT_FETCH 0x1 +#define CAUSE_ILLEGAL_INSTRUCTION 0x2 +#define CAUSE_BREAKPOINT 0x3 +#define CAUSE_MISALIGNED_LOAD 0x4 +#define CAUSE_FAULT_LOAD 0x5 +#define CAUSE_MISALIGNED_STORE 0x6 +#define CAUSE_FAULT_STORE 0x7 +#define CAUSE_USER_ECALL 0x8 +#define CAUSE_SUPERVISOR_ECALL 0x9 +#define CAUSE_HYPERVISOR_ECALL 0xa +#define CAUSE_MACHINE_ECALL 0xb +#endif +#ifdef DECLARE_INSN +DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ) +DECLARE_INSN(bne, MATCH_BNE, MASK_BNE) +DECLARE_INSN(blt, MATCH_BLT, MASK_BLT) +DECLARE_INSN(bge, MATCH_BGE, MASK_BGE) +DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU) +DECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU) +DECLARE_INSN(jalr, MATCH_JALR, MASK_JALR) +DECLARE_INSN(jal, MATCH_JAL, MASK_JAL) +DECLARE_INSN(lui, MATCH_LUI, MASK_LUI) +DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC) +DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI) +DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI) +DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI) +DECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU) +DECLARE_INSN(xori, MATCH_XORI, MASK_XORI) +DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI) +DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI) +DECLARE_INSN(ori, MATCH_ORI, MASK_ORI) +DECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI) +DECLARE_INSN(add, MATCH_ADD, MASK_ADD) +DECLARE_INSN(sub, MATCH_SUB, MASK_SUB) +DECLARE_INSN(sll, MATCH_SLL, MASK_SLL) +DECLARE_INSN(slt, MATCH_SLT, MASK_SLT) +DECLARE_INSN(sltu, MATCH_SLTU, MASK_SLTU) +DECLARE_INSN(xor, MATCH_XOR, MASK_XOR) +DECLARE_INSN(srl, MATCH_SRL, MASK_SRL) +DECLARE_INSN(sra, MATCH_SRA, MASK_SRA) +DECLARE_INSN(or, MATCH_OR, MASK_OR) +DECLARE_INSN(and, MATCH_AND, MASK_AND) +DECLARE_INSN(addiw, MATCH_ADDIW, MASK_ADDIW) +DECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW) +DECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW) +DECLARE_INSN(sraiw, MATCH_SRAIW, MASK_SRAIW) +DECLARE_INSN(addw, MATCH_ADDW, MASK_ADDW) +DECLARE_INSN(subw, MATCH_SUBW, MASK_SUBW) +DECLARE_INSN(sllw, MATCH_SLLW, MASK_SLLW) +DECLARE_INSN(srlw, MATCH_SRLW, MASK_SRLW) +DECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW) +DECLARE_INSN(lb, MATCH_LB, MASK_LB) +DECLARE_INSN(lh, MATCH_LH, MASK_LH) +DECLARE_INSN(lw, MATCH_LW, MASK_LW) +DECLARE_INSN(ld, MATCH_LD, MASK_LD) +DECLARE_INSN(lbu, MATCH_LBU, MASK_LBU) +DECLARE_INSN(lhu, MATCH_LHU, MASK_LHU) +DECLARE_INSN(lwu, MATCH_LWU, MASK_LWU) +DECLARE_INSN(sb, MATCH_SB, MASK_SB) +DECLARE_INSN(sh, MATCH_SH, MASK_SH) +DECLARE_INSN(sw, MATCH_SW, MASK_SW) +DECLARE_INSN(sd, MATCH_SD, MASK_SD) +DECLARE_INSN(fence, MATCH_FENCE, MASK_FENCE) +DECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I) +DECLARE_INSN(mul, MATCH_MUL, MASK_MUL) +DECLARE_INSN(mulh, MATCH_MULH, MASK_MULH) +DECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU) +DECLARE_INSN(mulhu, MATCH_MULHU, MASK_MULHU) +DECLARE_INSN(div, MATCH_DIV, MASK_DIV) +DECLARE_INSN(divu, MATCH_DIVU, MASK_DIVU) +DECLARE_INSN(rem, MATCH_REM, MASK_REM) +DECLARE_INSN(remu, MATCH_REMU, MASK_REMU) +DECLARE_INSN(mulw, MATCH_MULW, MASK_MULW) +DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW) +DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW) +DECLARE_INSN(remw, MATCH_REMW, MASK_REMW) +DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW) +DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W) +DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W) +DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W) +DECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W) +DECLARE_INSN(amomin_w, MATCH_AMOMIN_W, MASK_AMOMIN_W) +DECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W) +DECLARE_INSN(amominu_w, MATCH_AMOMINU_W, MASK_AMOMINU_W) +DECLARE_INSN(amomaxu_w, MATCH_AMOMAXU_W, MASK_AMOMAXU_W) +DECLARE_INSN(amoswap_w, MATCH_AMOSWAP_W, MASK_AMOSWAP_W) +DECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W) +DECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W) +DECLARE_INSN(amoadd_d, MATCH_AMOADD_D, MASK_AMOADD_D) +DECLARE_INSN(amoxor_d, MATCH_AMOXOR_D, MASK_AMOXOR_D) +DECLARE_INSN(amoor_d, MATCH_AMOOR_D, MASK_AMOOR_D) +DECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D) +DECLARE_INSN(amomin_d, MATCH_AMOMIN_D, MASK_AMOMIN_D) +DECLARE_INSN(amomax_d, MATCH_AMOMAX_D, MASK_AMOMAX_D) +DECLARE_INSN(amominu_d, MATCH_AMOMINU_D, MASK_AMOMINU_D) +DECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D) +DECLARE_INSN(amoswap_d, MATCH_AMOSWAP_D, MASK_AMOSWAP_D) +DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D) +DECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D) +DECLARE_INSN(ecall, MATCH_ECALL, MASK_ECALL) +DECLARE_INSN(ebreak, MATCH_EBREAK, MASK_EBREAK) +DECLARE_INSN(uret, MATCH_URET, MASK_URET) +DECLARE_INSN(sret, MATCH_SRET, MASK_SRET) +DECLARE_INSN(hret, MATCH_HRET, MASK_HRET) +DECLARE_INSN(mret, MATCH_MRET, MASK_MRET) +DECLARE_INSN(dret, MATCH_DRET, MASK_DRET) +DECLARE_INSN(sfence_vm, MATCH_SFENCE_VM, MASK_SFENCE_VM) +DECLARE_INSN(wfi, MATCH_WFI, MASK_WFI) +DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW) +DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS) +DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC) +DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI) +DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI) +DECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI) +DECLARE_INSN(fadd_s, MATCH_FADD_S, MASK_FADD_S) +DECLARE_INSN(fsub_s, MATCH_FSUB_S, MASK_FSUB_S) +DECLARE_INSN(fmul_s, MATCH_FMUL_S, MASK_FMUL_S) +DECLARE_INSN(fdiv_s, MATCH_FDIV_S, MASK_FDIV_S) +DECLARE_INSN(fsgnj_s, MATCH_FSGNJ_S, MASK_FSGNJ_S) +DECLARE_INSN(fsgnjn_s, MATCH_FSGNJN_S, MASK_FSGNJN_S) +DECLARE_INSN(fsgnjx_s, MATCH_FSGNJX_S, MASK_FSGNJX_S) +DECLARE_INSN(fmin_s, MATCH_FMIN_S, MASK_FMIN_S) +DECLARE_INSN(fmax_s, MATCH_FMAX_S, MASK_FMAX_S) +DECLARE_INSN(fsqrt_s, MATCH_FSQRT_S, MASK_FSQRT_S) +DECLARE_INSN(fadd_d, MATCH_FADD_D, MASK_FADD_D) +DECLARE_INSN(fsub_d, MATCH_FSUB_D, MASK_FSUB_D) +DECLARE_INSN(fmul_d, MATCH_FMUL_D, MASK_FMUL_D) +DECLARE_INSN(fdiv_d, MATCH_FDIV_D, MASK_FDIV_D) +DECLARE_INSN(fsgnj_d, MATCH_FSGNJ_D, MASK_FSGNJ_D) +DECLARE_INSN(fsgnjn_d, MATCH_FSGNJN_D, MASK_FSGNJN_D) +DECLARE_INSN(fsgnjx_d, MATCH_FSGNJX_D, MASK_FSGNJX_D) +DECLARE_INSN(fmin_d, MATCH_FMIN_D, MASK_FMIN_D) +DECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D) +DECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D) +DECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S) +DECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D) +DECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S) +DECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S) +DECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S) +DECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D) +DECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D) +DECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D) +DECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S) +DECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S) +DECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S) +DECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S) +DECLARE_INSN(fmv_x_s, MATCH_FMV_X_S, MASK_FMV_X_S) +DECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S) +DECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D) +DECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D) +DECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D) +DECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D) +DECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D) +DECLARE_INSN(fclass_d, MATCH_FCLASS_D, MASK_FCLASS_D) +DECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W) +DECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU) +DECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L) +DECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU) +DECLARE_INSN(fmv_s_x, MATCH_FMV_S_X, MASK_FMV_S_X) +DECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W) +DECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU) +DECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L) +DECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU) +DECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X) +DECLARE_INSN(flw, MATCH_FLW, MASK_FLW) +DECLARE_INSN(fld, MATCH_FLD, MASK_FLD) +DECLARE_INSN(fsw, MATCH_FSW, MASK_FSW) +DECLARE_INSN(fsd, MATCH_FSD, MASK_FSD) +DECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S) +DECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S) +DECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S) +DECLARE_INSN(fnmadd_s, MATCH_FNMADD_S, MASK_FNMADD_S) +DECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D) +DECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D) +DECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D) +DECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D) +DECLARE_INSN(c_nop, MATCH_C_NOP, MASK_C_NOP) +DECLARE_INSN(c_addi16sp, MATCH_C_ADDI16SP, MASK_C_ADDI16SP) +DECLARE_INSN(c_jr, MATCH_C_JR, MASK_C_JR) +DECLARE_INSN(c_jalr, MATCH_C_JALR, MASK_C_JALR) +DECLARE_INSN(c_ebreak, MATCH_C_EBREAK, MASK_C_EBREAK) +DECLARE_INSN(c_ld, MATCH_C_LD, MASK_C_LD) +DECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD) +DECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW) +DECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP) +DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP) +DECLARE_INSN(c_addi4spn, MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN) +DECLARE_INSN(c_fld, MATCH_C_FLD, MASK_C_FLD) +DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW) +DECLARE_INSN(c_flw, MATCH_C_FLW, MASK_C_FLW) +DECLARE_INSN(c_fsd, MATCH_C_FSD, MASK_C_FSD) +DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW) +DECLARE_INSN(c_fsw, MATCH_C_FSW, MASK_C_FSW) +DECLARE_INSN(c_addi, MATCH_C_ADDI, MASK_C_ADDI) +DECLARE_INSN(c_jal, MATCH_C_JAL, MASK_C_JAL) +DECLARE_INSN(c_li, MATCH_C_LI, MASK_C_LI) +DECLARE_INSN(c_lui, MATCH_C_LUI, MASK_C_LUI) +DECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI) +DECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI) +DECLARE_INSN(c_andi, MATCH_C_ANDI, MASK_C_ANDI) +DECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB) +DECLARE_INSN(c_xor, MATCH_C_XOR, MASK_C_XOR) +DECLARE_INSN(c_or, MATCH_C_OR, MASK_C_OR) +DECLARE_INSN(c_and, MATCH_C_AND, MASK_C_AND) +DECLARE_INSN(c_subw, MATCH_C_SUBW, MASK_C_SUBW) +DECLARE_INSN(c_addw, MATCH_C_ADDW, MASK_C_ADDW) +DECLARE_INSN(c_j, MATCH_C_J, MASK_C_J) +DECLARE_INSN(c_beqz, MATCH_C_BEQZ, MASK_C_BEQZ) +DECLARE_INSN(c_bnez, MATCH_C_BNEZ, MASK_C_BNEZ) +DECLARE_INSN(c_slli, MATCH_C_SLLI, MASK_C_SLLI) +DECLARE_INSN(c_fldsp, MATCH_C_FLDSP, MASK_C_FLDSP) +DECLARE_INSN(c_lwsp, MATCH_C_LWSP, MASK_C_LWSP) +DECLARE_INSN(c_flwsp, MATCH_C_FLWSP, MASK_C_FLWSP) +DECLARE_INSN(c_mv, MATCH_C_MV, MASK_C_MV) +DECLARE_INSN(c_add, MATCH_C_ADD, MASK_C_ADD) +DECLARE_INSN(c_fsdsp, MATCH_C_FSDSP, MASK_C_FSDSP) +DECLARE_INSN(c_swsp, MATCH_C_SWSP, MASK_C_SWSP) +DECLARE_INSN(c_fswsp, MATCH_C_FSWSP, MASK_C_FSWSP) +DECLARE_INSN(custom0, MATCH_CUSTOM0, MASK_CUSTOM0) +DECLARE_INSN(custom0_rs1, MATCH_CUSTOM0_RS1, MASK_CUSTOM0_RS1) +DECLARE_INSN(custom0_rs1_rs2, MATCH_CUSTOM0_RS1_RS2, MASK_CUSTOM0_RS1_RS2) +DECLARE_INSN(custom0_rd, MATCH_CUSTOM0_RD, MASK_CUSTOM0_RD) +DECLARE_INSN(custom0_rd_rs1, MATCH_CUSTOM0_RD_RS1, MASK_CUSTOM0_RD_RS1) +DECLARE_INSN(custom0_rd_rs1_rs2, MATCH_CUSTOM0_RD_RS1_RS2, MASK_CUSTOM0_RD_RS1_RS2) +DECLARE_INSN(custom1, MATCH_CUSTOM1, MASK_CUSTOM1) +DECLARE_INSN(custom1_rs1, MATCH_CUSTOM1_RS1, MASK_CUSTOM1_RS1) +DECLARE_INSN(custom1_rs1_rs2, MATCH_CUSTOM1_RS1_RS2, MASK_CUSTOM1_RS1_RS2) +DECLARE_INSN(custom1_rd, MATCH_CUSTOM1_RD, MASK_CUSTOM1_RD) +DECLARE_INSN(custom1_rd_rs1, MATCH_CUSTOM1_RD_RS1, MASK_CUSTOM1_RD_RS1) +DECLARE_INSN(custom1_rd_rs1_rs2, MATCH_CUSTOM1_RD_RS1_RS2, MASK_CUSTOM1_RD_RS1_RS2) +DECLARE_INSN(custom2, MATCH_CUSTOM2, MASK_CUSTOM2) +DECLARE_INSN(custom2_rs1, MATCH_CUSTOM2_RS1, MASK_CUSTOM2_RS1) +DECLARE_INSN(custom2_rs1_rs2, MATCH_CUSTOM2_RS1_RS2, MASK_CUSTOM2_RS1_RS2) +DECLARE_INSN(custom2_rd, MATCH_CUSTOM2_RD, MASK_CUSTOM2_RD) +DECLARE_INSN(custom2_rd_rs1, MATCH_CUSTOM2_RD_RS1, MASK_CUSTOM2_RD_RS1) +DECLARE_INSN(custom2_rd_rs1_rs2, MATCH_CUSTOM2_RD_RS1_RS2, MASK_CUSTOM2_RD_RS1_RS2) +DECLARE_INSN(custom3, MATCH_CUSTOM3, MASK_CUSTOM3) +DECLARE_INSN(custom3_rs1, MATCH_CUSTOM3_RS1, MASK_CUSTOM3_RS1) +DECLARE_INSN(custom3_rs1_rs2, MATCH_CUSTOM3_RS1_RS2, MASK_CUSTOM3_RS1_RS2) +DECLARE_INSN(custom3_rd, MATCH_CUSTOM3_RD, MASK_CUSTOM3_RD) +DECLARE_INSN(custom3_rd_rs1, MATCH_CUSTOM3_RD_RS1, MASK_CUSTOM3_RD_RS1) +DECLARE_INSN(custom3_rd_rs1_rs2, MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_RS2) +#endif +#ifdef DECLARE_CSR +DECLARE_CSR(fflags, CSR_FFLAGS) +DECLARE_CSR(frm, CSR_FRM) +DECLARE_CSR(fcsr, CSR_FCSR) +DECLARE_CSR(cycle, CSR_CYCLE) +DECLARE_CSR(time, CSR_TIME) +DECLARE_CSR(instret, CSR_INSTRET) +DECLARE_CSR(hpmcounter3, CSR_HPMCOUNTER3) +DECLARE_CSR(hpmcounter4, CSR_HPMCOUNTER4) +DECLARE_CSR(hpmcounter5, CSR_HPMCOUNTER5) +DECLARE_CSR(hpmcounter6, CSR_HPMCOUNTER6) +DECLARE_CSR(hpmcounter7, CSR_HPMCOUNTER7) +DECLARE_CSR(hpmcounter8, CSR_HPMCOUNTER8) +DECLARE_CSR(hpmcounter9, CSR_HPMCOUNTER9) +DECLARE_CSR(hpmcounter10, CSR_HPMCOUNTER10) +DECLARE_CSR(hpmcounter11, CSR_HPMCOUNTER11) +DECLARE_CSR(hpmcounter12, CSR_HPMCOUNTER12) +DECLARE_CSR(hpmcounter13, CSR_HPMCOUNTER13) +DECLARE_CSR(hpmcounter14, CSR_HPMCOUNTER14) +DECLARE_CSR(hpmcounter15, CSR_HPMCOUNTER15) +DECLARE_CSR(hpmcounter16, CSR_HPMCOUNTER16) +DECLARE_CSR(hpmcounter17, CSR_HPMCOUNTER17) +DECLARE_CSR(hpmcounter18, CSR_HPMCOUNTER18) +DECLARE_CSR(hpmcounter19, CSR_HPMCOUNTER19) +DECLARE_CSR(hpmcounter20, CSR_HPMCOUNTER20) +DECLARE_CSR(hpmcounter21, CSR_HPMCOUNTER21) +DECLARE_CSR(hpmcounter22, CSR_HPMCOUNTER22) +DECLARE_CSR(hpmcounter23, CSR_HPMCOUNTER23) +DECLARE_CSR(hpmcounter24, CSR_HPMCOUNTER24) +DECLARE_CSR(hpmcounter25, CSR_HPMCOUNTER25) +DECLARE_CSR(hpmcounter26, CSR_HPMCOUNTER26) +DECLARE_CSR(hpmcounter27, CSR_HPMCOUNTER27) +DECLARE_CSR(hpmcounter28, CSR_HPMCOUNTER28) +DECLARE_CSR(hpmcounter29, CSR_HPMCOUNTER29) +DECLARE_CSR(hpmcounter30, CSR_HPMCOUNTER30) +DECLARE_CSR(hpmcounter31, CSR_HPMCOUNTER31) +DECLARE_CSR(sstatus, CSR_SSTATUS) +DECLARE_CSR(sie, CSR_SIE) +DECLARE_CSR(stvec, CSR_STVEC) +DECLARE_CSR(sscratch, CSR_SSCRATCH) +DECLARE_CSR(sepc, CSR_SEPC) +DECLARE_CSR(scause, CSR_SCAUSE) +DECLARE_CSR(sbadaddr, CSR_SBADADDR) +DECLARE_CSR(sip, CSR_SIP) +DECLARE_CSR(sptbr, CSR_SPTBR) +DECLARE_CSR(mstatus, CSR_MSTATUS) +DECLARE_CSR(misa, CSR_MISA) +DECLARE_CSR(medeleg, CSR_MEDELEG) +DECLARE_CSR(mideleg, CSR_MIDELEG) +DECLARE_CSR(mie, CSR_MIE) +DECLARE_CSR(mtvec, CSR_MTVEC) +DECLARE_CSR(mscratch, CSR_MSCRATCH) +DECLARE_CSR(mepc, CSR_MEPC) +DECLARE_CSR(mcause, CSR_MCAUSE) +DECLARE_CSR(mbadaddr, CSR_MBADADDR) +DECLARE_CSR(mip, CSR_MIP) +DECLARE_CSR(tselect, CSR_TSELECT) +DECLARE_CSR(tdata1, CSR_TDATA1) +DECLARE_CSR(tdata2, CSR_TDATA2) +DECLARE_CSR(tdata3, CSR_TDATA3) +DECLARE_CSR(dcsr, CSR_DCSR) +DECLARE_CSR(dpc, CSR_DPC) +DECLARE_CSR(dscratch, CSR_DSCRATCH) +DECLARE_CSR(mcycle, CSR_MCYCLE) +DECLARE_CSR(minstret, CSR_MINSTRET) +DECLARE_CSR(mhpmcounter3, CSR_MHPMCOUNTER3) +DECLARE_CSR(mhpmcounter4, CSR_MHPMCOUNTER4) +DECLARE_CSR(mhpmcounter5, CSR_MHPMCOUNTER5) +DECLARE_CSR(mhpmcounter6, CSR_MHPMCOUNTER6) +DECLARE_CSR(mhpmcounter7, CSR_MHPMCOUNTER7) +DECLARE_CSR(mhpmcounter8, CSR_MHPMCOUNTER8) +DECLARE_CSR(mhpmcounter9, CSR_MHPMCOUNTER9) +DECLARE_CSR(mhpmcounter10, CSR_MHPMCOUNTER10) +DECLARE_CSR(mhpmcounter11, CSR_MHPMCOUNTER11) +DECLARE_CSR(mhpmcounter12, CSR_MHPMCOUNTER12) +DECLARE_CSR(mhpmcounter13, CSR_MHPMCOUNTER13) +DECLARE_CSR(mhpmcounter14, CSR_MHPMCOUNTER14) +DECLARE_CSR(mhpmcounter15, CSR_MHPMCOUNTER15) +DECLARE_CSR(mhpmcounter16, CSR_MHPMCOUNTER16) +DECLARE_CSR(mhpmcounter17, CSR_MHPMCOUNTER17) +DECLARE_CSR(mhpmcounter18, CSR_MHPMCOUNTER18) +DECLARE_CSR(mhpmcounter19, CSR_MHPMCOUNTER19) +DECLARE_CSR(mhpmcounter20, CSR_MHPMCOUNTER20) +DECLARE_CSR(mhpmcounter21, CSR_MHPMCOUNTER21) +DECLARE_CSR(mhpmcounter22, CSR_MHPMCOUNTER22) +DECLARE_CSR(mhpmcounter23, CSR_MHPMCOUNTER23) +DECLARE_CSR(mhpmcounter24, CSR_MHPMCOUNTER24) +DECLARE_CSR(mhpmcounter25, CSR_MHPMCOUNTER25) +DECLARE_CSR(mhpmcounter26, CSR_MHPMCOUNTER26) +DECLARE_CSR(mhpmcounter27, CSR_MHPMCOUNTER27) +DECLARE_CSR(mhpmcounter28, CSR_MHPMCOUNTER28) +DECLARE_CSR(mhpmcounter29, CSR_MHPMCOUNTER29) +DECLARE_CSR(mhpmcounter30, CSR_MHPMCOUNTER30) +DECLARE_CSR(mhpmcounter31, CSR_MHPMCOUNTER31) +DECLARE_CSR(mucounteren, CSR_MUCOUNTEREN) +DECLARE_CSR(mscounteren, CSR_MSCOUNTEREN) +DECLARE_CSR(mhpmevent3, CSR_MHPMEVENT3) +DECLARE_CSR(mhpmevent4, CSR_MHPMEVENT4) +DECLARE_CSR(mhpmevent5, CSR_MHPMEVENT5) +DECLARE_CSR(mhpmevent6, CSR_MHPMEVENT6) +DECLARE_CSR(mhpmevent7, CSR_MHPMEVENT7) +DECLARE_CSR(mhpmevent8, CSR_MHPMEVENT8) +DECLARE_CSR(mhpmevent9, CSR_MHPMEVENT9) +DECLARE_CSR(mhpmevent10, CSR_MHPMEVENT10) +DECLARE_CSR(mhpmevent11, CSR_MHPMEVENT11) +DECLARE_CSR(mhpmevent12, CSR_MHPMEVENT12) +DECLARE_CSR(mhpmevent13, CSR_MHPMEVENT13) +DECLARE_CSR(mhpmevent14, CSR_MHPMEVENT14) +DECLARE_CSR(mhpmevent15, CSR_MHPMEVENT15) +DECLARE_CSR(mhpmevent16, CSR_MHPMEVENT16) +DECLARE_CSR(mhpmevent17, CSR_MHPMEVENT17) +DECLARE_CSR(mhpmevent18, CSR_MHPMEVENT18) +DECLARE_CSR(mhpmevent19, CSR_MHPMEVENT19) +DECLARE_CSR(mhpmevent20, CSR_MHPMEVENT20) +DECLARE_CSR(mhpmevent21, CSR_MHPMEVENT21) +DECLARE_CSR(mhpmevent22, CSR_MHPMEVENT22) +DECLARE_CSR(mhpmevent23, CSR_MHPMEVENT23) +DECLARE_CSR(mhpmevent24, CSR_MHPMEVENT24) +DECLARE_CSR(mhpmevent25, CSR_MHPMEVENT25) +DECLARE_CSR(mhpmevent26, CSR_MHPMEVENT26) +DECLARE_CSR(mhpmevent27, CSR_MHPMEVENT27) +DECLARE_CSR(mhpmevent28, CSR_MHPMEVENT28) +DECLARE_CSR(mhpmevent29, CSR_MHPMEVENT29) +DECLARE_CSR(mhpmevent30, CSR_MHPMEVENT30) +DECLARE_CSR(mhpmevent31, CSR_MHPMEVENT31) +DECLARE_CSR(mvendorid, CSR_MVENDORID) +DECLARE_CSR(marchid, CSR_MARCHID) +DECLARE_CSR(mimpid, CSR_MIMPID) +DECLARE_CSR(mhartid, CSR_MHARTID) +DECLARE_CSR(cycleh, CSR_CYCLEH) +DECLARE_CSR(timeh, CSR_TIMEH) +DECLARE_CSR(instreth, CSR_INSTRETH) +DECLARE_CSR(hpmcounter3h, CSR_HPMCOUNTER3H) +DECLARE_CSR(hpmcounter4h, CSR_HPMCOUNTER4H) +DECLARE_CSR(hpmcounter5h, CSR_HPMCOUNTER5H) +DECLARE_CSR(hpmcounter6h, CSR_HPMCOUNTER6H) +DECLARE_CSR(hpmcounter7h, CSR_HPMCOUNTER7H) +DECLARE_CSR(hpmcounter8h, CSR_HPMCOUNTER8H) +DECLARE_CSR(hpmcounter9h, CSR_HPMCOUNTER9H) +DECLARE_CSR(hpmcounter10h, CSR_HPMCOUNTER10H) +DECLARE_CSR(hpmcounter11h, CSR_HPMCOUNTER11H) +DECLARE_CSR(hpmcounter12h, CSR_HPMCOUNTER12H) +DECLARE_CSR(hpmcounter13h, CSR_HPMCOUNTER13H) +DECLARE_CSR(hpmcounter14h, CSR_HPMCOUNTER14H) +DECLARE_CSR(hpmcounter15h, CSR_HPMCOUNTER15H) +DECLARE_CSR(hpmcounter16h, CSR_HPMCOUNTER16H) +DECLARE_CSR(hpmcounter17h, CSR_HPMCOUNTER17H) +DECLARE_CSR(hpmcounter18h, CSR_HPMCOUNTER18H) +DECLARE_CSR(hpmcounter19h, CSR_HPMCOUNTER19H) +DECLARE_CSR(hpmcounter20h, CSR_HPMCOUNTER20H) +DECLARE_CSR(hpmcounter21h, CSR_HPMCOUNTER21H) +DECLARE_CSR(hpmcounter22h, CSR_HPMCOUNTER22H) +DECLARE_CSR(hpmcounter23h, CSR_HPMCOUNTER23H) +DECLARE_CSR(hpmcounter24h, CSR_HPMCOUNTER24H) +DECLARE_CSR(hpmcounter25h, CSR_HPMCOUNTER25H) +DECLARE_CSR(hpmcounter26h, CSR_HPMCOUNTER26H) +DECLARE_CSR(hpmcounter27h, CSR_HPMCOUNTER27H) +DECLARE_CSR(hpmcounter28h, CSR_HPMCOUNTER28H) +DECLARE_CSR(hpmcounter29h, CSR_HPMCOUNTER29H) +DECLARE_CSR(hpmcounter30h, CSR_HPMCOUNTER30H) +DECLARE_CSR(hpmcounter31h, CSR_HPMCOUNTER31H) +DECLARE_CSR(mcycleh, CSR_MCYCLEH) +DECLARE_CSR(minstreth, CSR_MINSTRETH) +DECLARE_CSR(mhpmcounter3h, CSR_MHPMCOUNTER3H) +DECLARE_CSR(mhpmcounter4h, CSR_MHPMCOUNTER4H) +DECLARE_CSR(mhpmcounter5h, CSR_MHPMCOUNTER5H) +DECLARE_CSR(mhpmcounter6h, CSR_MHPMCOUNTER6H) +DECLARE_CSR(mhpmcounter7h, CSR_MHPMCOUNTER7H) +DECLARE_CSR(mhpmcounter8h, CSR_MHPMCOUNTER8H) +DECLARE_CSR(mhpmcounter9h, CSR_MHPMCOUNTER9H) +DECLARE_CSR(mhpmcounter10h, CSR_MHPMCOUNTER10H) +DECLARE_CSR(mhpmcounter11h, CSR_MHPMCOUNTER11H) +DECLARE_CSR(mhpmcounter12h, CSR_MHPMCOUNTER12H) +DECLARE_CSR(mhpmcounter13h, CSR_MHPMCOUNTER13H) +DECLARE_CSR(mhpmcounter14h, CSR_MHPMCOUNTER14H) +DECLARE_CSR(mhpmcounter15h, CSR_MHPMCOUNTER15H) +DECLARE_CSR(mhpmcounter16h, CSR_MHPMCOUNTER16H) +DECLARE_CSR(mhpmcounter17h, CSR_MHPMCOUNTER17H) +DECLARE_CSR(mhpmcounter18h, CSR_MHPMCOUNTER18H) +DECLARE_CSR(mhpmcounter19h, CSR_MHPMCOUNTER19H) +DECLARE_CSR(mhpmcounter20h, CSR_MHPMCOUNTER20H) +DECLARE_CSR(mhpmcounter21h, CSR_MHPMCOUNTER21H) +DECLARE_CSR(mhpmcounter22h, CSR_MHPMCOUNTER22H) +DECLARE_CSR(mhpmcounter23h, CSR_MHPMCOUNTER23H) +DECLARE_CSR(mhpmcounter24h, CSR_MHPMCOUNTER24H) +DECLARE_CSR(mhpmcounter25h, CSR_MHPMCOUNTER25H) +DECLARE_CSR(mhpmcounter26h, CSR_MHPMCOUNTER26H) +DECLARE_CSR(mhpmcounter27h, CSR_MHPMCOUNTER27H) +DECLARE_CSR(mhpmcounter28h, CSR_MHPMCOUNTER28H) +DECLARE_CSR(mhpmcounter29h, CSR_MHPMCOUNTER29H) +DECLARE_CSR(mhpmcounter30h, CSR_MHPMCOUNTER30H) +DECLARE_CSR(mhpmcounter31h, CSR_MHPMCOUNTER31H) +#endif +#ifdef DECLARE_CAUSE +DECLARE_CAUSE("misaligned fetch", CAUSE_MISALIGNED_FETCH) +DECLARE_CAUSE("fault fetch", CAUSE_FAULT_FETCH) +DECLARE_CAUSE("illegal instruction", CAUSE_ILLEGAL_INSTRUCTION) +DECLARE_CAUSE("breakpoint", CAUSE_BREAKPOINT) +DECLARE_CAUSE("misaligned load", CAUSE_MISALIGNED_LOAD) +DECLARE_CAUSE("fault load", CAUSE_FAULT_LOAD) +DECLARE_CAUSE("misaligned store", CAUSE_MISALIGNED_STORE) +DECLARE_CAUSE("fault store", CAUSE_FAULT_STORE) +DECLARE_CAUSE("user_ecall", CAUSE_USER_ECALL) +DECLARE_CAUSE("supervisor_ecall", CAUSE_SUPERVISOR_ECALL) +DECLARE_CAUSE("hypervisor_ecall", CAUSE_HYPERVISOR_ECALL) +DECLARE_CAUSE("machine_ecall", CAUSE_MACHINE_ECALL) +#endif diff --git a/fw/bsp/env/entry.S b/fw/bsp/env/entry.S new file mode 100644 index 0000000..1fd2403 --- /dev/null +++ b/fw/bsp/env/entry.S @@ -0,0 +1,97 @@ +// See LICENSE for license details + +#ifndef ENTRY_S +#define ENTRY_S + +#include "encoding.h" +#include "platform/bits.h" + + .section .text.entry + .align 2 + .weak trap_entry +trap_entry: + addi sp, sp, -32*REGBYTES + + STORE x1, 1*REGBYTES(sp) + STORE x2, 2*REGBYTES(sp) + STORE x3, 3*REGBYTES(sp) + STORE x4, 4*REGBYTES(sp) + STORE x5, 5*REGBYTES(sp) + STORE x6, 6*REGBYTES(sp) + STORE x7, 7*REGBYTES(sp) + STORE x8, 8*REGBYTES(sp) + STORE x9, 9*REGBYTES(sp) + STORE x10, 10*REGBYTES(sp) + STORE x11, 11*REGBYTES(sp) + STORE x12, 12*REGBYTES(sp) + STORE x13, 13*REGBYTES(sp) + STORE x14, 14*REGBYTES(sp) + STORE x15, 15*REGBYTES(sp) + STORE x16, 16*REGBYTES(sp) + STORE x17, 17*REGBYTES(sp) + STORE x18, 18*REGBYTES(sp) + STORE x19, 19*REGBYTES(sp) + STORE x20, 20*REGBYTES(sp) + STORE x21, 21*REGBYTES(sp) + STORE x22, 22*REGBYTES(sp) + STORE x23, 23*REGBYTES(sp) + STORE x24, 24*REGBYTES(sp) + STORE x25, 25*REGBYTES(sp) + STORE x26, 26*REGBYTES(sp) + STORE x27, 27*REGBYTES(sp) + STORE x28, 28*REGBYTES(sp) + STORE x29, 29*REGBYTES(sp) + STORE x30, 30*REGBYTES(sp) + STORE x31, 31*REGBYTES(sp) + + csrr a0, mcause + csrr a1, mepc + mv a2, sp + call handle_trap + csrw mepc, a0 + + # Remain in M-mode after mret + li t0, MSTATUS_MPP + csrs mstatus, t0 + + LOAD x1, 1*REGBYTES(sp) + LOAD x2, 2*REGBYTES(sp) + LOAD x3, 3*REGBYTES(sp) + LOAD x4, 4*REGBYTES(sp) + LOAD x5, 5*REGBYTES(sp) + LOAD x6, 6*REGBYTES(sp) + LOAD x7, 7*REGBYTES(sp) + LOAD x8, 8*REGBYTES(sp) + LOAD x9, 9*REGBYTES(sp) + LOAD x10, 10*REGBYTES(sp) + LOAD x11, 11*REGBYTES(sp) + LOAD x12, 12*REGBYTES(sp) + LOAD x13, 13*REGBYTES(sp) + LOAD x14, 14*REGBYTES(sp) + LOAD x15, 15*REGBYTES(sp) + LOAD x16, 16*REGBYTES(sp) + LOAD x17, 17*REGBYTES(sp) + LOAD x18, 18*REGBYTES(sp) + LOAD x19, 19*REGBYTES(sp) + LOAD x20, 20*REGBYTES(sp) + LOAD x21, 21*REGBYTES(sp) + LOAD x22, 22*REGBYTES(sp) + LOAD x23, 23*REGBYTES(sp) + LOAD x24, 24*REGBYTES(sp) + LOAD x25, 25*REGBYTES(sp) + LOAD x26, 26*REGBYTES(sp) + LOAD x27, 27*REGBYTES(sp) + LOAD x28, 28*REGBYTES(sp) + LOAD x29, 29*REGBYTES(sp) + LOAD x30, 30*REGBYTES(sp) + LOAD x31, 31*REGBYTES(sp) + + addi sp, sp, 32*REGBYTES + mret + +.weak handle_trap +handle_trap: +1: + j 1b + +#endif diff --git a/fw/bsp/env/start.S b/fw/bsp/env/start.S new file mode 100644 index 0000000..8932ee5 --- /dev/null +++ b/fw/bsp/env/start.S @@ -0,0 +1,90 @@ +// See LICENSE for license details. +#include + +/* This is defined in sifive/platform.h, but that can't be included from + * assembly. */ +#define CLINT_CTRL_ADDR 0x02000000 + + .section .init + .globl _start + .type _start,@function + +_start: + .cfi_startproc + .cfi_undefined ra +.option push +.option norelax + la gp, __global_pointer$ +.option pop + la sp, _sp + la a5, trap_entry + csrw mtvec,a5 + /* Load data section */ + la a0, _data_lma + la a1, _data + la a2, _edata + bgeu a1, a2, 2f +1: + lw t0, (a0) + sw t0, (a1) + addi a0, a0, 4 + addi a1, a1, 4 + bltu a1, a2, 1b +2: + + /* Clear bss section */ + la a0, __bss_start + la a1, _end + bgeu a0, a1, 2f +1: + sw zero, (a0) + addi a0, a0, 4 + bltu a0, a1, 1b +2: + + /* Call global constructors */ + la a0, __libc_fini_array + call atexit + call __libc_init_array + + auipc ra, 0 + addi sp, sp, -16 +#if __riscv_xlen == 32 + sw ra, 8(sp) +#else + sd ra, 8(sp) +#endif + + /* argc = argv = 0 */ + li a0, 0 + li a1, 0 + call main + tail exit +1: + j 1b + +#if defined(ENABLE_SMP) +2: + la t0, trap_entry + csrw mtvec, t0 + + csrr a0, mhartid + la t1, _sp + slli t0, a0, 10 + sub sp, t1, t0 + + auipc ra, 0 + addi sp, sp, -16 +#if __riscv_xlen == 32 + sw ra, 8(sp) +#else + sd ra, 8(sp) +#endif + + call secondary_main + tail exit + +1: + j 1b +#endif + .cfi_endproc diff --git a/fw/bsp/env/tgfs-vp/dhrystone.lds b/fw/bsp/env/tgfs-vp/dhrystone.lds new file mode 100644 index 0000000..cc9cd9b --- /dev/null +++ b/fw/bsp/env/tgfs-vp/dhrystone.lds @@ -0,0 +1,157 @@ +OUTPUT_ARCH( "riscv" ) + +ENTRY( _start ) + +MEMORY +{ + flash (rxai!w) : ORIGIN = 0x20400000, LENGTH = 512M + ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 16K +} + +PHDRS +{ + flash PT_LOAD; + ram_init PT_LOAD; + ram PT_NULL; +} + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 2K; + + .init : + { + KEEP (*(SORT_NONE(.init))) + } >flash AT>flash :flash + + .text : + { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >flash AT>flash :flash + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >flash AT>flash :flash + + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + . = ALIGN(4); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >flash AT>flash :flash + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >flash AT>flash :flash + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >flash AT>flash :flash + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >flash AT>flash :flash + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >flash AT>flash :flash + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + } >flash AT>flash :flash + + .dalign : + { + . = ALIGN(4); + PROVIDE( _data = . ); + } >ram AT>flash :ram_init + + .data : + { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram AT>flash :ram_init + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram AT>ram :ram + + . = ALIGN(8); + PROVIDE( _end = . ); + PROVIDE( end = . ); + + .stack ORIGIN(ram) + LENGTH(ram) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = __stack_size; + PROVIDE( _sp = . ); + } >ram AT>ram :ram +} diff --git a/fw/bsp/env/tgfs-vp/flash.lds b/fw/bsp/env/tgfs-vp/flash.lds new file mode 100644 index 0000000..6b37141 --- /dev/null +++ b/fw/bsp/env/tgfs-vp/flash.lds @@ -0,0 +1,161 @@ +OUTPUT_ARCH( "riscv" ) + +ENTRY( _start ) + +MEMORY +{ + flash (rxai!w) : ORIGIN = 0x20400000, LENGTH = 512M + ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 16K +} + +PHDRS +{ + flash PT_LOAD; + ram_init PT_LOAD; + ram PT_NULL; +} + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 2K; + + .init : + { + KEEP (*(SORT_NONE(.init))) + } >flash AT>flash :flash + + .text : + { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >flash AT>flash :flash + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >flash AT>flash :flash + + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + .rodata : + { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + } >flash AT>flash :flash + + . = ALIGN(4); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >flash AT>flash :flash + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >flash AT>flash :flash + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >flash AT>flash :flash + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >flash AT>flash :flash + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >flash AT>flash :flash + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + } >flash AT>flash :flash + + .dalign : + { + . = ALIGN(4); + PROVIDE( _data = . ); + } >ram AT>flash :ram_init + + .data : + { + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram AT>flash :ram_init + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram AT>ram :ram + + . = ALIGN(8); + PROVIDE( _end = . ); + PROVIDE( end = . ); + + .stack ORIGIN(ram) + LENGTH(ram) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = __stack_size; + PROVIDE( _sp = . ); + } >ram AT>ram :ram +} diff --git a/fw/bsp/env/tgfs-vp/init.c b/fw/bsp/env/tgfs-vp/init.c new file mode 100644 index 0000000..138c5cc --- /dev/null +++ b/fw/bsp/env/tgfs-vp/init.c @@ -0,0 +1,238 @@ +#include +#include +#include + +#include "../tgfs-vp/platform.h" +#include "encoding.h" + +extern int main(int argc, char** argv); +extern void trap_entry(); + +static unsigned long mtime_lo(void) +{ + return *(volatile unsigned long *)(CLINT_CTRL_ADDR + CLINT_MTIME); +} + +#ifdef __riscv32 + +static uint32_t mtime_hi(void) +{ + return *(volatile uint32_t *)(CLINT_CTRL_ADDR + CLINT_MTIME + 4); +} + +uint64_t get_timer_value() +{ + while (1) { + uint32_t hi = mtime_hi(); + uint32_t lo = mtime_lo(); + if (hi == mtime_hi()) + return ((uint64_t)hi << 32) | lo; + } +} + +#else /* __riscv32 */ + +uint64_t get_timer_value() +{ + return mtime_lo(); +} + +#endif + +unsigned long get_timer_freq() +{ + return 32768; +} + +static void use_hfrosc(int div, int trim) +{ + // Make sure the HFROSC is running at its default setting + PRCI_REG(PRCI_HFROSCCFG) = (ROSC_DIV(div) | ROSC_TRIM(trim) | ROSC_EN(1)); + while ((PRCI_REG(PRCI_HFROSCCFG) & ROSC_RDY(1)) == 0) ; + PRCI_REG(PRCI_PLLCFG) &= ~PLL_SEL(1); +} + +static void use_pll(int refsel, int bypass, int r, int f, int q) +{ + // Ensure that we aren't running off the PLL before we mess with it. + if (PRCI_REG(PRCI_PLLCFG) & PLL_SEL(1)) { + // Make sure the HFROSC is running at its default setting + use_hfrosc(4, 16); + } + + // Set PLL Source to be HFXOSC if available. + uint32_t config_value = 0; + + config_value |= PLL_REFSEL(refsel); + + if (bypass) { + // Bypass + config_value |= PLL_BYPASS(1); + + PRCI_REG(PRCI_PLLCFG) = config_value; + + // If we don't have an HFXTAL, this doesn't really matter. + // Set our Final output divide to divide-by-1: + PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV_BY_1(1) | PLL_FINAL_DIV(0)); + } else { + // In case we are executing from QSPI, + // (which is quite likely) we need to + // set the QSPI clock divider appropriately + // before boosting the clock frequency. + + // Div = f_sck/2 + SPI0_REG(SPI_REG_SCKDIV) = 8; + + // Set DIV Settings for PLL + // Both HFROSC and HFXOSC are modeled as ideal + // 16MHz sources (assuming dividers are set properly for + // HFROSC). + // (Legal values of f_REF are 6-48MHz) + + // Set DIVR to divide-by-2 to get 8MHz frequency + // (legal values of f_R are 6-12 MHz) + + config_value |= PLL_BYPASS(1); + config_value |= PLL_R(r); + + // Set DIVF to get 512Mhz frequncy + // There is an implied multiply-by-2, 16Mhz. + // So need to write 32-1 + // (legal values of f_F are 384-768 MHz) + config_value |= PLL_F(f); + + // Set DIVQ to divide-by-2 to get 256 MHz frequency + // (legal values of f_Q are 50-400Mhz) + config_value |= PLL_Q(q); + + // Set our Final output divide to divide-by-1: + PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV_BY_1(1) | PLL_FINAL_DIV(0)); + + PRCI_REG(PRCI_PLLCFG) = config_value; + + // Un-Bypass the PLL. + PRCI_REG(PRCI_PLLCFG) &= ~PLL_BYPASS(1); + + // Wait for PLL Lock + // Note that the Lock signal can be glitchy. + // Need to wait 100 us + // RTC is running at 32kHz. + // So wait 4 ticks of RTC. + uint32_t now = mtime_lo(); + while (mtime_lo() - now < 4) ; + + // Now it is safe to check for PLL Lock + while ((PRCI_REG(PRCI_PLLCFG) & PLL_LOCK(1)) == 0) ; + } + + // Switch over to PLL Clock source + PRCI_REG(PRCI_PLLCFG) |= PLL_SEL(1); +} + +static void use_default_clocks() +{ + // Turn off the LFROSC + AON_REG(AON_LFROSC) &= ~ROSC_EN(1); + + // Use HFROSC + use_hfrosc(4, 16); +} + +static unsigned long __attribute__((noinline)) measure_cpu_freq(size_t n) +{ + unsigned long start_mtime, delta_mtime; + unsigned long mtime_freq = get_timer_freq(); + + // Don't start measuruing until we see an mtime tick + unsigned long tmp = mtime_lo(); + do { + start_mtime = mtime_lo(); + } while (start_mtime == tmp); + + unsigned long start_mcycle = read_csr(mcycle); + + do { + delta_mtime = mtime_lo() - start_mtime; + } while (delta_mtime < n); + + unsigned long delta_mcycle = read_csr(mcycle) - start_mcycle; + + return (delta_mcycle / delta_mtime) * mtime_freq + + ((delta_mcycle % delta_mtime) * mtime_freq) / delta_mtime; +} + +unsigned long get_cpu_freq() +{ + static uint32_t cpu_freq; + + if (!cpu_freq) { + // warm up I$ + measure_cpu_freq(1); + // measure for real + cpu_freq = measure_cpu_freq(10); + } + + return cpu_freq; +} + +static void uart_init(size_t baud_rate) +{ + GPIO_REG(GPIO_IOF_SEL) &= ~IOF0_UART0_MASK; + GPIO_REG(GPIO_IOF_EN) |= IOF0_UART0_MASK; + UART0_REG(UART_REG_DIV) = get_cpu_freq() / baud_rate - 1; + UART0_REG(UART_REG_TXCTRL) |= UART_TXEN; +} + + + +#ifdef USE_PLIC +extern void handle_m_ext_interrupt(); +#endif + +#ifdef USE_M_TIME +extern void handle_m_time_interrupt(); +#endif + +uintptr_t handle_trap(uintptr_t mcause, uintptr_t epc) +{ + if (0){ +#ifdef USE_PLIC + // External Machine-Level interrupt from PLIC + } else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT)) { + handle_m_ext_interrupt(); +#endif +#ifdef USE_M_TIME + // External Machine-Level interrupt from PLIC + } else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_TIMER)){ + handle_m_time_interrupt(); +#endif + } + else { + write(1, "trap\n", 5); + _exit(1 + mcause); + } + return epc; +} + +void _init() +{ + + #ifndef NO_INIT + use_default_clocks(); + use_pll(0, 0, 1, 31, 1); + uart_init(115200); + + printf("core freq at %lu Hz\n", get_cpu_freq()); + + write_csr(mtvec, &trap_entry); + if (read_csr(misa) & (1 << ('F' - 'A'))) { // if F extension is present + write_csr(mstatus, MSTATUS_FS); // allow FPU instructions without trapping + write_csr(fcsr, 0); // initialize rounding mode, undefined at reset + } + #endif + +} + +void _fini() +{ +} diff --git a/fw/bsp/env/tgfs-vp/openocd.cfg b/fw/bsp/env/tgfs-vp/openocd.cfg new file mode 100644 index 0000000..b531e9c --- /dev/null +++ b/fw/bsp/env/tgfs-vp/openocd.cfg @@ -0,0 +1,34 @@ +adapter_khz 10000 + +interface ftdi +ftdi_device_desc "Dual RS232-HS" +ftdi_vid_pid 0x0403 0x6010 + +ftdi_layout_init 0x0008 0x001b +ftdi_layout_signal nSRST -oe 0x0020 -data 0x0020 + +#Reset Stretcher logic on FE310 is ~1 second long +#This doesn't apply if you use +# ftdi_set_signal, but still good to document +#adapter_nsrst_delay 1500 + +set _CHIPNAME riscv +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913 + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME riscv -chain-position $_TARGETNAME +$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1 + +flash bank onboard_spi_flash fespi 0x20000000 0 0 0 $_TARGETNAME +init +#reset -- This type of reset is not implemented yet +if {[ info exists pulse_srst]} { + ftdi_set_signal nSRST 0 + ftdi_set_signal nSRST z + #Wait for the reset stretcher + #It will work without this, but + #will incur lots of delays for later commands. + sleep 1500 +} +halt +#flash protect 0 64 last off diff --git a/fw/bsp/env/tgfs-vp/platform.h b/fw/bsp/env/tgfs-vp/platform.h new file mode 100644 index 0000000..6aa4296 --- /dev/null +++ b/fw/bsp/env/tgfs-vp/platform.h @@ -0,0 +1,133 @@ +// See LICENSE for license details. + +#ifndef _SIFIVE_PLATFORM_H +#define _SIFIVE_PLATFORM_H + +// Some things missing from the official encoding.h +#define MCAUSE_INT 0x80000000 +#define MCAUSE_CAUSE 0x7FFFFFFF + +#include "../../include/platform/const.h" +#include "../../include/platform/devices/aon.h" +#include "../../include/platform/devices/clint.h" +#include "../../include/platform/devices/gpio.h" +#include "../../include/platform/devices/otp.h" +#include "../../include/platform/devices/plic.h" +#include "../../include/platform/devices/prci.h" +#include "../../include/platform/devices/pwm.h" +#include "../../include/platform/devices/spi.h" +#include "../../include/platform/devices/uart.h" + +/**************************************************************************** + * Platform definitions + *****************************************************************************/ + +// Memory map +#define MASKROM_MEM_ADDR _AC(0x00001000,UL) +#define TRAPVEC_TABLE_CTRL_ADDR _AC(0x00001010,UL) +#define OTP_MEM_ADDR _AC(0x00020000,UL) +#define CLINT_CTRL_ADDR _AC(0x02000000,UL) +#define PLIC_CTRL_ADDR _AC(0x0C000000,UL) +#define AON_CTRL_ADDR _AC(0x10000000,UL) +#define PRCI_CTRL_ADDR _AC(0x10008000,UL) +#define OTP_CTRL_ADDR _AC(0x10010000,UL) +#define GPIO_CTRL_ADDR _AC(0x10012000,UL) +#define UART0_CTRL_ADDR _AC(0x10013000,UL) +#define SPI0_CTRL_ADDR _AC(0x10014000,UL) +#define PWM0_CTRL_ADDR _AC(0x10015000,UL) +#define UART1_CTRL_ADDR _AC(0x10023000,UL) +#define SPI1_CTRL_ADDR _AC(0x10024000,UL) +#define PWM1_CTRL_ADDR _AC(0x10025000,UL) +#define SPI2_CTRL_ADDR _AC(0x10034000,UL) +#define PWM2_CTRL_ADDR _AC(0x10035000,UL) +#define SPI0_MEM_ADDR _AC(0x20000000,UL) +#define MEM_CTRL_ADDR _AC(0x80000000,UL) + +// IOF masks +#define IOF0_SPI1_MASK _AC(0x000007FC,UL) +#define SPI11_NUM_SS (4) +#define IOF_SPI1_SS0 (2u) +#define IOF_SPI1_SS1 (8u) +#define IOF_SPI1_SS2 (9u) +#define IOF_SPI1_SS3 (10u) +#define IOF_SPI1_MOSI (3u) +#define IOF_SPI1_MISO (4u) +#define IOF_SPI1_SCK (5u) +#define IOF_SPI1_DQ0 (3u) +#define IOF_SPI1_DQ1 (4u) +#define IOF_SPI1_DQ2 (6u) +#define IOF_SPI1_DQ3 (7u) + +#define IOF0_SPI2_MASK _AC(0xFC000000,UL) +#define SPI2_NUM_SS (1) +#define IOF_SPI2_SS0 (26u) +#define IOF_SPI2_MOSI (27u) +#define IOF_SPI2_MISO (28u) +#define IOF_SPI2_SCK (29u) +#define IOF_SPI2_DQ0 (27u) +#define IOF_SPI2_DQ1 (28u) +#define IOF_SPI2_DQ2 (30u) +#define IOF_SPI2_DQ3 (31u) + +//#define IOF0_I2C_MASK _AC(0x00003000,UL) + +#define IOF0_UART0_MASK _AC(0x00030000, UL) +#define IOF_UART0_RX (16u) +#define IOF_UART0_TX (17u) + +#define IOF0_UART1_MASK _AC(0x03000000, UL) +#define IOF_UART1_RX (24u) +#define IOF_UART1_TX (25u) + +#define IOF1_PWM0_MASK _AC(0x0000000F, UL) +#define IOF1_PWM1_MASK _AC(0x00780000, UL) +#define IOF1_PWM2_MASK _AC(0x00003C00, UL) + +// Interrupt numbers +#define INT_RESERVED 0 +#define INT_WDOGCMP 1 +#define INT_RTCCMP 2 +#define INT_UART0_BASE 3 +#define INT_UART1_BASE 4 +#define INT_SPI0_BASE 5 +#define INT_SPI1_BASE 6 +#define INT_SPI2_BASE 7 +#define INT_GPIO_BASE 8 +#define INT_PWM0_BASE 40 +#define INT_PWM1_BASE 44 +#define INT_PWM2_BASE 48 + +// Helper functions +#define _REG32(p, i) (*(volatile uint32_t *) ((p) + (i))) +#define _REG32P(p, i) ((volatile uint32_t *) ((p) + (i))) +#define AON_REG(offset) _REG32(AON_CTRL_ADDR, offset) +#define CLINT_REG(offset) _REG32(CLINT_CTRL_ADDR, offset) +#define GPIO_REG(offset) _REG32(GPIO_CTRL_ADDR, offset) +#define OTP_REG(offset) _REG32(OTP_CTRL_ADDR, offset) +#define PLIC_REG(offset) _REG32(PLIC_CTRL_ADDR, offset) +#define PRCI_REG(offset) _REG32(PRCI_CTRL_ADDR, offset) +#define PWM0_REG(offset) _REG32(PWM0_CTRL_ADDR, offset) +#define PWM1_REG(offset) _REG32(PWM1_CTRL_ADDR, offset) +#define PWM2_REG(offset) _REG32(PWM2_CTRL_ADDR, offset) +#define SPI0_REG(offset) _REG32(SPI0_CTRL_ADDR, offset) +#define SPI1_REG(offset) _REG32(SPI1_CTRL_ADDR, offset) +#define SPI2_REG(offset) _REG32(SPI2_CTRL_ADDR, offset) +#define UART0_REG(offset) _REG32(UART0_CTRL_ADDR, offset) +#define UART1_REG(offset) _REG32(UART1_CTRL_ADDR, offset) + +// Misc + +#include + +#define NUM_GPIO 32 + +#define PLIC_NUM_INTERRUPTS 52 +#define PLIC_NUM_PRIORITIES 7 + +void write_hex(int fd, unsigned long int hex); + +unsigned long get_cpu_freq(void); +unsigned long get_timer_freq(void); +uint64_t get_timer_value(void); + +#endif /* _SIFIVE_PLATFORM_H */ diff --git a/fw/bsp/env/tgfs-vp/settings.mk b/fw/bsp/env/tgfs-vp/settings.mk new file mode 100644 index 0000000..230fccc --- /dev/null +++ b/fw/bsp/env/tgfs-vp/settings.mk @@ -0,0 +1,3 @@ +# Describes the CPU on this board to the rest of the SDK. +RISCV_ARCH := rv32imac +RISCV_ABI := ilp32 diff --git a/fw/bsp/env/ventry.S b/fw/bsp/env/ventry.S new file mode 100644 index 0000000..5c82c48 --- /dev/null +++ b/fw/bsp/env/ventry.S @@ -0,0 +1,288 @@ +// See LICENSE for license details + +#ifndef VENTRY_S +#define VENTRY_S + +#include "encoding.h" +#include "sifive/bits.h" + +#only save caller registers +.macro TRAP_ENTRY + addi sp, sp, -16*REGBYTES + + STORE x1, 0*REGBYTES(sp) + STORE x5, 1*REGBYTES(sp) + STORE x6, 2*REGBYTES(sp) + STORE x7, 3*REGBYTES(sp) + STORE x10, 4*REGBYTES(sp) + STORE x11, 5*REGBYTES(sp) + STORE x12, 6*REGBYTES(sp) + STORE x13, 7*REGBYTES(sp) + STORE x14, 8*REGBYTES(sp) + STORE x15, 9*REGBYTES(sp) + STORE x16, 10*REGBYTES(sp) + STORE x17, 11*REGBYTES(sp) + STORE x28, 12*REGBYTES(sp) + STORE x29, 13*REGBYTES(sp) + STORE x30, 14*REGBYTES(sp) + STORE x31, 15*REGBYTES(sp) +.endm + +#restore caller registers +.macro TRAP_EXIT +# Remain in M-mode after mret + li t0, MSTATUS_MPP + csrs mstatus, t0 + + LOAD x1, 0*REGBYTES(sp) + LOAD x5, 1*REGBYTES(sp) + LOAD x6, 2*REGBYTES(sp) + LOAD x7, 3*REGBYTES(sp) + LOAD x10, 4*REGBYTES(sp) + LOAD x11, 5*REGBYTES(sp) + LOAD x12, 6*REGBYTES(sp) + LOAD x13, 7*REGBYTES(sp) + LOAD x14, 8*REGBYTES(sp) + LOAD x15, 9*REGBYTES(sp) + LOAD x16, 10*REGBYTES(sp) + LOAD x17, 11*REGBYTES(sp) + LOAD x28, 12*REGBYTES(sp) + LOAD x29, 13*REGBYTES(sp) + LOAD x30, 14*REGBYTES(sp) + LOAD x31, 15*REGBYTES(sp) + + addi sp, sp, 16*REGBYTES + mret +.endm + + + +#Vector table for E31/E51 + + .section .text.entry + .align 8 + .global vtrap_entry +vtrap_entry: + j sync_trap + .align 2 + j reserved + .align 2 + j reserved + .align 2 + j vmsi_Handler + .align 2 + j reserved + .align 2 + j reserved + .align 2 + j reserved + .align 2 + j vmti_Handler + .align 2 + j reserved + .align 2 + j reserved + .align 2 + j reserved + .align 2 + j vmei_Handler + .align 2 + j reserved + .align 2 + j reserved + .align 2 + j reserved + .align 2 + j reserved + .align 2 + j vlip_Handler0 + .align 2 + j vlip_Handler1 + .align 2 + j vlip_Handler2 + .align 2 + j vlip_Handler3 + .align 2 + j vlip_Handler4 + .align 2 + j vlip_Handler5 + .align 2 + j vlip_Handler6 + .align 2 + j vlip_Handler7 + .align 2 + j vlip_Handler8 + .align 2 + j vlip_Handler9 + .align 2 + j vlip_Handler10 + .align 2 + j vlip_Handler11 + .align 2 + j vlip_Handler12 + .align 2 + j vlip_Handler13 + .align 2 + j vlip_Handler14 + .align 2 + j vlip_Handler15 + +#synchronous trap +sync_trap: + TRAP_ENTRY + jal handle_sync_trap + TRAP_EXIT + +#Machine Software Interrupt +vmsi_Handler: + TRAP_ENTRY + jal reserved + TRAP_EXIT + +#Machine Timer Interrupt +vmti_Handler: + TRAP_ENTRY + jal handle_m_time_interrupt + TRAP_EXIT + +#Machine External Interrupt +vmei_Handler: + TRAP_ENTRY + jal handle_m_external_interrupt + TRAP_EXIT + +#LIP0 +vlip_Handler0: + TRAP_ENTRY + jal handle_local_interrupt0 + TRAP_EXIT + +#LIP1 +vlip_Handler1: + TRAP_ENTRY + jal handle_local_interrupt1 + TRAP_EXIT + +#LIP2 +vlip_Handler2: + TRAP_ENTRY + jal handle_local_interrupt2 + TRAP_EXIT + +#LIP3 +vlip_Handler3: + TRAP_ENTRY + jal handle_local_interrupt3 + TRAP_EXIT + +#LIP4 +vlip_Handler4: + TRAP_ENTRY + jal handle_local_interrupt4 + TRAP_EXIT + +#LIP5 +vlip_Handler5: + TRAP_ENTRY + jal handle_local_interrupt5 + TRAP_EXIT + +#LIP6 +vlip_Handler6: + TRAP_ENTRY + jal handle_local_interrupt6 + TRAP_EXIT + +#LIP7 +vlip_Handler7: + TRAP_ENTRY + jal handle_local_interrupt7 + TRAP_EXIT + +#LIP8 +vlip_Handler8: + TRAP_ENTRY + jal handle_local_interrupt8 + TRAP_EXIT + +#LIP9 +vlip_Handler9: + TRAP_ENTRY + jal handle_local_interrupt9 + TRAP_EXIT + +#LIP10 +vlip_Handler10: + TRAP_ENTRY + jal handle_local_interrupt10 + TRAP_EXIT + +#LIP11 +vlip_Handler11: + TRAP_ENTRY + jal handle_local_interrupt11 + TRAP_EXIT + +#LIP12 +vlip_Handler12: + TRAP_ENTRY + jal handle_local_interrupt12 + TRAP_EXIT + +#LIP13 +vlip_Handler13: + TRAP_ENTRY + jal handle_local_interrupt13 + TRAP_EXIT + +#LIP14 +vlip_Handler14: + TRAP_ENTRY + jal handle_local_interrupt14 + TRAP_EXIT + +#LIP15 +vlip_Handler15: + TRAP_ENTRY + jal handle_local_interrupt15 + TRAP_EXIT + +#unimplemented ISRs trap here +.weak reserved +reserved: +.weak handle_local_interrupt0 +handle_local_interrupt0: +.weak handle_local_interrupt1 +handle_local_interrupt1: +.weak handle_local_interrupt2 +handle_local_interrupt2: +.weak handle_local_interrupt3 +handle_local_interrupt3: +.weak handle_local_interrupt4 +handle_local_interrupt4: +.weak handle_local_interrupt5 +handle_local_interrupt5: +.weak handle_local_interrupt6 +handle_local_interrupt6: +.weak handle_local_interrupt7 +handle_local_interrupt7: +.weak handle_local_interrupt8 +handle_local_interrupt8: +.weak handle_local_interrupt9 +handle_local_interrupt9: +.weak handle_local_interrupt10 +handle_local_interrupt10: +.weak handle_local_interrupt11 +handle_local_interrupt11: +.weak handle_local_interrupt12 +handle_local_interrupt12: +.weak handle_local_interrupt13 +handle_local_interrupt13: +.weak handle_local_interrupt14 +handle_local_interrupt14: +.weak handle_local_interrupt15 +handle_local_interrupt15: +1: + j 1b + +#endif diff --git a/fw/bsp/include/platform/bits.h b/fw/bsp/include/platform/bits.h new file mode 100644 index 0000000..bfe656f --- /dev/null +++ b/fw/bsp/include/platform/bits.h @@ -0,0 +1,36 @@ +// See LICENSE for license details. +#ifndef _RISCV_BITS_H +#define _RISCV_BITS_H + +#define likely(x) __builtin_expect((x), 1) +#define unlikely(x) __builtin_expect((x), 0) + +#define ROUNDUP(a, b) ((((a)-1)/(b)+1)*(b)) +#define ROUNDDOWN(a, b) ((a)/(b)*(b)) + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define CLAMP(a, lo, hi) MIN(MAX(a, lo), hi) + +#define EXTRACT_FIELD(val, which) (((val) & (which)) / ((which) & ~((which)-1))) +#define INSERT_FIELD(val, which, fieldval) (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1)))) + +#define STR(x) XSTR(x) +#define XSTR(x) #x + +#if __riscv_xlen == 64 +# define SLL32 sllw +# define STORE sd +# define LOAD ld +# define LWU lwu +# define LOG_REGBYTES 3 +#else +# define SLL32 sll +# define STORE sw +# define LOAD lw +# define LWU lw +# define LOG_REGBYTES 2 +#endif +#define REGBYTES (1 << LOG_REGBYTES) + +#endif diff --git a/fw/bsp/include/platform/const.h b/fw/bsp/include/platform/const.h new file mode 100644 index 0000000..8dcffbb --- /dev/null +++ b/fw/bsp/include/platform/const.h @@ -0,0 +1,18 @@ +// See LICENSE for license details. +/* Derived from */ + +#ifndef _SIFIVE_CONST_H +#define _SIFIVE_CONST_H + +#ifdef __ASSEMBLER__ +#define _AC(X,Y) X +#define _AT(T,X) X +#else +#define _AC(X,Y) (X##Y) +#define _AT(T,X) ((T)(X)) +#endif /* !__ASSEMBLER__*/ + +#define _BITUL(x) (_AC(1,UL) << (x)) +#define _BITULL(x) (_AC(1,ULL) << (x)) + +#endif /* _SIFIVE_CONST_H */ diff --git a/fw/bsp/include/platform/devices/aon.h b/fw/bsp/include/platform/devices/aon.h new file mode 100644 index 0000000..63f1db3 --- /dev/null +++ b/fw/bsp/include/platform/devices/aon.h @@ -0,0 +1,88 @@ +// See LICENSE for license details. + +#ifndef _SIFIVE_AON_H +#define _SIFIVE_AON_H + +/* Register offsets */ + +#define AON_WDOGCFG 0x000 +#define AON_WDOGCOUNT 0x008 +#define AON_WDOGS 0x010 +#define AON_WDOGFEED 0x018 +#define AON_WDOGKEY 0x01C +#define AON_WDOGCMP 0x020 + +#define AON_RTCCFG 0x040 +#define AON_RTCLO 0x048 +#define AON_RTCHI 0x04C +#define AON_RTCS 0x050 +#define AON_RTCCMP 0x060 + +#define AON_BACKUP0 0x080 +#define AON_BACKUP1 0x084 +#define AON_BACKUP2 0x088 +#define AON_BACKUP3 0x08C +#define AON_BACKUP4 0x090 +#define AON_BACKUP5 0x094 +#define AON_BACKUP6 0x098 +#define AON_BACKUP7 0x09C +#define AON_BACKUP8 0x0A0 +#define AON_BACKUP9 0x0A4 +#define AON_BACKUP10 0x0A8 +#define AON_BACKUP11 0x0AC +#define AON_BACKUP12 0x0B0 +#define AON_BACKUP13 0x0B4 +#define AON_BACKUP14 0x0B8 +#define AON_BACKUP15 0x0BC + +#define AON_PMUWAKEUPI0 0x100 +#define AON_PMUWAKEUPI1 0x104 +#define AON_PMUWAKEUPI2 0x108 +#define AON_PMUWAKEUPI3 0x10C +#define AON_PMUWAKEUPI4 0x110 +#define AON_PMUWAKEUPI5 0x114 +#define AON_PMUWAKEUPI6 0x118 +#define AON_PMUWAKEUPI7 0x11C +#define AON_PMUSLEEPI0 0x120 +#define AON_PMUSLEEPI1 0x124 +#define AON_PMUSLEEPI2 0x128 +#define AON_PMUSLEEPI3 0x12C +#define AON_PMUSLEEPI4 0x130 +#define AON_PMUSLEEPI5 0x134 +#define AON_PMUSLEEPI6 0x138 +#define AON_PMUSLEEPI7 0x13C +#define AON_PMUIE 0x140 +#define AON_PMUCAUSE 0x144 +#define AON_PMUSLEEP 0x148 +#define AON_PMUKEY 0x14C + +#define AON_LFROSC 0x070 +/* Constants */ + +#define AON_WDOGKEY_VALUE 0x51F15E +#define AON_WDOGFEED_VALUE 0xD09F00D + +#define AON_WDOGCFG_SCALE 0x0000000F +#define AON_WDOGCFG_RSTEN 0x00000100 +#define AON_WDOGCFG_ZEROCMP 0x00000200 +#define AON_WDOGCFG_ENALWAYS 0x00001000 +#define AON_WDOGCFG_ENCOREAWAKE 0x00002000 +#define AON_WDOGCFG_CMPIP 0x10000000 + +#define AON_RTCCFG_SCALE 0x0000000F +#define AON_RTCCFG_ENALWAYS 0x00001000 +#define AON_RTCCFG_CMPIP 0x10000000 + +#define AON_WAKEUPCAUSE_RESET 0x00 +#define AON_WAKEUPCAUSE_RTC 0x01 +#define AON_WAKEUPCAUSE_DWAKEUP 0x02 +#define AON_WAKEUPCAUSE_AWAKEUP 0x03 + +#define AON_RESETCAUSE_POWERON 0x0000 +#define AON_RESETCAUSE_EXTERNAL 0x0100 +#define AON_RESETCAUSE_WATCHDOG 0x0200 + +#define AON_PMUCAUSE_WAKEUPCAUSE 0x00FF +#define AON_PMUCAUSE_RESETCAUSE 0xFF00 + +#endif /* _SIFIVE_AON_H */ diff --git a/fw/bsp/include/platform/devices/clic.h b/fw/bsp/include/platform/devices/clic.h new file mode 100644 index 0000000..e8dc2df --- /dev/null +++ b/fw/bsp/include/platform/devices/clic.h @@ -0,0 +1,30 @@ +// See LICENSE for license details. + +#ifndef _SIFIVE_CLIC_H +#define _SIFIVE_CLIC_H + +#define CLIC_HART0 0x00800000 +#define CLIC_MSIP 0x0000 +#define CLIC_MSIP_size 0x4 +#define CLIC_MTIMECMP 0x4000 +#define CLIC_MTIMECMP_size 0x8 +#define CLIC_MTIME 0xBFF8 +#define CLIC_MTIME_size 0x8 + +#define CLIC_INTIP 0x000 +#define CLIC_INTIE 0x400 +#define CLIC_INTCFG 0x800 +#define CLIC_CFG 0xc00 + +// These interrupt IDs are consistent across old and new mtvec modes +#define SSIPID 1 +#define MSIPID 3 +#define STIPID 5 +#define MTIPID 7 +#define SEIPID 9 +#define MEIPID 11 +#define CSIPID 12 +#define LOCALINTIDBASE 16 + + +#endif /* _SIFIVE_CLIC_H */ diff --git a/fw/bsp/include/platform/devices/clint.h b/fw/bsp/include/platform/devices/clint.h new file mode 100644 index 0000000..cd3e0c7 --- /dev/null +++ b/fw/bsp/include/platform/devices/clint.h @@ -0,0 +1,14 @@ +// See LICENSE for license details + +#ifndef _SIFIVE_CLINT_H +#define _SIFIVE_CLINT_H + + +#define CLINT_MSIP 0x0000 +#define CLINT_MSIP_size 0x4 +#define CLINT_MTIMECMP 0x4000 +#define CLINT_MTIMECMP_size 0x8 +#define CLINT_MTIME 0xBFF8 +#define CLINT_MTIME_size 0x8 + +#endif /* _SIFIVE_CLINT_H */ diff --git a/fw/bsp/include/platform/devices/gpio.h b/fw/bsp/include/platform/devices/gpio.h new file mode 100644 index 0000000..f7f0acb --- /dev/null +++ b/fw/bsp/include/platform/devices/gpio.h @@ -0,0 +1,24 @@ +// See LICENSE for license details. + +#ifndef _SIFIVE_GPIO_H +#define _SIFIVE_GPIO_H + +#define GPIO_INPUT_VAL (0x00) +#define GPIO_INPUT_EN (0x04) +#define GPIO_OUTPUT_EN (0x08) +#define GPIO_OUTPUT_VAL (0x0C) +#define GPIO_PULLUP_EN (0x10) +#define GPIO_DRIVE (0x14) +#define GPIO_RISE_IE (0x18) +#define GPIO_RISE_IP (0x1C) +#define GPIO_FALL_IE (0x20) +#define GPIO_FALL_IP (0x24) +#define GPIO_HIGH_IE (0x28) +#define GPIO_HIGH_IP (0x2C) +#define GPIO_LOW_IE (0x30) +#define GPIO_LOW_IP (0x34) +#define GPIO_IOF_EN (0x38) +#define GPIO_IOF_SEL (0x3C) +#define GPIO_OUTPUT_XOR (0x40) + +#endif /* _SIFIVE_GPIO_H */ diff --git a/fw/bsp/include/platform/devices/otp.h b/fw/bsp/include/platform/devices/otp.h new file mode 100644 index 0000000..93833e2 --- /dev/null +++ b/fw/bsp/include/platform/devices/otp.h @@ -0,0 +1,23 @@ +// See LICENSE for license details. + +#ifndef _SIFIVE_OTP_H +#define _SIFIVE_OTP_H + +/* Register offsets */ + +#define OTP_LOCK 0x00 +#define OTP_CK 0x04 +#define OTP_OE 0x08 +#define OTP_SEL 0x0C +#define OTP_WE 0x10 +#define OTP_MR 0x14 +#define OTP_MRR 0x18 +#define OTP_MPP 0x1C +#define OTP_VRREN 0x20 +#define OTP_VPPEN 0x24 +#define OTP_A 0x28 +#define OTP_D 0x2C +#define OTP_Q 0x30 +#define OTP_READ_TIMINGS 0x34 + +#endif diff --git a/fw/bsp/include/platform/devices/plic.h b/fw/bsp/include/platform/devices/plic.h new file mode 100644 index 0000000..74edecc --- /dev/null +++ b/fw/bsp/include/platform/devices/plic.h @@ -0,0 +1,31 @@ +// See LICENSE for license details. + +#ifndef PLIC_H +#define PLIC_H + +#include "../../platform/const.h" + +// 32 bits per source +#define PLIC_PRIORITY_OFFSET _AC(0x0000,UL) +#define PLIC_PRIORITY_SHIFT_PER_SOURCE 2 +// 1 bit per source (1 address) +#define PLIC_PENDING_OFFSET _AC(0x1000,UL) +#define PLIC_PENDING_SHIFT_PER_SOURCE 0 + +//0x80 per target +#define PLIC_ENABLE_OFFSET _AC(0x2000,UL) +#define PLIC_ENABLE_SHIFT_PER_TARGET 7 + + +#define PLIC_THRESHOLD_OFFSET _AC(0x200000,UL) +#define PLIC_CLAIM_OFFSET _AC(0x200004,UL) +#define PLIC_THRESHOLD_SHIFT_PER_TARGET 12 +#define PLIC_CLAIM_SHIFT_PER_TARGET 12 + +#define PLIC_MAX_SOURCE 1023 +#define PLIC_SOURCE_MASK 0x3FF + +#define PLIC_MAX_TARGET 15871 +#define PLIC_TARGET_MASK 0x3FFF + +#endif /* PLIC_H */ diff --git a/fw/bsp/include/platform/devices/prci.h b/fw/bsp/include/platform/devices/prci.h new file mode 100644 index 0000000..1a3de58 --- /dev/null +++ b/fw/bsp/include/platform/devices/prci.h @@ -0,0 +1,56 @@ +// See LICENSE for license details. + +#ifndef _SIFIVE_PRCI_H +#define _SIFIVE_PRCI_H + +/* Register offsets */ + +#define PRCI_HFROSCCFG (0x0000) +#define PRCI_HFXOSCCFG (0x0004) +#define PRCI_PLLCFG (0x0008) +#define PRCI_PLLDIV (0x000C) +#define PRCI_PROCMONCFG (0x00F0) + +/* Fields */ +#define ROSC_DIV(x) (((x) & 0x2F) << 0 ) +#define ROSC_TRIM(x) (((x) & 0x1F) << 16) +#define ROSC_EN(x) (((x) & 0x1 ) << 30) +#define ROSC_RDY(x) (((x) & 0x1 ) << 31) + +#define XOSC_EN(x) (((x) & 0x1) << 30) +#define XOSC_RDY(x) (((x) & 0x1) << 31) + +#define PLL_R(x) (((x) & 0x7) << 0) +// single reserved bit for F LSB. +#define PLL_F(x) (((x) & 0x3F) << 4) +#define PLL_Q(x) (((x) & 0x3) << 10) +#define PLL_SEL(x) (((x) & 0x1) << 16) +#define PLL_REFSEL(x) (((x) & 0x1) << 17) +#define PLL_BYPASS(x) (((x) & 0x1) << 18) +#define PLL_LOCK(x) (((x) & 0x1) << 31) + +#define PLL_R_default 0x1 +#define PLL_F_default 0x1F +#define PLL_Q_default 0x3 + +#define PLL_REFSEL_HFROSC 0x0 +#define PLL_REFSEL_HFXOSC 0x1 + +#define PLL_SEL_HFROSC 0x0 +#define PLL_SEL_PLL 0x1 + +#define PLL_FINAL_DIV(x) (((x) & 0x3F) << 0) +#define PLL_FINAL_DIV_BY_1(x) (((x) & 0x1 ) << 8) + +#define PROCMON_DIV(x) (((x) & 0x1F) << 0) +#define PROCMON_TRIM(x) (((x) & 0x1F) << 8) +#define PROCMON_EN(x) (((x) & 0x1) << 16) +#define PROCMON_SEL(x) (((x) & 0x3) << 24) +#define PROCMON_NT_EN(x) (((x) & 0x1) << 28) + +#define PROCMON_SEL_HFCLK 0 +#define PROCMON_SEL_HFXOSCIN 1 +#define PROCMON_SEL_PLLOUTDIV 2 +#define PROCMON_SEL_PROCMON 3 + +#endif // _SIFIVE_PRCI_H diff --git a/fw/bsp/include/platform/devices/pwm.h b/fw/bsp/include/platform/devices/pwm.h new file mode 100644 index 0000000..067889a --- /dev/null +++ b/fw/bsp/include/platform/devices/pwm.h @@ -0,0 +1,37 @@ +// See LICENSE for license details. + +#ifndef _SIFIVE_PWM_H +#define _SIFIVE_PWM_H + +/* Register offsets */ + +#define PWM_CFG 0x00 +#define PWM_COUNT 0x08 +#define PWM_S 0x10 +#define PWM_CMP0 0x20 +#define PWM_CMP1 0x24 +#define PWM_CMP2 0x28 +#define PWM_CMP3 0x2C + +/* Constants */ + +#define PWM_CFG_SCALE 0x0000000F +#define PWM_CFG_STICKY 0x00000100 +#define PWM_CFG_ZEROCMP 0x00000200 +#define PWM_CFG_DEGLITCH 0x00000400 +#define PWM_CFG_ENALWAYS 0x00001000 +#define PWM_CFG_ONESHOT 0x00002000 +#define PWM_CFG_CMP0CENTER 0x00010000 +#define PWM_CFG_CMP1CENTER 0x00020000 +#define PWM_CFG_CMP2CENTER 0x00040000 +#define PWM_CFG_CMP3CENTER 0x00080000 +#define PWM_CFG_CMP0GANG 0x01000000 +#define PWM_CFG_CMP1GANG 0x02000000 +#define PWM_CFG_CMP2GANG 0x04000000 +#define PWM_CFG_CMP3GANG 0x08000000 +#define PWM_CFG_CMP0IP 0x10000000 +#define PWM_CFG_CMP1IP 0x20000000 +#define PWM_CFG_CMP2IP 0x40000000 +#define PWM_CFG_CMP3IP 0x80000000 + +#endif /* _SIFIVE_PWM_H */ diff --git a/fw/bsp/include/platform/devices/spi.h b/fw/bsp/include/platform/devices/spi.h new file mode 100644 index 0000000..80ef345 --- /dev/null +++ b/fw/bsp/include/platform/devices/spi.h @@ -0,0 +1,80 @@ +// See LICENSE for license details. + +#ifndef _SIFIVE_SPI_H +#define _SIFIVE_SPI_H + +/* Register offsets */ + +#define SPI_REG_SCKDIV 0x00 +#define SPI_REG_SCKMODE 0x04 +#define SPI_REG_CSID 0x10 +#define SPI_REG_CSDEF 0x14 +#define SPI_REG_CSMODE 0x18 + +#define SPI_REG_DCSSCK 0x28 +#define SPI_REG_DSCKCS 0x2a +#define SPI_REG_DINTERCS 0x2c +#define SPI_REG_DINTERXFR 0x2e + +#define SPI_REG_FMT 0x40 +#define SPI_REG_TXFIFO 0x48 +#define SPI_REG_RXFIFO 0x4c +#define SPI_REG_TXCTRL 0x50 +#define SPI_REG_RXCTRL 0x54 + +#define SPI_REG_FCTRL 0x60 +#define SPI_REG_FFMT 0x64 + +#define SPI_REG_IE 0x70 +#define SPI_REG_IP 0x74 + +/* Fields */ + +#define SPI_SCK_PHA 0x1 +#define SPI_SCK_POL 0x2 + +#define SPI_FMT_PROTO(x) ((x) & 0x3) +#define SPI_FMT_ENDIAN(x) (((x) & 0x1) << 2) +#define SPI_FMT_DIR(x) (((x) & 0x1) << 3) +#define SPI_FMT_LEN(x) (((x) & 0xf) << 16) + +/* TXCTRL register */ +#define SPI_TXWM(x) ((x) & 0xffff) +/* RXCTRL register */ +#define SPI_RXWM(x) ((x) & 0xffff) + +#define SPI_IP_TXWM 0x1 +#define SPI_IP_RXWM 0x2 + +#define SPI_FCTRL_EN 0x1 + +#define SPI_INSN_CMD_EN 0x1 +#define SPI_INSN_ADDR_LEN(x) (((x) & 0x7) << 1) +#define SPI_INSN_PAD_CNT(x) (((x) & 0xf) << 4) +#define SPI_INSN_CMD_PROTO(x) (((x) & 0x3) << 8) +#define SPI_INSN_ADDR_PROTO(x) (((x) & 0x3) << 10) +#define SPI_INSN_DATA_PROTO(x) (((x) & 0x3) << 12) +#define SPI_INSN_CMD_CODE(x) (((x) & 0xff) << 16) +#define SPI_INSN_PAD_CODE(x) (((x) & 0xff) << 24) + +#define SPI_TXFIFO_FULL (1 << 31) +#define SPI_RXFIFO_EMPTY (1 << 31) + +/* Values */ + +#define SPI_CSMODE_AUTO 0 +#define SPI_CSMODE_HOLD 2 +#define SPI_CSMODE_OFF 3 + +#define SPI_DIR_RX 0 +#define SPI_DIR_TX 1 + +#define SPI_PROTO_S 0 +#define SPI_PROTO_D 1 +#define SPI_PROTO_Q 2 + +#define SPI_ENDIAN_MSB 0 +#define SPI_ENDIAN_LSB 1 + + +#endif /* _SIFIVE_SPI_H */ diff --git a/fw/bsp/include/platform/devices/uart.h b/fw/bsp/include/platform/devices/uart.h new file mode 100644 index 0000000..71bea6f --- /dev/null +++ b/fw/bsp/include/platform/devices/uart.h @@ -0,0 +1,27 @@ +// See LICENSE for license details. + +#ifndef _SIFIVE_UART_H +#define _SIFIVE_UART_H + +/* Register offsets */ +#define UART_REG_TXFIFO 0x00 +#define UART_REG_RXFIFO 0x04 +#define UART_REG_TXCTRL 0x08 +#define UART_REG_RXCTRL 0x0c +#define UART_REG_IE 0x10 +#define UART_REG_IP 0x14 +#define UART_REG_DIV 0x18 + +/* TXCTRL register */ +#define UART_TXEN 0x1 +#define UART_TXWM(x) (((x) & 0xffff) << 16) + +/* RXCTRL register */ +#define UART_RXEN 0x1 +#define UART_RXWM(x) (((x) & 0xffff) << 16) + +/* IP register */ +#define UART_IP_TXWM 0x1 +#define UART_IP_RXWM 0x2 + +#endif /* _SIFIVE_UART_H */ diff --git a/fw/bsp/include/platform/sections.h b/fw/bsp/include/platform/sections.h new file mode 100644 index 0000000..6e1f051 --- /dev/null +++ b/fw/bsp/include/platform/sections.h @@ -0,0 +1,17 @@ +// See LICENSE for license details. +#ifndef _SECTIONS_H +#define _SECTIONS_H + +extern unsigned char _rom[]; +extern unsigned char _rom_end[]; + +extern unsigned char _ram[]; +extern unsigned char _ram_end[]; + +extern unsigned char _ftext[]; +extern unsigned char _etext[]; +extern unsigned char _fbss[]; +extern unsigned char _ebss[]; +extern unsigned char _end[]; + +#endif /* _SECTIONS_H */ diff --git a/fw/bsp/include/platform/smp.h b/fw/bsp/include/platform/smp.h new file mode 100644 index 0000000..8e34388 --- /dev/null +++ b/fw/bsp/include/platform/smp.h @@ -0,0 +1,65 @@ +#ifndef SIFIVE_SMP +#define SIFIVE_SMP + +// The maximum number of HARTs this code supports +#ifndef MAX_HARTS +#define MAX_HARTS 32 +#endif +#define CLINT_END_HART_IPI CLINT_CTRL_ADDR + (MAX_HARTS*4) + +// The hart that non-SMP tests should run on +#ifndef NONSMP_HART +#define NONSMP_HART 0 +#endif + +/* If your test cannot handle multiple-threads, use this: + * smp_disable(reg1) + */ +#define smp_disable(reg1, reg2) \ + csrr reg1, mhartid ;\ + li reg2, NONSMP_HART ;\ + beq reg1, reg2, hart0_entry ;\ +42: ;\ + wfi ;\ + j 42b ;\ +hart0_entry: + +/* If your test needs to temporarily block multiple-threads, do this: + * smp_pause(reg1, reg2) + * ... single-threaded work ... + * smp_resume(reg1, reg2) + * ... multi-threaded work ... + */ + +#define smp_pause(reg1, reg2) \ + li reg2, 0x8 ;\ + csrw mie, reg2 ;\ + csrr reg2, mhartid ;\ + bnez reg2, 42f + +#define smp_resume(reg1, reg2) \ + li reg1, CLINT_CTRL_ADDR ;\ +41: ;\ + li reg2, 1 ;\ + sw reg2, 0(reg1) ;\ + addi reg1, reg1, 4 ;\ + li reg2, CLINT_END_HART_IPI ;\ + blt reg1, reg2, 41b ;\ +42: ;\ + wfi ;\ + csrr reg2, mip ;\ + andi reg2, reg2, 0x8 ;\ + beqz reg2, 42b ;\ + li reg1, CLINT_CTRL_ADDR ;\ + csrr reg2, mhartid ;\ + slli reg2, reg2, 2 ;\ + add reg2, reg2, reg1 ;\ + sw zero, 0(reg2) ;\ +41: ;\ + lw reg2, 0(reg1) ;\ + bnez reg2, 41b ;\ + addi reg1, reg1, 4 ;\ + li reg2, CLINT_END_HART_IPI ;\ + blt reg1, reg2, 41b + +#endif diff --git a/fw/bsp/libwrap/libwrap.mk b/fw/bsp/libwrap/libwrap.mk new file mode 100644 index 0000000..c2e4192 --- /dev/null +++ b/fw/bsp/libwrap/libwrap.mk @@ -0,0 +1,57 @@ +# See LICENSE for license details. + +ifndef _SIFIVE_MK_LIBWRAP +_SIFIVE_MK_LIBWRAP := # defined + +LIBWRAP_DIR := $(dir $(lastword $(MAKEFILE_LIST))) +LIBWRAP_DIR := $(LIBWRAP_DIR:/=) + +LIBWRAP_SRCS := \ + stdlib/malloc.c \ + sys/open.c \ + sys/lseek.c \ + sys/read.c \ + sys/write.c \ + sys/fstat.c \ + sys/stat.c \ + sys/close.c \ + sys/link.c \ + sys/unlink.c \ + sys/execve.c \ + sys/fork.c \ + sys/getpid.c \ + sys/kill.c \ + sys/wait.c \ + sys/isatty.c \ + sys/times.c \ + sys/sbrk.c \ + sys/_exit.c \ + sys/puts.c \ + misc/write_hex.c \ + sys/printf.c + +LIBWRAP_SRCS := $(foreach f,$(LIBWRAP_SRCS),$(LIBWRAP_DIR)/$(f)) +LIBWRAP_OBJS := $(LIBWRAP_SRCS:.c=.o) + +LIBWRAP_SYMS := malloc free \ + open lseek read write fstat stat close link unlink \ + execve fork getpid kill wait \ + isatty times sbrk _exit puts printf + +LIBWRAP := libwrap.a + +LINK_DEPS += $(LIBWRAP) + +LDFLAGS += $(foreach s,$(LIBWRAP_SYMS),-Wl,--wrap=$(s)) +LDFLAGS += $(foreach s,$(LIBWRAP_SYMS),-Wl,--wrap=_$(s)) +LDFLAGS += -L. -Wl,--start-group -lwrap -lc -Wl,--end-group + +CLEAN_OBJS += $(LIBWRAP_OBJS) + +$(LIBWRAP_OBJS): %.o: %.c $(HEADERS) + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $< + +$(LIBWRAP): $(LIBWRAP_OBJS) + $(AR) rcs $@ $^ + +endif # _SIFIVE_MK_LIBWRAP diff --git a/fw/bsp/libwrap/misc/write_hex.c b/fw/bsp/libwrap/misc/write_hex.c new file mode 100644 index 0000000..a35ad7a --- /dev/null +++ b/fw/bsp/libwrap/misc/write_hex.c @@ -0,0 +1,19 @@ +/* See LICENSE of license details. */ + +#include +#include +#include "platform.h" + +void write_hex(int fd, unsigned long int hex) +{ + uint8_t ii; + uint8_t jj; + char towrite; + write(fd , "0x", 2); + for (ii = sizeof(unsigned long int) * 2 ; ii > 0; ii--) { + jj = ii - 1; + uint8_t digit = ((hex & (0xF << (jj*4))) >> (jj*4)); + towrite = digit < 0xA ? ('0' + digit) : ('A' + (digit - 0xA)); + write(fd, &towrite, 1); + } +} diff --git a/fw/bsp/libwrap/stdlib/malloc.c b/fw/bsp/libwrap/stdlib/malloc.c new file mode 100644 index 0000000..8f4f432 --- /dev/null +++ b/fw/bsp/libwrap/stdlib/malloc.c @@ -0,0 +1,17 @@ +/* See LICENSE for license details. */ + +/* These functions are intended for embedded RV32 systems and are + obviously incorrect in general. */ + +void* __wrap_malloc(unsigned long sz) +{ + extern void* sbrk(long); + void* res = sbrk(sz); + if ((long)res == -1) + return 0; + return res; +} + +void __wrap_free(void* ptr) +{ +} diff --git a/fw/bsp/libwrap/sys/_exit.c b/fw/bsp/libwrap/sys/_exit.c new file mode 100644 index 0000000..011464f --- /dev/null +++ b/fw/bsp/libwrap/sys/_exit.c @@ -0,0 +1,17 @@ +/* See LICENSE of license details. */ + +#include +#include "platform.h" +#include "weak_under_alias.h" + +void __wrap_exit(int code) +{ + const char message[] = "\nProgam has exited with code:"; + + write(STDERR_FILENO, message, sizeof(message) - 1); + write_hex(STDERR_FILENO, code); + write(STDERR_FILENO, "\n", 1); + + for (;;); +} +weak_under_alias(exit); diff --git a/fw/bsp/libwrap/sys/close.c b/fw/bsp/libwrap/sys/close.c new file mode 100644 index 0000000..199fe51 --- /dev/null +++ b/fw/bsp/libwrap/sys/close.c @@ -0,0 +1,11 @@ +/* See LICENSE of license details. */ + +#include +#include "stub.h" +#include "weak_under_alias.h" + +int __wrap_close(int fd) +{ + return _stub(EBADF); +} +weak_under_alias(close); diff --git a/fw/bsp/libwrap/sys/execve.c b/fw/bsp/libwrap/sys/execve.c new file mode 100644 index 0000000..f7be25a --- /dev/null +++ b/fw/bsp/libwrap/sys/execve.c @@ -0,0 +1,11 @@ +/* See LICENSE of license details. */ + +#include +#include "stub.h" +#include "weak_under_alias.h" + +int __wrap_execve(const char* name, char* const argv[], char* const env[]) +{ + return _stub(ENOMEM); +} +weak_under_alias(execve); diff --git a/fw/bsp/libwrap/sys/fork.c b/fw/bsp/libwrap/sys/fork.c new file mode 100644 index 0000000..13a3e65 --- /dev/null +++ b/fw/bsp/libwrap/sys/fork.c @@ -0,0 +1,9 @@ +/* See LICENSE of license details. */ + +#include +#include "stub.h" + +int fork(void) +{ + return _stub(EAGAIN); +} diff --git a/fw/bsp/libwrap/sys/fstat.c b/fw/bsp/libwrap/sys/fstat.c new file mode 100644 index 0000000..ff82bf9 --- /dev/null +++ b/fw/bsp/libwrap/sys/fstat.c @@ -0,0 +1,18 @@ +/* See LICENSE of license details. */ + +#include +#include +#include +#include "stub.h" +#include "weak_under_alias.h" + +int __wrap_fstat(int fd, struct stat* st) +{ + if (isatty(fd)) { + st->st_mode = S_IFCHR; + return 0; + } + + return _stub(EBADF); +} +weak_under_alias(fstat); diff --git a/fw/bsp/libwrap/sys/getpid.c b/fw/bsp/libwrap/sys/getpid.c new file mode 100644 index 0000000..195fbec --- /dev/null +++ b/fw/bsp/libwrap/sys/getpid.c @@ -0,0 +1,8 @@ +/* See LICENSE of license details. */ +#include "weak_under_alias.h" + +int __wrap_getpid(void) +{ + return 1; +} +weak_under_alias(getpid); diff --git a/fw/bsp/libwrap/sys/isatty.c b/fw/bsp/libwrap/sys/isatty.c new file mode 100644 index 0000000..7bb82ab --- /dev/null +++ b/fw/bsp/libwrap/sys/isatty.c @@ -0,0 +1,13 @@ +/* See LICENSE of license details. */ + +#include +#include "weak_under_alias.h" + +int __wrap_isatty(int fd) +{ + if (fd == STDOUT_FILENO || fd == STDERR_FILENO) + return 1; + + return 0; +} +weak_under_alias(isatty); diff --git a/fw/bsp/libwrap/sys/kill.c b/fw/bsp/libwrap/sys/kill.c new file mode 100644 index 0000000..18b9bd4 --- /dev/null +++ b/fw/bsp/libwrap/sys/kill.c @@ -0,0 +1,11 @@ +/* See LICENSE of license details. */ + +#include +#include "stub.h" +#include "weak_under_alias.h" + +int __wrap_kill(int pid, int sig) +{ + return _stub(EINVAL); +} +weak_under_alias(kill); diff --git a/fw/bsp/libwrap/sys/link.c b/fw/bsp/libwrap/sys/link.c new file mode 100644 index 0000000..0cad551 --- /dev/null +++ b/fw/bsp/libwrap/sys/link.c @@ -0,0 +1,11 @@ +/* See LICENSE of license details. */ + +#include +#include "stub.h" +#include "weak_under_alias.h" + +int __wrap_link(const char *old_name, const char *new_name) +{ + return _stub(EMLINK); +} +weak_under_alias(link); diff --git a/fw/bsp/libwrap/sys/lseek.c b/fw/bsp/libwrap/sys/lseek.c new file mode 100644 index 0000000..4131449 --- /dev/null +++ b/fw/bsp/libwrap/sys/lseek.c @@ -0,0 +1,16 @@ +/* See LICENSE of license details. */ + +#include +#include +#include +#include "stub.h" +#include "weak_under_alias.h" + +off_t __wrap_lseek(int fd, off_t ptr, int dir) +{ + if (isatty(fd)) + return 0; + + return _stub(EBADF); +} +weak_under_alias(lseek); diff --git a/fw/bsp/libwrap/sys/open.c b/fw/bsp/libwrap/sys/open.c new file mode 100644 index 0000000..c61415a --- /dev/null +++ b/fw/bsp/libwrap/sys/open.c @@ -0,0 +1,11 @@ +/* See LICENSE of license details. */ + +#include +#include "stub.h" +#include "weak_under_alias.h" + +int __wrap_open(const char* name, int flags, int mode) +{ + return _stub(ENOENT); +} +weak_under_alias(open); diff --git a/fw/bsp/libwrap/sys/openat.c b/fw/bsp/libwrap/sys/openat.c new file mode 100644 index 0000000..227c956 --- /dev/null +++ b/fw/bsp/libwrap/sys/openat.c @@ -0,0 +1,11 @@ +/* See LICENSE of license details. */ + +#include +#include "stub.h" +#include "weak_under_alias.h" + +int __wrap_openat(int dirfd, const char* name, int flags, int mode) +{ + return _stub(ENOENT); +} +weak_under_alias(openat); diff --git a/fw/bsp/libwrap/sys/printf.c b/fw/bsp/libwrap/sys/printf.c new file mode 100644 index 0000000..8abbb92 --- /dev/null +++ b/fw/bsp/libwrap/sys/printf.c @@ -0,0 +1,271 @@ +/* The functions in this file are only meant to support Dhrystone on an + * embedded RV32 system and are obviously incorrect in general. */ + +#include +#include +#include +#include +#include +#include + +#undef putchar +int putchar(int ch) +{ + return write(STDOUT_FILENO, &ch, 1) == 1 ? ch : -1; +} + +static void sprintf_putch(int ch, void** data) +{ + char** pstr = (char**)data; + **pstr = ch; + (*pstr)++; +} + +static unsigned long getuint(va_list *ap, int lflag) +{ + if (lflag) + return va_arg(*ap, unsigned long); + else + return va_arg(*ap, unsigned int); +} + +static long getint(va_list *ap, int lflag) +{ + if (lflag) + return va_arg(*ap, long); + else + return va_arg(*ap, int); +} + +static inline void printnum(void (*putch)(int, void**), void **putdat, + unsigned long num, unsigned base, int width, int padc) +{ + unsigned digs[sizeof(num)*8]; + int pos = 0; + + while (1) + { + digs[pos++] = num % base; + if (num < base) + break; + num /= base; + } + + while (width-- > pos) + putch(padc, putdat); + + while (pos-- > 0) + putch(digs[pos] + (digs[pos] >= 10 ? 'a' - 10 : '0'), putdat); +} +/* +static inline void print_double(void (*putch)(int, void**), void **putdat, + double num, int width, int prec) +{ + union { + double d; + uint64_t u; + } u; + u.d = num; + + if (u.u & (1ULL << 63)) { + putch('-', putdat); + u.u &= ~(1ULL << 63); + } + + for (int i = 0; i < prec; i++) + u.d *= 10; + + char buf[32], *pbuf = buf; + printnum(sprintf_putch, (void**)&pbuf, (unsigned long)u.d, 10, 0, 0); + if (prec > 0) { + for (int i = 0; i < prec; i++) { + pbuf[-i] = pbuf[-i-1]; + } + pbuf[-prec] = '.'; + pbuf++; + } + + for (char* p = buf; p < pbuf; p++) + putch(*p, putdat); +} +*/ +static void vprintfmt(void (*putch)(int, void**), void **putdat, const char *fmt, va_list ap) +{ + register const char* p; + const char* last_fmt; + register int ch, err; + unsigned long num; + int base, lflag, width, precision, altflag; + char padc; + + while (1) { + while ((ch = *(unsigned char *) fmt) != '%') { + if (ch == '\0') + return; + fmt++; + putch(ch, putdat); + } + fmt++; + + // Process a %-escape sequence + last_fmt = fmt; + padc = ' '; + width = -1; + precision = -1; + lflag = 0; + altflag = 0; + reswitch: + switch (ch = *(unsigned char *) fmt++) { + + // flag to pad on the right + case '-': + padc = '-'; + goto reswitch; + + // flag to pad with 0's instead of spaces + case '0': + padc = '0'; + goto reswitch; + + // width field + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + for (precision = 0; ; ++fmt) { + precision = precision * 10 + ch - '0'; + ch = *fmt; + if (ch < '0' || ch > '9') + break; + } + goto process_precision; + + case '*': + precision = va_arg(ap, int); + goto process_precision; + + case '.': + if (width < 0) + width = 0; + goto reswitch; + + case '#': + altflag = 1; + goto reswitch; + + process_precision: + if (width < 0) + width = precision, precision = -1; + goto reswitch; + + // long flag + case 'l': + if (lflag) + goto bad; + goto reswitch; + + // character + case 'c': + putch(va_arg(ap, int), putdat); + break; + + // double + case 'f': + //print_double(putch, putdat, va_arg(ap, double), width, precision); + break; + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) + p = "(null)"; + if (width > 0 && padc != '-') + for (width -= strnlen(p, precision); width > 0; width--) + putch(padc, putdat); + for (; (ch = *p) != '\0' && (precision < 0 || --precision >= 0); width--) { + putch(ch, putdat); + p++; + } + for (; width > 0; width--) + putch(' ', putdat); + break; + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); + if ((long) num < 0) { + putch('-', putdat); + num = -(long) num; + } + base = 10; + goto signed_number; + + // unsigned decimal + case 'u': + base = 10; + goto unsigned_number; + + // (unsigned) octal + case 'o': + // should do something with padding so it's always 3 octits + base = 8; + goto unsigned_number; + + // pointer + case 'p': + lflag = 1; + putch('0', putdat); + putch('x', putdat); + /* fall through to 'x' */ + + // (unsigned) hexadecimal + case 'x': + base = 16; + unsigned_number: + num = getuint(&ap, lflag); + signed_number: + printnum(putch, putdat, num, base, width, padc); + break; + + // escaped '%' character + case '%': + putch(ch, putdat); + break; + + // unrecognized escape sequence - just print it literally + default: + bad: + putch('%', putdat); + fmt = last_fmt; + break; + } + } +} + +int __wrap_printf(const char* fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + + vprintfmt((void*)putchar, 0, fmt, ap); + + va_end(ap); + return 0; // incorrect return value, but who cares, anyway? +} + +int __wrap_sprintf(char* str, const char* fmt, ...) +{ + va_list ap; + char* str0 = str; + va_start(ap, fmt); + + vprintfmt(sprintf_putch, (void**)&str, fmt, ap); + *str = 0; + + va_end(ap); + return str - str0; +} diff --git a/fw/bsp/libwrap/sys/puts.c b/fw/bsp/libwrap/sys/puts.c new file mode 100644 index 0000000..50d6437 --- /dev/null +++ b/fw/bsp/libwrap/sys/puts.c @@ -0,0 +1,28 @@ +/* See LICENSE of license details. */ + +#include +#include +#include +#include + +#include "platform.h" +#include "stub.h" +#include "weak_under_alias.h" + +int __wrap_puts(const char *s) +{ + while (*s != '\0') { + while (UART0_REG(UART_REG_TXFIFO) & 0x80000000) ; + UART0_REG(UART_REG_TXFIFO) = *s; + + if (*s == '\n') { + while (UART0_REG(UART_REG_TXFIFO) & 0x80000000) ; + UART0_REG(UART_REG_TXFIFO) = '\r'; + } + + ++s; + } + + return 0; +} +weak_under_alias(puts); diff --git a/fw/bsp/libwrap/sys/read.c b/fw/bsp/libwrap/sys/read.c new file mode 100644 index 0000000..3226cdb --- /dev/null +++ b/fw/bsp/libwrap/sys/read.c @@ -0,0 +1,32 @@ +/* See LICENSE of license details. */ + +#include +#include +#include +#include + +#include "platform.h" +#include "stub.h" +#include "weak_under_alias.h" + +ssize_t __wrap_read(int fd, void* ptr, size_t len) +{ + uint8_t * current = (uint8_t *)ptr; + volatile uint32_t * uart_rx = (uint32_t *)(UART0_CTRL_ADDR + UART_REG_RXFIFO); + volatile uint8_t * uart_rx_cnt = (uint8_t *)(UART0_CTRL_ADDR + UART_REG_RXCTRL + 2); + + ssize_t result = 0; + + if (isatty(fd)) { + for (current = (uint8_t *)ptr; + (current < ((uint8_t *)ptr) + len) && (*uart_rx_cnt > 0); + current ++) { + *current = *uart_rx; + result++; + } + return result; + } + + return _stub(EBADF); +} +weak_under_alias(read); diff --git a/fw/bsp/libwrap/sys/sbrk.c b/fw/bsp/libwrap/sys/sbrk.c new file mode 100644 index 0000000..12170b4 --- /dev/null +++ b/fw/bsp/libwrap/sys/sbrk.c @@ -0,0 +1,18 @@ +/* See LICENSE of license details. */ + +#include +#include "weak_under_alias.h" + +void *__wrap_sbrk(ptrdiff_t incr) +{ + extern char _end[]; + extern char _heap_end[]; + static char *curbrk = _end; + + if ((curbrk + incr < _end) || (curbrk + incr > _heap_end)) + return NULL - 1; + + curbrk += incr; + return curbrk - incr; +} +weak_under_alias(sbrk); diff --git a/fw/bsp/libwrap/sys/stat.c b/fw/bsp/libwrap/sys/stat.c new file mode 100644 index 0000000..1576ca1 --- /dev/null +++ b/fw/bsp/libwrap/sys/stat.c @@ -0,0 +1,12 @@ +/* See LICENSE of license details. */ + +#include +#include +#include "stub.h" +#include "weak_under_alias.h" + +int __wrap_stat(const char* file, struct stat* st) +{ + return _stub(EACCES); +} +weak_under_alias(stat); diff --git a/fw/bsp/libwrap/sys/stub.h b/fw/bsp/libwrap/sys/stub.h new file mode 100644 index 0000000..fb5e5be --- /dev/null +++ b/fw/bsp/libwrap/sys/stub.h @@ -0,0 +1,10 @@ +/* See LICENSE of license details. */ +#ifndef _SIFIVE_SYS_STUB_H +#define _SIFIVE_SYS_STUB_H + +static inline int _stub(int err) +{ + return -1; +} + +#endif /* _SIFIVE_SYS_STUB_H */ diff --git a/fw/bsp/libwrap/sys/times.c b/fw/bsp/libwrap/sys/times.c new file mode 100644 index 0000000..55969a7 --- /dev/null +++ b/fw/bsp/libwrap/sys/times.c @@ -0,0 +1,12 @@ +/* See LICENSE of license details. */ + +#include +#include +#include "stub.h" +#include "weak_under_alias.h" + +clock_t __wrap_times(struct tms* buf) +{ + return _stub(EACCES); +} +weak_under_alias(times); diff --git a/fw/bsp/libwrap/sys/unlink.c b/fw/bsp/libwrap/sys/unlink.c new file mode 100644 index 0000000..09f4da7 --- /dev/null +++ b/fw/bsp/libwrap/sys/unlink.c @@ -0,0 +1,11 @@ +/* See LICENSE of license details. */ + +#include +#include "stub.h" +#include "weak_under_alias.h" + +int __wrap_unlink(const char* name) +{ + return _stub(ENOENT); +} +weak_under_alias(unlink); diff --git a/fw/bsp/libwrap/sys/wait.c b/fw/bsp/libwrap/sys/wait.c new file mode 100644 index 0000000..ea3225b --- /dev/null +++ b/fw/bsp/libwrap/sys/wait.c @@ -0,0 +1,9 @@ +/* See LICENSE of license details. */ + +#include +#include "stub.h" + +int wait(int* status) +{ + return _stub(ECHILD); +} diff --git a/fw/bsp/libwrap/sys/weak_under_alias.h b/fw/bsp/libwrap/sys/weak_under_alias.h new file mode 100644 index 0000000..7629353 --- /dev/null +++ b/fw/bsp/libwrap/sys/weak_under_alias.h @@ -0,0 +1,7 @@ +#ifndef _BSP_LIBWRAP_WEAK_UNDER_ALIAS_H +#define _BSP_LIBWRAP_WEAK_UNDER_ALIAS_H + +#define weak_under_alias(name) \ + extern __typeof (__wrap_##name) __wrap__##name __attribute__ ((weak, alias ("__wrap_"#name))) + +#endif diff --git a/fw/bsp/libwrap/sys/write.c b/fw/bsp/libwrap/sys/write.c new file mode 100644 index 0000000..b1e9a7e --- /dev/null +++ b/fw/bsp/libwrap/sys/write.c @@ -0,0 +1,31 @@ +/* See LICENSE of license details. */ + +#include +#include +#include +#include + +#include "platform.h" +#include "stub.h" +#include "weak_under_alias.h" + +ssize_t __wrap_write(int fd, const void* ptr, size_t len) +{ + const uint8_t * current = (const char *)ptr; + + if (isatty(fd)) { + for (size_t jj = 0; jj < len; jj++) { + while (UART0_REG(UART_REG_TXFIFO) & 0x80000000) ; + UART0_REG(UART_REG_TXFIFO) = current[jj]; + + if (current[jj] == '\n') { + while (UART0_REG(UART_REG_TXFIFO) & 0x80000000) ; + UART0_REG(UART_REG_TXFIFO) = '\r'; + } + } + return len; + } + + return _stub(EBADF); +} +weak_under_alias(write); diff --git a/fw/hello-world/.gitignore b/fw/hello-world/.gitignore new file mode 100644 index 0000000..ebea2da --- /dev/null +++ b/fw/hello-world/.gitignore @@ -0,0 +1,3 @@ +/hello +/hello.dis +/firmware.map diff --git a/fw/hello-world/Makefile b/fw/hello-world/Makefile new file mode 100644 index 0000000..c8ea51e --- /dev/null +++ b/fw/hello-world/Makefile @@ -0,0 +1,18 @@ + +TARGET = hello +C_SRCS = $(wildcard *.c) +HEADERS = $(wildcard *.h) +CFLAGS += -O0 -g + +BOARD=tgfs-vp +LINK_TARGET=flash +RISCV_ARCH:=rv32i +RISCV_ABI:=ilp32 +LDFLAGS := -march=$(RISCV_ARCH) -mabi=$(RISCV_ABI) + +compiler := $(shell which riscv32-unknown-elf-gcc) +TOOL_DIR=$(dir $(compiler)) + +TRIPLET=riscv32-unknown-elf +BSP_BASE = ../bsp +include $(BSP_BASE)/env/common-gcc.mk diff --git a/fw/hello-world/hello.c b/fw/hello-world/hello.c new file mode 100644 index 0000000..b687874 --- /dev/null +++ b/fw/hello-world/hello.c @@ -0,0 +1,26 @@ +#include +#include +#include + +#include "platform.h" +#include "encoding.h" + +int factorial(int i){ + + volatile int result = 1; + for (int ii = 1; ii <= i; ii++) { + result = result * ii; + } + return result; + +} + +int main() +{ + *(uint32_t*)(GPIO_CTRL_ADDR+GPIO_IOF_SEL) &= ~IOF0_UART0_MASK; + *(uint32_t*)(GPIO_CTRL_ADDR+GPIO_IOF_EN) |= IOF0_UART0_MASK; + volatile int result = factorial (10); + printf("Factorial is %d\n", result); + printf("End of execution"); + return 0; +} diff --git a/fw/hello-world/prebuilt/hello.elf b/fw/hello-world/prebuilt/hello.elf new file mode 100755 index 0000000000000000000000000000000000000000..9b63df72a75d994b5d4fdb0d8ea230a51171fbb3 GIT binary patch literal 29716 zcmeHw4Rl<^m1e!aey#tO+qNWZaN8|evauzBJTXZ~(hdTf88$cxNtlh3cB|Ev6!aIV zWniMuKi0h z+H}H>N}|KpuU6pF6z6e@1nko`Y!6bsPCe_ zJKPZ2^hQHyQ#fEiuj75gp=Fznt%07mnxn&CGg~u}Ey7y8Uu0IF5Y`&Q$gJ67Ske7P zCVIlK>J2kfzs0l~_M4f86Q;G+urh16SXSeHE7N$wvYHG#)3n95*6p`5>rU9#dc(=A z-{M#o?{_j6pKz=VMj*3cOTgN=KakmYB49NeZl-yQYqjimGc6}v_$@drBCVdEW}|DX z;fMWZ*fy+a^8+(kHw3>;&B^E5sks3$YGxV_%w-xT&_Av?8;V_(b( zN2QJ7>1o+7*?V2%n7c|GoqkKSbxn(7u87I!mIq!!{v(?v*#Y z^94R<9q8cq%?$bt<3q-Y%{Yl}cyuPZeqtutbb2Pb_T?EZ*FrnTTtgh)GcA(0!*)j) zVJ9a0D7w~`F_Jw}V}!@ZXG%WC&Qa*jI6~~qChu}h;*Pnt(DmQh-zY#yrhY>#-#&K~_D45N%~*(q zOyk7NnGTPCJ#p>C%}So8shLc}fmy4;p2ax7h2t;N;N>ZC>faE~9zY&yv}ehu^4F+Q z$hUp3f<3wj$$Ce}rgWZ=e$3QwIj1kPW5#~=P4bXyhMf>&{g+{fd1=)z!_)zE#;oS^ z@=viZ3vwgLV;;do%Ozn87}mV@koof-T3qa<~im9lCq{Uz{@+ z=*;{S4r~`kFlS@Fe?$61#46Eea;}hlAjB%fP(fYz>Zf7MJ=wsd5f0#qIX%pIeKP*| zv6IM`2i*wb=^p{VM*Xw79Pj+{tk_hu6@0EkI?&Lh}D9Vuw=2D#_5%aU0FRg|N#HlEw{>cMwkogdKE5P>X?+pBY z<{1~`9_gB8UVTZ z5aaaMGA7hKwaA>EpMNNWYlCD^<-@ES5y|D#f;g-d@XXC&=bk^1BaW!NdOGtk{P^%z zVSN+1@|!1x^`L8H9^7hJ4~-eorlqsd_4aIZ1Lm7%%r_C_{xzpD2fjR)dG4eUUCwoi zJsS?3G8hkGCjwjUe-$>*+%6`@)=2FI{w zI#Q3h!ks^gbz1a4y!w{a2);)9&166N2>ez<`qGxw3l&)<%9>J--I z!u&=BpOf=kcgQE!9nm#de>B;$4&yYs=Hx+JaNb-mTbwAtsWeHvBg+d*&&Zu`?@WNq+hxM{+ zgRfofgD3C*PjdXN~KAC8wx7Ph+q zIpiGe!hShl$@Y;K5cg<*3~LImj}CB-oXrNP1N1_ydO94!+VfFa7yh>(17*2S34_Ns z_e!0z4(3#Rs1oK6Ho))8pzr*#nph;tbAz?j824kJ4BJ=-!d}{n@o=H_&Hba9#)Br- zhBCK>9UJSJYhRaj8&%!S^|45JZ0p@&yZ!Dq`{fwUp`^UKIKsG}rEIAa%!!H&x_33 zZK0#Dd>?bg^Py~@Muck`MfA^~lX*S*z%kk9UTk9h`bn%~6Y$}e4fGX#DbL$b#yR6^ zoVi_ML^o`~c;1h*q^}#{GQ`fE_?3r5=7AHV;k! z^A6E=;DAVev4nn>V*-9Q;b#-)f`+vo=ZWjL7}mvxfpbA&;mi%^g2LJ;`$3+^B}Yrm z+A z2;T-@VZ6ycEf1Jk^jq?#?}_B~$0dLEUex*0_vR=s`O1^x=)osrZK`#}A@MkG6 zAmwFmm3z&1sYlnSi8j9$OKy8a9CaRv!G_=Psd!fXhBWdJPCkv;yT;+ZV_MfG@0shJ zIr1TQz10So{8uHC>4Bl1L~o>LIMUEriY1%4vcEGjuq%?fF_j!i_YCwCmmW$Cl9(JA zN=0@JrM?_Vq$3TzBav-4$vV81ZXX)xO7um#6T_(7lTLL;_VlE?Bguiz)Q3QCy-|p! z{*m6^bwa#7JwIRn&is5ieti0Wr#u>Q-6+52!D&24-^b4{>tAZQ_3iojZNE`=$BOLF z=?orS9tZEk9zSu{d9*`5+$ofo!q2>{n?5CseTK23!o3j?nhgdK8*cDG&HbLn8K2pXkj zTd%m{Ly@MfpZLtW$R(FFU((zvroiP0TQuW|m$>g%R`9`j8b1_PnJCK3M7hc=W0^NY zI3UF$R>-i-lAtgw!*@4J>>`XIF&eL^#dq7QmB%mS*F364a{75xIj}&EuXWI1*jq5~ zcd?thd%4x8-G^v*d11?{h5ujfexEJW+4B5HAHO%}!n*%*Fn-M)TBLe@8Xd`=zmh?` zSj5{=P<|i3z4$$VpNxEG1xiBR{u>I$izK{)o8>G+NIY)DB6Us`+_h8~PMI1Ej%f)F z3MVW~+X4>Ie1DeOFp&xEy>*i2_ZSG>cLYBD1v8|SI1QH zai<0)cv2FFB~8a_+%PsF^lADI8nBq@0h%7f(4hG%@GNja@Rz`%B7Ss%`AL*4`oaD& zZ*+$9uYt224w4BIgQN`h`ZR$?)^ge)v9+Flcv_CM#m@_^;RW)p^1RyOd2=J4#D5G= zderjpD?OOD6JO?el;t+B%-*Q;==4o}t`!%p0CFyb6nZY;Np;i^aLO%P;=>*s0-c@? z04DzuJSm<0)NVztzAf>2I4Joq0-c&IvC1TU8MI-&C0@N{R=|_1^jYS$PdYsZvn4$* zSGDiKpi-NqmMg8&5n1l@NsZ4Z7y8O&Ufl{G@1EN$Jp5i*So{UDwP(7i> z#CpKg^fC`$>OH+N0?nwQizjOp_kYOKwi312YN=-lYeOSIlzjmpJ{e;wn$#%WfLhd> zv8r_-%-*6eF9N^z=}JhekX(*cDRrvwq&l7y1F@l`NnKT4+&Pk@|8Q5fs4TD?^{6v# zVk0xD|26BzJUVo)=0d;ueT(Y)a>Z`=$noi>>}WZEoAq9hLE zX6)uoCJyEdi`hda4(l{QCJsv`j-Lf%ks6sG*bQFiKwU?6OBjm5LFgtGJT!@>RV#Ba zER>0K8BMM9f`;Xbl~Jgx0%MKG%b`oU4u~r7(IFvUU7b+ty*drjaW_f6l^!4UD7Q)$ zga;id6Yvl$eeYF=cBEQu-3OUmHb?F(Haha z(z%|XwQcITxR;gzjo!}ZRfYj;S9sF7PM~zXmRlpOFGHGW0+t>Hx2K^Ch`dXzeNr>l zrAF&LnL#h_S3*^7 zFbUE#c$Xyc9Q>-D)Ys$ED_T-6L|^d9^i9pHtzfPNO5$wF7PSRzS-}eLX<`jaY^fD0 z;9d(oC|&DYn$urS5(AqCJ*Fk!_ug3KgYOCa0KTw*m??}-SW3oN9?*A*r%Va<$4C^au zq^VUNr>Rys?sW9&oCIdXqUvSIgDFi$25JC{GNTADPo-FnL?vFvH8_yZcO&7x_cVVw zk~4p5n!f=h!5jBY+m|Cp*L!n~QXXwmD|MIV6ksGC9BBDk%n`p!%W1aE8(U7Z<%wKF z+V%OS{c60YGM?HCRXrC*2FgOCQ~)g^P03j(O=-1I^M#y#jKA!&QMt6axus)xuqD;M zTMVZYL+R#Ei&TGlXfK}Ksovg!=A>xp9_UN8fI8eVlo}iuZnGa-3YqiAr9vGy--b8xWz);^p34J&>Rqe*RQ#US@Lb~>XPoI{-A-HfC_+d<9s0)IJ z(?GERpB4P8+_RC6f&@O21O2;tx)fgYjr4Z*v>~uMdv@c#TBZ>L1DoShUa`n`WGM)! zh3HYugv29^w{hd)Z>6CzAnC>qK+0HgR%+K<6ZQW-i%H73B(78fB+yowu?Z6u%@Fm4?10NxK77vrF zTdQ^H)kGP={dnMOUubFbFV;%_5(?N)Ijr{|@hct2txS}E5)WgEL^qkS2(iZa&vD1M zRYENPGD_y*UQuxy2|>w6lLjSUWe;#+iZl=JkQGW*h3=};V7eTHP!D*@$`lX(6FQGt z%2ibmUnyP1Q!lz|0`0F12=R~Lcpt8^&gm-aO~^KT>hQH2^pkF@Qf{+0lk(aHcaUPc z^q$4dxAkm|L@7^N^rWpkX-$J{U%oU+)(^7$sbzn}@)amM*&0qop0`8Xyaivtt@;D( z?UIULqg*0N>H5G^4q4gb&Px)#`?ZBu$j=B<9V!lc0ZCV;xzdqeL(UWO!*S zg})w{z&3s*u*UeZA>fU_3v2?0jK=t_K)8nhmIE~Lk9gT-NUIf}w_Vjs z#`xpF1@0wbH3?v}Q-et{(WanoQQi;YU$vvcqo5n(|AQ57B<>=%Ny%jw0DPc|4NV4O zk?SO10F9dyAUqiU1`v)lD8#5({sb__pR|(qZ6_Atz%s@k1FzjL{$!hyc#T;H#8;}7 z=AC8*p^FrBz4;fAaLA+eR;2p|Mb?A5%|8R}J`dVq{uIzxJ!pH)Ca6ZYj8ieX=Dvs$ zxl_2E9!=uE>fvEW?dPfPfrxsLse@ep{791RM( z-X0R0FHz;|>|J8>Wvaa0{<7HoF;%|CJcAmsa=HobbZ@s~k=IbJzzin#Rw{J25Oob` z#%QV7fyNJjZj6thaT_^Jw5(L3dhvHGNMK&$-Qt34sN{OtHJ77WL{?kDv}Hs~zYFMf z48H9WyYjyiTeh4|;gD>SSaA?orZ_Ck1^#LSDJ}_26a}6q&EVM(L_L+_%q>vSy14d( ztoz&2opo(pf_(NO=`Ntgtv6Q9D^zhQdtXG{GJfT4GIqV^)5=~7xCR|;|%nZJD)E!va8f}WH^$5KPbAQ}PEW{~W)-6TA^p3jnzM&rmiXE_rBuuv z6kn_*!RW9~gF9ZOxUO@P-C}2m78`$9CsX3irG(u6kv@^A{)&{CaQtvIsOZk zaIZ1`S-{d`P4)Dcb@;`brOTRPtZ5y7{$`tYu8Y!6>+tEDO&YrH5{9pJ_|(lNZCm$Y z>Tex>=4O)yth-8qPu*w&9XP8~1L)%=N9v$oM+v$jRoyeI_* zqq^cX3}LmjT4tjyba(YC#k0fwduUX>UPaIK);9r#OHZH`&Nr*@#!t8}%BW=;P%>D* zyjs;qCXaxbnd7gKBaF{f3&BI6`a`Jsr}(vin&0UCkUT#G507geHD(K#jA{|8sWz5W zS(Pg)8!Gu-Hr3^j$_!GGO`&=LMHoIa^L9Z$*0Tx?$Df;^wlv&h zz?&Reg759MM?8Y7TcowCZD}qIDlOJp*<9wKm2AH?^a#A5#jmbttkZ^)R3Q!Wt5mtL zE2{Ec5mJ3n?N>vou*8pQtQ#}x6h6#3XKAy@ca>`YraB>(`Rn-AS}rw~5mRhTjq(hY zuWio7m9C7vfxoJ5irg3Yb;wJl9xE0n?E`6LzKy~<1wCKb&sK5#*tt%07J4_3_pXj` zzgyU<@??n$mIWc8ZKsiCG6ub&#ttG$LZ64|vRvMx zGb;__>M-40wHo8LrL4$J3!*^UBYl7ow%TR-qZlVY=vI5EfNaV?4&8-L59XbIuH2_> zEu*ak*)KotG3s?t6!nMB5}s1NMD1Y~$zZwAMiQgFZr(VrQn1i3C8hafSB<%UK|HJ8 z#NT15WV!l)sU26&6o|x~(=%@rd!@2~l8gg8vDDhQX-i}@tw ze6TE^1NO;TWVy7q?86|bzO9iR=|j{ON2NdH>b&aS%y za3OsJHB|ixQyqI2(l=sdq3HT}rI7x;fTrtRex$V+;TI8uC{lh(7{rKZFvgLqecVbBF(tiyn*uWK+Z1z6bj%@5p z3?;iiB0uXU(9!dep5DQ>OHoet;m_N8Khl@#O!V&soF3^mI$fsu~hlt(6ZC^d|?MxrZ~jwc64;{2mK38Z`aQbY0GiQbWvXCTg; zU}1cCxaX!63ap`+WSx=WRPGg25--AT7#1UVqZa2ICee`?>5LC0(kVf#{=VeiBoyqUXr)cZ-oeE1u;@!AhDU}{c`X%7?|^_~(g|Hry>#&u z$Ge(7Px}vSqVjQ`)efb04X1i_H8!N%mSw8gy=!OyZ-nBzpuYU8#JGGf=*hYaqLL#+ zL%{Jh+eioSe7l7k-fU?=y|IGc!^4TL9G0)DgyiF!DEy^kXG)|8RK?DoE)WN~k@f_t z_fKNCdSWLWk9Ump^rn0IVPU)%@7P3dVmKY=COOfY-qoAv5}k>3LJT4{&~SWkD3$CP z=AT!hzu4b{BWW3gc!H6yvsy*3tQU`W^^YWTayt^}6Hkp{PY)eWaqI{?QbVlW&$CC! z<`BTUt*&9=F~?;~j4%9oCbmRU1b32qdOFhp6P?NYOR)t5Qocmp2!%GL2L^hfaZi5> zE$`$DwvGL%J$T2q5fRgsx^&U^l5z~S$kF4yj`Lo;iE`wFd0ZC%auLV+^? zTes~uZa3S@gTlP-MEg_aW@|e#isoxV&KyUb_R2_}Z&dO{$X6^s0^XhYO`u*Ap6!*P z_S+3gzYd~9tRgnxw-dkD!LuDt@NB0JcUxJToSjm9sQpLnKbHIv@a)7-pQq<#UXzol zd3NB;{Q!8Ouh*_Q2qvj3ZQ6<7&%ncX3GJ1!oK4olhHN#47B!!K2Z8o-d^dW!(GJ>2 zdHS^qjt=Go6bhLm^ zIY;tA-9@fggh=EjN#puX!RRDhP5AF<@M+;6UT@cG*p@K=e=#grIC1i>Q9dp8e~)2t zls8LYiH55;2V+Ub>oQHp63lm5qSObmK6haG%aT#(hp|NSU6x>W$X}MI$^$4_B2)z9 z49s^~Vu|Mwg|x-5=KUHHri2Moxgh%+KTe{Cq|1hxsQ8e)ulH`p_2NV~TqK z?+l7j>Jfr{4+7Ttn)IW95eD)KLEqzmbzUa@Z+-l00KW)$AC7Uip~e!^6t4i*a~=8L z0Ia`(AUqGa8~$OuRiphS81heq)mnq}dgf_Eef~l?4n94f5pD+k`lagCEn$8KvJ>@p zuzkSW08c=lkf+b5D9?NENBR!H%m=Fdp!{Z$e|yTehNSNUUBtA1N(5h901@GxqjMDS zKD5uZ5&7={+?kW-if;hc`!)LGJAhv|)q02gPXN|)7X9}Fz&eML{ybpn$M!<#h?fC3 zp}ubK9{}ro83F$kV7)$KeV)~8`GoPst2|~uKz*T4Enq$GlirE?A^2}8>45ox#ZI3+ zF9DBhl(!J_EB@xIK)nH~=gXIRw0Aiw5dH}0Z==6j z2}8fD0PA?8e{x?adf)KnwnM)Ci{5SVslN~OHfIaAQ+oG@KOD|)-1MhI9iU9J$9+Zbu?W6k4 zFW%KV(2?l%5Un636TKRgtP~kf3=JjrV&B#Y1|LFhGl8Pp3V5(pT7dH*biG10h1HuX zY@w8Dg99)#HB^sw3O0sdPu>vc4q8*ZU82XA+d+=tlbYe4Ho42zJyWo0)-5Tw#rZ)< z92>%pq|Y$lNrT?0c|3W4pwju$0ytgl%=)f~Qq@LZn#8?o`2twS4 z2Bi4rR5#8j5;#C;?oIUKyhk*5=ALN28KzJaIvsWRxBJcbigl=`VrTIPxh}HRH9_?jf^j%u?7T`1=ilgV^yV~PJTIDq=AP@6P?$YgE3rr9{^6B~K zo*Y-+4(@|ApI%2xgvYD(<2n+u2DJ$47tsKonvd&AmbIC8p|GTgk92;VrR$LVRq(CB zd9=PX?N%WC@{V62#7%U%cag^5-QLqfiw|8TM4NB +#include +#include +#include +#include +#ifdef ERROR +#undef ERROR +#endif +namespace po = boost::program_options; +using namespace sc_core; + +CLIParser::CLIParser(int argc, char *argv[]) +: desc("Options") +, valid(false) { + build(); + try { + po::store(po::parse_command_line(argc, argv, desc), vm_); // can throw + // --help option + if (vm_.count("help")) { + std::cout << "DBT-RISE-RiscV simulator for RISC-V" << std::endl << desc << std::endl; + } + po::notify(vm_); // throws on error, so do after help in case there are any problems + valid = true; + } catch (po::error &e) { + std::cerr << "ERROR: " << e.what() << std::endl << std::endl; + std::cerr << desc << std::endl; + } + auto log_level = vm_["verbose"].as(); + auto log_level_num = static_cast(log_level); + LOGGER(DEFAULT)::reporting_level() = logging::as_log_level(log_level_num > 6 ? 6 : log_level_num);; + LOGGER(DEFAULT)::print_time() = false; + LOG_OUTPUT(DEFAULT)::ostream() = &std::cout; + LOGGER(connection)::reporting_level() = logging::as_log_level(log_level_num > 4 ? log_level_num-1 : log_level_num);; + LOGGER(connection)::print_time() = false; + LOG_OUTPUT(connection)::ostream() = &std::cout; + /////////////////////////////////////////////////////////////////////////// + // configure logging + /////////////////////////////////////////////////////////////////////////// + scc::init_logging(scc::LogConfig() + .logFileName(vm_["log-file"].as()) + .logLevel(vm_["verbose"].as()) + .logFilterRegex(vm_["log-filter"].as()) + .logAsync(!vm_["log-sync"].as())); + scc::stream_redirection cout_redir(std::cout, scc::log::DEBUG); + scc::stream_redirection cerr_redir(std::cerr, scc::log::ERROR); + sc_core::sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", sc_core::SC_DO_NOTHING); + sc_core::sc_report_handler::set_actions(sc_core::SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_, sc_core::SC_DO_NOTHING); + sc_core::sc_report_handler::set_actions(sc_core::SC_ERROR, sc_core::SC_LOG | sc_core::SC_CACHE_REPORT | sc_core::SC_DISPLAY | sc_core::SC_STOP); +} + +void CLIParser::build() { + // clang-format off + desc.add_options() + ("help,h", + "Print help message") + ("verbose,v", po::value()->default_value(scc::log::INFO), + "debug output level (NONE, FATAL, ERROR, WARNING, INFO, DEBUG, TRACE, TRACEALL)") + ("log-file,l", po::value()->default_value(""), + "log file name") + ("log-filter", po::value()->default_value(""), + "log filter regular expression name") + ("log-sync", po::bool_switch(), + "Disable asynchronous logging") + ("disass,d", po::value()->implicit_value(""), + "Enables disassembly") + ("elf,f", po::value(), + "ELF file to load") + ("gdb-port,g", po::value()->default_value(0), + "enable gdb server and specify port to use") + ("dump-ir", + "dump the intermediate representation") + ("quantum", po::value(), + "SystemC quantum time in ns") + ("reset,r", po::value(), + "reset address") + ("trace-level,t", po::value()->default_value(0), + "enable tracing, or combination of 1=signals and 2=TX text, 4=TX compressed text, 6=TX in SQLite") + ("trace-default-on", + "enables tracing for all unspecified modules") + ("trace-file", po::value()->default_value("system"), + "set th ename of the trace file") + ("max_time,m", po::value(), + "maximum time to run") + ("config-file,c", po::value()->default_value(""), + "read configuration from file") + ("plugin,p", po::value>(), + "plugin(s) to activate") + ("dump-config,dc", po::value()->default_value(""), + "dump configuration to file file"); + // clang-format on +} + +CLIParser::~CLIParser() = default; diff --git a/src/CLIParser.h b/src/CLIParser.h new file mode 100644 index 0000000..858d75f --- /dev/null +++ b/src/CLIParser.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019 -2021 MINRES Technolgies GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef PLATFORM_SRC_CLIPARSER_H_ +#define PLATFORM_SRC_CLIPARSER_H_ + +#include +#include +#include + +class CLIParser { +public: + CLIParser(int argc, char *argv[]); + + virtual ~CLIParser(); + + bool is_valid() { return valid; } + + const boost::program_options::variables_map &vm() { return vm_; } + + bool is_set(const char *option) { return vm_.count(option) != 0; } + + template const T &get(const char *option) { return vm_[option].as(); } + +private: + void build(); + bool valid; + boost::program_options::variables_map vm_; + boost::program_options::options_description desc; + std::array, 2> redir; +}; + +#endif /* PLATFORM_SRC_CLIPARSER_H_ */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..f848d17 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,26 @@ +# +# Copyright (c) 2019 -2021 MINRES Technolgies GmbH +# +# SPDX-License-Identifier: Apache-2.0 +# +cmake_minimum_required(VERSION 3.12) + +project(tgc-vp LANGUAGES C CXX VERSION 0.0.1) + +find_package(Boost COMPONENTS program_options thread REQUIRED) +############################################################################### +# SiFive +############################################################################### +add_executable(${PROJECT_NAME} + sc_main.cpp + CLIParser.cpp + tgc_vp/tb.cpp + tgc_vp/system.cpp +) +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}) +target_link_libraries(${PROJECT_NAME} PUBLIC dbt-rise-tgc_sc vpvper_generic vpvper_sifive ${BOOST_program_options_LIBRARY}) +if(TARGET Boost::program_options) + target_link_libraries(${PROJECT_NAME} PUBLIC Boost::program_options Boost::thread) +else() + target_link_libraries(${PROJECT_NAME} PUBLIC ${BOOST_program_options_LIBRARY}) +endif() \ No newline at end of file diff --git a/src/sc_main.cpp b/src/sc_main.cpp new file mode 100644 index 0000000..967af21 --- /dev/null +++ b/src/sc_main.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2019 -2021 MINRES Technolgies GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "CLIParser.h" +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +const std::string core_path{"tb.top.core_complex"}; + +using namespace sysc; +using namespace sc_core; +namespace po = boost::program_options; + +namespace { +const size_t ERRORR_IN_COMMAND_LINE = 1; +const size_t SUCCESS = 0; +} // namespace + +int sc_main(int argc, char *argv[]) { + /////////////////////////////////////////////////////////////////////////// + // SystemC >=2.2 got picky about multiple drivers so disable check + /////////////////////////////////////////////////////////////////////////// + sc_report_handler::set_actions(SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_, SC_DO_NOTHING); + /////////////////////////////////////////////////////////////////////////// + // CLI argument parsing & logging setup + /////////////////////////////////////////////////////////////////////////// + CLIParser parser(argc, argv); + if (!parser.is_valid()) return ERRORR_IN_COMMAND_LINE; + scc::stream_redirection cout_redir(std::cout, scc::log::INFO); + scc::stream_redirection cerr_redir(std::cerr, scc::log::ERROR); + /////////////////////////////////////////////////////////////////////////// + // create the performance estimation module + /////////////////////////////////////////////////////////////////////////// + scc::perf_estimator estimator; + /////////////////////////////////////////////////////////////////////////// + // set up configuration + /////////////////////////////////////////////////////////////////////////// + scc::configurer cfg(parser.get("config-file")); + /////////////////////////////////////////////////////////////////////////// + // set up tracing & transaction recording + /////////////////////////////////////////////////////////////////////////// + auto trace_level = parser.get("trace-level"); + scc::configurable_tracer trace(parser.get("trace-file"), + static_cast(trace_level >> 1), // bit3-bit1 define the kind of transaction trace + (trace_level&0x1) != 0, // bit0 enables vcd + parser.is_set("trace-default-on")); + /////////////////////////////////////////////////////////////////////////// + // instantiate top level + /////////////////////////////////////////////////////////////////////////// + auto i_system = scc::make_unique("tb"); + /////////////////////////////////////////////////////////////////////////// + // add non-implemented 'enableTracing' properties + /////////////////////////////////////////////////////////////////////////// + trace.add_control(); + /////////////////////////////////////////////////////////////////////////// + // dump configuration if requested + /////////////////////////////////////////////////////////////////////////// + if (parser.get("dump-config").size() > 0) { + std::ofstream of{parser.get("dump-config")}; + if (of.is_open()) cfg.dump_configuration(of); + } + cfg.configure(); + /////////////////////////////////////////////////////////////////////////// + // overwrite config with command line settings + /////////////////////////////////////////////////////////////////////////// + cfg.set_value(core_path + ".gdb_server_port", parser.get("gdb-port")); + cfg.set_value(core_path + ".dump_ir", parser.is_set("dump-ir")); + if(parser.is_set("plugin")){ + auto plugins = util::join(parser.get>("plugin"),","); + cfg.set_value(core_path + ".plugins", plugins); + } + if (parser.is_set("elf")) cfg.set_value(core_path + ".elf_file", parser.get("elf")); + if (parser.is_set("quantum")) + tlm::tlm_global_quantum::instance().set(sc_core::sc_time(parser.get("quantum"), sc_core::SC_NS)); + if (parser.is_set("reset")) { + auto str = parser.get("reset"); + uint64_t start_address = str.find("0x") == 0 ? std::stoull(str.substr(2), nullptr, 16) : std::stoull(str, nullptr, 10); + cfg.set_value(core_path + ".reset_address", start_address); + } + if (parser.is_set("disass")) { + cfg.set_value(core_path + ".enable_disass", true); + LOGGER(disass)::reporting_level() = logging::INFO; + auto file_name = parser.get("disass"); + if (file_name.length() > 0) { + LOG_OUTPUT(disass)::stream() = fopen(file_name.c_str(), "w"); + LOGGER(disass)::print_time() = false; + LOGGER(disass)::print_severity() = false; + } + } + /////////////////////////////////////////////////////////////////////////// + // run simulation + /////////////////////////////////////////////////////////////////////////// + try { + if (parser.is_set("max_time")) { + sc_core::sc_start(scc::parse_from_string(parser.get("max_time"))); + } else + sc_core::sc_start(); + if (!sc_core::sc_end_of_simulation_invoked()) sc_core::sc_stop(); + } catch (sc_core::sc_report &rep) { + sc_core::sc_report_handler::get_handler()(rep, sc_core::SC_DISPLAY | sc_core::SC_STOP); + } + return 0; +} diff --git a/src/tgc_vp/gen/platform_mmap.h b/src/tgc_vp/gen/platform_mmap.h new file mode 100644 index 0000000..a821ba4 --- /dev/null +++ b/src/tgc_vp/gen/platform_mmap.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2019 -2021 MINRES Technolgies GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef _PLATFORM_MMAP_H_ +#define _PLATFORM_MMAP_H_ +// need double braces, see +// https://stackoverflow.com/questions/6893700/how-to-construct-stdarray-object-with-initializer-list#6894191 +const std::array, 13> platfrom_mmap = {{ + {clint.socket, 0x2000000, 0xc000}, + {plic.socket, 0xc000000, 0x200008}, + {aon.socket, 0x10000000, 0x150}, + {prci.socket, 0x10008000, 0x14}, + {gpio0.socket, 0x10012000, 0x44}, + {uart0.socket, 0x10013000, 0x1c}, + {qspi0.socket, 0x10014000, 0x78}, + {pwm0.socket, 0x10015000, 0x30}, + {uart1.socket, 0x10023000, 0x1c}, + {qspi1.socket, 0x10024000, 0x78}, + {pwm1.socket, 0x10025000, 0x30}, + {qspi2.socket, 0x10034000, 0x78}, + {pwm2.socket, 0x10035000, 0x30}, +}}; + +#endif /* _PLATFORM_MMAP_H_ */ diff --git a/src/tgc_vp/platform.rdl b/src/tgc_vp/platform.rdl new file mode 100644 index 0000000..aedabcb --- /dev/null +++ b/src/tgc_vp/platform.rdl @@ -0,0 +1,25 @@ +`include "gpio.rdl" +`include "uart.rdl" +`include "spi.rdl" +`include "pwm.rdl" +`include "plic.rdl" +`include "aon.rdl" +`include "prci.rdl" +`include "clint.rdl" + +addrmap e300_plat_t { + lsb0; + clint_regs clint @0x02000000; + plic_regs plic @0x0C000000; + aon_regs aon @0x10000000; + prci_regs prci @0x10008000; + gpio_regs gpio0 @0x10012000; + uart_regs uart0 @0x10013000; + spi_regs qspi0 @0x10014000; + pwm_regs pwm0 @0x10015000; + uart_regs uart1 @0x10023000; + spi_regs qspi1 @0x10024000; + pwm_regs pwm1 @0x10025000; + spi_regs qspi2 @0x10034000; + pwm_regs pwm2 @0x10035000; +} e300_plat; diff --git a/src/tgc_vp/rst_gen.h b/src/tgc_vp/rst_gen.h new file mode 100644 index 0000000..63b9bed --- /dev/null +++ b/src/tgc_vp/rst_gen.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2019 -2021 MINRES Technolgies GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +namespace tgc_vp { + +class rst_gen : public sc_core::sc_module { + SC_HAS_PROCESS(rst_gen); +public: + rst_gen(sc_core::sc_module_name const& nm) { + SC_THREAD(run); + } + sc_core::sc_out rst_n{"rst_n"}; +private: + void run(){ + rst_n.write(false); + wait(100_ns); + rst_n.write(true); + } +}; + +} /* namespace tgc_vp */ diff --git a/src/tgc_vp/system.cpp b/src/tgc_vp/system.cpp new file mode 100644 index 0000000..4525174 --- /dev/null +++ b/src/tgc_vp/system.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2019 -2021 MINRES Technolgies GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "tgc_vp/system.h" + +namespace tgc_vp { +using namespace sc_core; +using namespace vpvper::sifive; +using namespace sysc::tgfs; + +system::system(sc_core::sc_module_name nm) +: sc_core::sc_module(nm) +, NAMED(router, platfrom_mmap.size() + 2, 1) +, NAMEDC(qspi0_ptr, spi, spi_impl::beh) +, NAMEDC(qspi1_ptr, spi, spi_impl::beh) +, NAMEDC(qspi2_ptr, spi, spi_impl::beh) +, qspi0(*qspi0_ptr) +, qspi1(*qspi1_ptr) +, qspi2(*qspi2_ptr) +{ + auto& qspi0 = *qspi0_ptr; + auto& qspi1 = *qspi1_ptr; + auto& qspi2 = *qspi2_ptr; + core_complex.initiator(router.target[0]); + size_t i = 0; + for (const auto &e : platfrom_mmap) { + router.initiator.at(i)(e.target); + router.set_target_range(i, e.start, e.size); + i++; + } + router.initiator.at(i)(mem_qspi.target); + router.set_target_range(i, 0x20000000, 512_MB); + router.initiator.at(++i)(mem_ram.target); + router.set_target_range(i, 0x80000000, 128_kB); + + uart1.clk_i(tlclk_s); + qspi0.clk_i(tlclk_s); + qspi1.clk_i(tlclk_s); + qspi2.clk_i(tlclk_s); + pwm0.clk_i(tlclk_s); + pwm1.clk_i(tlclk_s); + pwm2.clk_i(tlclk_s); + gpio0.clk_i(tlclk_s); + plic.clk_i(tlclk_s); + aon.clk_i(tlclk_s); + aon.lfclkc_o(lfclk_s); + prci.hfclk_o(tlclk_s); // clock driver + clint.tlclk_i(tlclk_s); + clint.lfclk_i(lfclk_s); + core_complex.clk_i(tlclk_s); + + uart0.rst_i(rst_s); + uart1.rst_i(rst_s); + qspi0.rst_i(rst_s); + qspi1.rst_i(rst_s); + qspi2.rst_i(rst_s); + pwm0.rst_i(rst_s); + pwm1.rst_i(rst_s); + pwm2.rst_i(rst_s); + gpio0.rst_i(rst_s); + plic.rst_i(rst_s); + aon.rst_o(rst_s); + prci.rst_i(rst_s); + clint.rst_i(rst_s); + core_complex.rst_i(rst_s); + + aon.erst_n_i(erst_n); + + clint.mtime_int_o(mtime_int_s); + clint.msip_int_o(msie_int_s); + + plic.global_interrupts_i(global_int_s); + plic.core_interrupt_o(core_int_s); + + core_complex.sw_irq_i(msie_int_s); + core_complex.timer_irq_i(mtime_int_s); + core_complex.global_irq_i(core_int_s); + core_complex.local_irq_i(local_int_s); + + pins_i(gpio0.pins_i); + gpio0.pins_o(pins_o); + + uart0.irq_o(global_int_s[3]); + + gpio0.iof0_i[5](qspi1.sck_o); + gpio0.iof0_i[3](qspi1.mosi_o); + qspi1.miso_i(gpio0.iof0_o[4]); + gpio0.iof0_i[2](qspi1.scs_o[0]); + gpio0.iof0_i[9](qspi1.scs_o[2]); + gpio0.iof0_i[10](qspi1.scs_o[3]); + + qspi0.irq_o(global_int_s[5]); + qspi1.irq_o(global_int_s[6]); + qspi2.irq_o(global_int_s[7]); + + s_dummy_sck_i[0](uart1.tx_o); + uart1.rx_i(s_dummy_sck_o[0]); + uart1.irq_o(global_int_s[4]); + + gpio0.iof1_i[0](pwm0.cmpgpio_o[0]); + gpio0.iof1_i[1](pwm0.cmpgpio_o[1]); + gpio0.iof1_i[2](pwm0.cmpgpio_o[2]); + gpio0.iof1_i[3](pwm0.cmpgpio_o[3]); + + gpio0.iof1_i[10](pwm2.cmpgpio_o[0]); + gpio0.iof1_i[11](pwm2.cmpgpio_o[1]); + gpio0.iof1_i[12](pwm2.cmpgpio_o[2]); + gpio0.iof1_i[13](pwm2.cmpgpio_o[3]); + + gpio0.iof1_i[19](pwm1.cmpgpio_o[0]); + gpio0.iof1_i[20](pwm1.cmpgpio_o[1]); + gpio0.iof1_i[21](pwm1.cmpgpio_o[2]); + gpio0.iof1_i[22](pwm1.cmpgpio_o[3]); + + pwm0.cmpip_o[0](global_int_s[40]); + pwm0.cmpip_o[1](global_int_s[41]); + pwm0.cmpip_o[2](global_int_s[42]); + pwm0.cmpip_o[3](global_int_s[43]); + + pwm1.cmpip_o[0](global_int_s[44]); + pwm1.cmpip_o[1](global_int_s[45]); + pwm1.cmpip_o[2](global_int_s[46]); + pwm1.cmpip_o[3](global_int_s[47]); + + pwm2.cmpip_o[0](global_int_s[48]); + pwm2.cmpip_o[1](global_int_s[49]); + pwm2.cmpip_o[2](global_int_s[50]); + pwm2.cmpip_o[3](global_int_s[51]); + + for (auto &sock : s_dummy_sck_i) sock.error_if_no_callback = false; +} + +} /* namespace sysc */ diff --git a/src/tgc_vp/system.h b/src/tgc_vp/system.h new file mode 100644 index 0000000..ae19a4c --- /dev/null +++ b/src/tgc_vp/system.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2019 -2021 MINRES Technolgies GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _PLATFORM_H_ +#define _PLATFORM_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace tgc_vp { + +class system : public sc_core::sc_module { +public: + SC_HAS_PROCESS(system);// NOLINT + + sc_core::sc_vector> pins_o{"pins_o", 32}; + sc_core::sc_vector> pins_i{"pins_i", 32}; + + sc_core::sc_in erst_n{"erst_n"}; + + system(sc_core::sc_module_name nm); + +private: + sysc::tgfs::core_complex core_complex{"core_complex"}; + scc::router<> router; + vpvper::sifive::uart_terminal uart0{"uart0"}; + vpvper::sifive::uart uart1{"uart1"}; + std::unique_ptr qspi0_ptr, qspi1_ptr, qspi2_ptr; + vpvper::sifive::pwm pwm0{"pwm0"}, pwm1{"pwm1"}, pwm2{"pwm2"}; + vpvper::sifive::gpio gpio0{"gpio0"}; + vpvper::sifive::plic plic{"plic"}; + vpvper::sifive::aon aon{"aon"}; + vpvper::sifive::prci prci{"prci"}; + vpvper::sifive::clint clint{"clint"}; + + using mem_qspi_t = scc::memory<512_MB, 32>; + mem_qspi_t mem_qspi{"mem_qspi"}; + using mem_ram_t = scc::memory<128_kB, 32>; + mem_ram_t mem_ram{"mem_ram"}; + + sc_core::sc_signal tlclk_s{"tlclk_s"}; + sc_core::sc_signal lfclk_s{"lfclk_s"}; + + sc_core::sc_signal rst_s{"rst_s"}, mtime_int_s{"mtime_int_s"}, msie_int_s{"msie_int_s"}; + + sc_core::sc_vector> global_int_s{"global_int_s", 256}, local_int_s{"local_int_s", 16}; + sc_core::sc_signal core_int_s{"core_int_s"}; + + sc_core::sc_vector s_dummy_sck_i{"s_dummy_sck_i", 16}; + sc_core::sc_vector s_dummy_sck_o{"s_dummy_sck_o", 16}; + +protected: + void gen_reset(); + vpvper::sifive::spi& qspi0; + vpvper::sifive::spi& qspi1; + vpvper::sifive::spi& qspi2; +#include "tgc_vp/gen/platform_mmap.h" +}; + +} /* namespace sysc */ + +#endif /* _PLATFORM_H_ */ diff --git a/src/tgc_vp/tb.cpp b/src/tgc_vp/tb.cpp new file mode 100644 index 0000000..da2d0a6 --- /dev/null +++ b/src/tgc_vp/tb.cpp @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2019 -2021 MINRES Technolgies GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "tgc_vp/tb.h" +namespace tgc_vp { + +SC_HAS_PROCESS(tb); +tb::tb(const sc_core::sc_module_name &nm): sc_core::sc_module(nm) { + top.erst_n(rst_n); + rst_gen.rst_n(rst_n); + for (auto i = 0U; i < gpio_s.size(); ++i) { + gpio_s[i].in(top.pins_o[i]); + top.pins_i[i](gpio_s[i].out); + } + // terminal + terminal.tx_o(gpio_s[16].in); + gpio_s[17].out(terminal.rx_i); +} +} diff --git a/src/tgc_vp/tb.h b/src/tgc_vp/tb.h new file mode 100644 index 0000000..764e8c9 --- /dev/null +++ b/src/tgc_vp/tb.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2019 -2021 MINRES Technolgies GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SRC_TGC_VP_TB_H_ +#define SRC_TGC_VP_TB_H_ + +#include +#include + +#include "tgc_vp/rst_gen.h" +#include "tgc_vp/system.h" +namespace tgc_vp { + +class tb : public sc_core::sc_module { +public: + tb(sc_core::sc_module_name const& nm); + tgc_vp::system top{"top"}; + tgc_vp::rst_gen rst_gen{"rst_gen"}; + sc_core::sc_vector> gpio_s{"gpio_s", 32}; + sc_core::sc_signal rst_n{"rst_n"}; + vpvper::generic::terminal terminal{"terminal"}; +}; + +} /* namespace tgc_vp */ + +#endif /* SRC_TGC_VP_TB_H_ */ diff --git a/tgc-iss/dbt-rise-core b/tgc-iss/dbt-rise-core new file mode 160000 index 0000000..fd1a504 --- /dev/null +++ b/tgc-iss/dbt-rise-core @@ -0,0 +1 @@ +Subproject commit fd1a504ac63b330f6214710e9259637c3e9ef524 diff --git a/tgc-iss/dbt-rise-tgc b/tgc-iss/dbt-rise-tgc new file mode 160000 index 0000000..09b01af --- /dev/null +++ b/tgc-iss/dbt-rise-tgc @@ -0,0 +1 @@ +Subproject commit 09b01af3fa117e07c665f29b77b3771547771ac2 diff --git a/tgc-iss/generate.sh b/tgc-iss/generate.sh new file mode 100644 index 0000000..d735c0c --- /dev/null +++ b/tgc-iss/generate.sh @@ -0,0 +1,25 @@ +#!/bin/bash +## + + +JAVA_OPTS="--add-modules ALL-SYSTEM --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.annotation=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.lang.module=ALL-UNNAMED --add-opens=java.base/java.lang.ref=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.math=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.net.spi=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/java.nio.channels=ALL-UNNAMED --add-opens=java.base/java.nio.channels.spi=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.nio.charset.spi=ALL-UNNAMED --add-opens=java.base/java.nio.file=ALL-UNNAMED --add-opens=java.base/java.nio.file.attribute=ALL-UNNAMED --add-opens=java.base/java.nio.file.spi=ALL-UNNAMED --add-opens=java.base/java.security=ALL-UNNAMED --add-opens=java.base/java.security.acl=ALL-UNNAMED --add-opens=java.base/java.security.cert=ALL-UNNAMED --add-opens=java.base/java.security.interfaces=ALL-UNNAMED --add-opens=java.base/java.security.spec=ALL-UNNAMED --add-opens=java.base/java.text=ALL-UNNAMED --add-opens=java.base/java.text.spi=ALL-UNNAMED --add-opens=java.base/java.time=ALL-UNNAMED --add-opens=java.base/java.time.chrono=ALL-UNNAMED --add-opens=java.base/java.time.format=ALL-UNNAMED --add-opens=java.base/java.time.temporal=ALL-UNNAMED --add-opens=java.base/java.time.zone=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.locks=ALL-UNNAMED --add-opens=java.base/java.util.function=ALL-UNNAMED --add-opens=java.base/java.util.jar=ALL-UNNAMED --add-opens=java.base/java.util.regex=ALL-UNNAMED --add-opens=java.base/java.util.spi=ALL-UNNAMED --add-opens=java.base/java.util.stream=ALL-UNNAMED --add-opens=java.base/java.util.zip=ALL-UNNAMED --add-opens=java.datatransfer/java.awt.datatransfer=ALL-UNNAMED --add-opens=java.desktop/java.applet=ALL-UNNAMED --add-opens=java.desktop/java.awt=ALL-UNNAMED --add-opens=java.desktop/java.awt.color=ALL-UNNAMED --add-opens=java.desktop/java.awt.desktop=ALL-UNNAMED --add-opens=java.desktop/java.awt.dnd=ALL-UNNAMED --add-opens=java.desktop/java.awt.dnd.peer=ALL-UNNAMED --add-opens=java.desktop/java.awt.event=ALL-UNNAMED --add-opens=java.desktop/java.awt.font=ALL-UNNAMED --add-opens=java.desktop/java.awt.geom=ALL-UNNAMED --add-opens=java.desktop/java.awt.im=ALL-UNNAMED --add-opens=java.desktop/java.awt.im.spi=ALL-UNNAMED --add-opens=java.desktop/java.awt.image=ALL-UNNAMED --add-opens=java.desktop/java.awt.image.renderable=ALL-UNNAMED --add-opens=java.desktop/java.awt.peer=ALL-UNNAMED --add-opens=java.desktop/java.awt.print=ALL-UNNAMED --add-opens=java.desktop/java.beans=ALL-UNNAMED --add-opens=java.desktop/java.beans.beancontext=ALL-UNNAMED --add-opens=java.instrument/java.lang.instrument=ALL-UNNAMED --add-opens=java.logging/java.util.logging=ALL-UNNAMED --add-opens=java.management/java.lang.management=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.rmi/java.rmi=ALL-UNNAMED --add-opens=java.rmi/java.rmi.activation=ALL-UNNAMED --add-opens=java.rmi/java.rmi.dgc=ALL-UNNAMED --add-opens=java.rmi/java.rmi.registry=ALL-UNNAMED --add-opens=java.rmi/java.rmi.server=ALL-UNNAMED --add-opens=java.sql/java.sql=ALL-UNNAMED" + +GENERATOR="java $JAVA_OPTS -jar /scratch/eyck/workarea/RISC-V/TGFS-VERIF/tgfs_iss/coredsl/com.minres.coredsl.generator.repository/target/com.minres.coredsl.generator-2.0.0-SNAPSHOT.jar " + +CORE_NAME=$1 +BACKEND=$2 +CORE_NAME_LC=`echo $CORE_NAME | tr '[:upper:]' '[:lower:]' ` +INPUT_FILE=dbt-rise-tgc/gen_input/TGFS.core_desc + +REPO_DIR=dbt-rise-tgc/gen_input/CoreDSL-Instruction-Set-Description +TMPL_DIR=dbt-rise-tgc/gen_input/templates + +MAPPING="" +MAPPING="$MAPPING -m ${TMPL_DIR}/CORENAME.h.gtl:dbt-rise-tgc/incl/iss/arch/${CORE_NAME_LC}.h" +MAPPING="$MAPPING -m ${TMPL_DIR}/CORENAME.cpp.gtl:dbt-rise-tgc/src/iss/${CORE_NAME_LC}.cpp" +MAPPING="$MAPPING -m ${TMPL_DIR}/${BACKEND}/CORENAME.cpp.gtl:dbt-rise-tgc/src/vm/${BACKEND}/vm_${CORE_NAME_LC}.cpp" + +[ -f /scratch/eyck/workarea/RISC-V/TGFS-VERIF/tgfs_iss/coredsl/com.minres.coredsl.generator.repository/target/com.minres.coredsl.generator-2.0.0-SNAPSHOT.jar ] || (cd /scratch/eyck/workarea/RISC-V/TGFS-VERIF/tgfs_iss/coredsl; mvn package) + +$GENERATOR -c $CORE_NAME -r $REPO_DIR $MAPPING $INPUT_FILE + diff --git a/vpvper b/vpvper new file mode 160000 index 0000000..11e6dc5 --- /dev/null +++ b/vpvper @@ -0,0 +1 @@ +Subproject commit 11e6dc5926a4ee250dc1eb206c97445472049d80