aboutsummaryrefslogtreecommitdiff
path: root/debug/rbb_daisychain.py
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2021-05-07 11:49:42 -0700
committerGitHub <noreply@github.com>2021-05-07 11:49:42 -0700
commitc9f43c1652c1d8abf85f3466f41ffd5ec4d911d6 (patch)
tree21306f7c8d15ad937e2e234d564e81a0e43efa86 /debug/rbb_daisychain.py
parent1b05661baa79f03830f5ddefa999dc7aaf7b1ce1 (diff)
downloadriscv-tests-c9f43c1652c1d8abf85f3466f41ffd5ec4d911d6.zip
riscv-tests-c9f43c1652c1d8abf85f3466f41ffd5ec4d911d6.tar.gz
riscv-tests-c9f43c1652c1d8abf85f3466f41ffd5ec4d911d6.tar.bz2
Test daisy chained homogeneous spike instances. (#334)
* Test debugging multiple spikes in a daisy chain. * Hugely speed up rbb_daisychain. Now 2 dual-hart spikes are less than 4x slower than a single dual-hart spike. * WIP * Test daisy chained homogeneous spike instances. For OpenOCD, this means we're checking that we can talk to multiple TAPs. Next up is heterogeneous testing. * Enable Sv48Test. Didn't mean to disable it with this commit. * Test authentication again. Another change I hadn't meant to push...
Diffstat (limited to 'debug/rbb_daisychain.py')
-rwxr-xr-xdebug/rbb_daisychain.py111
1 files changed, 111 insertions, 0 deletions
diff --git a/debug/rbb_daisychain.py b/debug/rbb_daisychain.py
new file mode 100755
index 0000000..b7c21e6
--- /dev/null
+++ b/debug/rbb_daisychain.py
@@ -0,0 +1,111 @@
+#!/usr/bin/python3
+
+import argparse
+import sys
+import socket
+
+# https://github.com/ntfreak/openocd/blob/master/doc/manual/jtag/drivers/remote_bitbang.txt
+
+class Tap:
+ def __init__(self, port):
+ self.port = port
+ self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.socket.connect(("localhost", port))
+
+ def execute(self, commands):
+ sent = self.socket.send(commands)
+ assert len(commands) == sent
+ read_count = 0
+ for command in commands:
+ if command == ord('R'):
+ read_count += 1
+ result = b""
+ while len(result) < read_count:
+ result += self.socket.recv(read_count - len(result))
+ assert len(result) == read_count
+ return result
+
+class Chain:
+ def __init__(self, debug=False):
+ self.debug = debug
+ self.taps = []
+
+ def append(self, tap):
+ self.taps.append(tap)
+
+ def execute(self, commands):
+ values = []
+ for i, tap in enumerate(self.taps):
+ tmp_commands = []
+ for command in commands:
+ if i > 0 and ord('0') <= command <= ord('7'):
+ # Replace TDI with the value from the previous TAP.
+ v = values.pop(0)
+ command &= 0xfe
+ if v == ord('1'):
+ command |= 1
+
+ if i < len(self.taps) - 1:
+ if command != ord('R'):
+ tmp_commands.append(command)
+ if ord('0') <= command <= ord('7'):
+ # Read TDO before every scan.
+ tmp_commands.append(ord('R'))
+ else:
+ tmp_commands.append(command)
+ assert len(values) == 0
+ values = list(tap.execute(bytes(tmp_commands)))
+ if self.debug:
+ sys.stdout.write(" %d %r -> %r\n" % (i, bytes(tmp_commands),
+ bytes(values)))
+ return bytes(values)
+
+def main():
+ parser = argparse.ArgumentParser(
+ description='Combine multiple remote_bitbang processes into a '
+ 'single scan-chain.')
+ parser.add_argument("listen_port", type=int,
+ help="port to listen on")
+ parser.add_argument("tap_port", nargs="+", type=int,
+ help="port of a remote_bitbang TAP to connect to")
+ parser.add_argument("--debug", action='store_true',
+ help="Print out debug messages.")
+ args = parser.parse_args()
+
+ server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ server.bind(("localhost", args.listen_port))
+ server.listen(1)
+
+ chain = Chain(args.debug)
+ for port in args.tap_port:
+ chain.append(Tap(port))
+
+ sys.stdout.write("Listening on port %d.\n" % server.getsockname()[1])
+ sys.stdout.flush()
+
+ while True:
+ (client, _) = server.accept()
+
+ while True:
+ try:
+ commands = client.recv(4096)
+ except (ConnectionResetError, OSError):
+ sys.stdout.write("Client disconnected due to exception.\n")
+ break
+
+ if len(commands) == 0:
+ sys.stdout.write("Client disconnected.\n")
+ break
+
+ if args.debug:
+ sys.stdout.write("%r\n" % commands)
+ result = chain.execute(commands)
+ if args.debug:
+ sys.stdout.write(" -> %r\n" % result)
+ client.send(result)
+
+ client.close()
+ sys.stdout.flush()
+
+if __name__ == '__main__':
+ sys.exit(main())