Skip to content

Automate prebuilt executable updates via GitHub Actions #474

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

Merged
merged 25 commits into from
Aug 21, 2024
Merged
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .ci/gdbstub-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

set -e -u -o pipefail

export PATH=`pwd`/toolchain/riscv/bin:$PATH
export PATH=`pwd`/toolchain/bin:$PATH

GDB=
prefixes=("${CROSS_COMPILE}" "riscv32-unknown-elf" "riscv-none-elf")
prefixes=("${CROSS_COMPILE}" "riscv32-unknown-elf-" "riscv-none-elf-")
for prefix in "${prefixes[@]}"; do
utility=${prefix}-gdb
utility=${prefix}gdb
set +e # temporarily disable exit on error
command -v "${utility}" &> /dev/null
if [[ $? == 0 ]]; then
Expand All @@ -21,7 +21,7 @@ if [ -z ${GDB} ]; then
exit 1
fi

build/rv32emu -g build/puzzle.elf &
build/rv32emu -g build/riscv32/puzzle &
PID=$!

# Before starting GDB, we should ensure rv32emu is still running.
Expand All @@ -31,9 +31,9 @@ fi

OPTS=
tmpfile=/tmp/rv32emu-gdbstub.$PID
breakpoints=(0x10700 0x10800 0x10900)
breakpoints=(0x10500 0x10600 0x10700)
bkpt_count=${#breakpoints[@]}
OPTS+="-ex 'file build/puzzle.elf' "
OPTS+="-ex 'file build/riscv32/puzzle' "
OPTS+="-ex 'target remote :1234' "
for t in ${breakpoints[@]}; do
OPTS+="-ex 'break *$t' "
Expand Down
2 changes: 1 addition & 1 deletion .ci/riscv-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pip3 install git+https://github.com/riscv/riscof.git@d38859f85fe407bcacddd2efcd3

set -x

export PATH=`pwd`/toolchain/riscv/bin:$PATH
export PATH=`pwd`/toolchain/bin:$PATH

make clean
make arch-test RISCV_DEVICE=IMAFCZicsrZifencei || exit 1
Expand Down
17 changes: 11 additions & 6 deletions .ci/riscv-toolchain-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,15 @@ check_platform

mkdir -p toolchain

# GNU Toolchain for RISC-V
GCC_VER=2024.04.12
TOOLCHAIN_REPO=https://github.com/riscv-collab/riscv-gnu-toolchain/releases
if [[ "$#" == "0" ]] || [[ "$1" != "riscv-collab" ]]; then
GCC_VER=14.2.0-1
TOOLCHAIN_REPO=https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack
TOOLCHAIN_URL=${TOOLCHAIN_REPO}/releases/download/v${GCC_VER}/xpack-riscv-none-elf-gcc-${GCC_VER}-linux-x64.tar.gz
else
UBUNTU_VER=`lsb_release -r | cut -f2`
GCC_VER=2024.04.12
TOOLCHAIN_REPO=https://github.com/riscv-collab/riscv-gnu-toolchain
TOOLCHAIN_URL=${TOOLCHAIN_REPO}/releases/download/${GCC_VER}/riscv32-elf-ubuntu-${UBUNTU_VER}-gcc-nightly-${GCC_VER}-nightly.tar.gz
fi

wget -q \
${TOOLCHAIN_REPO}/download/${GCC_VER}/riscv32-elf-ubuntu-22.04-gcc-nightly-${GCC_VER}-nightly.tar.gz -O- \
| tar -C toolchain -xz
wget -q ${TOOLCHAIN_URL} -O- | tar -C toolchain --strip-components=1 -xz
87 changes: 87 additions & 0 deletions .github/workflows/build-artifact.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
name: Build artifact

on:
push:
branches:
- master
workflow_dispatch:

jobs:
detect-file-change:
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: 'true'
- name: Test file change
id: test-file-change
uses: tj-actions/changed-files@v45
with:
fetch_additional_submodule_history: 'true'
files: |
tests/ansibench/*
tests/rv8-bench/*
tests/*.c
- name: Set alias
id: has_changed_files
run: |
if [[ ${{ steps.test-file-change.outputs.any_modified }} == true ]]; then
echo "has_changed_files=true" >> $GITHUB_OUTPUT
else
echo "has_changed_files=false" >> $GITHUB_OUTPUT
fi
outputs:
has_changed_files: ${{ steps.has_changed_files.outputs.has_changed_files }}

build-artifact:
needs: [detect-file-change]
if: ${{ needs.detect-file-change.outputs.has_changed_files == 'true' || github.event_name == 'workflow_dispatch' }}
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: 'true'
- name: Install dependencies
run: |
sudo apt-get update -q -y
sudo apt-get upgrade -q -y
sudo apt-get install -q -y gcc-multilib g++-multilib
sudo apt-get install -q -y opam build-essential libgmp-dev z3 pkg-config zlib1g-dev
.ci/riscv-toolchain-install.sh
echo "$PWD/toolchain/bin" >> $GITHUB_PATH
- name: Build binaries
run: |
make artifact ENABLE_PREBUILT=0
mkdir -p /tmp/rv32emu-prebuilt
mv build/linux-x86-softfp build/riscv32 /tmp/rv32emu-prebuilt
- name: Build Sail model
run: |
cd /tmp
opam init -y --disable-sandboxing
opam switch create ocaml-base-compiler.4.06.1
opam install sail -y
eval $(opam config env)
git clone https://github.com/riscv/sail-riscv.git
cd sail-riscv
git checkout 9547a30bf84572c458476591b569a95f5232c1c7
ARCH=RV32 make -j
mkdir -p /tmp/rv32emu-prebuilt/sail_cSim
mv c_emulator/riscv_sim_RV32 /tmp/rv32emu-prebuilt/sail_cSim
- name: Create tarball
run: |
cd /tmp
tar -zcvf rv32emu-prebuilt.tar.gz rv32emu-prebuilt
- name: Create GitHub Release
env:
GH_TOKEN: ${{ secrets.RV32EMU_PREBUILT_TOKEN }}
run: |
RELEASE_TAG=$(date +'%Y.%m.%d')
cd /tmp
gh release create $RELEASE_TAG \
--repo sysprog21/rv32emu-prebuilt \
--title "$RELEASE_TAG""-nightly"
gh release upload $RELEASE_TAG \
rv32emu-prebuilt.tar.gz \
--repo sysprog21/rv32emu-prebuilt
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,14 @@ build/softfloat
build/cache/
build/map/
build/path/
build/linux-x86-softfp/
build/riscv32/
build/sail_cSim/
*.a
*.o
*.o.d
tests/**/*.elf
tests/arch-test-target/config.ini
tests/arch-test-target/sail_cSim/riscv_sim_RV32
__pycache__/
src/rv32_jit.c
12 changes: 12 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,15 @@
url = https://github.com/sysprog21/berkeley-softfloat-3
branch = rv32emu
shallow = true
[submodule "tests/ansibench"]
path = tests/ansibench
url = https://github.com/sysprog21/ansibench
shallow = true
[submodule "tests/rv8-bench"]
path = tests/rv8-bench
url = https://github.com/sysprog21/rv8-bench
shallow = true
[submodule "src/ieeelib"]
path = src/ieeelib
url = https://github.com/sysprog21/ieeelib
shallow = true
31 changes: 20 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ $(OUT)/emulate.o: CFLAGS += -foptimize-sibling-calls -fomit-frame-pointer -fno-s
.DEFAULT_GOAL := all

include mk/external.mk

include mk/artifact.mk
include mk/wasm.mk

all: config $(BIN)
Expand Down Expand Up @@ -229,13 +229,13 @@ tool: $(TOOLS_BIN)
include mk/riscv-arch-test.mk
include mk/tests.mk

CHECK_ELF_FILES := \
hello \
puzzle \
fcalc
# the prebuilt executables are built for "rv32im"
CHECK_ELF_FILES :=

ifeq ($(call has, EXT_M), 1)
CHECK_ELF_FILES += \
puzzle \
fcalc \
pi
endif

Expand All @@ -244,10 +244,19 @@ EXPECTED_puzzle = success in 2005 trials
EXPECTED_fcalc = Performed 12 tests, 0 failures, 100% success rate.
EXPECTED_pi = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086

check: $(BIN)
check-hello: $(BIN)
$(Q)$(PRINTF) "Running hello.elf ..."; \
if [ "$(shell $(BIN) $(OUT)/hello.elf | uniq)" = "$(strip $(EXPECTED_hello)) inferior exit code 0" ]; then \
$(call notice, [OK]); \
else \
$(PRINTF) "Failed.\n"; \
exit 1; \
fi;

check: $(BIN) check-hello artifact
$(Q)$(foreach e,$(CHECK_ELF_FILES),\
$(PRINTF) "Running $(e).elf ... "; \
if [ "$(shell $(BIN) $(OUT)/$(e).elf | uniq)" = "$(strip $(EXPECTED_$(e))) inferior exit code 0" ]; then \
$(PRINTF) "Running $(e) ... "; \
if [ "$(shell $(BIN) $(OUT)/riscv32/$(e) | uniq)" = "$(strip $(EXPECTED_$(e))) inferior exit code 0" ]; then \
$(call notice, [OK]); \
else \
$(PRINTF) "Failed.\n"; \
Expand All @@ -256,9 +265,9 @@ check: $(BIN)
)

EXPECTED_aes_sha1 = 1242a6757c8aef23e50b5264f5941a2f4b4a347e -
misalign: $(BIN)
$(Q)$(PRINTF) "Running aes.elf ... ";
$(Q)if [ "$(shell $(BIN) -m $(OUT)/aes.elf | $(SHA1SUM))" = "$(EXPECTED_aes_sha1)" ]; then \
misalign: $(BIN) artifact
$(Q)$(PRINTF) "Running uaes ... ";
$(Q)if [ "$(shell $(BIN) -m $(OUT)/riscv32/uaes | $(SHA1SUM))" = "$(EXPECTED_aes_sha1)" ]; then \
$(call notice, [OK]); \
else \
$(PRINTF) "Failed.\n"; \
Expand Down
42 changes: 2 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -327,46 +327,8 @@ Use of this source code is governed by a MIT license that can be found in the [L

## External sources

In `rv32emu` repository, there are some prebuilt ELF files for testing purpose.
* `aes.elf` : See [tests/aes.c](tests/aes.c)
* `captcha.elf` : See [tests/captcha.c](tests/captcha.c)
* `cc.elf` : See [tests/cc](tests/cc)
* `chacha20.elf` : See [tests/chacha20](tests/chacha20)
* `coremark.elf` : See [eembc/coremark](https://github.com/eembc/coremark) [RV32M]
* `dhrystone.elf` : See [rv8-bench](https://github.com/michaeljclark/rv8-bench)
* `donut.elf` : See [donut.c](tests/donut.c)
* `doom.elf` : See [sysprog21/doom_riscv](https://github.com/sysprog21/doom_riscv) [RV32M]
* `fcalc.elf` : See [fcalc.c](tests/fcalc.c)
* `hamilton.elf` : See [hamilton.c](tests/hamilton.c)
* `ieee754.elf` : See [tests/ieee754.c](tests/ieee754.c) [RV32F]
* `jit-bf.elf` : See [ezaki-k/xkon_beta](https://github.com/ezaki-k/xkon_beta)
* `lena.elf`: See [tests/lena.c](tests/lena.c)
* `line.elf` : See [tests/line.c](tests/line.c) [RV32M]
* `maj2random.elf` : See [tests/maj2random.c](tests/maj2random.c) [RV32F]
* `mandelbrot.elf` : See [tests/mandelbrot.c](tests/mandelbrot.c)
* `nqueens.elf` : See [tests/nqueens.c](tests/nqueens.c)
* `nyancat.elf` : See [tests/nyancat.c](tests/nyancat.c)
* `pi.elf` : See [tests/pi.c](tests/pi.c) [RV32M]
* `qrcode.elf` : See [tests/qrcode.c](tests/qrcode.c)
* `quake.elf` : See [sysprog21/quake-embedded](https://github.com/sysprog21/quake-embedded) [RV32F]
* `readelf.elf` : See [tests/readelf](tests/readelf)
* `richards.elf` : See [tests/richards.c](tests/richards.c)
* `rvsim.elf` : See [tests/rvsim.c](tests/rvsim.c)
* `scimark2.elf` : See [tests/scimark2](tests/scimark2) [RV32MF]
* `smolnes.elf` : See [tests/smolnes](tests/smolnes.c) [RV32M]
* `spirograph.elf` : See [tests/spirograph.c](tests/spirograph.c)
* `stream.elf` : See [tests/stream](tests/stream.c) [RV32MF]
* `qsort.elf` : See [rv8-bench](https://github.com/michaeljclark/rv8-bench)
* `miniz.elf` : See [rv8-bench](https://github.com/michaeljclark/rv8-bench)
* `primes.elf` : See [rv8-bench](https://github.com/michaeljclark/rv8-bench)
* `sha512.elf` : See [rv8-bench](https://github.com/michaeljclark/rv8-bench)
* `numeric_sort.elf` : See [nbench](https://github.com/nfinit/ansibench/tree/master/nbench)
* `FP_emulation.elf` : See [nbench](https://github.com/nfinit/ansibench/tree/master/nbench)
* `bitfield.elf` : See [nbench](https://github.com/nfinit/ansibench/tree/master/nbench)
* `idea.elf` : See [nbench](https://github.com/nfinit/ansibench/tree/master/nbench)
* `assignment.elf` : See [nbench](https://github.com/nfinit/ansibench/tree/master/nbench)
* `string_sort.elf` : See [nbench](https://github.com/nfinit/ansibench/tree/master/nbench)
* `huffman.elf` : See [nbench](https://github.com/nfinit/ansibench/tree/master/nbench)
See [docs/prebuilt.md](docs/prebuilt.md).

## Reference

* [Writing a simple RISC-V emulator in plain C](https://fmash16.github.io/content/posts/riscv-emulator-in-c.html)
Expand Down
Binary file removed build/FP_emulation.elf
Binary file not shown.
Binary file removed build/aes.elf
Binary file not shown.
Binary file removed build/assignment.elf
Binary file not shown.
Binary file removed build/bitfield.elf
Binary file not shown.
Binary file removed build/captcha.elf
Binary file not shown.
Binary file removed build/coremark.elf
Binary file not shown.
Binary file removed build/dhrystone.elf
Binary file not shown.
Binary file removed build/donut.elf
Binary file not shown.
Binary file removed build/fcalc.elf
Binary file not shown.
Binary file removed build/hamilton.elf
Binary file not shown.
Binary file removed build/huffman.elf
Binary file not shown.
Binary file removed build/idea.elf
Binary file not shown.
Binary file removed build/lena.elf
Binary file not shown.
Binary file removed build/line.elf
Binary file not shown.
Binary file removed build/maj2random.elf
Binary file not shown.
Binary file removed build/mandelbrot.elf
Binary file not shown.
Binary file removed build/miniz.elf
Binary file not shown.
Binary file removed build/nqueens.elf
Binary file not shown.
Binary file removed build/numeric_sort.elf
Binary file not shown.
Binary file removed build/nyancat.elf
Binary file not shown.
Binary file removed build/pi.elf
Binary file not shown.
Binary file removed build/primes.elf
Binary file not shown.
Binary file removed build/puzzle.elf
Binary file not shown.
Binary file removed build/qrcode.elf
Binary file not shown.
Binary file removed build/qsort.elf
Binary file not shown.
Binary file removed build/richards.elf
Binary file not shown.
Binary file removed build/rvsim.elf
Binary file not shown.
Binary file removed build/sha512.elf
Binary file not shown.
Binary file removed build/spirograph.elf
Binary file not shown.
Binary file removed build/stream.elf
Binary file not shown.
Binary file removed build/string_sort.elf
Binary file not shown.
67 changes: 67 additions & 0 deletions docs/prebuilt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Prebuilt Binaries

The prebuilt binaries for [rv32emu](https://github.com/sysprog21/rv32emu) are prepared primarily because the [RISC-V Sail Model](https://github.com/riscv/sail-riscv) executable is required for the [RISC-V Architecture Test](https://github.com/riscv-non-isa/riscv-arch-test), and selected RISC-V ELF files are useful for ISA simulation validation and testing.
Some of these prebuilt binaries are stored in [rv32emu-prebuilt](https://github.com/sysprog21/rv32emu-prebuilt).
During testing or benchmarking, these binaries are automatically downloaded into the `build/linux-x86-softfp/` and `build/riscv32/` directories by default.
The RISC-V binaries are compiled using the [xPack RISC-V GCC toolchain](https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack) with the options `-march=rv32im -mabi=ilp32`.
The x86 binaries are compiled by GCC with `-m32 -mno-sse -mno-sse2 -msoft-float` options and use [ieeelib](https://github.com/sysprog21/ieeelib) as the soft-fp library.

To fetch the prebuilt binaries manually, run:

```shell
$ make artifact
```

Or build the binaries from scratch (the RISC-V cross-compiler is required):

```shell
$ make artifact ENABLE_PREBUILT=0 [CROSS_COMPILE=<COMPILER_PREFIX>]
```

The compiler prefix varies according to the used toolchain, such as `riscv-none-elf-`, `riscv32-unknown-elf-`, etc.

The prebuilt binaries in `rv32emu-prebuilt` are built from the following repositories and resources:

- [ansibench](https://github.com/sysprog21/ansibench)
- coremark
- stream
- nbench
- [rv8-bench](https://github.com/sysprog21/rv8-bench)
- aes
- dhrystone
- miniz
- norx
- primes
- qsort
- sha512
- `captcha` : See [tests/captcha.c](/tests/captcha.c)
- `donut` : See [tests/donut.c](/tests/donut.c)
- `fcalc` : See [tests/fcalc.c](/tests/fcalc.c)
- `hamilton` : See [tests/hamilton.c](/tests/hamilton.c)
- `jit` : See [tests/jit.c](/tests/jit.c)
- `lena`: See [tests/lena.c](/tests/lena.c)
- `line` : See [tests/line.c](/tests/line.c)
- `maj2random` : See [tests/maj2random.c](/tests/maj2random.c)
- `mandelbrot` : See [tests/mandelbrot.c](/tests/mandelbrot.c)
- `nqueens` : See [tests/nqueens.c](/tests/nqueens.c)
- `nyancat` : See [tests/nyancat.c](/tests/nyancat.c)
- `pi` : See [tests/pi.c](/tests/pi.c)
- `puzzle` : See [tests/puzzle.c](/tests/puzzle.c)
- `qrcode` : See [tests/qrcode.c](/tests/qrcode.c)
- `richards` : See [tests/richards.c](/tests/richards.c)
- `rvsim` : See [tests/rvsim.c](/tests/rvsim.c)
- `spirograph` : See [tests/spirograph.c](/tests/spirograph.c)
- `uaes` : See [tests/uaes.c](/tests/uaes.c)

There are still some prebuilt standalone RISC-V binaries under `build/` directory only for testing purpose:

- `hello.elf` : See [tests/asm-hello](/tests/asm-hello)
- `cc.elf` : See [tests/cc](/tests/cc)
- `chacha20.elf` : See [tests/chacha20](/tests/chacha20)
- `doom.elf` : See [sysprog21/doom_riscv](https://github.com/sysprog21/doom_riscv) [RV32M]
- `ieee754.elf` : See [tests/ieee754.c](/tests/ieee754.c) [RV32F]
- `jit-bf.elf` : See [ezaki-k/xkon_beta](https://github.com/ezaki-k/xkon_beta)
- `quake.elf` : See [sysprog21/quake-embedded](https://github.com/sysprog21/quake-embedded) [RV32F]
- `readelf.elf` : See [tests/readelf](/tests/readelf)
- `scimark2.elf` : See [tests/scimark2](/tests/scimark2) [RV32MF]
- `smolnes.elf` : See [tests/smolnes](/tests/smolnes.c) [RV32M]
Loading
Loading