Add platform for sparrow board Bug: 325672220 Change-Id: Ie1a825ab55bdab903f4b13f0c9da29af959f4ea3
diff --git a/platforms/sparrow/builtins.repl b/platforms/sparrow/builtins.repl new file mode 100644 index 0000000..470f2c7 --- /dev/null +++ b/platforms/sparrow/builtins.repl
@@ -0,0 +1,36 @@ +builtins +start hello +sleep 100 +stop hello + +start fibonacci +sleep 1000 +stop fibonacci + +start keyval +sleep 100 +stop keyval + +start logtest +sleep 100 +stop logtest + +start panic +sleep 100 +stop panic + +start timer +sleep 2500 +stop timer + +bundles +mstats + +mstats +start mltest +mstats +sleep 10000 +stop mltest + +bundles +mstats
diff --git a/platforms/sparrow/cantrip.mk b/platforms/sparrow/cantrip.mk new file mode 100644 index 0000000..622ed67 --- /dev/null +++ b/platforms/sparrow/cantrip.mk
@@ -0,0 +1,13 @@ +# For debug builds override the hardware memory config (4MiB -> 64MiB); +# this assumes debug builds run in simulation only or the target hardware +# has a large memory config. +CANTRIP_EXTRA_CMAKE_OPTS_DEBUG := -DKernelCustomDTSOverlay="${ROOTDIR}/build/platforms/nexus/overlay-debug.dts" + +# seL4 platform identity passed to cargo to bring in platform-specific deps +CONFIG_PLATFORM := CONFIG_PLAT_NEXUS + +# NB: seL4 platform identity is passed to cargo to bring in platform-specific deps +# NB: the kcargo shell function searchs for CONFIG_PLATFORM +CANTRIP_GLOBAL_FEATURES_RELEASE := ${CONFIG_PLATFORM} +CANTRIP_GLOBAL_FEATURES_DEBUG := ${CANTRIP_GLOBAL_FEATURES_RELEASE} +
diff --git a/platforms/sparrow/cantrip_apps.mk b/platforms/sparrow/cantrip_apps.mk new file mode 100644 index 0000000..de31bee --- /dev/null +++ b/platforms/sparrow/cantrip_apps.mk
@@ -0,0 +1,3 @@ +# CantripOS Test Application configuration +CANTRIP_APP_ARCH := riscv32 +RUST_TARGET := riscv32imac-unknown-none-elf
diff --git a/platforms/sparrow/cantrip_builtins.mk b/platforms/sparrow/cantrip_builtins.mk new file mode 100644 index 0000000..c8d5c33 --- /dev/null +++ b/platforms/sparrow/cantrip_builtins.mk
@@ -0,0 +1,50 @@ +# Copyright 2022 Google LLC +# +# 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 +# +# https://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. + +CANTRIP_APPS_RELEASE := $(CANTRIP_OUT_C_APP_RELEASE)/hello/hello.app \ + $(CANTRIP_OUT_RUST_APP_RELEASE)/fibonacci/fibonacci.app \ + $(CANTRIP_OUT_RUST_APP_RELEASE)/keyval/keyval.app \ + $(CANTRIP_OUT_RUST_APP_RELEASE)/logtest/logtest.app \ + $(CANTRIP_OUT_RUST_APP_RELEASE)/mltest/mltest.app \ + $(CANTRIP_OUT_RUST_APP_RELEASE)/panic/panic.app \ + $(CANTRIP_OUT_RUST_APP_RELEASE)/playback/playback.app \ + $(CANTRIP_OUT_RUST_APP_RELEASE)/sound/sound.app \ + $(CANTRIP_OUT_C_APP_RELEASE)/suicide/suicide.app \ + $(CANTRIP_OUT_RUST_APP_RELEASE)/timer/timer.app +# Builtins are loaded from SPI flash which is 16M by default +CANTRIP_MODEL_RELEASE := $(OUT)/kelvin/sw/bazel_out/hello_world.kelvin \ + $(OUT)/kelvin_iree/sparrow_iree/samples/microbenchmarks/conv1x1_test_emitc_static.kelvin +ifneq ("$(wildcard $(ROOTDIR)/ml/ml-models)", "") +CANTRIP_MODEL_RELEASE += $(OUT)/kelvin/sw/bazel_out/soundstream_encoder_non_streaming.kelvin +else +# TODO(sleffler): fallback to IREE version +endif + +CANTRIP_APPS_DEBUG := $(CANTRIP_OUT_C_APP_DEBUG)/hello/hello.app \ + $(CANTRIP_OUT_RUST_APP_DEBUG)/fibonacci/fibonacci.app \ + $(CANTRIP_OUT_RUST_APP_DEBUG)/keyval/keyval.app \ + $(CANTRIP_OUT_RUST_APP_DEBUG)/logtest/logtest.app \ + $(CANTRIP_OUT_RUST_APP_DEBUG)/mltest/mltest.app \ + $(CANTRIP_OUT_RUST_APP_DEBUG)/panic/panic.app \ + $(CANTRIP_OUT_RUST_APP_DEBUG)/playback/playback.app \ + $(CANTRIP_OUT_RUST_APP_DEBUG)/sound/sound.app \ + $(CANTRIP_OUT_C_APP_DEBUG)/suicide/suicide.app \ + $(CANTRIP_OUT_RUST_APP_DEBUG)/timer/timer.app +# NB: debug builds only run on Renode where we have 16M for builtins +CANTRIP_MODEL_DEBUG := $(OUT)/kelvin_iree/sparrow_iree/samples/microbenchmarks/conv1x1_test_emitc_static.kelvin + +CANTRIP_SCRIPTS := $(ROOTDIR)/build/platforms/$(PLATFORM)/builtins.repl + +$(patsubst %.kelvin,%.elf,$(CANTRIP_MODEL_RELEASE)): kelvin_hello_world kelvin_soundstream +$(CANTRIP_MODEL_DEBUG): iree_model_builtins
diff --git a/platforms/sparrow/iree.mk b/platforms/sparrow/iree.mk new file mode 100644 index 0000000..782d93b --- /dev/null +++ b/platforms/sparrow/iree.mk
@@ -0,0 +1,181 @@ +# Copyright 2023 Google LLC +# +# 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 +# +# https://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. + +IREE_SRC:=$(ROOTDIR)/toolchain/iree +TOOLCHAINRV32_PATH:=$(CACHE)/toolchain_kelvin +IREE_COMPILER_DIR:=${CACHE}/iree_compiler + +IREE_RUNTIME_ROOT:=$(ROOTDIR)/sw/vec_iree +MODEL_SRC_DIR:=$(ROOTDIR)/ml/ml-models-public +IREE_RUNTIME_OUT=$(OUT)/kelvin_iree +IREE_RUNTIME_STATS_OUT=$(OUT)/kelvin_iree_stats + +MODEL_INTERNAL_SRC_DIR:=$(ROOTDIR)/ml/ml-models +IREE_RUNTIME_INTERNAL_OUT=$(OUT)/kelvin_iree_internal +IREE_RUNTIME_INTERNAL_STATS_OUT=$(OUT)/kelvin_iree_internal_stats + +RV32_EXE_LINKER_FLAGS=-Wl,--print-memory-usage + +RV32_COMPILER_FLAGS=-g3 \ + -ggdb + +# The following targets are always rebuilt when the iree target is made + +iree_check: + @if echo "$${PIN_TOOLCHAINS}" |grep -qw 'iree'; then \ + echo "****************************************************"; \ + echo "* *"; \ + echo "* PIN_TOOLCHAINS includes iree! Skipping the *"; \ + echo "* download of the latest IREE compiler binaries. *"; \ + echo "* Please DO NOT file bugs for IREE mis-behavior! *"; \ + echo "* *"; \ + echo "****************************************************"; \ + else \ + echo Updating $(IREE_SRC) submodules...; \ + git -C $(IREE_SRC) submodule sync && \ + git -C $(IREE_SRC) submodule update --init --jobs=8 --depth=10; \ + fi + +$(IREE_COMPILER_DIR)/build.ninja: | iree_check + cmake -G Ninja -B $(IREE_COMPILER_DIR) \ + -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -DCMAKE_INSTALL_PREFIX=$(IREE_COMPILER_DIR)/install \ + -DIREE_BUILD_TESTS=OFF \ + $(IREE_SRC) + +## Builds the IREE compiler from source and records the HEAD commit ID +iree_compiler_src: $(IREE_COMPILER_DIR)/build.ninja | iree_check + cmake --build $(IREE_COMPILER_DIR) --target install + git -C "$(IREE_SRC)" rev-parse HEAD > $(IREE_COMPILER_DIR)/tag + +$(IREE_COMPILER_DIR): + mkdir -p $(IREE_COMPILER_DIR) + +## Downloads the latest release of the IREE compiler and tflite tools. +# +# The release tag and commit are recorded for consistency checks in +# the `iree_runtime` target. The outputs of this target are placed in +# out/host/iree_compiler. +# +iree_compiler: | $(IREE_COMPILER_DIR) + $(ROOTDIR)/scripts/download_iree_compiler.py --iree_compiler_dir "$(IREE_COMPILER_DIR)" +iree_commit_check: + $(ROOTDIR)/scripts/check-iree-commit.sh "$(IREE_SRC)" "$(IREE_COMPILER_DIR)" + +IREE_RUNTIME_DEFAULT_CONFIG :=\ + -DCMAKE_TOOLCHAIN_FILE="$(IREE_RUNTIME_ROOT)/cmake/riscv_iree_gcc.cmake" \ + -DCMAKE_BUILD_TYPE=MinSizeRel \ + -DIREE_HOST_BIN_DIR="$(IREE_COMPILER_DIR)/install/bin" \ + -DRISCV_TOOLCHAIN_ROOT=$(TOOLCHAINRV32_PATH) \ + -DRISCV_COMPILER_FLAGS="$(RV32_COMPILER_FLAGS)" \ + -DCMAKE_EXE_LINKER_FLAGS="$(RV32_EXE_LINKER_FLAGS)" \ + -DBUILD_WITH_KELVIN=ON \ + -DBUILD_WITH_RVV=OFF + +IREE_RUNTIME_CONFIG :=\ + $(IREE_RUNTIME_DEFAULT_CONFIG) \ + -DPRINT_IREE_STATS=OFF + +IREE_RUNTIME_STATS_CONFIG :=\ + $(IREE_RUNTIME_DEFAULT_CONFIG) \ + -DPRINT_IREE_STATS=ON + +$(IREE_RUNTIME_OUT)/build.ninja: | iree_compiler iree_check iree_commit_check + cmake -G Ninja -B $(IREE_RUNTIME_OUT) \ + $(IREE_RUNTIME_CONFIG) \ + $(MODEL_SRC_DIR) + +## Model artifact used in cantrip-builtins-* +# +# IREE executables used in cantrip-builtins-* +iree_model_builtins: $(IREE_RUNTIME_OUT)/build.ninja | iree_check iree_commit_check + PYTHONPATH=$(IREE_COMPILER_DIR) cmake --build $(IREE_RUNTIME_OUT) --target \ + sparrow_iree/samples/microbenchmarks/conv1x1_test_emitc_static + ln -sfn $(IREE_RUNTIME_OUT)/sparrow_iree/samples/microbenchmarks/conv1x1_test_emitc_static \ + $(IREE_RUNTIME_OUT)/sparrow_iree/samples/microbenchmarks/conv1x1_test_emitc_static.elf + +$(IREE_RUNTIME_INTERNAL_OUT)/build.ninja: | iree_check iree_commit_check + cmake -G Ninja -B $(IREE_RUNTIME_INTERNAL_OUT) \ + $(IREE_RUNTIME_CONFIG) \ + $(MODEL_INTERNAL_SRC_DIR) + +$(IREE_RUNTIME_STATS_OUT)/build.ninja: | iree_check iree_commit_check + cmake -G Ninja -B $(IREE_RUNTIME_STATS_OUT) \ + $(IREE_RUNTIME_STATS_CONFIG) \ + $(MODEL_SRC_DIR) + +$(IREE_RUNTIME_INTERNAL_STATS_OUT)/build.ninja: | iree_check iree_commit_check + cmake -G Ninja -B $(IREE_RUNTIME_INTERNAL_STATS_OUT) \ + $(IREE_RUNTIME_STATS_CONFIG) \ + $(MODEL_INTERNAL_SRC_DIR) + +## Installs the IREE runtime applications. +# +# Unlike the `iree_compiler` target, this target actually builds the runtime +# from source in toolchain/iree. The results of the build are placed in +# out/kelvin_iree. +# +# In general, you probably want the `iree` target instead, which combines +# `iree_compiler` and `iree_runtime`. +iree_runtime: $(IREE_RUNTIME_OUT)/build.ninja | iree_check iree_commit_check + PYTHONPATH=$(IREE_COMPILER_DIR) cmake --build $(IREE_RUNTIME_OUT) + +## Installs the IREE compiler and its runtime applications. +iree: iree_compiler iree_runtime + +## Installs the IREE runtime internal applications. +# +# Unlike the `iree_runtime` target, this target builds the runtime application +# for internal models. The results of the build are placed in +# out/kelvin_iree_internal. +# +# In general, you probably want the `iree_runtime` target instead. +iree_runtime_internal: $(IREE_RUNTIME_INTERNAL_OUT)/build.ninja | \ + iree_check iree_commit_check + PYTHONPATH=$(IREE_COMPILER_DIR) cmake --build $(IREE_RUNTIME_INTERNAL_OUT) + +## Installs the IREE compiler and internal runtime applications. +# +# In general, you probably want to run `iree` target to build the public +# applications. +iree_internal: iree_compiler iree_runtime_internal + +## Installs the IREE runtime applications, with IREE stats printed. +iree_runtime_stats: $(IREE_RUNTIME_STATS_OUT)/build.ninja | iree_check iree_commit_check + PYTHONPATH=$(IREE_COMPILER_DIR) cmake --build $(IREE_RUNTIME_STATS_OUT) + +## Installs the IREE compiler and its runtime applications with IREE stats, for single core testing. +iree_stats: iree_compiler iree_runtime_stats + +## Installs the IREE runtime internal applications, with IREE stats printed. +iree_internal_runtime_stats: $(IREE_RUNTIME_INTERNAL_STATS_OUT)/build.ninja | iree_check iree_commit_check + PYTHONPATH=$(IREE_COMPILER_DIR) cmake --build $(IREE_RUNTIME_INTERNAL_STATS_OUT) + +## Installs the IREE compiler and its runtime applications with IREE stats, for single core testing. +iree_internal_stats: iree_compiler iree_internal_runtime_stats + +## Clean IREE compiler and runtime applications. +iree_clean: + rm -rf $(IREE_COMPILER_DIR) $(IREE_RUNTIME_OUT) $(IREE_RUNTIME_STATS_OUT) + +## Clean IREE compiler and runtime application of internal models +iree_internal_clean: + rm -rf $(IREE_COMPILER_DIR) $(IREE_RUNTIME_INTERNAL_OUT) $(IREE_RUNTIME_INTERNAL_STATS_OUT) + +.PHONY:: iree iree_check iree_compiler iree_runtime iree_clean +.PHONY:: iree_commit_check iree_compiler_src +.PHONY:: iree_runtime_internal iree_internal iree_internal_clean +.PHONY:: iree_runtime_stats iree_stats iree_internal_runtime_stats iree_internal_stats +.PHONY:: iree_model_builtins
diff --git a/platforms/sparrow/kelvin.mk b/platforms/sparrow/kelvin.mk new file mode 100644 index 0000000..f986586 --- /dev/null +++ b/platforms/sparrow/kelvin.mk
@@ -0,0 +1,130 @@ +# Build Kelvin ISS and artifacts. + +KELVIN_SW_SRC_DIR := $(ROOTDIR)/sw/kelvin +KELVIN_SW_OUT_DIR := $(OUT)/kelvin/sw +KELVIN_SW_BAZEL_OUT_DIR := $(KELVIN_SW_OUT_DIR)/bazel_out +KELVIN_SW_TESTLOG_DIR := $(KELVIN_SW_OUT_DIR)/bazel_testlog + +KELVIN_HW_SRC_DIR := $(ROOTDIR)/hw/kelvin +KELVIN_HW_OUT_DIR := $(OUT)/kelvin/hw +KELVIN_HW_BAZEL_OUT_DIR := $(KELVIN_HW_OUT_DIR)/bazel_out +KELVIN_HW_TESTLOG_DIR := $(KELVIN_HW_OUT_DIR)/bazel_testlog + +KELVIN_SIM_SRC_DIR := $(ROOTDIR)/sim/kelvin +KELVIN_SIM_OUT_DIR := $(OUT)/kelvin/sim + +MODEL_INTERNAL_SRC_DIR:=$(ROOTDIR)/ml/ml-models + +$(KELVIN_SW_BAZEL_OUT_DIR): + mkdir -p "$(KELVIN_SW_BAZEL_OUT_DIR)" + +$(KELVIN_SW_TESTLOG_DIR): + mkdir -p "$(KELVIN_SW_TESTLOG_DIR)" + +## Build Kelvin SW artifacts +# +# Some of the artifacts are built with bazel, and need to be copied to out/ +kelvin_sw: | $(KELVIN_SW_BAZEL_OUT_DIR) + cd "$(KELVIN_SW_SRC_DIR)" && \ + bazel build //... + cd "$(KELVIN_SW_SRC_DIR)/bazel-out" && \ + find . -type f \( \ + -wholename "*ST-*/*.elf" -o \ + -wholename "*ST-*/*.bin" \) \ + -exec cp -f {} "$(KELVIN_SW_BAZEL_OUT_DIR)/" \; + +## Build Kelvin hello_world artifacts +# +# Used as the simplest Kelvin SW that has all the syntax CantripOS expects +kelvin_hello_world: | $(KELVIN_SW_BAZEL_OUT_DIR) + cd "$(KELVIN_SW_SRC_DIR)" && \ + bazel build //examples/hello_world:all && \ + cd bazel-out ; find . -type f \( \ + -wholename "*ST-*/*.elf" -o \ + -wholename "*ST-*/*.bin" \) \ + -exec cp -f {} "$(KELVIN_SW_BAZEL_OUT_DIR)/" \; + +## Build Kelvin soundstream artifacts +kelvin_soundstream: | $(KELVIN_SW_BAZEL_OUT_DIR) + cd "$(MODEL_INTERNAL_SRC_DIR)" && \ + bazel build //quant_models/tflm/soundstream:soundstream_encoder_non_streaming && \ + cd bazel-out ; find . -type f -wholename "*ST-*/*.elf" \ + -exec cp -f {} "$(KELVIN_SW_BAZEL_OUT_DIR)/" \; + + +## Test Kelvin SW artifacts +# +# Test Kelvin SW artifacts with kelvin ISS and SystemC simulations +kelvin_sw_test: kelvin_sim kelvin_hw_sim | $(KELVIN_SW_TESTLOG_DIR) + cd "$(KELVIN_SW_SRC_DIR)" && \ + bazel test --test_output=errors --test_tag_filters="-broken" //... && \ + cp -rf bazel-testlogs/tests "$(KELVIN_SW_TESTLOG_DIR)" + +## Clean Kelvin SW artifacts +kelvin_sw_clean: + rm -rf "$(KELVIN_SW_OUT_DIR)" + cd "$(KELVIN_SW_SRC_DIR)" && bazel clean --expunge + + +$(KELVIN_HW_BAZEL_OUT_DIR): + mkdir -p "$(KELVIN_HW_BAZEL_OUT_DIR)" + +$(KELVIN_HW_TESTLOG_DIR): + mkdir -p "$(KELVIN_HW_TESTLOG_DIR)" + +## Verilog Source for Kelvin +# +# This generates the kelvin.v file that can be used to update hw/matcha +kelvin_hw_verilog: | $(KELVIN_HW_BAZEL_OUT_DIR) + cd "$(KELVIN_HW_SRC_DIR)" && \ + bazel clean --expunge && \ + bazel build //hdl/chisel:matcha_kelvin_verilog && \ + cp -rf bazel-bin/hdl/chisel/kelvin.v "$(KELVIN_HW_BAZEL_OUT_DIR)" + +## Verilated Kelvin HW simulator +kelvin_hw_sim: | $(KELVIN_HW_BAZEL_OUT_DIR) + cd "$(KELVIN_HW_SRC_DIR)" && \ + bazel build //tests/verilator_sim:core_sim && \ + cp -rf bazel-bin/tests/verilator_sim/core_sim "$(KELVIN_HW_BAZEL_OUT_DIR)" + +## Tests for Kelvin HW +kelvin_hw_test: | $(KELVIN_HW_TESTLOG_DIR) + cd "$(KELVIN_HW_SRC_DIR)" && \ + bazel test --test_output=errors //... \ + --sandbox_tmpfs_path=/tmp && \ + cp -rf bazel-testlogs/tests "$(KELVIN_HW_TESTLOG_DIR)" + +## Clean Kelvin HW artifacts +kelvin_hw_clean: + rm -rf "$(KELVIN_HW_OUT_DIR)" + cd "$(KELVIN_HW_SRC_DIR)" && bazel clean --expunge + + +$(KELVIN_SIM_OUT_DIR): + mkdir -p "$(KELVIN_SIM_OUT_DIR)" + +## Build Kelvin ISS +# +# Build mpact-sim-based Kelvin ISS with bazel, and copy it to out/ +# Use /tmp as the bazel tmpfs to unblock CI +kelvin_sim: | $(KELVIN_SIM_OUT_DIR) + cd "$(KELVIN_SIM_SRC_DIR)" && \ + bazel build --sandbox_tmpfs_path=/tmp //sim:kelvin_sim \ + //sim/renode:renode_kelvin + cd "$(KELVIN_SIM_SRC_DIR)/bazel-bin" && \ + cp -f sim/kelvin_sim "$(KELVIN_SIM_OUT_DIR)" && \ + cp -f sim/renode/librenode_kelvin.so "$(KELVIN_SIM_OUT_DIR)" + +## Clean Kelvin ISS +# +# Clean the Kelvin ISS +kelvin_sim_clean: + cd "$(KELVIN_SIM_SRC_DIR)" && \ + bazel clean --expunge + rm -rf $(KELVIN_SIM_OUT_DIR) + +PHONY:: kelvin_hw_clean kelvin_hw_sim kelvin_hw_test kelvin_hw_verilog +PHONY:: kelvin_sw kelvin_sw_clean kelvin_sw_test +PHONY:: kelvin_hello_world +PHONY:: kelvin_soundstream +PHONY:: kelvin_sim kelvin_sim_clean
diff --git a/platforms/sparrow/matcha_hw.mk b/platforms/sparrow/matcha_hw.mk new file mode 100644 index 0000000..3dd470c --- /dev/null +++ b/platforms/sparrow/matcha_hw.mk
@@ -0,0 +1,169 @@ +# Copyright 2022 Google LLC +# +# 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 +# +# https://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. + +MATCHA_SRC_DIR := $(ROOTDIR)/hw/matcha +MATCHA_OUT_DIR := $(OUT)/matcha/hw +MATCHA_VERILATOR_TB := $(MATCHA_OUT_DIR)/sim-verilator/Vchip_sim_tb +MATCHA_TESTLOG_DIR := $(MATCHA_OUT_DIR)/test-log +MATCHA_FPGA_BINARY_DIR := $(MATCHA_OUT_DIR)/fpga_tests +MATCHA_FPGA_MATCHA_BINARY_DIR := $(MATCHA_FPGA_BINARY_DIR)/matcha +MATCHA_FPGA_KELVIN_BINARY_DIR := $(MATCHA_FPGA_BINARY_DIR)/kelvin +BOOT_ROM_ELF := boot_rom.elf + +$(MATCHA_OUT_DIR): + mkdir -p $(MATCHA_OUT_DIR) + +## Regenerate Matcha HW files frop IPs and top_matcha definition. +# This target uses Open Titan's autogen tools as well as the HW IPs to generate +# the system verilog files as well as the DV register definition cores and +# system verilog files. The source code is from both hw/opentitan-upstream and +# hw/matcha/, while the output is stored at out/matcha/hw. +# +# This is a dev-only target (not for CI), as it modifies the hw/matcha source +# tree with generated code. +matcha_hw_generate_all: | $(MATCHA_OUT_DIR) + $(MAKE) -C "$(MATCHA_SRC_DIR)/hw" all + +## Build Matcha verilator testbench. +# This target builds the verilator testbench binary from hw/matcha using +# hw/opentitan-upstream as the library. The output is stored in +# out/matcha/hw/. +# This target is compute-intensive. Make sure you have a powerful enough machine +# to build it. +matcha_hw_verilator_sim: $(MATCHA_VERILATOR_TB) + +# TODO(ykwang): Copy only needed files into matcha output directory. +# TODO(ykwang): Revise the structure of matcha output directory. +$(MATCHA_VERILATOR_TB): $(MATCHA_OUT_DIR) verilator + cd $(MATCHA_SRC_DIR) && \ + bazel build //hw:verilator + cd $(MATCHA_SRC_DIR) && \ + cp -rf --no-preserve=mode bazel-bin/hw/build.verilator_real/* "$(MATCHA_OUT_DIR)" && \ + chmod +x "$(MATCHA_OUT_DIR)/sim-verilator/Vchip_sim_tb" + +$(MATCHA_TESTLOG_DIR): + mkdir -p $(MATCHA_TESTLOG_DIR) + +## Build Matcha sw artifacts +# +# Checks the matcha sw code integrity for targets not covered by the verilator +# tests. +# +matcha_sw_all: | $(MATCHA_OUT_DIR) + cd $(MATCHA_SRC_DIR) && \ + bazel build --define DISABLE_VERILATOR_BUILD=true --build_tag_filters="-kelvin_fpga" \ + //sw/device/... + cd $(MATCHA_SRC_DIR) && \ + find "bazel-out/" \( -type f -name "*.elf" -o -name "*.bin" -o -name "*.vmem" \) \ + -exec cp -f --parents "{}" "$(MATCHA_OUT_DIR)" \; + +$(MATCHA_FPGA_MATCHA_BINARY_DIR): + mkdir -p $(MATCHA_FPGA_MATCHA_BINARY_DIR) + +## Build test binaries that run on FPGA +matcha_fpga_tests: | $(MATCHA_FPGA_MATCHA_BINARY_DIR) + cd $(MATCHA_SRC_DIR) && \ + bazel query //sw/device/tests/... \ + | grep 'fpga_nexus' \ + | egrep '_bin$$' \ + | grep -v '/smc:' \ + | grep -v 'kelvin' \ + | grep -v 'example_test_from_rom_rom_prog_fpga_nexus_bin' \ + | xargs bazel build + cd $(MATCHA_SRC_DIR) && \ + find 'bazel-out/' \ + -type f \ + \( -wholename "*ST-*/*fpga_nexus.elf" -o -wholename "*ST-*/*fpga_nexus.bin" \) \ + -exec cp -f '{}' "$(MATCHA_FPGA_MATCHA_BINARY_DIR)" \; + +$(MATCHA_FPGA_KELVIN_BINARY_DIR): + mkdir -p "$(MATCHA_FPGA_KELVIN_BINARY_DIR)" + + +## Build Matcha Kelvin SW FPGA test artifacts +# +# Build kelvin artifacts and package it in a tarball and ready for use on the FPGA +# The output is at out/matcha/hw/fpga_tests/kelvin +# +matcha_kelvin_fpga_tarballs: kelvin_sw | $(MATCHA_FPGA_KELVIN_BINARY_DIR) + cd $(MATCHA_SRC_DIR) && \ + bazel build --define DISABLE_VERILATOR_BUILD=true \ + @kelvin-binary//... +# Copy the tarballs and sc binary to out/. + cd $(MATCHA_SRC_DIR) && \ + find "bazel-out/" -type f -wholename "*fastbuild-*/sw/device/tests/kelvin/fpga_tests/kelvin_test_sc_extflash_fpga_nexus.bin" |\ + xargs -I {} cp -f {} "$(MATCHA_FPGA_KELVIN_BINARY_DIR)" + cd $(MATCHA_SRC_DIR) && \ + find "bazel-bin/external/kelvin-binary" -name "*.tar" |\ + xargs -I {} cp -f {} "$(MATCHA_FPGA_KELVIN_BINARY_DIR)" + + +## Build opentitantool for matcha FPGA tests +opentitantool_pkg: | $(MATCHA_OUT_DIR) + cd $(MATCHA_SRC_DIR) && \ + bazel build //sw:opentitantool_pkg + cd $(MATCHA_SRC_DIR) && \ + cp -f bazel-bin/sw/opentitantool_pkg.tar.gz $(MATCHA_OUT_DIR) + +## Build and run matcha verilator test suite +# +matcha_hw_verilator_tests: verilator | $(MATCHA_TESTLOG_DIR) + cd $(MATCHA_SRC_DIR) && \ + bazel test --test_output=errors --test_timeout=180,600,1800,3600 \ + --local_test_jobs=HOST_CPUS*0.25 \ + --//hw:make_options=-j,16 \ + //sw/device/tests:verilator_test_suite + cd $(MATCHA_SRC_DIR) && cp -rf "bazel-testlogs/sw" "$(MATCHA_TESTLOG_DIR)" + +## Build the boot ROM image +# +# This builds the HW boot rom executable for simulation. +# Source is in hw/matcha, while output is placed in +# out/matcha/hw/ +multihart_boot_rom: | $(MATCHA_OUT_DIR) + cd $(MATCHA_SRC_DIR) && \ + bazel build --config=riscv32 //sw/device/lib/testing/test_rom:test_rom_no_otp_fpga_nexus.elf + cd $(MATCHA_SRC_DIR) && \ + find "bazel-out/" -wholename "*test_rom/test_rom_no_otp_fpga_nexus.elf" \ + -exec cp -f '{}' "$(MATCHA_OUT_DIR)/$(BOOT_ROM_ELF)" \; + +## Clean Matcha HW artifact +matcha_hw_clean: + rm -rf $(MATCHA_OUT_DIR) + cd $(MATCHA_SRC_DIR) && \ + bazel clean --expunge + +## Build the spi_passthough binary +# +# This builds the spi_passthrough_fpga_nexus.bin binary that can be used to +# write flash tarballs to the nexus SPI boot flash. The binary will be copied +# to out/spi_passthrough_fpga_nexus.bin +spi_passthrough: | $(OUT) + cd $(MATCHA_SRC_DIR) && \ + bazel build --define DISABLE_VERILATOR_BUILD=true \ + sw/device/examples/spi_passthrough + find "$(MATCHA_SRC_DIR)/bazel-out/" -type f -wholename "*fastbuild-*/sw/device/examples/spi_passthrough/spi_passthrough_fpga_nexus.bin" |\ + xargs -I '{}' cp -f '{}' "$(OUT)" + +## Fetch latest prebuilt opentitantool +latest_opentitantool: | $(OUT) + curl https://storage.googleapis.com/shodan-public-artifacts/opentitantool_pkg_latest.tar.gz -o $(OUT)/opentitantool_pkg.tar.gz + tar -C $(OUT) -xf $(OUT)/opentitantool_pkg.tar.gz + +.PHONY:: matcha_hw_verilator_sim matcha_hw_clean matcha_hw_verilator_tests +.PHONY:: matcha_sw_all opentitantool_pkg +.PHONY:: matcha_kelvin_fpga_tarballs +.PHONY:: multihart_boot_rom +.PHONY:: spi_passthrough +.PHONY:: latest_opentitantool \ No newline at end of file
diff --git a/platforms/sparrow/opentitan_hw.mk b/platforms/sparrow/opentitan_hw.mk new file mode 100644 index 0000000..548f7ec --- /dev/null +++ b/platforms/sparrow/opentitan_hw.mk
@@ -0,0 +1,48 @@ +# Copyright 2022 Google LLC +# +# 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 +# +# https://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. + +## Run OpenTitan earlgrey smoketests in verilator +# Build the verilated model, the test software and runs the tests +earlgrey_hw_verilator_smoketests: | $(VERILATOR_BIN) $(OPENTITAN_BUILD_LOG_DIR) + cd $(OPENTITAN_SRC_DIR) && \ + bazel query "kind(test, //sw/device/tests:all)" \ + | grep "_smoketest" \ + | xargs bazel test --test_tag_filters=verilator,-broken \ + --define bitstream=skip \ + --test_timeout=180,600,1800,3600 \ + --test_output=errors \ + --local_test_jobs=HOST_CPUS*0.25 \ + --//hw:make_options=-j,8 \ + --build_tests_only=true + cd $(OPENTITAN_SRC_DIR) && \ + cp -rf "bazel-testlogs/sw/device" "$(OPENTITAN_BUILD_LOG_SW_DIR)" + +## Run All the OpenTitan earlgrey device tests in verilator +# Build the verilated model, the test software and runs the tests. +# +# Note: This will take hours to finish. Run it with caution. +earlgrey_hw_verilator_tests_all: | $(VERILATOR_BIN) $(OPENTITAN_BUILD_LOG_DIR) + cd $(OPENTITAN_SRC_DIR) && \ + bazel test --test_tag_filters=verilator,-broken \ + --define bitstream=skip \ + --test_timeout=180,900,1800,3600 \ + --test_output=errors \ + --local_test_jobs=HOST_CPUS*0.25 \ + --//hw:make_options=-j,8 \ + --build_tests_only=true \ + //sw/device/tests:all + cd $(OPENTITAN_SRC_DIR) && \ + cp -rf "bazel-testlogs/sw/device" "$(OPENTITAN_BUILD_LOG_SW_DIR)" + +.PHONY:: earlgrey_hw_verilator_smoketests earlgrey_hw_verilator_tests_all
diff --git a/platforms/sparrow/opentitan_sw.mk b/platforms/sparrow/opentitan_sw.mk new file mode 100644 index 0000000..95e098a --- /dev/null +++ b/platforms/sparrow/opentitan_sw.mk
@@ -0,0 +1,117 @@ +# Copyright 2022 Google LLC +# +# 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 +# +# https://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. + +OPENTITAN_SRC_DIR := $(ROOTDIR)/hw/opentitan-upstream +OPENTITAN_BUILD_DIR := $(OUT)/opentitan/sw +OPENTITAN_BUILD_OUT_DIR := $(OPENTITAN_BUILD_DIR)/build-out +OPENTITAN_BUILD_SW_DIR := $(OPENTITAN_BUILD_DIR)/build-out/sw +OPENTITAN_BUILD_SW_DEVICE_DIR := $(OPENTITAN_BUILD_DIR)/build-out/sw/device +OPENTITAN_BUILD_SW_DEVICE_TESTS_DIR := $(OPENTITAN_BUILD_DIR)/build-out/sw/device/tests +OPENTITAN_BUILD_LOG_DIR := $(OPENTITAN_BUILD_DIR)/build-log +OPENTITAN_BUILD_LOG_SW_DIR := $(OPENTITAN_BUILD_DIR)/build-log/sw + +$(OPENTITAN_BUILD_OUT_DIR): + @echo "Creating output directory $(OPENTITAN_BUILD_DIR)" + @mkdir -p "$(OPENTITAN_BUILD_DIR)" + @mkdir -p "$(OPENTITAN_BUILD_SW_DIR)" + @mkdir -p "$(OPENTITAN_BUILD_SW_DEVICE_DIR)" + @mkdir -p "$(OPENTITAN_BUILD_SW_DEVICE_TESTS_DIR)" + +## Builds the hardware testing binaries from OpenTitan in hw/opentitan-upstream +# The output is stored at out/opentitan/sw/build-out/sw/device +opentitan_sw_all: | $(OPENTITAN_BUILD_OUT_DIR) \ + opentitan_sw_verilator_sim + cd $(OPENTITAN_SRC_DIR) && \ + bazel query "kind(test, //sw/device/tests/...)" | \ + grep "_fpga" | grep -v "power_virus" | \ + xargs bazel build --define bitstream=skip && \ + find "bazel-out/" -type f -wholename "*fastbuild-*/sw/device/tests*/*.elf" | \ + xargs -I {} cp -f {} "$(OPENTITAN_BUILD_SW_DEVICE_TESTS_DIR)/" + cd $(OPENTITAN_SRC_DIR) && \ + bazel build //hw/ip/otbn:all && \ + cp -f bazel-bin/hw/ip/otbn/otbn_simple_smoke_test.elf "$(OPENTITAN_BUILD_SW_DEVICE_TESTS_DIR)/" + +$(OPENTITAN_BUILD_SW_DEVICE_DIR)/examples/hello_world: | $(OPENTITAN_BUILD_OUT_DIR) + @mkdir -p "$(OPENTITAN_BUILD_SW_DEVICE_DIR)/examples/hello_world" + +## Build the sw helloworld ELF from hw/opentitan-upstream +# The output is stored at out/opentitan/sw/build-out/sw/device/examples/hello_world +opentitan_sw_helloworld: | $(OPENTITAN_BUILD_SW_DEVICE_DIR)/examples/hello_world + cd $(OPENTITAN_SRC_DIR) && \ + bazel build //sw/device/examples/hello_world:hello_world + cd $(OPENTITAN_SRC_DIR) && \ + find "bazel-out/" -name "hello_world*.elf" \ + -exec cp -f '{}' "$(OPENTITAN_BUILD_SW_DEVICE_DIR)/examples/hello_world" \; + +$(OPENTITAN_BUILD_SW_DEVICE_DIR)/boot_rom: | $(OPENTITAN_BUILD_OUT_DIR) + @mkdir -p "$(OPENTITAN_BUILD_SW_DEVICE_DIR)/boot_rom" + +## Build the boot rom artifacts for Open Titan from hw/opentitan-upstream +# The artifacts are stored at out/opentitan/sw/build-out/sw/device/boot_rom +# TODO(ykwang): revise boot_rom to test_rom. +opentitan_sw_bootrom: | $(OPENTITAN_BUILD_SW_DEVICE_DIR)/boot_rom + cd $(OPENTITAN_SRC_DIR) && \ + bazel build //sw/device/lib/testing/test_rom:test_rom + cd $(OPENTITAN_SRC_DIR) && \ + find "bazel-out/" -wholename "*fastbuild-*/*test_rom_fpga_cw310.39.scr.vmem" \ + -exec cp -f '{}' "$(OPENTITAN_BUILD_SW_DEVICE_DIR)/boot_rom/" \; + +$(OPENTITAN_BUILD_SW_DEVICE_DIR)/otp_img: | $(OPENTITAN_BUILD_OUT_DIR) + @mkdir -p "$(OPENTITAN_BUILD_SW_DEVICE_DIR)/otp_img" + +## Build the opt image for Open Titan from hw/opentitan-upstream +# The artifacts are stored at out/opentitan/sw/build-out/sw/device/otp_img/otp_img_sim_verilator.vmem +opentitan_opt_img: | $(OPENTITAN_BUILD_SW_DEVICE_DIR)/otp_img + cd $(OPENTITAN_SRC_DIR) && \ + bazel build //hw/ip/otp_ctrl/data:img_dev + cd $(OPENTITAN_SRC_DIR) && \ + find "bazel-bin/" -name "img_dev*.vmem" \ + -exec cp -f '{}' "$(OPENTITAN_BUILD_SW_DEVICE_DIR)/otp_img/otp_img_sim_verilator.vmem" \; + +## Build the Verilator sim SW for Open Titan from hw/opentitan-upstream +# The artifacts include boot_rom, hello_world ELF, and otp image. The artifacts +# are stored at out/opentitan/sw/build-bin +opentitan_sw_verilator_sim: | $(OPENTITAN_BUILD_OUT_DIR) \ + opentitan_sw_helloworld \ + opentitan_sw_bootrom \ + opentitan_opt_img + +$(OPENTITAN_BUILD_LOG_DIR): + @echo "Creating log directory $(OPENTITAN_BUILD_LOG_DIR)" + @mkdir -p "$(OPENTITAN_BUILD_LOG_DIR)" + @mkdir -p "$(OPENTITAN_BUILD_LOG_SW_DIR)" + +## Build and run host based opentitan unittests +# The artifacts are stored at out/opentitan/sw/build-out/sw/device +opentitan_sw_test: | $(OPENTITAN_BUILD_OUT_DIR) \ + $(OPENTITAN_BUILD_LOG_DIR) + cd $(OPENTITAN_SRC_DIR) && \ + export CC=gcc-11; export CXX=g++-11; \ + bazel query "kind(test, //sw/device/...)" | \ + grep "_unittest" | \ + xargs bazel test --build_tests_only=false \ + --define DISABLE_VERILATOR_BUILD=true \ + --test_tag_filters=-broken,-cw310,-verilator,-dv + cd $(OPENTITAN_SRC_DIR) && \ + cp -rf "bazel-bin/sw/device" "$(OPENTITAN_BUILD_SW_DIR)" + cd $(OPENTITAN_SRC_DIR) && \ + cp -rf "bazel-testlogs/sw/device" "$(OPENTITAN_BUILD_LOG_SW_DIR)" + + +## Removes only the OpenTitan build artifacts from out/opentitan/sw +opentitan_sw_clean: + rm -rf $(OPENTITAN_BUILD_DIR) + +.PHONY:: opentitan_sw_all opentitan_sw_clean opentitan_sw_verilator_sim opentitan_sw_test +.PHONY:: opentitan_sw_helloworld opentitan_sw_bootrom opentitan_opt_img
diff --git a/platforms/sparrow/overlay-debug.dts b/platforms/sparrow/overlay-debug.dts new file mode 100644 index 0000000..2a746c1 --- /dev/null +++ b/platforms/sparrow/overlay-debug.dts
@@ -0,0 +1,19 @@ +/* + * Copyright 2021, HENSOLDT Cyber + * + * SPDX-License-Identifier: GPL-2.0-or-later or BSD-3-Clause + */ + +/ { + /* + * Override memory configuration for debug in simulation. The + * real hardware has 4MiB of RAM while the debug simulation + * uses 64MiB. + */ + memory@50000000 { + #address-cells = <1>; + #size-cells = <1>; + device_type = "memory"; + reg = <0x50000000 0x4000000>; + }; +};
diff --git a/platforms/sparrow/platform.mk b/platforms/sparrow/platform.mk new file mode 100644 index 0000000..f9a603c --- /dev/null +++ b/platforms/sparrow/platform.mk
@@ -0,0 +1,95 @@ +# Platform-specific requirements handled by "m prereqs" +CANTRIP_PLATFORM_PYTHON_DEPS=\ + ${ROOTDIR}/hw/opentitan-upstream/python-requirements.txt +CANTRIP_PLATFORM_APT_DEPS=\ + ${ROOTDIR}/hw/opentitan-upstream/apt-requirements.txt + +# Put host tool targets first. +include $(ROOTDIR)/build/platforms/sparrow/renode.mk + +include $(ROOTDIR)/build/platforms/sparrow/cantrip.mk +include $(ROOTDIR)/build/platforms/sparrow/cantrip_builtins.mk +include $(ROOTDIR)/build/platforms/sparrow/iree.mk +include $(ROOTDIR)/build/platforms/sparrow/kelvin.mk +include $(ROOTDIR)/build/platforms/sparrow/opentitan_sw.mk +include $(ROOTDIR)/build/platforms/sparrow/opentitan_hw.mk +include $(ROOTDIR)/build/platforms/sparrow/matcha_hw.mk +include $(ROOTDIR)/build/platforms/sparrow/tock.mk + + +# Put simulation targets at the end +include $(ROOTDIR)/build/platforms/sparrow/sim.mk +include $(ROOTDIR)/build/platforms/sparrow/sim_sel4test.mk + +# Driver include files auto-generated from opentitan definitions. + +ifeq ($(OPENTITAN_SOURCE),) +$(error "OPENTITAN_SOURCE not set. Did build/platforms/sparrow/setup.sh get sourced?") +endif + +ifeq ($(OPENTITAN_GEN_DIR),) +$(error "OPENTITAN_GEN_DIR not set. Did build/platforms/sparrow/setup.sh get sourced?") +endif + +$(OPENTITAN_GEN_DIR): + mkdir -p $(OPENTITAN_GEN_DIR) + +TIMER_IP_DIR=$(OPENTITAN_SOURCE)/hw/ip/rv_timer +TIMER_NINJA=$(TIMER_IP_DIR)/util/reg_timer.py +TIMER_TEMPLATE=$(TIMER_IP_DIR)/data/rv_timer.hjson.tpl + +TIMER_HEADER=$(OPENTITAN_GEN_DIR)/timer.h + +# NB: TIMER_HJSON is set in platforms/sparrow/setup.sh. +$(TIMER_HJSON): $(TIMER_NINJA) $(TIMER_TEMPLATE) | $(OPENTITAN_GEN_DIR) + $(TIMER_NINJA) -s 2 -t 1 $(TIMER_TEMPLATE) > $(TIMER_HJSON) + +$(TIMER_HEADER): $(REGTOOL) $(TIMER_HJSON) + $(REGTOOL) -D -o $@ $(TIMER_HJSON) + +# Matcha hw config #defines generated from RTL + +TOP_MATCHA_DIR=${CANTRIP_OUT_DIR}/top_matcha +TOP_MATCHA_MEMORY_HEADER=$(TOP_MATCHA_DIR)/sw/autogen/top_matcha_memory.h +TOP_MATCHA_IRQ_HEADER=$(TOP_MATCHA_DIR)/sw/autogen/top_matcha_smc_irq.h +# NB: could depend on the templates instead +TOPGEN_MATCHA=${ROOTDIR}/hw/matcha/util/topgen_matcha.py + +${TOP_MATCHA_DIR}: + mkdir -p $(TOP_MATCHA_DIR) + +# NB: no way to generate just the files we need +$(TOP_MATCHA_IRQ_HEADER): $(TOPGEN_MATCHA) ${TOP_MATCHA_DIR} $(TOP_MATCHA_HJSON) + PYTHONPATH=${OPENTITAN_SOURCE}/util/ ${TOPGEN_MATCHA} -t ${TOP_MATCHA_HJSON} -o ${TOP_MATCHA_DIR}/ --top-only +$(TOP_MATCHA_MEMORY_HEADER): $(TOPGEN_MATCHA) ${TOP_MATCHA_DIR} $(TOP_MATCHA_HJSON) + PYTHONPATH=${OPENTITAN_SOURCE}/util/ ${TOPGEN_MATCHA} -t ${TOP_MATCHA_HJSON} -o ${TOP_MATCHA_DIR}/ --top-only + +# Targets to install the symlink to opentitan headers for each build + +cantrip-build-debug-prepare:: | $(CANTRIP_OUT_DEBUG) + ln -sf $(CANTRIP_OUT_DIR)/opentitan-gen $(CANTRIP_OUT_DEBUG)/ + +cantrip-build-release-prepare:: | $(CANTRIP_OUT_RELEASE) + ln -sf $(CANTRIP_OUT_DIR)/opentitan-gen $(CANTRIP_OUT_RELEASE)/ + +sel4test-build-debug-prepare:: | $(SEL4TEST_OUT_DEBUG) + ln -sf $(CANTRIP_OUT_DIR)/opentitan-gen $(SEL4TEST_OUT_DEBUG)/ + +sel4test-build-release-prepare:: | $(SEL4TEST_OUT_RELEASE) + ln -sf $(CANTRIP_OUT_DIR)/opentitan-gen $(SEL4TEST_OUT_RELEASE)/ + +sel4test-build-wrapper-release-prepare:: | $(SEL4TEST_WRAPPER_OUT_RELEASE) + ln -sf $(CANTRIP_OUT_DIR)/opentitan-gen $(SEL4TEST_WRAPPER_OUT_RELEASE)/ + +sel4test-build-wrapper-debug-prepare:: | $(SEL4TEST_WRAPPER_OUT_DEBUG) + ln -sf $(CANTRIP_OUT_DIR)/opentitan-gen $(SEL4TEST_WRAPPER_OUT_DEBUG)/ + +cantrip-gen-headers:: $(TIMER_HEADER) $(TOP_MATCHA_IRQ_HEADER) $(TOP_MATCHA_MEMORY_HEADER) + +cantrip-clean-headers:: + rm -f $(TIMER_HJSON) + rm -f $(TIMER_HEADER) + rm -f $(TOP_MATCHA_IRQ_HEADER) $(TOP_MATCHA_MEMORY_HEADER) + +# Ensure we build verilator as part of tools for this platform +tools:: verilator
diff --git a/platforms/sparrow/renode.mk b/platforms/sparrow/renode.mk new file mode 100644 index 0000000..7100793 --- /dev/null +++ b/platforms/sparrow/renode.mk
@@ -0,0 +1,55 @@ +# Copyright 2022 Google LLC +# +# 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 +# +# https://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. + +RENODE_SRC_DIR := $(ROOTDIR)/sim/renode +RENODE_OUT_DIR := $(CACHE)/renode +RENODE_BIN := $(RENODE_OUT_DIR)/renode +RENODE_PORT ?= 1234 +RENODE_CMD := cd $(ROOTDIR) && $(RENODE_BIN) --disable-xwt --port $(RENODE_PORT) +RENODE_COMMIT := $(shell git -C $(RENODE_SRC_DIR) rev-parse --short=8 HEAD) +RENODE_SIM_GENERATOR_SCRIPT := $(ROOTDIR)/scripts/generate_renode_configs.sh + +$(RENODE_OUT_DIR): + mkdir -p $(RENODE_OUT_DIR) + +$(RENODE_BIN): | $(RENODE_SRC_DIR) $(RENODE_OUT_DIR) + cd $(RENODE_SRC_DIR); unset PLATFORM; \ + ./build.sh --no-gui -d -o $(RENODE_OUT_DIR) + echo -e "built_from_src\ncommit_sha: $(RENODE_COMMIT)\n" > $(RENODE_OUT_DIR)/tag + +## Builds the Renode system simulator +# +# Using sources in sim/renode, this target builds Renode from source and stores +# its output in out/host/renode. +# +# To rebuild this target, run `m renode_clean` and re-run. +# +# This is for debug purpose only. You probably want to use `m renode` target. +renode_src: $(RENODE_BIN) + +## Download and install the nightly release Renode system simulator +# +# From AntMicro's release. If there is a local build from `m renode_src` with +# the same commit sha as the release build, it will be treated as up-to-date. +renode: | $(RENODE_OUT_DIR) + $(ROOTDIR)/scripts/download_renode.py --renode_dir $(RENODE_OUT_DIR) + +## Removes Renode build artifacts from sim/renode and out/ +renode_clean: + @rm -rf $(RENODE_OUT_DIR) + @rm -rf $(RENODE_SRC_DIR)/output + @cd $(RENODE_SRC_DIR); find . -type d -name bin | xargs rm -rf + @cd $(RENODE_SRC_DIR); find . -type d -name obj | xargs rm -rf + +.PHONY:: renode renode_src renode_clean
diff --git a/platforms/sparrow/setup.sh b/platforms/sparrow/setup.sh new file mode 100644 index 0000000..e8fb481 --- /dev/null +++ b/platforms/sparrow/setup.sh
@@ -0,0 +1,247 @@ +#!/bin/bash +# +# Copyright 2020 Google LLC +# +# 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 +# +# https://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. + +export C_PREFIX="riscv32-unknown-elf-" +export IREE_PREFIX="riscv32-unknown-elf-" +export IREE_ARCH="rv32imf" +export RUST_PREFIX="riscv32-unknown-linux-gnu" + +# NB: $(CANTRIP_SRC_DIR)/apps/system/rust.cmake forces riscv32imac for +# the target when building Rust code +export CANTRIP_TARGET_ARCH="riscv32-unknown-elf" + +# Shodan's toolchains are setup specially, just setup the environment. +export RUSTDIR="${CACHE}/rust_toolchain" +export CARGO_HOME="${RUSTDIR}" +export RUSTUP_HOME="${RUSTDIR}" +export PATH="${RUSTDIR}/bin:${PATH}" + +export OPENTITAN_GEN_DIR="${CANTRIP_OUT_DIR}/opentitan-gen/include/opentitan" +export OPENTITAN_SOURCE="${ROOTDIR}/hw/opentitan-upstream" + +# Some build.rs files use the regtool crate which needs to know where to find +# regtool.py. +export REGTOOL="${OPENTITAN_SOURCE}/util/regtool.py" +# The following files are the input to regtool.py +export I2S_HJSON="${ROOTDIR}/hw/matcha/hw/top_matcha/ip/i2s/data/i2s.hjson" +export MBOX_HJSON="${ROOTDIR}/hw/matcha/hw/top_matcha/ip/tlul_mailbox/data/tlul_mailbox.hjson" +export ML_TOP_HJSON="${ROOTDIR}/hw/matcha/hw/top_matcha/ip/ml_top/data/ml_top.hjson" +export TIMER_HJSON="${OPENTITAN_GEN_DIR}/rv_timer.hjson" +export UART_HJSON="${OPENTITAN_SOURCE}/hw/ip/uart/data/uart.hjson" +export VC_TOP_HJSON="${ROOTDIR}/hw/matcha/hw/top_matcha/ip/vc_top/data/vc_top.hjson" +# Input for topgen_matcha.py to generate hw configuration +export TOP_MATCHA_HJSON="${ROOTDIR}/hw/matcha/hw/top_matcha/data/top_matcha.hjson" + +# Standard locations of Sparrow configs and binaries +export OT_TOOL="${ROOTDIR}/out/opentitantool" +export SPARROW_JSON="${ROOTDIR}/out/nexus.json" +export SPARROW_SPI_PASSTHRU="${ROOTDIR}/out/spi_passthrough_asic.bin" + +function parting_messages() { + if [[ ! -d "${RUSTDIR}" ]] || + [[ ! -d "${ROOTDIR}/cache/toolchain" ]] || + [[ ! -d "${ROOTDIR}/cache/toolchain_iree_rv32imf" ]] || + [[ ! -d "${ROOTDIR}/cache/renode" ]]; then + echo + echo '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' + echo You have missing tools. Please run \'m prereqs\' followed + echo by \'m tools\' to install them. + echo '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' + echo + [[ -d "${RUSTDIR}" ]] || echo "${RUSTDIR} is missing!" + [[ -d "${ROOTDIR}/cache/toolchain" ]] || echo "${ROOTDIR}/cache/toolchain is missing" + [[ -d "${ROOTDIR}/cache/toolchain_iree_rv32imf" ]] || echo "${ROOTDIR}/cache/toolchain_iree_rv32imf is missing!" + [[ -d "${ROOTDIR}/cache/renode" ]] || echo "${ROOTDIR}/cache/renode is missing!" + fi + echo Run \'set-sparrow-id NN\' to set your Sparrow board ID +} + +function sim_kelvin +{ + # Run the ELF/Bin program with kelvin_sim + local bin_file="$(realpath $1)" + local magic_bytes="$(xxd -p -l 4 ${bin_file})" + local -a flags=() + local is_elf=false + if [[ ${magic_bytes} == "7f454c46" ]]; then + is_elf=true + else + flags+=("--entry_point 0 ") + fi + + if [[ "$2" == "debug" ]]; then + flags+=("-i") + if [[ "${is_elf}" == false ]]; then + echo "debug mode only works on ELF files" + return 1 + fi + fi + + ("${OUT}/kelvin/sim/kelvin_sim" "${bin_file}" ${flags[@]}) +} + +function sim_kelvin_renode +{ + # Run the Bin program with renode + local bin_file="$(realpath $1)" + local command="start;" + + (cd "${ROOTDIR}" && renode -e "\$bin=@${bin_file}; i @sim/config/kelvin.resc; \ + ${command} sysbus.ml_top_controlblock WriteDoubleWord 0xc 0" \ + --disable-xwt --console) + +} + +function set-sparrow-id +{ + local sparrow_id="${1}"; shift + + if [[ -z "${sparrow_id}" ]]; then + ( + echo "Usage: set-sparrow-id <NN>" + echo + echo "Sets the target Sparrow board to run on. Must be a two digit number" + echo + ) | fmt + return 1 + fi + if [[ "${#sparrow_id}" -ne 2 ]]; then + echo "Sparrow number must be two digits" + return 1 + fi + + export SPARROW_ID="${sparrow_id}" +} + +function opentitantool +{ + # Run built opentitantool with standard flags + if [[ -z "${SPARROW_ID}" ]]; then + echo "Run set-sparrow-id first" + return 1 + fi + + "${OT_TOOL}" --conf "${SPARROW_JSON}" --interface nexus --usb-serial \ + "Sparrow-${SPARROW_ID}" "$@" +} + +function sparrow_reset +{ + # Reset sparrow board + if [[ -z "${SPARROW_ID}" ]]; then + echo "Run set-sparrow-id first" + return 1 + fi + + echo "Resetting sparrow-${SPARROW_ID}" + opentitantool gpio write RESET true + opentitantool gpio write RESET false + opentitantool gpio write RESET true +} + +function sparrow_flash +{ + # Write tar file to sparrow SPI flash and verify + + local flash_tar="$(realpath $1)" + if [[ -z "${flash_tar}" ]]; then + ( + echo "Usage: sparrow_flash path/to/file.tar" + echo + echo "Writes tar file to Sparrow SPI flash for booting." + echo + ) | fmt + return 1 + fi + + if [[ -z "${SPARROW_ID}" ]]; then + echo "Run set-sparrow-id first" + return 1 + fi + + if [[ ! -f "${SPARROW_SPI_PASSTHRU}" ]]; then + echo "INFO: spi_passthrough binary not found at ${SPARROW_SPI_PASSTHRU}" + echo "running `m spi_passthrough` to build it" + m spi_passthrough + if [[ "$?" -ne 0 ]]; then + echo "ERROR: Unable to find or build spi_passthrough!" + return 1 + fi + fi + + sparrow_reset + + local read_size="$(du -b ${flash_tar} | awk '{print $1}')" + local erase_size="$(du -b ${flash_tar} \ + | awk '{ print $1 + (n - $1 % n) % n }' n=262144)" + + echo "Program SPI using ${SPARROW_SPI_PASSTHRU} on sparrow-${SPARROW_ID}" + opentitantool bootstrap "${SPARROW_SPI_PASSTHRU}" + opentitantool spi block-erase --start 0 --length "${erase_size}" + opentitantool spi program --start 0 "${flash_tar}" + + local readback_file="$(mktemp -d)/$(basename ${flash_tar}).readback" + opentitantool spi read --start 0 --length "${read_size}" "${readback_file}" + diff "${flash_tar}" "${readback_file}" + if [[ "$?" -ne 0 ]]; then + echo "ERROR: Sparrow flash verify failed!" + return 1 + fi + rm "${readback_file}" + + sparrow_reset +} + +function sparrow_clear_flash +{ + # Clear the first page of the SPI flash to prevent restarting from the + # loaded program at the next reset. + if [[ -z "${SPARROW_ID}" ]]; then + echo "Run set-sparrow-id first" + return 1 + fi + + echo "Clearing sparrow-${SPARROW_ID} SPI flash" + sparrow_reset + opentitantool bootstrap "${SPARROW_SPI_PASSTHRU}" + opentitantool spi block-erase --start 0 --length 262144 +} + +function sparrow_boot +{ + # Boot the Sparrow board. If flashed, will boot from flash + # This command is a synomym for `opentitantool boot` + echo "Booting Sparrow-${SPARROW_ID}" + opentitantool boot +} + +function sparrow_bootstrap +{ + # Bootstrap a binary on the Sparrow board + + local binary="$(realpath $1)" + if [[ -z "${binary}" ]]; then + ( + echo "Usage: sparrow_flash path/to/file.bin" + echo + echo "Run a binary on the sparrow board." + echo + ) | fmt + return 1 + fi + echo "Bootstrapping ${binary} onto Sparrow-${SPARROW_ID}" + opentitantool bootstrap "${binary}" +}
diff --git a/platforms/sparrow/sim.mk b/platforms/sparrow/sim.mk new file mode 100644 index 0000000..4708391 --- /dev/null +++ b/platforms/sparrow/sim.mk
@@ -0,0 +1,164 @@ +# Copyright 2022 Google LLC +# +# 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 +# +# https://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. + +# NB: keep tarballs in CANTRIP_OUT_DIR to avoid shodan/nexus collisions +EXT_FLASH_DEBUG=$(CANTRIP_OUT_DEBUG)/ext_flash.tar +EXT_FLASH_RELEASE=$(CANTRIP_OUT_RELEASE)/ext_flash.tar + +TMP_DEBUG=$(CANTRIP_OUT_DEBUG)/tmp +TMP_RELEASE=$(CANTRIP_OUT_RELEASE)/tmp + +sim_configs: + $(RENODE_SIM_GENERATOR_SCRIPT) + +clean_sim_configs: + @rm -rf $(OUT)/renode_configs + +$(TMP_DEBUG): + mkdir $(TMP_DEBUG) +$(TMP_RELEASE): + mkdir $(TMP_RELEASE) + +# NB: $(CANTRIP_ROOTSERVER_*) is built together with $(CANTRIP_KERNEL_*) + +$(EXT_FLASH_DEBUG): $(MATCHA_BUNDLE_DEBUG) $(CANTRIP_KERNEL_DEBUG) $(CANTRIP_ROOTSERVER_DEBUG) | $(TMP_DEBUG) + cp -f $(MATCHA_BUNDLE_DEBUG) $(TMP_DEBUG)/matcha-tock-bundle + ${C_PREFIX}strip $(TMP_DEBUG)/matcha-tock-bundle + ${C_PREFIX}objcopy -O binary -g $(TMP_DEBUG)/matcha-tock-bundle $(TMP_DEBUG)/matcha-tock-bundle.bin + ln -sf $(CANTRIP_KERNEL_DEBUG) $(TMP_DEBUG)/kernel + ln -sf $(CANTRIP_ROOTSERVER_DEBUG) $(TMP_DEBUG)/capdl-loader + tar -C $(TMP_DEBUG) -cvhf $@ matcha-tock-bundle.bin kernel capdl-loader +ext_flash_debug: $(EXT_FLASH_DEBUG) + +$(EXT_FLASH_RELEASE): $(MATCHA_BUNDLE_RELEASE) $(CANTRIP_KERNEL_RELEASE) $(CANTRIP_ROOTSERVER_RELEASE) | $(TMP_RELEASE) + cp -f $(MATCHA_BUNDLE_RELEASE) $(TMP_RELEASE)/matcha-tock-bundle + ${C_PREFIX}strip $(TMP_RELEASE)/matcha-tock-bundle + ${C_PREFIX}objcopy -O binary -g $(TMP_RELEASE)/matcha-tock-bundle $(TMP_RELEASE)/matcha-tock-bundle.bin + ln -sf $(CANTRIP_KERNEL_RELEASE) $(TMP_RELEASE)/kernel + ln -sf $(CANTRIP_ROOTSERVER_RELEASE) $(TMP_RELEASE)/capdl-loader + tar -C $(TMP_RELEASE) -cvhf $@ matcha-tock-bundle.bin kernel capdl-loader + +## Packages the builtins in the tarball for writing to SPI flash. +# TODO(sleffler): reorder builtins to before build artifacts to reduce lookup time +ext_flash_release: $(EXT_FLASH_RELEASE) $(EXT_BUILTINS_RELEASE) | $(TMP_RELEASE) + cd $(CANTRIP_OUT_RELEASE)/builtins && \ + ${CPIO} -i < ${CANTRIP_OUT_RELEASE}/archive.capdl-loader_archive.o.cpio && \ + tar -rvhf ${EXT_FLASH_RELEASE} $$(${CPIO} -t < ${CANTRIP_OUT_RELEASE}/archive.capdl-loader_archive.o.cpio) + tar -C $(CANTRIP_OUT_RELEASE)/builtins -rvhf ${EXT_FLASH_RELEASE} $$(${CPIO} -t < ${EXT_BUILTINS_RELEASE}) + +# Renode commands to issue before the initial start of a simulation. +# This pauses all cores and then sets cpu0 (SC) & cpu1 (SMC) running. +RENODE_PRESTART_CMDS=pause; cpu0 IsHalted false; +PORT_PRESTART_CMDS:=$(shell $(ROOTDIR)/scripts/generate-renode-port-cmd.sh $(RENODE_PORT)) + +## Launches an end-to-end build of the Shodan system and starts Renode +# +# This top-level target triggers the `matcha_tock_release`, `cantrip`, `renode`, +# `multihart_boot_rom`, and `iree` targets to build the entire system and then +# finally starts the Renode simulator. +# +# This is the default target for the build system, and is generally what you +# need for day-to-day work on the software side of Shodan. +simulate: renode kelvin_sim multihart_boot_rom ext_flash_release kelvin_hello_world cantrip-builtins-release + $(RENODE_CMD) -e "\ + \$$repl_file = @sim/config/platforms/nexus-release.repl; \ + \$$tar = @$(EXT_FLASH_RELEASE); \ + \$$cpio = @/dev/null; \ + \$$kernel = @$(CANTRIP_KERNEL_RELEASE); \ + \$$sc_bin =@$(TMP_RELEASE)/matcha-tock-bundle.bin; \ + $(PORT_PRESTART_CMDS) i @sim/config/shodan.resc; \ + $(RENODE_PRESTART_CMDS) start" + +## Debug version of the `simulate` target +# +# This top-level target does the same job as `simulate`, but instead of +# unhalting the CPUs and starting the system, this alternate target only unhalts +# cpu0, and uses the debug build of TockOS from the `matcha_tock_debug` target. +# +# NB: requires editing of platform.camkes for alternate cpio_load_address +simulate-debug: renode kelvin_sim multihart_boot_rom ext_flash_debug iree_model_builtins cantrip-builtins-debug + $(RENODE_CMD) -e "\ + \$$repl_file = @sim/config/platforms/nexus-debug.repl; \ + \$$tar = @$(EXT_FLASH_DEBUG); \ + \$$cpio = @/dev/null; \ + \$$kernel = @$(CANTRIP_KERNEL_DEBUG); \ + \$$sc_bin =@$(TMP_DEBUG)/matcha-tock-bundle.bin; \ + $(PORT_PRESTART_CMDS) i @sim/config/shodan.resc; \ + $(RENODE_PRESTART_CMDS) cpu1 CreateSeL4 0xffffffee; start" + +## Debug version of the `simulate` target +# +# This top-level target does the same job as `simulate-debug`, but instead of +# unhalting the CPUs and starting the system, this alternate target starts +# renode with no CPUs unhalted, allowing for GDB to be used for early system +# start. +# +# NB: requires editing of platform.camkes for alternate cpio_load_address +debug-simulation: renode kelvin_sim multihart_boot_rom ext_flash_debug iree_model_builtins cantrip-builtins-debug + $(RENODE_CMD) -e "\ + \$$repl_file = @sim/config/platforms/nexus-debug.repl; \ + \$$tar = @$(EXT_FLASH_DEBUG); \ + \$$cpio = @/dev/null; \ + \$$kernel = @$(CANTRIP_KERNEL_DEBUG); \ + \$$sc_bin =@$(TMP_DEBUG)/matcha-tock-bundle.bin; \ + $(PORT_PRESTART_CMDS) i @sim/config/shodan.resc; start" + +EXT_FLASH_MINISEL_DEBUG=$(CANTRIP_OUT_DEBUG)/ext_flash_minisel.tar +EXT_FLASH_MINISEL_RELEASE=$(CANTRIP_OUT_RELEASE)/ext_flash_minisel.tar + +# Launches Shodan with Minisel as the rootserver for low-level testing purposes. +# NB: the minisel bundle renames "minisel.elf" to "capdl-loader" +# because we don't currently have any way to specify the rootserver app other +# than via filename +# TODO(sleffler): the rootserver is built as a byproduct of building the kernel +$(EXT_FLASH_MINISEL_DEBUG): $(MATCHA_BUNDLE_DEBUG) $(CANTRIP_KERNEL_DEBUG) $(CANTRIP_OUT_DEBUG)/minisel/minisel.elf | $(TMP_DEBUG) + cp -f $(MATCHA_BUNDLE_DEBUG) $(TMP_DEBUG)/matcha-tock-bundle + ${C_PREFIX}strip $(TMP_DEBUG)/matcha-tock-bundle + ${C_PREFIX}objcopy -O binary -g $(TMP_DEBUG)/matcha-tock-bundle $(TMP_DEBUG)/matcha-tock-bundle.bin + ln -sf $(CANTRIP_KERNEL_DEBUG) $(TMP_DEBUG)/kernel + ln -sf $(CANTRIP_OUT_DEBUG)/minisel/minisel.elf $(TMP_DEBUG)/capdl-loader + tar -C $(TMP_DEBUG) -cvhf $@ matcha-tock-bundle.bin kernel capdl-loader +ext_flash_minisel_debug: $(EXT_FLASH_MINISEL_DEBUG) + +# TODO(sleffler): the rootserver is built as a byproduct of building the kernel +$(EXT_FLASH_MINISEL_RELEASE): $(MATCHA_BUNDLE_RELEASE) $(CANTRIP_KERNEL_RELEASE) $(CANTRIP_OUT_RELEASE)/minisel/minisel.elf | $(TMP_RELEASE) + cp -f $(MATCHA_BUNDLE_RELEASE) $(TMP_RELEASE)/matcha-tock-bundle + ${C_PREFIX}strip $(TMP_RELEASE)/matcha-tock-bundle + ${C_PREFIX}objcopy -O binary -g $(TMP_RELEASE)/matcha-tock-bundle $(TMP_RELEASE)/matcha-tock-bundle.bin + ln -sf $(CANTRIP_KERNEL_RELEASE) $(TMP_RELEASE)/kernel + ln -sf $(CANTRIP_OUT_RELEASE)/minisel/minisel.elf $(TMP_RELEASE)/capdl-loader + tar -C $(TMP_RELEASE) -cvhf $@ matcha-tock-bundle.bin kernel capdl-loader +ext_flash_minisel_release: $(EXT_FLASH_MINISEL_RELEASE) + +simulate_minisel: renode multihart_boot_rom ext_flash_minisel_debug + $(RENODE_CMD) -e "\ + \$$repl_file = @sim/config/platforms/nexus-debug.repl; \ + \$$tar = @$(EXT_FLASH_MINISEL_DEBUG); \ + \$$kernel = @$(CANTRIP_KERNEL_DEBUG); \ + \$$cpio = @/dev/null; \ + \$$sc_bin =@$(TMP_DEBUG)/matcha-tock-bundle.bin; \ + $(PORT_PRESTART_CMDS) i @sim/config/shodan.resc; \ + $(RENODE_PRESTART_CMDS) start" + +simulate_minisel_release: renode multihart_boot_rom ext_flash_minisel_release + $(RENODE_CMD) -e "\ + \$$repl_file = @sim/config/platforms/nexus-release.repl; \ + \$$tar = @$(EXT_FLASH_MINISEL_RELEASE); \ + \$$kernel = @$(CANTRIP_KERNEL_RELEASE); \ + \$$cpio = @/dev/null; \ + \$$sc_bin =@$(TMP_RELEASE)/matcha-tock-bundle.bin; \ + $(PORT_PRESTART_CMDS) i @sim/config/shodan.resc; \ + $(RENODE_PRESTART_CMDS) start" + +.PHONY:: sim_configs clean_sim_configs simulate simulate-debug debug-simulation
diff --git a/platforms/sparrow/sim_sel4test.mk b/platforms/sparrow/sim_sel4test.mk new file mode 100644 index 0000000..ecaf7d2 --- /dev/null +++ b/platforms/sparrow/sim_sel4test.mk
@@ -0,0 +1,78 @@ +# Copyright 2022 Google LLC +# +# 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 +# +# https://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. + +# sel4test simulation support; this is meant to be included from sim.mk + +SEL4TEST_TMP=$(SEL4TEST_OUT_DEBUG)/tmp +${SEL4TEST_TMP}: + mkdir $@ + +SEL4TEST_EXT_FLASH_TAR=$(SEL4TEST_OUT_DEBUG)/ext_flash.tar + +# NB: release builds do not have enough memory to run sel4test; they +# will fail to build when elfloader looks for a location to load the image + +$(SEL4TEST_EXT_FLASH_TAR): $(MATCHA_BUNDLE_DEBUG) \ + $(SEL4TEST_KERNEL_DEBUG) $(SEL4TEST_ROOTSERVER_DEBUG) | $(SEL4TEST_TMP) + cp -f $(MATCHA_BUNDLE_DEBUG) $(SEL4TEST_TMP)/matcha-tock-bundle + ${C_PREFIX}strip $(SEL4TEST_TMP)/matcha-tock-bundle + ${C_PREFIX}objcopy -O binary -g $(SEL4TEST_TMP)/matcha-tock-bundle ${SEL4TEST_TMP}/matcha-tock-bundle.bin + ln -sf $(SEL4TEST_KERNEL_DEBUG) $(SEL4TEST_TMP)/kernel + ln -sf $(SEL4TEST_ROOTSERVER_DEBUG) $(SEL4TEST_TMP)/capdl-loader + tar -C $(SEL4TEST_TMP) -cvhf $@ matcha-tock-bundle.bin kernel capdl-loader + +## Launches the sel4test target with minimal modifications. +sel4test: renode multihart_boot_rom $(SEL4TEST_EXT_FLASH_TAR) + $(RENODE_CMD) -e "\ + \$$repl_file = @sim/config/platforms/$(PLATFORM)-debug.repl; \ + \$$tar = @$(SEL4TEST_EXT_FLASH_TAR); \ + \$$kernel = @$(SEL4TEST_KERNEL_DEBUG); \ + \$$cpio = @/dev/null; \ + \$$sc_bin =@$(SEL4TEST_TMP)/matcha-tock-bundle.bin; \ + $(PORT_PRESTART_CMDS) i @sim/config/shodan.resc; \ + $(RENODE_PRESTART_CMDS) start" + +# NB: for compatability +sel4test-debug: sel4test + +SEL4TEST_WRAPPER_TMP=$(SEL4TEST_WRAPPER_OUT_DEBUG)/tmp +${SEL4TEST_WRAPPER_TMP}: + mkdir $@ + +SEL4TEST_WRAPPER_EXT_FLASH_TAR=$(SEL4TEST_WRAPPER_OUT_DEBUG)/ext_flash.tar + +$(SEL4TEST_WRAPPER_EXT_FLASH_TAR): $(MATCHA_BUNDLE_DEBUG) \ + $(SEL4TEST_KERNEL_DEBUG) $(SEL4TEST_WRAPPER_ROOTSERVER_DEBUG) | $(SEL4TEST_WRAPPER_TMP) + cp -f $(MATCHA_BUNDLE_DEBUG) $(SEL4TEST_WRAPPER_TMP)/matcha-tock-bundle + ${C_PREFIX}strip $(SEL4TEST_WRAPPER_TMP)/matcha-tock-bundle + ${C_PREFIX}objcopy -O binary -g $(SEL4TEST_WRAPPER_TMP)/matcha-tock-bundle ${SEL4TEST_WRAPPER_TMP}/matcha-tock-bundle.bin + ln -sf $(SEL4TEST_KERNEL_DEBUG) $(SEL4TEST_WRAPPER_TMP)/kernel + ln -sf $(SEL4TEST_WRAPPER_ROOTSERVER_DEBUG) $(SEL4TEST_WRAPPER_TMP)/capdl-loader + tar -C $(SEL4TEST_WRAPPER_TMP) -cvhf $@ matcha-tock-bundle.bin kernel capdl-loader + +## Launches a version of the sel4test target that uses the sel4-sys Rust +## crate wrapped with C shims. The result is run under Renode. +sel4test+wrapper: renode multihart_boot_rom $(SEL4TEST_WRAPPER_EXT_FLASH_TAR) + $(RENODE_CMD) -e "\ + \$$repl_file = @sim/config/platforms/$(PLATFORM)-debug.repl; \ + \$$tar = @$(SEL4TEST_WRAPPER_EXT_FLASH_TAR); \ + \$$kernel = @$(SEL4TEST_KERNEL_DEBUG); \ + \$$cpio = @/dev/null; \ + \$$sc_bin =@$(SEL4TEST_WRAPPER_TMP)/matcha-tock-bundle.bin; \ + $(PORT_PRESTART_CMDS) i @sim/config/shodan.resc; \ + $(RENODE_PRESTART_CMDS) start" + +.PHONY:: sel4test +.PHONY:: sel4test-debug +.PHONY:: sel4test+wrapper
diff --git a/platforms/sparrow/tock.mk b/platforms/sparrow/tock.mk new file mode 100644 index 0000000..348251d --- /dev/null +++ b/platforms/sparrow/tock.mk
@@ -0,0 +1,73 @@ +# Copyright 2022 Google LLC +# +# 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 +# +# https://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. + +# Matcha platform + kernel binaries +MATCHA_PLATFORM_SRC_DIR := $(ROOTDIR)/sw/matcha/platform/ +MATCHA_PLATFORM_DEBUG := $(OUT)/matcha/riscv32imc-unknown-none-elf/debug/matcha_platform +MATCHA_PLATFORM_RELEASE := $(OUT)/matcha/riscv32imc-unknown-none-elf/release/matcha_platform + +# Matcha app binaries +MATCHA_APP_SRC_DIR := $(ROOTDIR)/sw/matcha/app/ +MATCHA_APP_DEBUG := $(OUT)/matcha/riscv32imc-unknown-none-elf/debug/matcha_app +MATCHA_APP_RELEASE := $(OUT)/matcha/riscv32imc-unknown-none-elf/release/matcha_app + +# Bundled platform+kernel+app binaries +MATCHA_BUNDLE_DEBUG := $(OUT)/matcha-bundle-debug.elf +MATCHA_BUNDLE_RELEASE := $(OUT)/matcha-bundle-release.elf + +######################################## + +$(RUSTDIR)/bin/elf2tab: | rust_presence_check + cargo install elf2tab --version 0.6.0 + +$(MATCHA_APP_DEBUG): | rust_presence_check + export CARGO_NET_GIT_FETCH_WITH_CLI=true; \ + cd $(MATCHA_PLATFORM_SRC_DIR); cargo -Z unstable-options --config 'build.rustflags = ["-C", "link-arg=-Tlayout_debug.ld"]' build + cd $(MATCHA_APP_SRC_DIR); PLATFORM=opentitan cargo -Z unstable-options --config 'build.rustflags = ["-C", "link-arg=-Tlayout_matcha_debug.ld",]' build + +$(MATCHA_APP_RELEASE): | rust_presence_check + export CARGO_NET_GIT_FETCH_WITH_CLI=true; \ + cd $(MATCHA_PLATFORM_SRC_DIR); cargo -Z unstable-options --config 'build.rustflags = ["-C", "link-arg=-Tlayout.ld"]' build --release + cd $(MATCHA_APP_SRC_DIR); PLATFORM=opentitan cargo -Z unstable-options --config 'build.rustflags = ["-C", "link-arg=-Tlayout_matcha.ld",]' build --release + +$(MATCHA_BUNDLE_DEBUG): $(MATCHA_APP_DEBUG) $(RUSTDIR)/bin/elf2tab | rust_presence_check + elf2tab -n matcha -o $(MATCHA_APP_DEBUG).tab $(MATCHA_APP_DEBUG) --stack 4096 --app-heap 1024 --kernel-heap 1024 --protected-region-size=64 + cp $(MATCHA_PLATFORM_DEBUG) $(MATCHA_BUNDLE_DEBUG) + riscv32-unknown-elf-objcopy --update-section .apps=$(MATCHA_APP_DEBUG).tbf $(MATCHA_BUNDLE_DEBUG) + +$(MATCHA_BUNDLE_RELEASE): $(MATCHA_APP_RELEASE) $(RUSTDIR)/bin/elf2tab | rust_presence_check + elf2tab -n matcha -o $(MATCHA_APP_RELEASE).tab $(MATCHA_APP_RELEASE) --stack 4096 --app-heap 1024 --kernel-heap 1024 --protected-region-size=64 + cp $(MATCHA_PLATFORM_RELEASE) $(MATCHA_BUNDLE_RELEASE) + riscv32-unknown-elf-objcopy --update-section .apps=$(MATCHA_APP_RELEASE).tbf $(MATCHA_BUNDLE_RELEASE) + +######################################## + +## Builds TockOS for the security core in debug mode +matcha_tock_debug: $(MATCHA_BUNDLE_DEBUG) + +## Builds TockOS for the security core in release mode +matcha_tock_release: $(MATCHA_BUNDLE_RELEASE) + +## Removes the TockOS and libtockrs build artifacts from out/ +matcha_tock_clean: + cd $(MATCHA_PLATFORM_SRC_DIR); PLATFORM=opentitan cargo clean --target-dir=$(OUT)/matcha + cd $(MATCHA_APP_SRC_DIR); PLATFORM=opentitan cargo clean --target-dir=$(OUT)/matcha + rm -rf $(OUT)/matcha + rm -f $(MATCHA_BUNDLE_DEBUG) $(MATCHA_BUNDLE_RELEASE) + +.PHONY:: matcha_tock_debug matcha_tock_release matcha_tock_clean + +# Mark these real files as phony since building them requires calling out to a +# separate build system (cargo) +.PHONY:: $(MATCHA_APP_DEBUG) $(MATCHA_APP_RELEASE)