| From 12485c998481c4414e157a7b6d475c2c118fce77 Mon Sep 17 00:00:00 2001 |
| From: Greg Chadwick <gac@lowrisc.org> |
| Date: Wed, 15 Apr 2020 15:44:54 +0100 |
| Subject: [PATCH 2/5] Add OpenTitan target |
| |
| |
| diff --git a/Makefile b/Makefile |
| index 25557c1..a6fd315 100644 |
| --- a/Makefile |
| +++ b/Makefile |
| @@ -50,6 +50,11 @@ else |
| ifeq ($(RISCV_TARGET),riscvOVPsim) |
| JOBS ?= -j8 --max-load=4 |
| endif |
| + ifeq ($(RISCV_TARGET),opentitan) |
| + ifeq ($(OT_TARGET),sim_verilator) |
| + JOBS ?= -j4 |
| + endif |
| + endif |
| endif |
| |
| default: $(DEFAULT_TARGET) |
| @@ -90,4 +95,3 @@ help: |
| @echo "RISCV_ISA='$(RISCV_ISA_OPT)'" |
| @echo "RISCV_TEST='I-ADD-01'" |
| @echo "make all_variant // all combinations" |
| - |
| diff --git a/riscv-target/opentitan/README.md b/riscv-target/opentitan/README.md |
| new file mode 100644 |
| index 0000000..353a9b3 |
| --- /dev/null |
| +++ b/riscv-target/opentitan/README.md |
| @@ -0,0 +1,152 @@ |
| + |
| +# Overview |
| +The RISC-V compliance test can be run on either OpenTitan FPGA or Verilator. |
| +OpenTitan is an open source project to build transparent, high-quality reference |
| +designs for silicon root of trust chips. Please see the [OpenTitan |
| +website](https://opentitan.org) for more details. |
| + |
| +To run on Verilator, set the variables below |
| + |
| +```console |
| +$ export RISCV_TARGET=opentitan |
| +$ export RISCV_DEVICE=rv32imc |
| +$ export OT_TARGET=sim_verilator |
| +``` |
| + |
| +To run on FPGA, set the variables below. The `OT_FPGA_UART` variable must be |
| +set to wherever a valid device is connected. |
| + |
| +```console |
| +$ export RISCV_TARGET=opentitan |
| +$ export RISCV_DEVICE=rv32imc |
| +$ export OT_TARGET=fpga_nexysvideo |
| +$ export OT_FPGA_UART=/dev/tty* |
| +``` |
| + |
| +By default, the test assumes there exists a valid Verilator build at |
| +`${REPO_TOP}/build/lowrisc_systems_top_earlgrey_verilator_0.1/sim-verilator/Vtop_earlgrey_verilator`. |
| +If your Verilator build is at a different location, please set that as well when |
| +running with Verilator. |
| + |
| +```console |
| +$ export TARGET_SIM=${PATH_TO_VERILATOR_BUILD} |
| +``` |
| + |
| +When running against FPGA, the test assumes the FPGA is already programmed and |
| +ready to go with spiflash available at `$BIN_DIR/sw/host/spiflash/spiflash`. |
| +To quickly get started with a verilator binary or FPGA bitfile, please see the |
| +[OpenTitan quick start guide](https://docs.opentitan.org/doc/ug/quickstart/). |
| + |
| +Finally the support software must be built, including the test_rom when using |
| +the verilator target. |
| + |
| +```console |
| +$ cd $REPO_TOP |
| +$ ./meson_init.sh |
| +$ ninja -C ./build-out all |
| +``` |
| + |
| +Now, run the tests from the riscv_compliance directory. The following output |
| +will be seen (software build steps are truncated). The example below uses |
| +Verilator as an example, but the FPGA output is nearly identical. |
| + |
| +```console |
| +$ cd $RISCV_COMPLIANCE_REPO_BASE |
| +$ make RISCV_ISA=rv32i |
| + |
| +... verbose test output ... |
| + |
| +Compare to reference files ... |
| + |
| +Check I-ADD-01 ... OK |
| +Check I-ADDI-01 ... OK |
| +Check I-AND-01 ... OK |
| +Check I-ANDI-01 ... OK |
| +Check I-AUIPC-01 ... OK |
| +Check I-BEQ-01 ... OK |
| +Check I-BGE-01 ... OK |
| +Check I-BGEU-01 ... OK |
| +Check I-BLT-01 ... OK |
| +Check I-BLTU-01 ... OK |
| +Check I-BNE-01 ... OK |
| +Check I-DELAY_SLOTS-01 ... OK |
| +Check I-EBREAK-01 ... OK |
| +Check I-ECALL-01 ... OK |
| +Check I-ENDIANESS-01 ... OK |
| +Check I-IO-01 ... OK |
| +Check I-JAL-01 ... OK |
| +Check I-JALR-01 ... OK |
| +Check I-LB-01 ... OK |
| +Check I-LBU-01 ... OK |
| +Check I-LH-01 ... OK |
| +Check I-LHU-01 ... OK |
| +Check I-LUI-01 ... OK |
| +Check I-LW-01 ... OK |
| +Check I-MISALIGN_JMP-01 ... IGNORE |
| +Check I-MISALIGN_LDST-01 ... IGNORE |
| +Check I-NOP-01 ... OK |
| +Check I-OR-01 ... OK |
| +Check I-ORI-01 ... OK |
| +Check I-RF_size-01 ... OK |
| +Check I-RF_width-01 ... OK |
| +Check I-RF_x0-01 ... OK |
| +Check I-SB-01 ... OK |
| +Check I-SH-01 ... OK |
| +Check I-SLL-01 ... OK |
| +Check I-SLLI-01 ... OK |
| +Check I-SLT-01 ... OK |
| +Check I-SLTI-01 ... OK |
| +Check I-SLTIU-01 ... OK |
| +Check I-SLTU-01 ... OK |
| +Check I-SRA-01 ... OK |
| +Check I-SRAI-01 ... OK |
| +Check I-SRL-01 ... OK |
| +Check I-SRLI-01 ... OK |
| +Check I-SUB-01 ... OK |
| +Check I-SW-01 ... OK |
| +Check I-XOR-01 ... OK |
| +Check I-XORI-01 ... OK |
| +-------------------------------- |
| +OK: 48/48 |
| +``` |
| + |
| +There are several test suites that can be run `rv32i`, `rv32im`, `rv32imc` and |
| +`rv32Zicsr`. Change the `RISCV_ISA` argument passed to `make` to choose between |
| +them. |
| + |
| +## Changing targets |
| +When switching between targets (i.e. between FPGA and verilator) the `work` |
| +directory in the `riscv_compliance` tree must be remove to force a software |
| +rebuild. |
| + |
| +```console |
| +$ cd $RISCV_COMPLIANCE_REPO_BASE |
| +$ rm -rf ./work |
| +``` |
| + |
| +## Parallel runs |
| +When running against the `sim_verilator` target parallel make jobs are used (via |
| +passing `-j4` to make internally). Parallel runs can be disabled by passing |
| +`PARALLEL=0` to the `make` command or the `-j` used can be altered with the |
| +`JOBS` argument. |
| + |
| +Disable parallel runs: |
| +```console |
| +$ make RISCV_ISA=rv32i PARALLEL=0 |
| +``` |
| + |
| +Use a different `-j` parameter: |
| +```console |
| +$ make RISCV_ISA=rv32i JOBS=-j8 |
| +``` |
| + |
| +## Removed/Broken Tests |
| +A small number of tests are not run for OpenTitan riscv_compliance as they fail |
| +due to flaws in the compliance test suite rather than Ibex/OpenTitan itself (see |
| +https://github.com/lowRISC/ibex/issues/100). The I-FENCE.I-01 test attempts to |
| +write instruction memory which fails in the OT system as this writes to flash |
| +which can't be done. |
| + |
| +* I-MISALIGN_JMP-01 |
| +* I-MISALIGN_LDST-01 |
| +* I-FENCE.I-01 |
| diff --git a/riscv-target/opentitan/compliance_io.h b/riscv-target/opentitan/compliance_io.h |
| new file mode 100644 |
| index 0000000..d5d88d4 |
| --- /dev/null |
| +++ b/riscv-target/opentitan/compliance_io.h |
| @@ -0,0 +1,22 @@ |
| +// Copyright lowRISC contributors. |
| +// Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| +// SPDX-License-Identifier: Apache-2.0 |
| + |
| +// RISC-V Compliance IO Test Header File |
| + |
| + |
| +#ifndef _COMPLIANCE_IO_H |
| +#define _COMPLIANCE_IO_H |
| + |
| +//----------------------------------------------------------------------- |
| +// RV IO Macros (Non functional) |
| +//----------------------------------------------------------------------- |
| + |
| +#define RVTEST_IO_INIT |
| +#define RVTEST_IO_WRITE_STR(_SP, _STR) |
| +#define RVTEST_IO_CHECK() |
| +#define RVTEST_IO_ASSERT_GPR_EQ(_SP, _R, _I) |
| +#define RVTEST_IO_ASSERT_SFPR_EQ(_F, _R, _I) |
| +#define RVTEST_IO_ASSERT_DFPR_EQ(_D, _R, _I) |
| + |
| +#endif // _COMPLIANCE_IO_H |
| diff --git a/riscv-target/opentitan/compliance_test.h b/riscv-target/opentitan/compliance_test.h |
| new file mode 100644 |
| index 0000000..6a889cf |
| --- /dev/null |
| +++ b/riscv-target/opentitan/compliance_test.h |
| @@ -0,0 +1,35 @@ |
| +// Copyright lowRISC contributors. |
| +// Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| +// SPDX-License-Identifier: Apache-2.0 |
| + |
| +// RISC-V Compliance Test Header File |
| + |
| +#ifndef _COMPLIANCE_TEST_H |
| +#define _COMPLIANCE_TEST_H |
| + |
| +#include "riscv_test.h" |
| + |
| +//----------------------------------------------------------------------- |
| +// RV Compliance Macros |
| +//----------------------------------------------------------------------- |
| +#define RV_COMPLIANCE_HALT \ |
| + j end_rvc_test; \ |
| + |
| +#define RV_COMPLIANCE_RV32M \ |
| + RVTEST_RV32M \ |
| + |
| + |
| +#define RV_COMPLIANCE_CODE_BEGIN \ |
| + RVTEST_CODE_BEGIN \ |
| + |
| +#define RV_COMPLIANCE_CODE_END \ |
| + RVTEST_CODE_END \ |
| + |
| +#define RV_COMPLIANCE_DATA_BEGIN \ |
| + .section .data; \ |
| + RVTEST_DATA_BEGIN \ |
| + |
| +#define RV_COMPLIANCE_DATA_END \ |
| + RVTEST_DATA_END \ |
| + |
| +#endif |
| diff --git a/riscv-target/opentitan/device/rv32imc/Makefile.include b/riscv-target/opentitan/device/rv32imc/Makefile.include |
| new file mode 100644 |
| index 0000000..b71105c |
| --- /dev/null |
| +++ b/riscv-target/opentitan/device/rv32imc/Makefile.include |
| @@ -0,0 +1,75 @@ |
| +# Copyright lowRISC contributors. |
| +# Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| +# SPDX-License-Identifier: Apache-2.0 |
| + |
| +OPENTITAN = $(ROOTDIR)/riscv-target/$(RISCV_TARGET)/device/rv32imc |
| +OT_ROOT ?= $(ROOTDIR)/../../../ |
| +OT_SW = $(OT_ROOT)/sw/device |
| +OT_BIN ?= $(OT_ROOT)/build-bin |
| +OT_TOOLS ?= /tools/riscv/bin |
| +OT_FPGA_UART ?= |
| +OT_TARGET ?= fpga_nexysvideo |
| +LDSCRIPT = $(OT_ROOT)/sw/device/exts/common/flash_link.ld |
| +DEFINES = $(CARG) -DPRIV_MISA_S=0 -DPRIV_MISA_U=0 -DRVTEST_ENTRY=_rvc_start -DTRAPALIGN=8 |
| +TARGET_SIM ?= $(OT_ROOT)/build/lowrisc_systems_top_earlgrey_verilator_0.1/sim-verilator/Vtop_earlgrey_verilator |
| + |
| +COMPLIANCE_LIB_EXPORT = sw/device/riscv_compliance_support/riscv_compliance_support_export_$(OT_TARGET) |
| +COMPLIANCE_LIB = ot_riscv_compliance_support_$(OT_TARGET) |
| + |
| +# The run target recipe does the following things: |
| +# Invoke pytest to run the test |
| +# Parse the resulting log for the output signatures |
| +# Convert all signatures to lower case since the reference is in all lower case |
| +ifeq ($(OT_TARGET),sim_verilator) |
| + MAKEARG = SIM=1 |
| + CARG = -DSIMULATION=1 |
| + RUN_TARGET = \ |
| + $(TARGET_SIM) \ |
| + --meminit="rom,$(OT_BIN)/sw/device/lib/testing/test_rom/test_rom_sim_verilator.elf" \ |
| + --meminit="flash,$(<)" \ |
| + +UARTDPI_LOG_uart0="$(*).uart.log" > $@ 2>&1 \ |
| + && sed -e 's/^/[UART $(shell basename $(*))] /' "$(*).uart.log" $(REDIR) \ |
| + && grep -o 'SIG: [a-zA-Z0-9_]*' "$(*).uart.log" \ |
| + | sed 's/SIG: //' > $(*).signature.output |
| +else ifeq ($(OT_TARGET),fpga_nexysvideo) |
| + MAKEARG = |
| + CARG = |
| + RUN_TARGET = \ |
| + ( test -e "$(OT_FPGA_UART)" || ( echo "UART device '$(OT_FPGA_UART)' not available. Set OT_FPGA_UART." >&2 && exit 1 ) ) \ |
| + && echo "Writing '$(<).bin' to device." \ |
| + && $(OT_BIN)/sw/host/spiflash/spiflash --input="$(<).bin" \ |
| + && stty -F "$(OT_FPGA_UART)" speed 115200 cs8 -cstopb -parenb \ |
| + && grep -o 'SIG: [a-zA-Z0-9_]*' "$(OT_FPGA_UART)" \ |
| + | sed 's/SIG: //' > $(*).signature.output |
| +else |
| + $(error Unsupported target $(OT_TARGET)) |
| +endif |
| + |
| +RISCV_PREFIX ?= ${OT_TOOLS}/riscv32-unknown-elf- |
| +RISCV_GCC ?= ${OT_TOOLS}/riscv32-unknown-elf-gcc |
| +RISCV_OBJDUMP ?= ${OT_TOOLS}/riscv32-unknown-elf-objdump |
| +RISCV_OBJCOPY ?= ${OT_TOOLS}/riscv32-unknown-elf-objcopy |
| +RISCV_NM ?= ${OT_TOOLS}/riscv32-unknown-elf-nm |
| +RISCV_READELF ?= ${OT_TOOLS}/riscv32-unknown-elf-readelf |
| +RISCV_GCC_OPTS ?= -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -fno-builtin -g -Wl,--no-relax |
| + |
| +COMPILE_TARGET += \ |
| + $$(RISCV_GCC) $(1) $$(RISCV_GCC_OPTS) \ |
| + -I$(ROOTDIR)/riscv-test-env/ \ |
| + -I$(ROOTDIR)/riscv-test-env/p/ \ |
| + -I$(OT_ROOT) \ |
| + -I$(TARGETDIR)/$(RISCV_TARGET)/ \ |
| + -I$(TARGETDIR)/$(RISCV_TARGET)/ \ |
| + $(DEFINES) \ |
| + -L$(OT_ROOT) -T$(LDSCRIPT) $$< \ |
| + $(OPENTITAN)/main.c \ |
| + $(OPENTITAN)/run_rvc_test.S \ |
| + $(OT_ROOT)/sw/device/exts/common/ibex_interrupt_vectors.S \ |
| + $(OT_ROOT)/sw/device/exts/common/flash_crt.S \ |
| + -L$(OT_BIN)/sw/device/riscv_compliance_support \ |
| + -l$(COMPLIANCE_LIB) \ |
| + -o $$(@); \ |
| + $$(RISCV_OBJDUMP) -SD $$(@) > $$(@).objdump; \ |
| + $$(RISCV_READELF) -a $$(@) > $$(@).readelf; \ |
| + $$(RISCV_NM) $$(@) > $$(@).nm; \ |
| + $$(RISCV_OBJCOPY) -O binary $$(@) $$(@).bin; |
| diff --git a/riscv-target/opentitan/device/rv32imc/isa.yaml b/riscv-target/opentitan/device/rv32imc/isa.yaml |
| new file mode 100644 |
| index 0000000..c526fec |
| --- /dev/null |
| +++ b/riscv-target/opentitan/device/rv32imc/isa.yaml |
| @@ -0,0 +1,49 @@ |
| +## Copyright lowRISC contributors. |
| +## Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| +## SPDX-License-Identifier: Apache-2.0 |
| + |
| +Device: rv32imc |
| +Vendor: opentitan |
| + |
| +ISA: RV32IMC |
| +misa: |
| + implemented: True |
| + MXL: |
| + range: |
| + rangelist: [[1]] |
| + mode: Unchanged |
| + Extensions: |
| + bitmask: |
| + mask: 0x0 |
| + default: 0x1104 |
| +hw_data_misaligned_support: True |
| +mtvec: |
| + MODE: |
| + range: |
| + rangelist: [[1]] |
| + BASE: |
| + range: |
| + rangelist: [[0x20000020]] |
| + |
| +mstatus: |
| + MPP: |
| + range: |
| + rangelist: [[3]] |
| + |
| +User_Spec_Version: "2.3" |
| +Privilege_Spec_Version: "1.11" |
| + |
| +mvendorid: |
| + implemented: false |
| +marchid: |
| + implemented: false |
| +mimpid: |
| + implemented: false |
| +mhartid: 0 |
| + |
| +mcycle: |
| + is_hardwired: true |
| + implemented: true |
| +minstret: |
| + is_hardwired: true |
| + implemented: true |
| diff --git a/riscv-target/opentitan/device/rv32imc/main.c b/riscv-target/opentitan/device/rv32imc/main.c |
| new file mode 100644 |
| index 0000000..8d67e4e |
| --- /dev/null |
| +++ b/riscv-target/opentitan/device/rv32imc/main.c |
| @@ -0,0 +1,13 @@ |
| +// Copyright lowRISC contributors. |
| +// Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| +// SPDX-License-Identifier: Apache-2.0 |
| + |
| +// NOTE: This is the only header from OpenTitan that can be imported here. Any |
| +// OpenTitan-specific work should be done in support.c, instead. |
| +// Doing this avoids having to create patches for this file any time |
| +// requirements for the wrapper change. |
| +#include "sw/device/riscv_compliance_support/support.h" |
| + |
| +int main(int argc, char **argv) { |
| + return opentitan_compliance_main(argc, argv); |
| +} |
| diff --git a/riscv-target/opentitan/device/rv32imc/platform.yaml b/riscv-target/opentitan/device/rv32imc/platform.yaml |
| new file mode 100644 |
| index 0000000..7d547d9 |
| --- /dev/null |
| +++ b/riscv-target/opentitan/device/rv32imc/platform.yaml |
| @@ -0,0 +1,10 @@ |
| +# Copyright lowRISC contributors. |
| +# Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| +# SPDX-License-Identifier: Apache-2.0 |
| + |
| +mtime: |
| + implemented: False |
| +nmi: |
| + address: 0x800000FC # trap vec (mtvec base) + 0x7C |
| +reset: |
| + address: 0x80000080 # boot address + 0x80 |
| diff --git a/riscv-target/opentitan/device/rv32imc/run_rvc_test.S b/riscv-target/opentitan/device/rv32imc/run_rvc_test.S |
| new file mode 100644 |
| index 0000000..1b1b5c7 |
| --- /dev/null |
| +++ b/riscv-target/opentitan/device/rv32imc/run_rvc_test.S |
| @@ -0,0 +1,85 @@ |
| +// Copyright lowRISC contributors. |
| +// Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| +// SPDX-License-Identifier: Apache-2.0 |
| + |
| +// Allocate space in .bss for saving architectural state before jumping into the |
| +// test |
| + .lcomm arch_state_store, 4 * 17 //(ra, sp, gp, tp, s0-s11, mtvec) |
| + |
| + .section .text |
| + |
| +run_rvc_test: |
| + .globl run_rvc_test |
| + |
| + // Save the architectural state. There is no need to save caller preserved |
| + // registers as C calling run_rvc_test will expect them to be clobbered anyway |
| + // and act appropriately. RA is the exception as we need to know where to jump |
| + // back to after the test is complete. mtvec is saved as the compliance test |
| + // environment alters it, other CSRs may also be changed but no adverse |
| + // effects have yet been observed from this. |
| + la t0, arch_state_store |
| + |
| + sw ra, 0(t0) |
| + sw sp, 4(t0) |
| + sw gp, 8(t0) |
| + sw tp, 12(t0) |
| + sw s0, 16(t0) |
| + sw s1, 20(t0) |
| + sw s2, 24(t0) |
| + sw s3, 28(t0) |
| + sw s4, 32(t0) |
| + sw s5, 36(t0) |
| + sw s6, 40(t0) |
| + sw s7, 44(t0) |
| + sw s8, 48(t0) |
| + sw s9, 52(t0) |
| + sw s10, 56(t0) |
| + sw s11, 60(t0) |
| + |
| + csrr t1, mtvec |
| + sw t1, 64(t0) |
| + |
| +// jump to compliance test |
| + j _rvc_start |
| + |
| +end_rvc_test: |
| + .globl end_rvc_test |
| + |
| + // restore architectural state |
| + la t0, arch_state_store |
| + |
| + lw ra, 0(t0) |
| + lw sp, 4(t0) |
| + lw gp, 8(t0) |
| + lw tp, 12(t0) |
| + lw s0, 16(t0) |
| + lw s1, 20(t0) |
| + lw s2, 24(t0) |
| + lw s3, 28(t0) |
| + lw s4, 32(t0) |
| + lw s5, 36(t0) |
| + lw s6, 40(t0) |
| + lw s7, 44(t0) |
| + lw s8, 48(t0) |
| + lw s9, 52(t0) |
| + lw s10, 56(t0) |
| + lw s11, 60(t0) |
| + |
| + lw t1, 64(t0) |
| + csrw mtvec, t1 |
| + |
| + jr ra |
| + |
| +// riscv-compliance loads its own mtvec that will jump to mtvec_handler if the |
| +// symbol exists |
| +mtvec_handler: |
| + .globl mtvec_handler |
| + |
| + // restore gp/sp so handler from OT library can work |
| + la t0, arch_state_store |
| + |
| + lw sp, 4(t0) |
| + lw gp, 8(t0) |
| + |
| + // jump to the handler from the OT library |
| + j crt_interrupt_vector |