RISCV_SIM ?= spike
XLEN ?= 64
+OPENOCD_INSTALL ?= $(abspath .)/openocd-install
+OPENOCD_VERSION = 860b42a3c4f6aa37d8d4fe50a71000b7cff66b85
+
+OPENOCD_DIR = $(OPENOCD_INSTALL)_$(OPENOCD_VERSION)/
+
+$(OPENOCD_DIR)/bin/openocd:
+ rm -rf riscv-openocd
+ git clone http://github.com/riscv/riscv-openocd.git
+ cd riscv-openocd ; \
+ git checkout $(OPENOCD_VERSION) ; \
+ ./bootstrap ; \
+ ./configure --enable-remote_bitbang --prefix=$(OPENOCD_INSTALL)_$(OPENOCD_VERSION) --disable-werror; \
+ make ; \
+ make install
+
+install_openocd: $(OPENOCD_DIR)/bin/openocd
+
src_dir ?= .
GDBSERVER_PY = $(src_dir)/gdbserver.py
pylint --rcfile=pylint.rc *.py
%.log:
- $(GDBSERVER_PY) --isolate --$(subst .log,,$@) \
+ $(GDBSERVER_PY) --isolate --$(subst .log,,$@) --server_cmd $(OPENOCD_DIR)/bin/openocd \
> $@ 2>&1 || (sed s/^/$@:\ / $@ && false)
clean:
===========
Debugging requires many system components to all work together. The tests here
-perform an end-to-end test, communicating only with gdb. If a simulator or
-hardware passes all these tests, then you can be pretty confident that the
-actual debug interface is functioning correctly.
+perform an end-to-end test, communicating with gdb and OpenOCD.
+If a simulator or hardware passes all these tests, then you can be pretty
+confident that the actual debug interface is functioning correctly.
Targets
=======
-------------------------------------
`./gdbserver.py --freedom-e300`
+`./gdbserver.py --hifive1`
+
32-bit rocket-chip core in Simulation
-------------------------------------
`./gdbserver.py --freedom-e300-sim`
-
Debug Tips
==========
epilog="""
Example command line from the real world:
Run all RegsTest cases against a physical FPGA, with custom openocd command:
- ./gdbserver.py --freedom-e300 --cmd "$HOME/SiFive/openocd/src/openocd -s $HOME/SiFive/openocd/tcl -d" Simple
+ ./gdbserver.py --freedom-e300 --server_cmd "$HOME/SiFive/openocd/src/openocd -s $HOME/SiFive/openocd/tcl -d" Simple
""")
targets.add_target_options(parser)
global parsed # pylint: disable=global-statement
parsed = parser.parse_args()
- target = parsed.target(parsed.cmd, parsed.run, parsed.isolate)
+ target = parsed.target(parsed.server_cmd, parsed.sim_cmd, parsed.isolate)
if parsed.xlen:
target.xlen = parsed.xlen
use_fpu = False
misa = None
- def __init__(self, cmd, run, isolate):
- self.cmd = cmd
- self.run = run
+ def __init__(self, server_cmd, sim_cmd, isolate):
+ self.server_cmd = server_cmd
+ self.sim_cmd = sim_cmd
self.isolate = isolate
def target(self):
def server(self):
"""Start the debug server that gdb connects to, eg. OpenOCD."""
if self.openocd_config:
- return testlib.Openocd(cmd=self.cmd, config=self.openocd_config)
+ return testlib.Openocd(server_cmd=self.server_cmd, config=self.openocd_config)
else:
raise NotImplementedError
use_fpu = True
def target(self):
- return testlib.Spike(self.cmd, halted=True)
+ return testlib.Spike(self.sim_cmd, halted=True)
class Spike32Target(SpikeTarget):
name = "spike32"
xlen = 32
def target(self):
- return testlib.Spike(self.cmd, halted=True, xlen=32)
+ return testlib.Spike(self.sim_cmd, halted=True, xlen=32)
class FreedomE300Target(Target):
name = "freedom-e300"
openocd_config = "targets/%s/openocd.cfg" % name
def target(self):
- return testlib.VcsSim(simv=self.run, debug=False)
+ return testlib.VcsSim(simv=self.sim_cmd, debug=False)
class FreedomU500Target(Target):
name = "freedom-u500"
openocd_config = "targets/%s/openocd.cfg" % name
def target(self):
- return testlib.VcsSim(simv=self.run, debug=False)
+ return testlib.VcsSim(simv=self.sim_cmd, debug=False)
targets = [
Spike32Target,
for t in targets:
group.add_argument("--%s" % t.name, action="store_const", const=t,
dest="target")
- parser.add_argument("--run",
+ parser.add_argument("--sim_cmd",
help="The command to use to start the actual target (e.g. "
"simulation)")
- parser.add_argument("--cmd",
- help="The command to use to start the debug server.")
+ parser.add_argument("--server_cmd",
+ help="The command to use to start the debug server (e.g. OpenOCD)")
xlen_group = parser.add_mutually_exclusive_group()
xlen_group.add_argument("--32", action="store_const", const=32, dest="xlen",
class Spike(object):
logname = "spike.log"
- def __init__(self, cmd, binary=None, halted=False, with_jtag_gdb=True,
+ def __init__(self, sim_cmd, binary=None, halted=False, with_jtag_gdb=True,
timeout=None, xlen=64):
"""Launch spike. Return tuple of its process and the port it's running
on."""
- if cmd:
- cmd = shlex.split(cmd)
+ if sim_cmd:
+ cmd = shlex.split(sim_cmd)
else:
- cmd = ["spike"]
+ spike = os.path.expandvars("$RISCV/bin/spike")
+ cmd = [spike]
if xlen == 32:
cmd += ["--isa", "RV32"]
return self.process.wait(*args, **kwargs)
class VcsSim(object):
- def __init__(self, simv=None, debug=False):
- if simv:
+ def __init__(self, sim_cmd=None, debug=False):
+ if sim_cmd:
cmd = shlex.split(simv)
else:
cmd = ["simv"]
class Openocd(object):
logname = "openocd.log"
- def __init__(self, cmd=None, config=None, debug=False):
- if cmd:
- cmd = shlex.split(cmd)
+ def __init__(self, server_cmd=None, config=None, debug=False):
+ if server_cmd:
+ cmd = shlex.split(server_cmd)
else:
- cmd = ["openocd", "-d"]
-
+ openocd = os.path.expandvars("$RISCV/bin/riscv-openocd")
+ cmd = [openocd]
+ if (debug):
+ cmd.append("-d")
+
# This command needs to come before any config scripts on the command
# line, since they are executed in order.
cmd += [