Make -H halt the core right out of reset.
[riscv-isa-sim.git] / tests / testlib.py
1 import os.path
2 import pexpect
3 import subprocess
4 import tempfile
5 import testlib
6 import unittest
7
8 # Note that gdb comes with its own testsuite. I was unable to figure out how to
9 # run that testsuite against the spike simulator.
10
11 def find_file(path):
12 for directory in (os.getcwd(), os.path.dirname(testlib.__file__)):
13 fullpath = os.path.join(directory, path)
14 if os.path.exists(fullpath):
15 return fullpath
16 raise ValueError("Couldn't find %r." % path)
17
18 def compile(src):
19 """Compile a single .c file into a binary."""
20 src = find_file(src)
21 dst = os.path.splitext(src)[0]
22 cc = os.path.expandvars("$RISCV/bin/riscv64-unknown-elf-gcc")
23 cmd = "%s -g -o %s %s" % (cc, dst, src)
24 result = os.system(cmd)
25 assert result == 0, "%r failed" % cmd
26 return dst
27
28 def unused_port():
29 # http://stackoverflow.com/questions/2838244/get-open-tcp-port-in-python/2838309#2838309
30 import socket
31 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
32 s.bind(("",0))
33 port = s.getsockname()[1]
34 s.close()
35 return port
36
37 def spike(binary, halted=False, with_gdb=True, timeout=None):
38 """Launch spike. Return tuple of its process and the port it's running on."""
39 cmd = []
40 if timeout:
41 cmd += ["timeout", str(timeout)]
42
43 cmd += [find_file("spike")]
44 if halted:
45 cmd.append('-H')
46 if with_gdb:
47 port = unused_port()
48 cmd += ['--gdb-port', str(port)]
49 cmd += ['pk', binary]
50 logfile = open("spike.log", "w")
51 process = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=logfile,
52 stderr=logfile)
53 if with_gdb:
54 return process, port
55 else:
56 return process
57
58 class Gdb(object):
59 def __init__(self):
60 path = os.path.expandvars("$RISCV/bin/riscv64-unknown-elf-gdb")
61 self.child = pexpect.spawn(path)
62 self.child.logfile = file("gdb.log", "w")
63 self.wait()
64 self.command("set width 0")
65 self.command("set height 0")
66
67 def wait(self):
68 """Wait for prompt."""
69 self.child.expect("\(gdb\)")
70
71 def command(self, command):
72 self.child.sendline(command)
73 self.child.expect("\n")
74 self.child.expect("\(gdb\)")
75 return self.child.before.strip()
76
77 def c(self, wait=True):
78 if wait:
79 return self.command("c")
80 else:
81 self.child.sendline("c")
82 self.child.expect("Continuing")
83
84 def interrupt(self):
85 self.child.send("\003");
86 self.child.expect("\(gdb\)")
87
88 def x(self, address, size='w'):
89 output = self.command("x/%s %s" % (size, address))
90 value = int(output.split(':')[1].strip(), 0)
91 return value
92
93 def p(self, obj):
94 output = self.command("p %s" % obj)
95 value = int(output.split('=')[-1].strip())
96 return value
97
98 def stepi(self):
99 return self.command("stepi")