From e96a2c8eb113db48045bb32f14173ea922f7a34e Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Sun, 27 Dec 2020 14:02:51 +0100 Subject: [PATCH 01/15] Adding CI for riscv-openocd. Adding an automation that runs riscv-tests/debug on the build of riscv-openocd. The steps performed are: - Build of OpenOCD - Build of Spike - Download a pre-built RISC-V toolchain - Run riscv-tests/debug - Collect test results - Collect OpenOCD code coverage Change-Id: Id10cfa26828c22d9759399bee6c2f24def6e4318 Signed-off-by: Jan Matyas --- .github/workflows/riscv-openocd-ci.yml | 64 +++++++ tools/riscv-openocd-ci/.gitignore | 1 + tools/riscv-openocd-ci/README.md | 21 +++ tools/riscv-openocd-ci/build_openocd.sh | 36 ++++ tools/riscv-openocd-ci/build_spike.sh | 26 +++ tools/riscv-openocd-ci/download_toolchain.sh | 31 ++++ .../patches/openocd_gcov_flush.patch | 15 ++ .../riscv-openocd-ci/process_test_results.py | 172 ++++++++++++++++++ tools/riscv-openocd-ci/run_tests.sh | 21 +++ 9 files changed, 387 insertions(+) create mode 100644 .github/workflows/riscv-openocd-ci.yml create mode 100644 tools/riscv-openocd-ci/.gitignore create mode 100644 tools/riscv-openocd-ci/README.md create mode 100644 tools/riscv-openocd-ci/build_openocd.sh create mode 100644 tools/riscv-openocd-ci/build_spike.sh create mode 100644 tools/riscv-openocd-ci/download_toolchain.sh create mode 100644 tools/riscv-openocd-ci/patches/openocd_gcov_flush.patch create mode 100644 tools/riscv-openocd-ci/process_test_results.py create mode 100644 tools/riscv-openocd-ci/run_tests.sh diff --git a/.github/workflows/riscv-openocd-ci.yml b/.github/workflows/riscv-openocd-ci.yml new file mode 100644 index 0000000000..b31b333dc8 --- /dev/null +++ b/.github/workflows/riscv-openocd-ci.yml @@ -0,0 +1,64 @@ +name: riscv-openocd-ci +on: [push] + +jobs: + + run-riscv-tests: + runs-on: ubuntu-18.04 + steps: + + - name: Install required pkgs + run: | + sudo apt-get install libtool pkg-config autoconf automake libusb-1.0 libftdi1 lcov device-tree-compiler + sudo python3 -m pip install pexpect + + - name: Checkout OpenOCD + uses: actions/checkout@v2 + + - name: Build OpenOCD + run: bash tools/riscv-openocd-ci/build_openocd.sh + + - name: Checkout & build Spike + run: bash tools/riscv-openocd-ci/build_spike.sh + + - name: Download RISC-V toolchain + run: bash tools/riscv-openocd-ci/download_toolchain.sh + + - name: Update env. variables + # Change RISCV and PATH env variables for subsequent steps. + run: | + echo "`pwd`/tools/riscv-openocd-ci/work/install/bin" >> $GITHUB_PATH + echo "RISCV=`pwd`/tools/riscv-openocd-ci/work/install" >> $GITHUB_ENV + + - name: Checkout & run riscv-tests + id: run_tests + run: bash tools/riscv-openocd-ci/run_tests.sh + + - name: Process test results + run: | + cd tools/riscv-openocd-ci + python3 process_test_results.py --log-dir work/riscv-tests/debug/logs --output-dir work/results/logs + + - name: Store test results + # Run if tests were executed. + if: steps.run_tests.outputs.exit_code == 0 + uses: actions/upload-artifact@v2 + with: + name: test-results + path: tools/riscv-openocd-ci/work/results/logs + + - name: Collect OpenOCD code coverage + id: collect_cov + # Run if tests were executed. + if: steps.run_tests.outputs.exit_code == 0 + run: | + lcov --capture --directory . --output-file tools/riscv-openocd-ci/work/openocd-coverage.info + genhtml tools/riscv-openocd-ci/work/openocd-coverage.info --output-directory tools/riscv-openocd-ci/work/results/openocd-coverage + + - name: Store OpenOCD code coverage + # Run if coverage was collected. + if: steps.collect_cov.outputs.exit_code == 0 + uses: actions/upload-artifact@v2 + with: + name: openocd-coverage + path: tools/riscv-openocd-ci/work/results/openocd-coverage diff --git a/tools/riscv-openocd-ci/.gitignore b/tools/riscv-openocd-ci/.gitignore new file mode 100644 index 0000000000..b8f99f5be5 --- /dev/null +++ b/tools/riscv-openocd-ci/.gitignore @@ -0,0 +1 @@ +work diff --git a/tools/riscv-openocd-ci/README.md b/tools/riscv-openocd-ci/README.md new file mode 100644 index 0000000000..7e5cfb11a8 --- /dev/null +++ b/tools/riscv-openocd-ci/README.md @@ -0,0 +1,21 @@ +# CI for riscv-openocd + +This directory contains a set of scripts that automatically +run [riscv-tests/debug](https://github.com/riscv/riscv-tests/tree/master/debug) +against riscv-openocd. + +The scripts are intended to be called automatically by Github +Actions as a means of testing & continuous integration for riscv-openocd. + +The scripts perform these actions: + +- Build OpenOCD from source +- Checkout and build Spike (RISC-V ISA simulator) from source +- Download a pre-built RISC-V toolchain +- Use these components together to run + [riscv-tests/debug](https://github.com/riscv/riscv-tests/tree/master/debug) +- Process the test results +- Collect code coverage for OpenOCD + +See [.github/workflows](../../.github/workflows) for an example of how this is +used in practice. diff --git a/tools/riscv-openocd-ci/build_openocd.sh b/tools/riscv-openocd-ci/build_openocd.sh new file mode 100644 index 0000000000..8acf521ae5 --- /dev/null +++ b/tools/riscv-openocd-ci/build_openocd.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +INSTALL_DIR=`pwd`/riscv-openocd-ci/work/install + +# Fail on first error. +set -e + +# Echo commands. +set -o xtrace + +# Assuming OpenOCD source is already checked-out in the current workdir. + +./bootstrap + +# Enable most frequently used JTAG drivers. +# Allow for code coverage collection. +./configure \ + --enable-remote-bitbang \ + --enable-jtag_vpi \ + --enable-ftdi \ + --prefix=$INSTALL_DIR \ + CFLAGS="-O0 --coverage -fprofile-arcs -ftest-coverage" \ + CXXFLAGS="-O0 --coverage -fprofile-arcs -ftest-coverage" \ + LDFLAGS="-fprofile-arcs -lgcov" + +# Patch OpenOCD so that coverage is recorded also when terminated +# by a signal. +git apply tools/riscv-openocd-ci/patches/openocd_gcov_flush.patch + +# Build and install OpenOCD +make clean # safety +make -j`nproc` +make install + +# Check that OpenOCD runs +$INSTALL_DIR/bin/openocd --version diff --git a/tools/riscv-openocd-ci/build_spike.sh b/tools/riscv-openocd-ci/build_spike.sh new file mode 100644 index 0000000000..148d6e8ca5 --- /dev/null +++ b/tools/riscv-openocd-ci/build_spike.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +CHECKOUT_DIR=`pwd`/riscv-openocd-ci/work/riscv-isa-sim +INSTALL_DIR=`pwd`/riscv-openocd-ci/work/install + +# Fail on first error. +set -e + +# Echo commands. +set -o xtrace + +# Checkout Spike. +mkdir -p "$CHECKOUT_DIR" +cd "$CHECKOUT_DIR" +git clone --recursive https://github.com/riscv/riscv-isa-sim.git . + +# Build Spike +mkdir build +cd build +bash ../configure --prefix=$INSTALL_DIR +make clean # safety +make -j`nproc` +make install + +# Check that Spike runs +$INSTALL_DIR/bin/spike --help diff --git a/tools/riscv-openocd-ci/download_toolchain.sh b/tools/riscv-openocd-ci/download_toolchain.sh new file mode 100644 index 0000000000..52323dda26 --- /dev/null +++ b/tools/riscv-openocd-ci/download_toolchain.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +TOOLCHAIN_URL="https://buildbot.embecosm.com/job/riscv32-gcc-ubuntu1804" +TOOLCHAIN_URL+="/25/artifact/riscv32-embecosm-gcc-ubuntu1804-20201108.tar.gz" +ARCHIVE_NAME=${TOOLCHAIN_URL##*/} +DOWNLOAD_DIR=`pwd`/tools/riscv-openocd-ci/work +INSTALL_DIR=`pwd`/tools/riscv-openocd-ci/work/install + +# Fail on first error. +set -e + +# Echo commands. +set -o xtrace + +# Download the toolchain. +# Use a pre-built toolchain binaries provided by Embecosm: https://buildbot.embecosm.com/ +mkdir -p "$DOWNLOAD_DIR" +cd "$DOWNLOAD_DIR" +wget --progress dot:mega "$TOOLCHAIN_URL" + +# Extract +mkdir -p "$INSTALL_DIR" +cd "$INSTALL_DIR" +tar xvf "$DOWNLOAD_DIR/$ARCHIVE_NAME" --strip-components=1 + +# Make symlinks: riscv64-* --> riscv32-* +cd "$INSTALL_DIR/bin" +find . -name 'riscv32-*' | while read F; do ln -s $F $(echo $F | sed -e 's/riscv32/riscv64/'); done + +# Check that the compiler runs +./riscv64-unknown-elf-gcc --version diff --git a/tools/riscv-openocd-ci/patches/openocd_gcov_flush.patch b/tools/riscv-openocd-ci/patches/openocd_gcov_flush.patch new file mode 100644 index 0000000000..f8a0f3f93c --- /dev/null +++ b/tools/riscv-openocd-ci/patches/openocd_gcov_flush.patch @@ -0,0 +1,15 @@ +diff --git a/src/server/server.c b/src/server/server.c +index 4e970fa8f..43bd9fb2e 100644 +--- a/src/server/server.c ++++ b/src/server/server.c +@@ -725,6 +725,10 @@ void server_free(void) + + void exit_on_signal(int sig) + { ++ /* dump coverage before being killed by the signal ++ * (otherwise gcov's *.gcda files would not be created) */ ++ void __gcov_flush(void); ++ __gcov_flush(); + #ifndef _WIN32 + /* bring back default system handler and kill yourself */ + signal(sig, SIG_DFL); diff --git a/tools/riscv-openocd-ci/process_test_results.py b/tools/riscv-openocd-ci/process_test_results.py new file mode 100644 index 0000000000..f34e9b6c14 --- /dev/null +++ b/tools/riscv-openocd-ci/process_test_results.py @@ -0,0 +1,172 @@ + +from glob import glob +import logging +from logging import info, error +import os +import re +import shutil +import sys + +KNOWN_RESULTS = ["pass", "fail", "not_applicable", "exception"] + + +def info_box(msg): + """Display an emphasized message - print an ASCII box around it. """ + box = " +==" + ("=" * len(msg)) + "==+" + info("") + info(box) + info(" | " + msg + " |") + info(box) + info("") + + +def parse_args(): + """Process command-line arguments. """ + import argparse + parser = argparse.ArgumentParser("Process logs from riscv-tests/debug") + parser.add_argument("--log-dir", required=True, help="Directory where logs from RISC-V debug tests are stored") + parser.add_argument("--output-dir", required=True, help="Directory where put post-processed logs") + return parser.parse_args() + + +def process_test_logs(log_dir, output_dir): + """Process all logs from the testing. """ + + assert os.path.isdir(log_dir) + os.makedirs(output_dir, exist_ok=True) + + # process log files + file_pattern = os.path.join(log_dir, "*.log") + log_files = sorted(glob(file_pattern)) + + if not len(log_files): + # Did not find any *.log. + # Either the tests did not start at all or a wrong log directory was specified. + raise RuntimeError("No log files (*.log) in directory {}".format(log_dir)) + + tests = [] + for lf in log_files: + target, result = process_one_log(lf) + copy_one_log(lf, result, output_dir) + tests += [{"log": lf, "target": target, "result": result}] + + return tests + + +def process_one_log(log_file): + """Parse a single log file, extract required pieces from it. """ + assert os.path.isfile(log_file) + target = None + result = None + # Find target name and the test result in the log file + for line in open(log_file, "r"): + target_match = re.match(r"^Target: (\S+)$", line) + if target_match is not None: + target = target_match.group(1) + result_match = re.match(r"^Result: (\S+)$", line) + if result_match is not None: + result = result_match.group(1) + if result not in KNOWN_RESULTS: + msg = ("Unknown test result '{}' in file {}. Expected one of: {}" + .format(result, log_file, KNOWN_RESULTS)) + raise RuntimeError(msg) + + if target is None: + raise RuntimeError("Could not find target name in log file {}".format(log_file)) + if result is None: + raise RuntimeError("Could not find test result in log file {}".format(log_file)) + + return target, result + + +def copy_one_log(log_file, result, output_dir): + """Copy the log to a sub-folder based on the result. """ + target_dir = os.path.join(output_dir, result) + os.makedirs(target_dir, exist_ok=True) + assert os.path.isdir(target_dir) + shutil.copy2(log_file, target_dir) + + +def print_aggregated_results(tests): + """Print the tests grouped by the result. Print also pass/fail/... counts.""" + + def _filter_tests(tests, target=None, result=None): + tests_out = tests + if target is not None: + tests_out = filter(lambda t: t["target"] == target, tests_out) + if result is not None: + tests_out = filter(lambda t: t["result"] == result, tests_out) + return list(tests_out) + + # Print lists of passed/failed/... tests + outcomes = { + "Passed tests": "pass", + "Not applicable tests": "not_applicable", + "Failed tests": "fail", + "Tests ended with exception": "exception", + } + for caption, result in outcomes.items(): + info_box(caption) + tests_filtered = _filter_tests(tests, result=result) + for t in tests_filtered: + name = os.path.splitext(os.path.basename(t["log"]))[0] + info(name) + if not tests_filtered: + info("(none)") + + target_names = sorted(set([t["target"] for t in tests])) + + # Print summary - passed/failed/... counts, for each target and total + + info_box("Summary") + + def _print_row(target, total, num_pass, num_na, num_fail, num_exc): + info("{:<25} {:<10} {:<10} {:<10} {:<10} {:<10}".format(target, total, num_pass, num_na, num_fail, num_exc)) + + _print_row("Target", "# tests", "Pass", "Not_appl.", "Fail", "Exception") + _print_row("-----", "-----", "-----", "-----", "-----", "-----") + sum_pass = sum_na = sum_fail = sum_exc = 0 + for tn in target_names: + t_pass = len(_filter_tests(tests, target=tn, result="pass")) + t_na = len(_filter_tests(tests, target=tn, result="not_applicable")) + t_fail = len(_filter_tests(tests, target=tn, result="fail")) + t_exc = len(_filter_tests(tests, target=tn, result="exception")) + t_sum = len(_filter_tests(tests, target=tn)) + assert t_sum == t_pass + t_na + t_fail + t_exc # self-check + _print_row(tn, t_sum, t_pass, t_na, t_fail, t_exc) + sum_pass += t_pass + sum_na += t_na + sum_fail += t_fail + sum_exc += t_exc + assert len(tests) == sum_pass + sum_na + sum_fail + sum_exc # self-check + _print_row("-----", "-----", "-----", "-----", "-----", "-----") + _print_row("All targets:", len(tests), sum_pass, sum_na, sum_fail, sum_exc) + _print_row("-----", "-----", "-----", "-----", "-----", "-----") + + any_failed = (sum_fail + sum_exc) > 0 + return any_failed + + +def main(): + args = parse_args() + + # Use absolute paths. + args.log_dir = os.path.abspath(args.log_dir) + args.output_dir = os.path.abspath(args.output_dir) + + # Process the log files and print results. + tests = process_test_logs(args.log_dir, args.output_dir) + any_failed = print_aggregated_results(tests) + + # The overall exit code. + exit_code = 1 if any_failed else 0 + if any_failed: + error("Encountered failed test(s). Exiting with non-zero code.") + else: + info("Success - no failed tests encountered.") + return exit_code + + +if __name__ == '__main__': + logging.getLogger().setLevel(logging.INFO) + sys.exit(main()) diff --git a/tools/riscv-openocd-ci/run_tests.sh b/tools/riscv-openocd-ci/run_tests.sh new file mode 100644 index 0000000000..c98407675b --- /dev/null +++ b/tools/riscv-openocd-ci/run_tests.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +CHECKOUT_DIR=`pwd`/tools/riscv-openocd-ci/work/riscv-tests + +# Fail on first error. +set -e + +# Echo commands. +set -o xtrace + +# Checkout riscv-tests. +mkdir -p "$CHECKOUT_DIR" +cd "$CHECKOUT_DIR" +git clone --recursive https://github.com/riscv/riscv-tests . + +# Run the debug tests. +# Do not stop even on a failed test. +# Use slightly more jobs than CPUs. Observed that this still speeds up the testing. +cd debug +JOBS=$(($(nproc) + 2)) +make -k -j$JOBS all || true From 903ad73220e3f56b9019fd27a3f49bf388928dce Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Wed, 30 Dec 2020 15:38:04 +0100 Subject: [PATCH 02/15] fix Change-Id: I3f818a2f438856231f18da2b535eee1e23bba03c Signed-off-by: Jan Matyas --- .github/workflows/riscv-openocd-ci.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/riscv-openocd-ci.yml b/.github/workflows/riscv-openocd-ci.yml index b31b333dc8..2babc81daa 100644 --- a/.github/workflows/riscv-openocd-ci.yml +++ b/.github/workflows/riscv-openocd-ci.yml @@ -32,7 +32,9 @@ jobs: - name: Checkout & run riscv-tests id: run_tests - run: bash tools/riscv-openocd-ci/run_tests.sh + run: | + bash tools/riscv-openocd-ci/run_tests.sh + echo ::set-output name=exit_code::$? - name: Process test results run: | @@ -54,6 +56,7 @@ jobs: run: | lcov --capture --directory . --output-file tools/riscv-openocd-ci/work/openocd-coverage.info genhtml tools/riscv-openocd-ci/work/openocd-coverage.info --output-directory tools/riscv-openocd-ci/work/results/openocd-coverage + echo ::set-output name=exit_code::$? - name: Store OpenOCD code coverage # Run if coverage was collected. From 7bb2321d2e56feb1afcc997305b87889be2ef04b Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Wed, 30 Dec 2020 20:12:05 +0100 Subject: [PATCH 03/15] fix 2 Change-Id: Ib52fc36ed44af1cd259f6698be90acb7e0c9fbba Signed-off-by: Jan Matyas --- .github/workflows/riscv-openocd-ci.yml | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/.github/workflows/riscv-openocd-ci.yml b/.github/workflows/riscv-openocd-ci.yml index 2babc81daa..118680c70b 100644 --- a/.github/workflows/riscv-openocd-ci.yml +++ b/.github/workflows/riscv-openocd-ci.yml @@ -25,42 +25,38 @@ jobs: run: bash tools/riscv-openocd-ci/download_toolchain.sh - name: Update env. variables - # Change RISCV and PATH env variables for subsequent steps. + # Change RISCV and PATH env variables. Needed for the next step. run: | echo "`pwd`/tools/riscv-openocd-ci/work/install/bin" >> $GITHUB_PATH echo "RISCV=`pwd`/tools/riscv-openocd-ci/work/install" >> $GITHUB_ENV - name: Checkout & run riscv-tests - id: run_tests - run: | - bash tools/riscv-openocd-ci/run_tests.sh - echo ::set-output name=exit_code::$? + run: bash tools/riscv-openocd-ci/run_tests.sh - name: Process test results + # If at least one test failed (or ended with an exception), this step fails: non-zero exit code. run: | cd tools/riscv-openocd-ci python3 process_test_results.py --log-dir work/riscv-tests/debug/logs --output-dir work/results/logs - name: Store test results - # Run if tests were executed. - if: steps.run_tests.outputs.exit_code == 0 + # Run even if there was a failed test + if: succeeded() || failed() uses: actions/upload-artifact@v2 with: name: test-results path: tools/riscv-openocd-ci/work/results/logs - name: Collect OpenOCD code coverage - id: collect_cov - # Run if tests were executed. - if: steps.run_tests.outputs.exit_code == 0 + # Run even if there was a failed test + if: succeeded() || failed() run: | lcov --capture --directory . --output-file tools/riscv-openocd-ci/work/openocd-coverage.info genhtml tools/riscv-openocd-ci/work/openocd-coverage.info --output-directory tools/riscv-openocd-ci/work/results/openocd-coverage - echo ::set-output name=exit_code::$? - name: Store OpenOCD code coverage - # Run if coverage was collected. - if: steps.collect_cov.outputs.exit_code == 0 + # Run even if there was a failed test + if: succeeded() || failed() uses: actions/upload-artifact@v2 with: name: openocd-coverage From dcf90fd77c6b5b869f4e3c9627cb17af36e5cf8d Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Wed, 30 Dec 2020 20:18:42 +0100 Subject: [PATCH 04/15] fix 3 Change-Id: If85f59f88001780b615e5f33af501478bd3ad838 Signed-off-by: Jan Matyas --- .github/workflows/riscv-openocd-ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/riscv-openocd-ci.yml b/.github/workflows/riscv-openocd-ci.yml index 118680c70b..b511d3c3ea 100644 --- a/.github/workflows/riscv-openocd-ci.yml +++ b/.github/workflows/riscv-openocd-ci.yml @@ -34,14 +34,14 @@ jobs: run: bash tools/riscv-openocd-ci/run_tests.sh - name: Process test results - # If at least one test failed (or ended with an exception), this step fails: non-zero exit code. + # If at least one test failed (or ended with an exception), this step fails. run: | cd tools/riscv-openocd-ci python3 process_test_results.py --log-dir work/riscv-tests/debug/logs --output-dir work/results/logs - name: Store test results # Run even if there was a failed test - if: succeeded() || failed() + if: ${{ success() || failure() }} uses: actions/upload-artifact@v2 with: name: test-results @@ -49,14 +49,14 @@ jobs: - name: Collect OpenOCD code coverage # Run even if there was a failed test - if: succeeded() || failed() + if: ${{ success() || failure() }} run: | lcov --capture --directory . --output-file tools/riscv-openocd-ci/work/openocd-coverage.info genhtml tools/riscv-openocd-ci/work/openocd-coverage.info --output-directory tools/riscv-openocd-ci/work/results/openocd-coverage - name: Store OpenOCD code coverage # Run even if there was a failed test - if: succeeded() || failed() + if: ${{ success() || failure() }} uses: actions/upload-artifact@v2 with: name: openocd-coverage From e423f9fcc4145a98219fd7baadc999aa2c6bfcf5 Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Wed, 30 Dec 2020 20:43:43 +0100 Subject: [PATCH 05/15] fix 4 Change-Id: Id3417e4b8b9a4dd4063e387d3c5ca025bafff9d1 Signed-off-by: Jan Matyas --- tools/riscv-openocd-ci/build_spike.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/riscv-openocd-ci/build_spike.sh b/tools/riscv-openocd-ci/build_spike.sh index 148d6e8ca5..c5f566af72 100644 --- a/tools/riscv-openocd-ci/build_spike.sh +++ b/tools/riscv-openocd-ci/build_spike.sh @@ -1,7 +1,7 @@ #!/bin/bash -CHECKOUT_DIR=`pwd`/riscv-openocd-ci/work/riscv-isa-sim -INSTALL_DIR=`pwd`/riscv-openocd-ci/work/install +CHECKOUT_DIR=`pwd`/tools/riscv-openocd-ci/work/riscv-isa-sim +INSTALL_DIR=`pwd`/tools/riscv-openocd-ci/work/install # Fail on first error. set -e From cd014411b38fbb1e78c44373bd491f602c49ebeb Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Wed, 30 Dec 2020 21:51:09 +0100 Subject: [PATCH 06/15] fix 5 Change-Id: I5939ed01ded16879dae441a2b2af80b769cf44e1 Signed-off-by: Jan Matyas --- .github/workflows/riscv-openocd-ci.yml | 2 +- tools/riscv-openocd-ci/build_openocd.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/riscv-openocd-ci.yml b/.github/workflows/riscv-openocd-ci.yml index b511d3c3ea..aec94d1363 100644 --- a/.github/workflows/riscv-openocd-ci.yml +++ b/.github/workflows/riscv-openocd-ci.yml @@ -9,7 +9,7 @@ jobs: - name: Install required pkgs run: | - sudo apt-get install libtool pkg-config autoconf automake libusb-1.0 libftdi1 lcov device-tree-compiler + sudo apt-get install libtool pkg-config autoconf automake libusb-1.0 libftdi1 lcov device-tree-compiler pylint3 sudo python3 -m pip install pexpect - name: Checkout OpenOCD diff --git a/tools/riscv-openocd-ci/build_openocd.sh b/tools/riscv-openocd-ci/build_openocd.sh index 8acf521ae5..eb2a9dbf5a 100644 --- a/tools/riscv-openocd-ci/build_openocd.sh +++ b/tools/riscv-openocd-ci/build_openocd.sh @@ -1,6 +1,6 @@ #!/bin/bash -INSTALL_DIR=`pwd`/riscv-openocd-ci/work/install +INSTALL_DIR=`pwd`/tools/riscv-openocd-ci/work/install # Fail on first error. set -e From 05e32dcacc03a2c6c2e81c227d8900468956a415 Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Sat, 16 Jan 2021 12:13:36 +0100 Subject: [PATCH 07/15] Use depth=1 for git clone. Show revision after clone. Change-Id: Idc997c4ebbf83aebf4d767343c59e19abc4fb761 Signed-off-by: Jan Matyas --- tools/riscv-openocd-ci/build_openocd.sh | 3 +++ tools/riscv-openocd-ci/build_spike.sh | 5 ++++- tools/riscv-openocd-ci/run_tests.sh | 5 ++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/tools/riscv-openocd-ci/build_openocd.sh b/tools/riscv-openocd-ci/build_openocd.sh index eb2a9dbf5a..58765035f8 100644 --- a/tools/riscv-openocd-ci/build_openocd.sh +++ b/tools/riscv-openocd-ci/build_openocd.sh @@ -10,6 +10,9 @@ set -o xtrace # Assuming OpenOCD source is already checked-out in the current workdir. +# Show revision info +git log --no-walk --pretty=format:'%C(auto)%h%d (%cd) %cn <%ce> %s' + ./bootstrap # Enable most frequently used JTAG drivers. diff --git a/tools/riscv-openocd-ci/build_spike.sh b/tools/riscv-openocd-ci/build_spike.sh index c5f566af72..e5a7ed8ee0 100644 --- a/tools/riscv-openocd-ci/build_spike.sh +++ b/tools/riscv-openocd-ci/build_spike.sh @@ -12,7 +12,10 @@ set -o xtrace # Checkout Spike. mkdir -p "$CHECKOUT_DIR" cd "$CHECKOUT_DIR" -git clone --recursive https://github.com/riscv/riscv-isa-sim.git . +git clone --depth=1 --recursive https://github.com/riscv/riscv-isa-sim.git . + +# Show revision info +git log --no-walk --pretty=format:'%C(auto)%h%d (%cd) %cn <%ce> %s' # Build Spike mkdir build diff --git a/tools/riscv-openocd-ci/run_tests.sh b/tools/riscv-openocd-ci/run_tests.sh index c98407675b..e3a7b416db 100644 --- a/tools/riscv-openocd-ci/run_tests.sh +++ b/tools/riscv-openocd-ci/run_tests.sh @@ -11,7 +11,10 @@ set -o xtrace # Checkout riscv-tests. mkdir -p "$CHECKOUT_DIR" cd "$CHECKOUT_DIR" -git clone --recursive https://github.com/riscv/riscv-tests . +git clone --depth=1 --recursive https://github.com/riscv/riscv-tests . + +# Show revision info +git log --no-walk --pretty=format:'%C(auto)%h%d (%cd) %cn <%ce> %s' # Run the debug tests. # Do not stop even on a failed test. From 00b75c5f503e6208548166f13ea99f6d73904dff Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Sat, 16 Jan 2021 13:06:15 +0100 Subject: [PATCH 08/15] test Change-Id: I2030d95d4d7fad5759ba8afb65171e7cecbe7a6b Signed-off-by: Jan Matyas --- tools/riscv-openocd-ci/build_openocd.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/riscv-openocd-ci/build_openocd.sh b/tools/riscv-openocd-ci/build_openocd.sh index 58765035f8..c4126a6662 100644 --- a/tools/riscv-openocd-ci/build_openocd.sh +++ b/tools/riscv-openocd-ci/build_openocd.sh @@ -11,7 +11,7 @@ set -o xtrace # Assuming OpenOCD source is already checked-out in the current workdir. # Show revision info -git log --no-walk --pretty=format:'%C(auto)%h%d (%cd) %cn <%ce> %s' +git log --no-walk --pretty="format:'%C(auto)%h%d (%cd) %cn <%ce> %s" --no-color ./bootstrap From 1c63ab97c912ee2bdf94ba524079e9072f5be4e2 Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Sat, 16 Jan 2021 13:16:47 +0100 Subject: [PATCH 09/15] test 2 Change-Id: I7fa2af93e7595244e66f4ae1bfcc4b9dbe718fb6 Signed-off-by: Jan Matyas --- tools/riscv-openocd-ci/build_openocd.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/riscv-openocd-ci/build_openocd.sh b/tools/riscv-openocd-ci/build_openocd.sh index c4126a6662..f57bd82ffd 100644 --- a/tools/riscv-openocd-ci/build_openocd.sh +++ b/tools/riscv-openocd-ci/build_openocd.sh @@ -11,7 +11,7 @@ set -o xtrace # Assuming OpenOCD source is already checked-out in the current workdir. # Show revision info -git log --no-walk --pretty="format:'%C(auto)%h%d (%cd) %cn <%ce> %s" --no-color +git --no-pager log --no-walk --pretty="format:'%C(auto)%h%d (%cd) %cn <%ce> %s" ./bootstrap From a065236bcad6659ca1f098f19c80610e76680687 Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Sat, 16 Jan 2021 13:20:28 +0100 Subject: [PATCH 10/15] test 3 Change-Id: I10c692c9f86eb185feb17e2744e98dc3dffc0049 Signed-off-by: Jan Matyas --- tools/riscv-openocd-ci/build_openocd.sh | 2 +- tools/riscv-openocd-ci/build_spike.sh | 2 +- tools/riscv-openocd-ci/run_tests.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/riscv-openocd-ci/build_openocd.sh b/tools/riscv-openocd-ci/build_openocd.sh index f57bd82ffd..f939da4448 100644 --- a/tools/riscv-openocd-ci/build_openocd.sh +++ b/tools/riscv-openocd-ci/build_openocd.sh @@ -11,7 +11,7 @@ set -o xtrace # Assuming OpenOCD source is already checked-out in the current workdir. # Show revision info -git --no-pager log --no-walk --pretty="format:'%C(auto)%h%d (%cd) %cn <%ce> %s" +git --no-pager log --no-walk --pretty=reference ./bootstrap diff --git a/tools/riscv-openocd-ci/build_spike.sh b/tools/riscv-openocd-ci/build_spike.sh index e5a7ed8ee0..aa73b9f4e8 100644 --- a/tools/riscv-openocd-ci/build_spike.sh +++ b/tools/riscv-openocd-ci/build_spike.sh @@ -15,7 +15,7 @@ cd "$CHECKOUT_DIR" git clone --depth=1 --recursive https://github.com/riscv/riscv-isa-sim.git . # Show revision info -git log --no-walk --pretty=format:'%C(auto)%h%d (%cd) %cn <%ce> %s' +git --no-pager log --no-walk --pretty=reference # Build Spike mkdir build diff --git a/tools/riscv-openocd-ci/run_tests.sh b/tools/riscv-openocd-ci/run_tests.sh index e3a7b416db..ab015a1ffa 100644 --- a/tools/riscv-openocd-ci/run_tests.sh +++ b/tools/riscv-openocd-ci/run_tests.sh @@ -14,7 +14,7 @@ cd "$CHECKOUT_DIR" git clone --depth=1 --recursive https://github.com/riscv/riscv-tests . # Show revision info -git log --no-walk --pretty=format:'%C(auto)%h%d (%cd) %cn <%ce> %s' +git --no-pager log --no-walk --pretty=reference # Run the debug tests. # Do not stop even on a failed test. From 994df0e601f37b148b75831e8e4eb8613e96a06e Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Sat, 16 Jan 2021 13:23:45 +0100 Subject: [PATCH 11/15] test 4 Change-Id: Ibe5e0f08514a640b84691f9521883533bdde9159 Signed-off-by: Jan Matyas --- tools/riscv-openocd-ci/build_openocd.sh | 2 +- tools/riscv-openocd-ci/build_spike.sh | 2 +- tools/riscv-openocd-ci/run_tests.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/riscv-openocd-ci/build_openocd.sh b/tools/riscv-openocd-ci/build_openocd.sh index f939da4448..8e5fb4b9a5 100644 --- a/tools/riscv-openocd-ci/build_openocd.sh +++ b/tools/riscv-openocd-ci/build_openocd.sh @@ -11,7 +11,7 @@ set -o xtrace # Assuming OpenOCD source is already checked-out in the current workdir. # Show revision info -git --no-pager log --no-walk --pretty=reference +git --no-pager log --no-walk --pretty=short ./bootstrap diff --git a/tools/riscv-openocd-ci/build_spike.sh b/tools/riscv-openocd-ci/build_spike.sh index aa73b9f4e8..8964946563 100644 --- a/tools/riscv-openocd-ci/build_spike.sh +++ b/tools/riscv-openocd-ci/build_spike.sh @@ -15,7 +15,7 @@ cd "$CHECKOUT_DIR" git clone --depth=1 --recursive https://github.com/riscv/riscv-isa-sim.git . # Show revision info -git --no-pager log --no-walk --pretty=reference +git --no-pager log --no-walk --pretty=short # Build Spike mkdir build diff --git a/tools/riscv-openocd-ci/run_tests.sh b/tools/riscv-openocd-ci/run_tests.sh index ab015a1ffa..284b29217f 100644 --- a/tools/riscv-openocd-ci/run_tests.sh +++ b/tools/riscv-openocd-ci/run_tests.sh @@ -14,7 +14,7 @@ cd "$CHECKOUT_DIR" git clone --depth=1 --recursive https://github.com/riscv/riscv-tests . # Show revision info -git --no-pager log --no-walk --pretty=reference +git --no-pager log --no-walk --pretty=short # Run the debug tests. # Do not stop even on a failed test. From d0a307b19605c6ce6189204b0e6d881c15ec793c Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Mon, 15 Mar 2021 20:44:16 +0100 Subject: [PATCH 12/15] Added gcov-generated files to .gitignore Change-Id: I0005603ad60d8e104f7bec4fe16d2a9ae1342df3 --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 41573d881d..b47d516a1e 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,10 @@ *.la *.in +# coverage files (gcov) +*.gcda +*.gcno + # generated source files src/jtag/minidriver_imp.h src/jtag/jtag_minidriver.h From f0f0b81d65c7937750d75f00eca6f312c83b3c88 Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Mon, 15 Mar 2021 21:24:56 +0100 Subject: [PATCH 13/15] Changed toolchain to: xPack GNU RISC-V Embedded GCC v10.1.0-1.1 Change-Id: Ic285cd0147fb9285adb5edb20f27b0a3e06ff82a Signed-off-by: Jan Matyas --- tools/riscv-openocd-ci/download_toolchain.sh | 27 ++++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/tools/riscv-openocd-ci/download_toolchain.sh b/tools/riscv-openocd-ci/download_toolchain.sh index 52323dda26..a1332e9491 100644 --- a/tools/riscv-openocd-ci/download_toolchain.sh +++ b/tools/riscv-openocd-ci/download_toolchain.sh @@ -1,7 +1,17 @@ #!/bin/bash -TOOLCHAIN_URL="https://buildbot.embecosm.com/job/riscv32-gcc-ubuntu1804" -TOOLCHAIN_URL+="/25/artifact/riscv32-embecosm-gcc-ubuntu1804-20201108.tar.gz" +# Toolchain builds provided by Embecosm (buildbot.embecosm.com) +# TOOLCHAIN_URL="https://buildbot.embecosm.com/job/riscv32-gcc-ubuntu1804" +# TOOLCHAIN_URL+="/25/artifact/riscv32-embecosm-gcc-ubuntu1804-20201108.tar.gz" +# TOOLCHAIN_PREFIX=riscv32-unknown-elf- + +# Toolchain builds from "The xPack Project" +# (https://xpack.github.io/riscv-none-embed-gcc/) +TOOLCHAIN_URL="https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack/" +TOOLCHAIN_URL+="releases/download/v10.1.0-1.1/" +TOOLCHAIN_URL+="xpack-riscv-none-embed-gcc-10.1.0-1.1-linux-x64.tar.gz" +TOOLCHAIN_PREFIX=riscv-none-embed- + ARCHIVE_NAME=${TOOLCHAIN_URL##*/} DOWNLOAD_DIR=`pwd`/tools/riscv-openocd-ci/work INSTALL_DIR=`pwd`/tools/riscv-openocd-ci/work/install @@ -23,9 +33,16 @@ mkdir -p "$INSTALL_DIR" cd "$INSTALL_DIR" tar xvf "$DOWNLOAD_DIR/$ARCHIVE_NAME" --strip-components=1 -# Make symlinks: riscv64-* --> riscv32-* cd "$INSTALL_DIR/bin" -find . -name 'riscv32-*' | while read F; do ln -s $F $(echo $F | sed -e 's/riscv32/riscv64/'); done -# Check that the compiler runs +# Make symlinks so that the tools are accessible as riscv64-unknown-elf-* +if [ "$TOOLCHAIN_PREFIX" != "riscv64-unknown-elf-" ]; then + find . -name "$TOOLCHAIN_PREFIX*" | while read F; do + ln -s $F $(echo $F | sed -e "s/$TOOLCHAIN_PREFIX/riscv64-unknown-elf-/"); + done +fi + +# Check that the compiler and debugger run ./riscv64-unknown-elf-gcc --version +./riscv64-unknown-elf-gdb --version + From 24960b9be61637e2da02a316279c041205262531 Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Thu, 3 Jun 2021 14:44:44 -0700 Subject: [PATCH 14/15] Call keep_alive() more often. When it doesn't do anything (most of the time) it has negligible performance impact. With slower remote bitbang, and multiple spike instances being tested in a single chain, things are sufficiently slow that if a computer is busy then this is required to pass riscv-tests/debug. Change-Id: I8816efedaa0cc3b25734ba8fdc979ee4502284a1 Signed-off-by: Tim Newsome --- src/target/riscv/batch.c | 6 ++++-- src/target/riscv/riscv-013.c | 7 +++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/target/riscv/batch.c b/src/target/riscv/batch.c index 43f2ffb8c0..073f80888f 100644 --- a/src/target/riscv/batch.c +++ b/src/target/riscv/batch.c @@ -82,8 +82,6 @@ int riscv_batch_run(struct riscv_batch *batch) return ERROR_OK; } - keep_alive(); - riscv_batch_add_nop(batch); for (size_t i = 0; i < batch->used_scans; ++i) { @@ -96,11 +94,15 @@ int riscv_batch_run(struct riscv_batch *batch) jtag_add_runtest(batch->idle_count, TAP_IDLE); } + keep_alive(); + if (jtag_execute_queue() != ERROR_OK) { LOG_ERROR("Unable to execute JTAG queue"); return ERROR_FAIL; } + keep_alive(); + if (bscan_tunnel_ir_width != 0) { /* need to right-shift "in" by one bit, because of clock skew between BSCAN TAP and DM TAP */ for (size_t i = 0; i < batch->used_scans; ++i) diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index ace362929b..4b9bd93e12 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -591,6 +591,8 @@ static int dmi_op_timeout(struct target *target, uint32_t *data_in, return ERROR_FAIL; } + keep_alive(); + time_t start = time(NULL); /* This first loop performs the request. Note that if for some reason this * stays busy, it is actually due to the previous access. */ @@ -1307,8 +1309,6 @@ static int register_write_direct(struct target *target, unsigned number, LOG_DEBUG("{%d} %s <- 0x%" PRIx64, riscv_current_hartid(target), gdb_regno_name(number), value); - keep_alive(); - int result = register_write_abstract(target, number, value, register_size(target, number)); if (result == ERROR_OK || !has_sufficient_progbuf(target, 2) || @@ -2730,6 +2730,7 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address, next_read); return ERROR_FAIL; } + keep_alive(); dmi_status_t status = dmi_scan(target, NULL, &value, DMI_OP_READ, sbdata[j], 0, false); if (status == DMI_STATUS_BUSY) @@ -2745,7 +2746,6 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address, } next_read = address + i * size + j * 4; } - keep_alive(); } uint32_t sbcs_read = 0; @@ -3507,7 +3507,6 @@ static int read_memory_progbuf(struct target *target, target_addr_t address, uint8_t *buffer_i = buffer; for (uint32_t i = 0; i < count; i++, address_i += increment, buffer_i += size) { - keep_alive(); /* TODO: This is much slower than it needs to be because we end up * writing the address to read for every word we read. */ result = read_memory_progbuf_inner(target, address_i, size, count_i, buffer_i, increment); From a198155b97437e530662435ebf08a8a2db12ebbd Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Fri, 4 Jun 2021 12:27:45 +0200 Subject: [PATCH 15/15] Fixed halt reason after single-step After single step operation, we should not assume that the halt reason is single-step. There can be a higher-priority halt cause, e.g. a breakpoint. The real halt reason should be obtained from the target (dcsr.cause). Change-Id: I3f1649aa46b91ea456d642d31ec2c50788b96084 Signed-off-by: Jan Matyas --- src/target/riscv/riscv.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 8cfb2275ad..42b0483587 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -2227,6 +2227,8 @@ int riscv_openocd_poll(struct target *target) int riscv_openocd_step(struct target *target, int current, target_addr_t address, int handle_breakpoints) { + RISCV_INFO(r); + LOG_DEBUG("stepping rtos hart"); if (!current) @@ -2249,8 +2251,11 @@ int riscv_openocd_step(struct target *target, int current, target->state = TARGET_RUNNING; target_call_event_callbacks(target, TARGET_EVENT_RESUMED); + target->state = TARGET_HALTED; - target->debug_reason = DBG_REASON_SINGLESTEP; + /* Read real debug reason from the target. Do not presume the target halted due + * to the single-step. There may be a higher-priority halt cause, e.g. a breakpoint. */ + set_debug_reason(target, r->current_hartid); target_call_event_callbacks(target, TARGET_EVENT_HALTED); return out; }