import testlib
from testlib import assertEqual, assertNotEqual, assertIn, assertNotIn
from testlib import assertGreater, assertRegexpMatches, assertLess
-from testlib import GdbTest, GdbSingleHartTest
+from testlib import GdbTest, GdbSingleHartTest, TestFailed
MSTATUS_UIE = 0x00000001
MSTATUS_SIE = 0x00000002
assertEqual(self.gdb.p("sizeof(%s)" % data_type), size)
a = 0x86753095555aaaa & ((1<<(size*8))-1)
b = 0xdeadbeef12345678 & ((1<<(size*8))-1)
- addrA = self.target.ram
- addrB = self.target.ram + self.target.ram_size - size
+ addrA = self.hart.ram
+ addrB = self.hart.ram + self.hart.ram_size - size
self.gdb.p("*((%s*)0x%x) = 0x%x" % (data_type, addrA, a))
self.gdb.p("*((%s*)0x%x) = 0x%x" % (data_type, addrB, b))
assertEqual(self.gdb.p("*((%s*)0x%x)" % (data_type, addrA)), a)
# self.gdb.p("*((int*)0x%x)=6874742" % self.hart.ram)
class MemTestBlock(GdbTest):
+ length = 1024
+ line_length = 16
+
def test(self):
- length = 1024
- line_length = 16
a = tempfile.NamedTemporaryFile(suffix=".ihex")
data = ""
- for i in range(length / line_length):
+ for i in range(self.length / self.line_length):
line_data = "".join(["%c" % random.randrange(256)
- for _ in range(line_length)])
+ for _ in range(self.line_length)])
data += line_data
- a.write(ihex_line(i * line_length, 0, line_data))
+ a.write(ihex_line(i * self.line_length, 0, line_data))
a.flush()
self.gdb.command("restore %s 0x%x" % (a.name, self.hart.ram))
- for offset in range(0, length, 19*4) + [length-4]:
+ for offset in range(0, self.length, 19*4) + [self.length-4]:
value = self.gdb.p("*((int*)0x%x)" % (self.hart.ram + offset))
written = ord(data[offset]) | \
(ord(data[offset+1]) << 8) | \
b = tempfile.NamedTemporaryFile(suffix=".ihex")
self.gdb.command("dump ihex memory %s 0x%x 0x%x" % (b.name,
- self.hart.ram, self.hart.ram + length))
+ self.hart.ram, self.hart.ram + self.length))
for line in b:
record_type, address, line_data = ihex_parse(line)
if record_type == 0:
- assertEqual(readable_binary_string(line_data),
- readable_binary_string(
- data[address:address+len(line_data)]))
+ written_data = data[address:address+len(line_data)]
+ if line_data != written_data:
+ raise TestFailed(
+ "Data mismatch at 0x%x; wrote %s but read %s" % (
+ address, readable_binary_string(written_data),
+ readable_binary_string(line_data)))
class InstantHaltTest(GdbTest):
def test(self):
self.gdb.p("i=0")
self.exit()
+class InterruptTest(GdbSingleHartTest):
+ compile_args = ("programs/interrupt.c",)
+
+ def early_applicable(self):
+ return self.target.supports_clint_mtime
+
+ def setup(self):
+ self.gdb.load()
+
+ def test(self):
+ self.gdb.b("main")
+ output = self.gdb.c()
+ assertIn(" main ", output)
+ self.gdb.b("trap_entry")
+ output = self.gdb.c()
+ assertIn(" trap_entry ", output)
+ assertEqual(self.gdb.p("$mip") & 0x80, 0x80)
+ assertEqual(self.gdb.p("interrupt_count"), 0)
+ # You'd expect local to still be 0, but it looks like spike doesn't
+ # jump to the interrupt handler immediately after the write to
+ # mtimecmp.
+ assertLess(self.gdb.p("local"), 1000)
+ self.gdb.command("delete breakpoints")
+ for _ in range(10):
+ self.gdb.c(wait=False)
+ time.sleep(2)
+ self.gdb.interrupt()
+ interrupt_count = self.gdb.p("interrupt_count")
+ local = self.gdb.p("local")
+ if interrupt_count > 1000 and \
+ local > 1000:
+ return
+
+ assertGreater(interrupt_count, 1000)
+ assertGreater(local, 1000)
+
+ def postMortem(self):
+ GdbSingleHartTest.postMortem(self)
+ self.gdb.p("*((long long*) 0x200bff8)")
+ self.gdb.p("*((long long*) 0x2004000)")
+ self.gdb.p("interrupt_count")
+ self.gdb.p("local")
+
class MulticoreRegTest(GdbTest):
compile_args = ("programs/infinite_loop.S", "-DMULTICORE")
value = self.gdb.p("$x%d" % n)
assertEqual(value, hart.index * 0x800 + n - 1)
-class MulticoreRunHaltTest(GdbTest):
+class MulticoreRunHaltStepiTest(GdbTest):
compile_args = ("programs/multicore.c", "-DMULTICORE")
def early_applicable(self):
def test(self):
previous_hart_count = [0 for h in self.target.harts]
+ previous_interrupt_count = [0 for h in self.target.harts]
for _ in range(10):
self.gdb.c(wait=False)
- time.sleep(1)
+ time.sleep(2)
self.gdb.interrupt()
+ self.gdb.p("$mie")
+ self.gdb.p("$mip")
+ self.gdb.p("$mstatus")
+ self.gdb.p("$priv")
self.gdb.p("buf", fmt="")
hart_count = self.gdb.p("hart_count")
+ interrupt_count = self.gdb.p("interrupt_count")
for i, h in enumerate(self.target.harts):
assertGreater(hart_count[i], previous_hart_count[i])
+ assertGreater(interrupt_count[i], previous_interrupt_count[i])
self.gdb.select_hart(h)
pc = self.gdb.p("$pc")
self.gdb.stepi()
if self.crc < 0:
self.crc += 2**32
- self.binary = self.hart.compile(self.download_c.name,
+ self.binary = self.target.compile(self.hart, self.download_c.name,
"programs/checksum.c")
self.gdb.command("file %s" % self.binary)