def find_file(path):
for directory in (os.getcwd(), os.path.dirname(__file__)):
fullpath = os.path.join(directory, path)
- if os.path.exists(fullpath):
- return fullpath
+ relpath = os.path.relpath(fullpath)
+ if len(relpath) >= len(fullpath):
+ relpath = fullpath
+ if os.path.exists(relpath):
+ return relpath
return None
def compile(args, xlen=32): # pylint: disable=redefined-builtin
else:
harts = [target]
+ cmd = self.command(target, harts, halted, timeout, with_jtag_gdb)
+ self.infinite_loop = target.compile(harts[0],
+ "programs/checksum.c", "programs/tiny-malloc.c",
+ "programs/infinite_loop.S", "-DDEFINE_MALLOC", "-DDEFINE_FREE")
+ cmd.append(self.infinite_loop)
+ logfile = open(self.logname, "w")
+ logfile.write("+ %s\n" % " ".join(cmd))
+ logfile.flush()
+ self.process = subprocess.Popen(cmd, stdin=subprocess.PIPE,
+ stdout=logfile, stderr=logfile)
+
+ if with_jtag_gdb:
+ self.port = None
+ for _ in range(30):
+ m = re.search(r"Listening for remote bitbang connection on "
+ r"port (\d+).", open(self.logname).read())
+ if m:
+ self.port = int(m.group(1))
+ os.environ['REMOTE_BITBANG_PORT'] = m.group(1)
+ break
+ time.sleep(0.11)
+ if not self.port:
+ print_log(self.logname)
+ raise Exception("Didn't get spike message about bitbang "
+ "connection")
+
+ def command(self, target, harts, halted, timeout, with_jtag_gdb):
+ # pylint: disable=no-self-use
if target.sim_cmd:
cmd = shlex.split(target.sim_cmd)
else:
if with_jtag_gdb:
cmd += ['--rbb-port', '0']
os.environ['REMOTE_BITBANG_HOST'] = 'localhost'
- self.infinite_loop = harts[0].compile(
- "programs/checksum.c", "programs/tiny-malloc.c",
- "programs/infinite_loop.S", "-DDEFINE_MALLOC", "-DDEFINE_FREE")
- cmd.append(self.infinite_loop)
- logfile = open(self.logname, "w")
- logfile.write("+ %s\n" % " ".join(cmd))
- logfile.flush()
- self.process = subprocess.Popen(cmd, stdin=subprocess.PIPE,
- stdout=logfile, stderr=logfile)
- if with_jtag_gdb:
- self.port = None
- for _ in range(30):
- m = re.search(r"Listening for remote bitbang connection on "
- r"port (\d+).", open(self.logname).read())
- if m:
- self.port = int(m.group(1))
- os.environ['REMOTE_BITBANG_PORT'] = m.group(1)
- break
- time.sleep(0.11)
- assert self.port, "Didn't get spike message about bitbang " \
- "connection"
+ return cmd
def __del__(self):
if self.process:
print "OpenOCD Temporary Log File: %s" % logname
def __init__(self, server_cmd=None, config=None, debug=False, timeout=60):
+ self.timeout = timeout
+
if server_cmd:
cmd = shlex.split(server_cmd)
else:
if not messaged and time.time() - start > 1:
messaged = True
print "Waiting for OpenOCD to start..."
- if (time.time() - start) > timeout:
+ if (time.time() - start) > self.timeout:
raise Exception("ERROR: Timed out waiting for OpenOCD to "
"listen for gdb")
return process
self.child.expect(r"\(gdb\)")
def command(self, command, timeout=6000):
+ """timeout is in seconds"""
self.child.sendline(command)
self.child.expect("\n", timeout=timeout)
self.child.expect(r"\(gdb\)", timeout=timeout)
raise CannotAccess(int(m.group(1), 0))
return output.split('=')[-1].strip()
- def p(self, obj):
- output = self.command("p/x %s" % obj)
+ def parse_string(self, text):
+ text = text.strip()
+ if text.startswith("{") and text.endswith("}"):
+ inner = text[1:-1]
+ return [self.parse_string(t) for t in inner.split(", ")]
+ elif text.startswith('"') and text.endswith('"'):
+ return text[1:-1]
+ else:
+ return int(text, 0)
+
+ def p(self, obj, fmt="/x"):
+ output = self.command("p%s %s" % (fmt, obj))
m = re.search("Cannot access memory at address (0x[0-9a-f]+)", output)
if m:
raise CannotAccess(int(m.group(1), 0))
- value = int(output.split('=')[-1].strip(), 0)
- return value
+ rhs = output.split('=')[-1]
+ return self.parse_string(rhs)
def p_string(self, obj):
output = self.command("p %s" % obj)
def print_log(path):
header(path)
- lines = open(path, "r").readlines()
- for l in lines:
+ for l in open(path, "r"):
sys.stdout.write(l)
print
self.hart = hart
else:
self.hart = random.choice(target.harts)
+ self.hart = target.harts[-1] #<<<
self.server = None
self.target_process = None
self.binary = None
if compile_args not in BaseTest.compiled:
# pylint: disable=star-args
BaseTest.compiled[compile_args] = \
- self.hart.compile(*compile_args)
+ self.target.compile(self.hart, *compile_args)
self.binary = BaseTest.compiled.get(compile_args)
def classSetup(self):
del self.server
del self.target_process
+ def postMortem(self):
+ pass
+
def run(self):
"""
If compile_args is set, compile a program and set self.binary.
print e.message
header("Traceback")
traceback.print_exc(file=sys.stdout)
+ self.postMortem()
return result
finally:
# FIXME: OpenOCD doesn't handle PRIV now
#self.gdb.p("$priv=3")
+ def postMortem(self):
+ if not self.gdb:
+ return
+ self.gdb.interrupt()
+ self.gdb.command("info registers all", timeout=10)
+
def classTeardown(self):
del self.gdb
BaseTest.classTeardown(self)
class ExamineTarget(GdbTest):
def test(self):
- self.target.misa = self.gdb.p("$misa")
+ self.hart.misa = self.gdb.p("$misa")
txt = "RV"
- if (self.target.misa >> 30) == 1:
+ if (self.hart.misa >> 30) == 1:
txt += "32"
- elif (self.target.misa >> 62) == 2:
+ elif (self.hart.misa >> 62) == 2:
txt += "64"
- elif (self.target.misa >> 126) == 3:
+ elif (self.hart.misa >> 126) == 3:
txt += "128"
else:
raise TestFailed("Couldn't determine XLEN from $misa (0x%x)" %
- self.target.misa)
+ self.hart.misa)
for i in range(26):
- if self.target.misa & (1<<i):
+ if self.hart.misa & (1<<i):
txt += chr(i + ord('A'))
print txt,