Skip to content
Draft
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
63 changes: 63 additions & 0 deletions .github/workflows/riscv-openocd-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
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 pylint3
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. 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
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.
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: ${{ success() || failure() }}
uses: actions/upload-artifact@v2
with:
name: test-results
path: tools/riscv-openocd-ci/work/results/logs

- name: Collect OpenOCD code coverage
# Run even if there was a failed test
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: ${{ success() || failure() }}
uses: actions/upload-artifact@v2
with:
name: openocd-coverage
path: tools/riscv-openocd-ci/work/results/openocd-coverage
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
*.la
*.in

# coverage files (gcov)
*.gcda
*.gcno

# generated source files
src/jtag/minidriver_imp.h
src/jtag/jtag_minidriver.h
Expand Down
6 changes: 4 additions & 2 deletions src/target/riscv/batch.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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)
Expand Down
7 changes: 3 additions & 4 deletions src/target/riscv/riscv-013.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down Expand Up @@ -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) ||
Expand Down Expand Up @@ -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)
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
7 changes: 6 additions & 1 deletion src/target/riscv/riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
}
Expand Down
1 change: 1 addition & 0 deletions tools/riscv-openocd-ci/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
work
21 changes: 21 additions & 0 deletions tools/riscv-openocd-ci/README.md
Original file line number Diff line number Diff line change
@@ -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.
39 changes: 39 additions & 0 deletions tools/riscv-openocd-ci/build_openocd.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash

INSTALL_DIR=`pwd`/tools/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.

# Show revision info
git --no-pager log --no-walk --pretty=short

./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
29 changes: 29 additions & 0 deletions tools/riscv-openocd-ci/build_spike.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash

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

# Echo commands.
set -o xtrace

# Checkout Spike.
mkdir -p "$CHECKOUT_DIR"
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=short

# 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
48 changes: 48 additions & 0 deletions tools/riscv-openocd-ci/download_toolchain.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/bin/bash

# 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

# 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

cd "$INSTALL_DIR/bin"

# 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

15 changes: 15 additions & 0 deletions tools/riscv-openocd-ci/patches/openocd_gcov_flush.patch
Original file line number Diff line number Diff line change
@@ -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);
Loading