Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Official Risc-V tests (WIP) #562

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
riscv-testdata/testdata/ linguist-generated=true
riscv-testdata/testdata/.testdata_generated_from_this_commit linguist-generated=false
4 changes: 4 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@ updates:
directories: ["/", "/examples"]
schedule:
interval: "weekly"
- package-ecosystem: "docker"
directory: "riscv-testdata/create_testdata"
schedule:
interval: "weekly"
9 changes: 5 additions & 4 deletions ceno_emul/src/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ pub struct Platform {
pub ram_end: Addr,
}

// TODO(Matthias): read from elf.
pub const CENO_PLATFORM: Platform = Platform {
rom_start: 0x2000_0000,
rom_end: 0x3000_0000 - 1,
ram_start: 0x8000_0000,
ram_end: 0xFFFF_FFFF,
rom_start: 0x8000_0000,
rom_end: 0xB000_0000 - 1,
ram_start: 0x2000_0000,
ram_end: 0x8000_0000 - 1,
};

impl Platform {
Expand Down
8 changes: 4 additions & 4 deletions ceno_emul/src/rv32im.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ pub struct Emulator {
pub enum TrapCause {
InstructionAddressMisaligned,
InstructionAccessFault,
IllegalInstruction(u32),
IllegalInstruction(u32, u32),
Breakpoint,
LoadAddressMisaligned,
LoadAccessFault(ByteAddr),
Expand Down Expand Up @@ -471,7 +471,7 @@ impl Emulator {
let word = ctx.fetch(pc.waddr())?;
if word & 0x03 != 0x03 {
// Opcode must end in 0b11 in RV32IM.
ctx.trap(TrapCause::IllegalInstruction(word))?;
ctx.trap(TrapCause::IllegalInstruction(pc.0, word))?;
return Err(anyhow!(
"Fatal: illegal instruction at pc={:?}: 0x{:08x}",
pc,
Expand All @@ -490,7 +490,7 @@ impl Emulator {
InsnCategory::Load => self.step_load(ctx, insn.kind, &decoded)?,
InsnCategory::Store => self.step_store(ctx, insn.kind, &decoded)?,
InsnCategory::System => self.step_system(ctx, insn.kind, &decoded)?,
InsnCategory::Invalid => ctx.trap(TrapCause::IllegalInstruction(word))?,
InsnCategory::Invalid => ctx.trap(TrapCause::IllegalInstruction(pc.0, word))?,
} {
ctx.on_normal_end(&decoded);
};
Expand Down Expand Up @@ -765,7 +765,7 @@ impl Emulator {
InsnKind::EANY => match decoded.rs2 {
0 => ctx.ecall(),
1 => ctx.trap(TrapCause::Breakpoint),
_ => ctx.trap(TrapCause::IllegalInstruction(decoded.insn)),
_ => ctx.trap(TrapCause::IllegalInstruction(ctx.get_pc().0, decoded.insn)),
},
_ => unreachable!(),
}
Expand Down
12 changes: 12 additions & 0 deletions ceno_emul/tests/test_elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,18 @@ fn test_ceno_rt_mini() -> Result<()> {
Ok(())
}

#[test]
fn test_ceno_rt_official() -> Result<()> {
let program_elf = include_bytes!("../../riscv-testdata/testdata/rv32ui-p-addi");
let mut state = VMState::new_from_elf(CENO_PLATFORM, program_elf)?;
let steps = run(&mut state)?;
let last = steps.last().unwrap();
// assert_eq!(last.insn().codes().kind, InsnKind::EANY);
// assert_eq!(last.rs1().unwrap().value, CENO_PLATFORM.ecall_halt());
// assert_eq!(last.rs2().unwrap().value, 1); // panic / halt(1)
Ok(())
}

#[test]
fn test_ceno_rt_panic() -> Result<()> {
let program_elf = ceno_examples::ceno_rt_panic;
Expand Down
47 changes: 47 additions & 0 deletions riscv-testdata/create-testdata/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
FROM --platform=linux/amd64 ubuntu:latest AS builder-stage_amd64

# Set the working directory
WORKDIR /root

# Install necessary tools to build RISC-V tests
RUN apt-get update && apt-get install --yes curl git autoconf g++ build-essential

# Download and extract RISC-V GNU toolchain binaries
RUN curl --fail --silent --show-error --location \
https://github.com/riscv-collab/riscv-gnu-toolchain/releases/download/2023.07.05/riscv32-elf-ubuntu-22.04-gcc-nightly-2023.07.05-nightly.tar.gz \
| tar --extract --gzip --verbose

# Set the environment variables
ENV PATH="/root/riscv/bin:${PATH}"
ENV RISCV="/root"

# Clone the RISC-V tests repository
# (Get only the specific commit we want)
## The ADD is to invalidate the Docker cache, if the repository changes.
## So that we get a fresh clone.
ADD https://api.github.com/repos/riscv/riscv-tests/git/refs/heads/master version.json
RUN git clone --depth=1 https://github.com/riscv/riscv-tests.git
WORKDIR /root/riscv-tests/

# Set the environment variable for the RISC-V tests
ENV RISCV_TEST="/root/riscv-tests/isa"

# Update tests
RUN git submodule update --init --depth=1 --recursive && \
git rev-parse HEAD | tee .testdata_generated_from_this_commit

# Build the tests - we are interested in rv32ui and rv32um
# We want to add the CFLAGS "-save-temps -frandom-seed=1" to the build,
# but upstream forces us to repeat all their default flags here, too.
RUN autoconf && \
./configure --prefix=/root/riscv-tests && \
cd isa && \
make rv32ui rv32um XLEN=32 RISCV_GCC_OPTS="-save-temps -frandom-seed=1 -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles"

RUN rm --force /root/riscv-tests/isa/.gitignore

FROM scratch AS exporter-stage

# Copy all built tests to the host system
COPY --from=builder-stage_amd64 /root/riscv-tests/isa /
COPY --from=builder-stage_amd64 /root/riscv-tests/.testdata_generated_from_this_commit /
8 changes: 8 additions & 0 deletions riscv-testdata/create-testdata/update-testdata
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash
set -euo pipefail

dir="$(git rev-parse --show-toplevel)/riscv-testdata"
docker buildx build \
--file "${dir}/create-testdata/Dockerfile" \
--output "${dir}/testdata" \
.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fa2f65c4f5546a3f9dd7d4f23bc3f6d8761ed6b2
139 changes: 139 additions & 0 deletions riscv-testdata/testdata/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#=======================================================================
# Makefile for riscv-tests/isa
#-----------------------------------------------------------------------

XLEN ?= 64

src_dir := .

ifeq ($(XLEN),64)
include $(src_dir)/rv64ui/Makefrag
include $(src_dir)/rv64uc/Makefrag
include $(src_dir)/rv64um/Makefrag
include $(src_dir)/rv64ua/Makefrag
include $(src_dir)/rv64uf/Makefrag
include $(src_dir)/rv64ud/Makefrag
include $(src_dir)/rv64uzfh/Makefrag
include $(src_dir)/rv64uzba/Makefrag
include $(src_dir)/rv64uzbb/Makefrag
include $(src_dir)/rv64uzbc/Makefrag
include $(src_dir)/rv64uzbs/Makefrag
include $(src_dir)/rv64si/Makefrag
include $(src_dir)/rv64ssvnapot/Makefrag
include $(src_dir)/rv64mi/Makefrag
include $(src_dir)/rv64mzicbo/Makefrag
endif
include $(src_dir)/rv32ui/Makefrag
include $(src_dir)/rv32uc/Makefrag
include $(src_dir)/rv32um/Makefrag
include $(src_dir)/rv32ua/Makefrag
include $(src_dir)/rv32uf/Makefrag
include $(src_dir)/rv32ud/Makefrag
include $(src_dir)/rv32uzfh/Makefrag
include $(src_dir)/rv32uzba/Makefrag
include $(src_dir)/rv32uzbb/Makefrag
include $(src_dir)/rv32uzbc/Makefrag
include $(src_dir)/rv32uzbs/Makefrag
include $(src_dir)/rv32si/Makefrag
include $(src_dir)/rv32mi/Makefrag

default: all

#--------------------------------------------------------------------
# Build rules
#--------------------------------------------------------------------

RISCV_PREFIX ?= riscv$(XLEN)-unknown-elf-
RISCV_GCC ?= $(RISCV_PREFIX)gcc
RISCV_GCC_OPTS ?= -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump --disassemble-all --disassemble-zeroes --section=.text --section=.text.startup --section=.text.init --section=.data
RISCV_SIM ?= spike

vpath %.S $(src_dir)

#------------------------------------------------------------
# Build assembly tests

%.dump: %
$(RISCV_OBJDUMP) $< > $@

%.out: %
$(RISCV_SIM) --isa=rv64gc_zfh_zicboz_svnapot_zicntr_zba_zbb_zbc_zbs --misaligned $< 2> $@

%.out32: %
$(RISCV_SIM) --isa=rv32gc_zfh_zicboz_svnapot_zicntr_zba_zbb_zbc_zbs --misaligned $< 2> $@

define compile_template

$$($(1)_p_tests): $(1)-p-%: $(1)/%.S
$$(RISCV_GCC) $(2) $$(RISCV_GCC_OPTS) -I$(src_dir)/../env/p -I$(src_dir)/macros/scalar -T$(src_dir)/../env/p/link.ld $$< -o $$@
$(1)_tests += $$($(1)_p_tests)

$$($(1)_v_tests): $(1)-v-%: $(1)/%.S
$$(RISCV_GCC) $(2) $$(RISCV_GCC_OPTS) -DENTROPY=0x$$(shell echo \$$@ | md5sum | cut -c 1-7) -std=gnu99 -O2 -I$(src_dir)/../env/v -I$(src_dir)/macros/scalar -T$(src_dir)/../env/v/link.ld $(src_dir)/../env/v/entry.S $(src_dir)/../env/v/*.c $$< -o $$@
$(1)_tests += $$($(1)_v_tests)

$(1)_tests_dump = $$(addsuffix .dump, $$($(1)_tests))

$(1): $$($(1)_tests_dump)

.PHONY: $(1)

COMPILER_SUPPORTS_$(1) := $$(shell $$(RISCV_GCC) $(2) -c -x c /dev/null -o /dev/null 2> /dev/null; echo $$$$?)

ifeq ($$(COMPILER_SUPPORTS_$(1)),0)
tests += $$($(1)_tests)
endif

endef

$(eval $(call compile_template,rv32ui,-march=rv32g -mabi=ilp32))
$(eval $(call compile_template,rv32uc,-march=rv32g -mabi=ilp32))
$(eval $(call compile_template,rv32um,-march=rv32g -mabi=ilp32))
$(eval $(call compile_template,rv32ua,-march=rv32g -mabi=ilp32))
$(eval $(call compile_template,rv32uf,-march=rv32g -mabi=ilp32))
$(eval $(call compile_template,rv32ud,-march=rv32g -mabi=ilp32))
$(eval $(call compile_template,rv32uzfh,-march=rv32g_zfh -mabi=ilp32))
$(eval $(call compile_template,rv32uzba,-march=rv32g_zba -mabi=ilp32))
$(eval $(call compile_template,rv32uzbb,-march=rv32g_zbb -mabi=ilp32))
$(eval $(call compile_template,rv32uzbc,-march=rv32g_zbc -mabi=ilp32))
$(eval $(call compile_template,rv32uzbs,-march=rv32g_zbs -mabi=ilp32))
$(eval $(call compile_template,rv32si,-march=rv32g -mabi=ilp32))
$(eval $(call compile_template,rv32mi,-march=rv32g -mabi=ilp32))
ifeq ($(XLEN),64)
$(eval $(call compile_template,rv64ui,-march=rv64g -mabi=lp64))
$(eval $(call compile_template,rv64uc,-march=rv64g -mabi=lp64))
$(eval $(call compile_template,rv64um,-march=rv64g -mabi=lp64))
$(eval $(call compile_template,rv64ua,-march=rv64g -mabi=lp64))
$(eval $(call compile_template,rv64uf,-march=rv64g -mabi=lp64))
$(eval $(call compile_template,rv64ud,-march=rv64g -mabi=lp64))
$(eval $(call compile_template,rv64uzfh,-march=rv64g_zfh -mabi=lp64))
$(eval $(call compile_template,rv64uzba,-march=rv64g_zba -mabi=lp64))
$(eval $(call compile_template,rv64uzbb,-march=rv64g_zbb -mabi=lp64))
$(eval $(call compile_template,rv64uzbc,-march=rv64g_zbc -mabi=lp64))
$(eval $(call compile_template,rv64uzbs,-march=rv64g_zbs -mabi=lp64))
$(eval $(call compile_template,rv64mzicbo,-march=rv64g_zicboz -mabi=lp64))
$(eval $(call compile_template,rv64si,-march=rv64g -mabi=lp64))
$(eval $(call compile_template,rv64ssvnapot,-march=rv64g -mabi=lp64))
$(eval $(call compile_template,rv64mi,-march=rv64g -mabi=lp64))
endif

tests_dump = $(addsuffix .dump, $(tests))
tests_hex = $(addsuffix .hex, $(tests))
tests_out = $(addsuffix .out, $(filter rv64%,$(tests)))
tests32_out = $(addsuffix .out32, $(filter rv32%,$(tests)))

run: $(tests_out) $(tests32_out)

junk += $(tests) $(tests_dump) $(tests_hex) $(tests_out) $(tests32_out)

#------------------------------------------------------------
# Default

all: $(tests_dump)

#------------------------------------------------------------
# Clean up

clean:
rm -rf $(junk)
Loading
Loading