From: Tim Newsome Date: Fri, 12 Aug 2016 01:43:46 +0000 (-0700) Subject: Merge pull request #21 from sifive/add_freedom_sim_targets X-Git-Url: https://git.libre-soc.org/?p=riscv-tests.git;a=commitdiff_plain;h=37a93a9f86521aea2758271a1cc87c23bca06f59;hp=b974a55ac40030fc61120b8881f16ef1abc20e34 Merge pull request #21 from sifive/add_freedom_sim_targets Add freedom sim targets --- diff --git a/debug/README.md b/debug/README.md index 4a90c0c..56f69db 100644 --- a/debug/README.md +++ b/debug/README.md @@ -19,11 +19,17 @@ Targets `./gdbserver.py --spike32 --cmd $RISCV/bin/spike` -32-bit SiFive Core on Arty FPGA board +32-bit SiFive Core on Supported FPGA Boards & Hardware ------------------------------------- `./gdbserver.py --freedom-e300` +32-bit rocket-chip core in Simulation +------------------------------------- + +`./gdbserver.py --freedom-e300-sim` + + Debug Tips ========== diff --git a/debug/gdbserver.py b/debug/gdbserver.py index 2558a6c..8a6e874 100755 --- a/debug/gdbserver.py +++ b/debug/gdbserver.py @@ -10,6 +10,7 @@ import time import random import binascii + MSTATUS_UIE = 0x00000001 MSTATUS_SIE = 0x00000002 MSTATUS_HIE = 0x00000004 @@ -30,12 +31,29 @@ MSTATUS_VM = 0x1F000000 MSTATUS32_SD = 0x80000000 MSTATUS64_SD = 0x8000000000000000 -def gdb(): +def gdb( + target=None, + port=None, + binary=None + ): + + gdb = None if parsed.gdb: - return testlib.Gdb(parsed.gdb) + gdb = testlib.Gdb(parsed.gdb) else: - return testlib.Gdb() + gdb = testlib.Gdb() + + if (binary): + gdb.command("file %s" % self.binary) + if (target): + gdb.command("set arch riscv:rv%d" % target.xlen) + gdb.command("set remotetimeout %d" % target.timeout_sec) + if (port): + gdb.command("target extended-remote localhost:%d" % port) + + return gdb + def ihex_line(address, record_type, data): assert len(data) < 128 line = ":%02X%04X%02X" % (len(data), address, record_type) @@ -71,12 +89,7 @@ class DeleteServer(unittest.TestCase): class SimpleRegisterTest(DeleteServer): def setUp(self): self.server = target.server() - self.gdb = gdb() - # For now gdb has to be told what the architecture is when it's not - # given an ELF file. - self.gdb.command("set arch riscv:rv%d" % target.xlen) - - self.gdb.command("target extended-remote localhost:%d" % self.server.port) + self.gdb = gdb(target, self.server.port) # 0x13 is nop self.gdb.command("p *((int*) 0x%x)=0x13" % target.ram) @@ -113,9 +126,7 @@ class SimpleRegisterTest(DeleteServer): class SimpleMemoryTest(DeleteServer): def setUp(self): self.server = target.server() - self.gdb = gdb() - self.gdb.command("set arch riscv:rv%d" % target.xlen) - self.gdb.command("target extended-remote localhost:%d" % self.server.port) + self.gdb = gdb(target, self.server.port) def access_test(self, size, data_type): self.assertEqual(self.gdb.p("sizeof(%s)" % data_type), @@ -171,10 +182,8 @@ class SimpleMemoryTest(DeleteServer): class InstantHaltTest(DeleteServer): def setUp(self): self.server = target.server() - self.gdb = gdb() - self.gdb.command("set arch riscv:rv%d" % target.xlen) - self.gdb.command("target extended-remote localhost:%d" % self.server.port) - + self.gdb = gdb(target, self.server.port) + def test_instant_halt(self): self.assertEqual(target.reset_vector, self.gdb.p("$pc")) # mcycle and minstret have no defined reset value. @@ -202,9 +211,7 @@ class DebugTest(DeleteServer): self.binary = target.compile("programs/debug.c", "programs/checksum.c", "programs/tiny-malloc.c", "-DDEFINE_MALLOC", "-DDEFINE_FREE") self.server = target.server() - self.gdb = gdb() - self.gdb.command("file %s" % self.binary) - self.gdb.command("target extended-remote localhost:%d" % self.server.port) + self.gdb = gdb(target, self.server.port, self.binary) self.gdb.load() self.gdb.b("_exit") @@ -355,9 +362,7 @@ class StepTest(DeleteServer): def setUp(self): self.binary = target.compile("programs/step.S") self.server = target.server() - self.gdb = gdb() - self.gdb.command("file %s" % self.binary) - self.gdb.command("target extended-remote localhost:%d" % self.server.port) + self.gdb = gdb(target, self.server.port, self.binary) self.gdb.load() self.gdb.b("main") self.gdb.c() @@ -373,9 +378,7 @@ class RegsTest(DeleteServer): def setUp(self): self.binary = target.compile("programs/regs.S") self.server = target.server() - self.gdb = gdb() - self.gdb.command("file %s" % self.binary) - self.gdb.command("target extended-remote localhost:%d" % self.server.port) + self.gdb = gdb(target, self.server.port, self.binary) self.gdb.load() self.gdb.b("main") self.gdb.b("handle_trap") @@ -443,10 +446,8 @@ class DownloadTest(DeleteServer): self.binary = target.compile(download_c.name, "programs/checksum.c") self.server = target.server() - self.gdb = gdb() - self.gdb.command("file %s" % self.binary) - self.gdb.command("target extended-remote localhost:%d" % self.server.port) - + self.gdb = gdb(target, self.server.port, self.binary) + def test_download(self): output = self.gdb.load() self.gdb.command("b _exit") @@ -457,9 +458,7 @@ class MprvTest(DeleteServer): def setUp(self): self.binary = target.compile("programs/mprv.S") self.server = target.server() - self.gdb = gdb() - self.gdb.command("file %s" % self.binary) - self.gdb.command("target extended-remote localhost:%d" % self.server.port) + self.gdb = gdb(target, self.server.port, self.binary) self.gdb.load() def test_mprv(self): @@ -474,9 +473,7 @@ class PrivTest(DeleteServer): def setUp(self): self.binary = target.compile("programs/priv.S") self.server = target.server() - self.gdb = gdb() - self.gdb.command("file %s" % self.binary) - self.gdb.command("target extended-remote localhost:%d" % self.server.port) + self.gdb = gdb(target, self.server.port, self.binary) self.gdb.load() misa = self.gdb.p("$misa") @@ -524,7 +521,8 @@ class PrivTest(DeleteServer): class Target(object): directory = None - + timeout_sec = 2 + def server(self): raise NotImplementedError @@ -578,23 +576,70 @@ class FreedomE300Target(Target): return testlib.Openocd(cmd=parsed.cmd, config="targets/%s/openocd.cfg" % self.name) +class FreedomE300SimTarget(Target): + name = "freedom-e300-sim" + xlen = 32 + timeout_sec = 240 + ram = 0x80000000 + ram_size = 256 * 1024 * 1024 + instruction_hardware_breakpoint_count = 2 + + def server(self): + sim = testlib.VcsSim(simv=parsed.run, debug=False) + openocd = testlib.Openocd(cmd=parsed.cmd, + config="targets/%s/openocd.cfg" % self.name, + otherProcess = sim) + time.sleep(20) + return openocd + +class FreedomU500Target(Target): + name = "freedom-u500" + xlen = 64 + ram = 0x80000000 + ram_size = 16 * 1024 + instruction_hardware_breakpoint_count = 2 + + def server(self): + return testlib.Openocd(cmd=parsed.cmd, + config="targets/%s/openocd.cfg" % self.name) + +class FreedomU500SimTarget(Target): + name = "freedom-u500-sim" + xlen = 64 + timeout_sec = 240 + ram = 0x80000000 + ram_size = 256 * 1024 * 1024 + instruction_hardware_breakpoint_count = 2 + + def server(self): + sim = testlib.VcsSim(simv=parsed.run, debug=False) + openocd = testlib.Openocd(cmd=parsed.cmd, + config="targets/%s/openocd.cfg" % self.name, + otherProcess = sim) + time.sleep(20) + return openocd + targets = [ Spike32Target, Spike64Target, - FreedomE300Target - ] + FreedomE300Target, + FreedomU500Target, + FreedomE300SimTarget, + FreedomU500SimTarget] def main(): parser = argparse.ArgumentParser( epilog=""" Example command line from the real world: - Run all RegsTest cases against a MicroSemi m2gl_m2s board, with custom openocd command: - ./gdbserver.py --m2gl_m2s --cmd "$HOME/SiFive/openocd/src/openocd -s $HOME/SiFive/openocd/tcl -d" -- -vf RegsTest + Run all RegsTest cases against a physical FPGA, with custom openocd command: + ./gdbserver.py --freedom-e-300 --cmd "$HOME/SiFive/openocd/src/openocd -s $HOME/SiFive/openocd/tcl -d" -- -vf RegsTest """) group = parser.add_mutually_exclusive_group(required=True) for t in targets: group.add_argument("--%s" % t.name, action="store_const", const=t, dest="target") + parser.add_argument("--run", + 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("--gdb", @@ -613,7 +658,7 @@ def main(): # TROUBLESHOOTING TIPS # If a particular test fails, run just that one test, eg.: -# ./tests/gdbserver.py MprvTest.test_mprv +# ./gdbserver.py MprvTest.test_mprv # Then inspect gdb.log and spike.log to see what happened in more detail. if __name__ == '__main__': diff --git a/debug/targets/freedom-e300-sim/link.lds b/debug/targets/freedom-e300-sim/link.lds new file mode 100755 index 0000000..1dbb99c --- /dev/null +++ b/debug/targets/freedom-e300-sim/link.lds @@ -0,0 +1,34 @@ +OUTPUT_ARCH( "riscv" ) + +SECTIONS +{ + . = 0x80000000; + .text : + { + *(.text.entry) + *(.text) + } + + /* data segment */ + .data : { *(.data) } + + .sdata : { + _gp = . + 0x800; + *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) + *(.srodata*) + *(.sdata .sdata.* .gnu.linkonce.s.*) + } + + /* bss segment */ + .sbss : { + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } + .bss : { *(.bss) } + + __malloc_start = .; + . = . + 512; + + /* End of uninitalized data segement */ + _end = .; +} diff --git a/debug/targets/freedom-e300-sim/openocd.cfg b/debug/targets/freedom-e300-sim/openocd.cfg new file mode 100644 index 0000000..e8edda4 --- /dev/null +++ b/debug/targets/freedom-e300-sim/openocd.cfg @@ -0,0 +1,13 @@ +adapter_khz 10000 + +source [find interface/jtag_vpi.cfg] + +set _CHIPNAME riscv +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913 + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME riscv -chain-position $_TARGETNAME + +init + +halt diff --git a/debug/targets/freedom-e300/openocd.cfg b/debug/targets/freedom-e300/openocd.cfg index 3884a3e..d448989 100644 --- a/debug/targets/freedom-e300/openocd.cfg +++ b/debug/targets/freedom-e300/openocd.cfg @@ -8,12 +8,6 @@ jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913 set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME riscv -chain-position $_TARGETNAME -#reset_config trst_and_srst separate -# Stupid long so I can see the LEDs -#adapter_nsrst_delay 2000 -#jtag_ntrst_delay 1000 -# init -#reset halt diff --git a/debug/targets/freedom-u500-sim/link.lds b/debug/targets/freedom-u500-sim/link.lds new file mode 100755 index 0000000..1dbb99c --- /dev/null +++ b/debug/targets/freedom-u500-sim/link.lds @@ -0,0 +1,34 @@ +OUTPUT_ARCH( "riscv" ) + +SECTIONS +{ + . = 0x80000000; + .text : + { + *(.text.entry) + *(.text) + } + + /* data segment */ + .data : { *(.data) } + + .sdata : { + _gp = . + 0x800; + *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) + *(.srodata*) + *(.sdata .sdata.* .gnu.linkonce.s.*) + } + + /* bss segment */ + .sbss : { + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } + .bss : { *(.bss) } + + __malloc_start = .; + . = . + 512; + + /* End of uninitalized data segement */ + _end = .; +} diff --git a/debug/targets/freedom-u500-sim/openocd.cfg b/debug/targets/freedom-u500-sim/openocd.cfg new file mode 100644 index 0000000..e8edda4 --- /dev/null +++ b/debug/targets/freedom-u500-sim/openocd.cfg @@ -0,0 +1,13 @@ +adapter_khz 10000 + +source [find interface/jtag_vpi.cfg] + +set _CHIPNAME riscv +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913 + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME riscv -chain-position $_TARGETNAME + +init + +halt diff --git a/debug/targets/freedom-u500/link.lds b/debug/targets/freedom-u500/link.lds new file mode 100755 index 0000000..1dbb99c --- /dev/null +++ b/debug/targets/freedom-u500/link.lds @@ -0,0 +1,34 @@ +OUTPUT_ARCH( "riscv" ) + +SECTIONS +{ + . = 0x80000000; + .text : + { + *(.text.entry) + *(.text) + } + + /* data segment */ + .data : { *(.data) } + + .sdata : { + _gp = . + 0x800; + *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) + *(.srodata*) + *(.sdata .sdata.* .gnu.linkonce.s.*) + } + + /* bss segment */ + .sbss : { + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } + .bss : { *(.bss) } + + __malloc_start = .; + . = . + 512; + + /* End of uninitalized data segement */ + _end = .; +} diff --git a/debug/targets/freedom-u500/openocd.cfg b/debug/targets/freedom-u500/openocd.cfg new file mode 100644 index 0000000..d448989 --- /dev/null +++ b/debug/targets/freedom-u500/openocd.cfg @@ -0,0 +1,13 @@ +adapter_khz 10000 + +source [find interface/ftdi/olimex-arm-usb-tiny-h.cfg] + +set _CHIPNAME riscv +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913 + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME riscv -chain-position $_TARGETNAME + +init + +halt diff --git a/debug/testlib.py b/debug/testlib.py index b3f8f66..99c4a76 100644 --- a/debug/testlib.py +++ b/debug/testlib.py @@ -5,6 +5,7 @@ import subprocess import tempfile import testlib import unittest +import time # Note that gdb comes with its own testsuite. I was unable to figure out how to # run that testsuite against the spike simulator. @@ -76,8 +77,46 @@ class Spike(object): def wait(self, *args, **kwargs): return self.process.wait(*args, **kwargs) +class VcsSim(object): + def __init__(self, simv=None, debug=False): + if simv: + cmd = shlex.split(simv) + else: + cmd = ["simv"] + cmd += ["+jtag_vpi_enable"] + if debug: + cmd[0] = cmd[0] + "-debug" + cmd += ["+vcdplusfile=output/gdbserver.vpd"] + logfile = open("simv.log", "w") + logfile.write("+ %s\n" % " ".join(cmd)) + logfile.flush() + listenfile = open("simv.log", "r") + listenfile.seek(0,2) + self.process = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=logfile, + stderr=logfile) + done = False + while (not done): + line = listenfile.readline() + if (not line): + time.sleep(1) + if ("Listening on port 5555" in line): + done = True + + def __del__(self): + try: + self.process.kill() + self.process.wait() + except OSError: + pass + + class Openocd(object): - def __init__(self, cmd=None, config=None, debug=False): + def __init__(self, cmd=None, config=None, debug=False, otherProcess=None): + + # keep handles to other processes -- don't let them be + # garbage collected yet. + + self.otherProcess = otherProcess if cmd: cmd = shlex.split(cmd) else: