Add --gdb-port
[riscv-isa-sim.git] / tests / testlib.py
index 274ba6ce576764654cd82f0a88cd5f2a24eec374..2db25491c433ed3dcdf5678e4009cd9330c6363c 100644 (file)
@@ -15,18 +15,35 @@ def find_file(path):
             return fullpath
     raise ValueError("Couldn't find %r." % path)
 
-def compile(src, dst):
+def compile(src):
     """Compile a single .c file into a binary."""
+    src = find_file(src)
+    dst = os.path.splitext(src)[0]
     cc = os.path.expandvars("$RISCV/bin/riscv64-unknown-elf-gcc")
-    return os.system("%s -g -o %s %s" % (cc, dst, find_file(src)))
+    cmd = "%s -g -o %s %s" % (cc, dst, src)
+    result = os.system(cmd)
+    assert result == 0, "%r failed" % cmd
+    return dst
+
+def unused_port():
+    # http://stackoverflow.com/questions/2838244/get-open-tcp-port-in-python/2838309#2838309
+    import socket
+    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    s.bind(("",0))
+    port = s.getsockname()[1]
+    s.close()
+    return port
 
 def spike(binary, halted=False):
+    """Launch spike. Return tuple of its process and the port it's running on."""
     cmd = [find_file("spike")]
     if halted:
         cmd.append('-H')
-    cmd += ['pk', binary]
+    port = unused_port()
+    cmd += ['--gdb-port', str(port), 'pk', binary]
     logfile = open("spike.log", "w")
-    return subprocess.Popen(cmd, stdout=logfile, stderr=logfile)
+    return subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=logfile,
+            stderr=logfile), port
 
 class Gdb(object):
     def __init__(self):
@@ -34,6 +51,8 @@ class Gdb(object):
         self.child = pexpect.spawn(path)
         self.child.logfile = file("gdb.log", "w")
         self.wait()
+        self.command("set width 0")
+        self.command("set height 0")
 
     def wait(self):
         """Wait for prompt."""
@@ -44,3 +63,16 @@ class Gdb(object):
         self.child.expect("\n")
         self.child.expect("\(gdb\)")
         return self.child.before.strip()
+
+    def x(self, address, size='w'):
+        output = self.command("x/%s %s" % (size, address))
+        value = int(output.split(':')[1].strip(), 0)
+        return value
+
+    def p(self, obj):
+        output = self.command("p %s" % obj)
+        value = int(output.split('=')[-1].strip())
+        return value
+
+    def stepi(self):
+        return self.command("stepi")