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 test(self): length = 1024 line_length = 16 a = tempfile.NamedTemporaryFile(suffix=".ihex") data = "" for i in range(length / line_length): line_data = "".join(["%c" % random.randrange(256) for _ in range(line_length)]) data += line_data a.write(ihex_line(i * line_length, 0, line_data)) a.flush() self.gdb.command("restore %s 0x%x" % (a.name, self.target.ram)) for offset in range(0, length, 19*4) + [length-4]: value = self.gdb.p("*((int*)0x%x)" % (self.target.ram + offset)) written = ord(data[offset]) | \ (ord(data[offset+1]) << 8) | \ (ord(data[offset+2]) << 16) | \ (ord(data[offset+3]) << 24) assertEqual(value, written) b = tempfile.NamedTemporaryFile(suffix=".ihex") self.gdb.command("dump ihex memory %s 0x%x 0x%x" % (b.name, self.target.ram, self.target.ram + 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)]))
def test(self): self.gdb.command("rwatch *((&data)+1)") output = self.gdb.c() assertIn("read_loop", output) assertEqual(self.gdb.p("$a0"), self.gdb.p("(&data)+1")) self.exit()
def test(self): self.gdb.command("watch *((&data)+3)") output = self.gdb.c() assertIn("write_loop", output) assertEqual(self.gdb.p("$a0"), self.gdb.p("(&data)+3")) self.exit()
def exit(self, expected_result=10): self.gdb.command("delete") self.gdb.b("_exit") output = self.gdb.c() assertIn("Breakpoint", output) assertIn("_exit", output) assertEqual(self.gdb.p("status"), expected_result)
def test(self): self.gdb.load() self.parkOtherHarts() self.gdb.command("b _exit") self.gdb.c(ops=100) assertEqual(self.gdb.p("status"), self.crc) os.unlink(self.download_c.name)
def test(self): self.write_nops(4) self.cli.command("step 0x%x" % self.target.ram) for i in range(4): pc = self.cli.reg("pc") assertEqual(pc, self.target.ram + 4 * (i+1)) self.cli.command("step")
def memory_test(self, start_addr, end_addr, expected_values): dump = tempfile.NamedTemporaryFile(suffix=".simdata") self.gdb.command("dump verilog memory %s 0x%x 0x%x" % (dump.name, start_addr, end_addr)) self.gdb.command("shell cat %s" % dump.name) line = dump.readline() line = dump.readline() assertEqual(line.strip(), expected_values)
def check_reg(self, name): a = random.randrange(1<<self.target.xlen) b = random.randrange(1<<self.target.xlen) self.gdb.p("$%s=0x%x" % (name, a)) self.gdb.stepi() assertEqual(self.gdb.p("$%s" % name), a) self.gdb.p("$%s=0x%x" % (name, b)) self.gdb.stepi() assertEqual(self.gdb.p("$%s" % name), b)
def test(self): """Test reading/writing priv.""" for privilege in range(4): self.gdb.p("$priv=%d" % privilege) self.gdb.stepi() actual = self.gdb.p("$priv") assertIn(actual, self.supported) if privilege in self.supported: assertEqual(actual, privilege)
def test(self): # This test relies on 'gdb_report_data_abort enable' being executed in # the openocd.cfg file. try: self.gdb.p("*((int*)0xdeadbeef)=8675309") assert False, "Write should have failed." except testlib.CannotAccess as e: assertEqual(e.address, 0xdeadbeef) self.gdb.p("*((int*)0x%x)=6874742" % self.target.ram)
def test(self): self.gdb.command("b just_before_read_loop") self.gdb.c() read_loop = self.gdb.p("&read_loop") self.gdb.command("rwatch data") self.gdb.c() # Accept hitting the breakpoint before or after the load instruction. assertIn(self.gdb.p("$pc"), [read_loop, read_loop + 4]) assertEqual(self.gdb.p("$a0"), self.gdb.p("&data"))
def test(self): self.write_nops(4) regs = self.cli.reg() assertIn("x18", regs) self.cli.command("reg x18 0x11782") self.cli.command("step 0x%x" % self.target.ram) assertEqual(self.cli.reg("x18"), 0x11782)
def test(self): main_address = self.gdb.p("$pc") if self.target.extensionSupported("c"): sequence = (4, 8, 0xc, 0xe, 0x14, 0x18, 0x22, 0x1c, 0x24, 0x24) else: sequence = (4, 8, 0xc, 0x10, 0x18, 0x1c, 0x28, 0x20, 0x2c, 0x2c) for expected in sequence: self.gdb.stepi() pc = self.gdb.p("$pc") assertEqual("%x" % (pc - main_address), "%x" % expected)
def test(self): """Change the PC right as we come out of reset.""" # 0x13 is nop self.gdb.command("p *((int*) 0x%x)=0x13" % self.target.ram) self.gdb.command("p *((int*) 0x%x)=0x13" % (self.target.ram + 4)) self.gdb.command("p *((int*) 0x%x)=0x13" % (self.target.ram + 8)) self.gdb.p("$pc=0x%x" % self.target.ram) self.gdb.stepi() assertEqual((self.target.ram + 4), self.gdb.p("$pc")) self.gdb.stepi() assertEqual((self.target.ram + 8), self.gdb.p("$pc"))
def test(self): """Test reading/writing priv.""" # Leave the PC at _start, where the first 4 instructions should be # legal in any mode. for privilege in range(4): self.gdb.p("$priv=%d" % privilege) self.gdb.stepi() actual = self.gdb.p("$priv") assertIn(actual, self.supported) if privilege in self.supported: assertEqual(actual, privilege)
def test(self): """Test a store address breakpoint on the first instruction executed out of debug mode.""" self.gdb.command("b just_before_write_loop") self.gdb.c() write_loop = self.gdb.p("&write_loop") self.gdb.command("watch data") self.gdb.c() # Accept hitting the breakpoint before or after the store instruction. assertIn(self.gdb.p("$pc"), [write_loop, write_loop + 4]) assertEqual(self.gdb.p("$a0"), self.gdb.p("&data"))
def check_reg(self, name, alias): if self.hart.extensionSupported('F'): self.gdb.p_raw("$mstatus=$mstatus | 0x00006000") self.gdb.stepi() a = random.random() b = random.random() self.gdb.p_raw("$%s=%f" % (name, a)) assertLess(abs(float(self.gdb.p_raw("$%s" % alias)) - a), .001) self.gdb.stepi() assertLess(abs(float(self.gdb.p_raw("$%s" % name)) - a), .001) assertLess(abs(float(self.gdb.p_raw("$%s" % alias)) - a), .001) self.gdb.p_raw("$%s=%f" % (alias, b)) assertLess(abs(float(self.gdb.p_raw("$%s" % name)) - b), .001) self.gdb.stepi() assertLess(abs(float(self.gdb.p_raw("$%s" % name)) - b), .001) assertLess(abs(float(self.gdb.p_raw("$%s" % alias)) - b), .001) size = self.gdb.p("sizeof($%s)" % name) if self.hart.extensionSupported('D'): assertEqual(size, 8) else: assertEqual(size, 4) else: output = self.gdb.p_raw("$" + name) assertEqual(output, "void") output = self.gdb.p_raw("$" + alias) assertEqual(output, "void")
def test(self): """Assert that reset is really resetting what it should.""" self.gdb.command("monitor reset halt") self.gdb.command("flushregs") threads = self.gdb.threads() pcs = [] for t in threads: self.gdb.thread(t) pcs.append(self.gdb.p("$pc")) for pc in pcs: assertIn(pc, self.hart.reset_vectors) # mcycle and minstret have no defined reset value. mstatus = self.gdb.p("$mstatus") assertEqual(mstatus & (MSTATUS_MIE | MSTATUS_MPRV | MSTATUS_VM), 0)
def check_custom(self, magic): regs = {k: v for k, v in self.gdb.info_registers("all").iteritems() if k.startswith("custom")} assertEqual(set(regs.keys()), set(("custom1", "custom12345", "custom12346", "custom12347", "custom12348"))) for name, value in regs.iteritems(): number = int(name[6:]) if number % 2: expect = number + magic assertIn(value, (expect, expect + (1<<32))) else: assertIn("Could not fetch register", value)
def test(self): regs = [("x%d" % n) for n in range(2, 32)] self.gdb.p("$pc=write_regs") for i, r in enumerate(regs): self.gdb.p("$%s=%d" % (r, (0xdeadbeef<<i)+17)) self.gdb.p("$x1=data") self.gdb.command("b all_done") output = self.gdb.c() assertIn("Breakpoint ", output) # Just to get this data in the log. self.gdb.command("x/30gx data") self.gdb.command("info registers") for n in range(len(regs)): assertEqual(self.gdb.x("data+%d" % (8*n), 'g'), ((0xdeadbeef<<n)+17) & ((1<<self.target.xlen)-1))
def test(self): # As much a test of gdb as of the simulator. self.gdb.p("$mscratch=0") self.gdb.stepi() assertEqual(self.gdb.p("$mscratch"), 0) self.gdb.p("$mscratch=123") self.gdb.stepi() assertEqual(self.gdb.p("$mscratch"), 123) self.gdb.p("$pc=write_regs") self.gdb.p("$x1=data") self.gdb.command("b all_done") self.gdb.command("c") assertEqual(123, self.gdb.p("$mscratch")) assertEqual(123, self.gdb.p("$x1")) assertEqual(123, self.gdb.p("$csr832"))
def test(self): mainbp = self.gdb.b("main") output = self.gdb.c() assertIn("Breakpoint", output) assertIn("main", output) self.gdb.command("delete %d" % mainbp) self.gdb.watch("counter == 5") # Watchpoint hits when counter becomes 5. output = self.gdb.c() assertEqual(self.gdb.p("counter"), 5) # Watchpoint hits when counter no longer is 5. output = self.gdb.c() assertEqual(self.gdb.p("counter"), 6) # The watchpoint is going out of scope output = self.gdb.c() assertIn("Watchpoint", output) assertIn("deleted", output) self.exit()
def test(self): """Test that the core's privilege level actually changes.""" if 0 not in self.supported: return 'not_applicable' self.gdb.b("main") self.gdb.c() # Machine mode self.gdb.p("$priv=3") main_address = self.gdb.p("$pc") self.gdb.stepi() assertEqual("%x" % self.gdb.p("$pc"), "%x" % (main_address+4)) # User mode self.gdb.p("$priv=0") self.gdb.stepi() # Should have taken an exception, so be nowhere near main. pc = self.gdb.p("$pc") assertTrue(pc < main_address or pc > main_address + 0x100)
def check_triggers(self, tdata1_lsbs, tdata2): dmode = 1 << (self.target.xlen-5) triggers = [] if self.target.xlen == 32: xlen_type = 'int' elif self.target.xlen == 64: xlen_type = 'long long' else: raise NotImplementedError dmode_count = 0 i = 0 for i in range(16): tdata1 = self.gdb.p("((%s *)&data)[%d]" % (xlen_type, 2*i)) if tdata1 == 0: break tdata2 = self.gdb.p("((%s *)&data)[%d]" % (xlen_type, 2*i+1)) if tdata1 & dmode: dmode_count += 1 else: assertEqual(tdata1 & 0xffff, tdata1_lsbs) assertEqual(tdata2, tdata2) assertGreater(i, 1) assertEqual(dmode_count, 1) return triggers
def test(self): a = tempfile.NamedTemporaryFile(suffix=".ihex") data = self.write(a) self.gdb.command("shell cat %s" % a.name) self.gdb.command("monitor riscv reset_delays 50") self.gdb.command("restore %s 0x%x" % (a.name, self.hart.ram)) increment = 19 * 4 for offset in range(0, self.length, increment) + [self.length-4]: value = self.gdb.p("*((int*)0x%x)" % (self.hart.ram + offset)) written = ord(data[offset]) | \ (ord(data[offset+1]) << 8) | \ (ord(data[offset+2]) << 16) | \ (ord(data[offset+3]) << 24) assertEqual(value, written) b = tempfile.NamedTemporaryFile(suffix=".srec") self.gdb.command("monitor riscv reset_delays 100") self.gdb.command("dump srec memory %s 0x%x 0x%x" % (b.name, self.hart.ram, self.hart.ram + self.length), ops=self.length / 32) self.gdb.command("shell cat %s" % b.name) highest_seen = 0 for line in b.xreadlines(): record_type, address, line_data = srec_parse(line) if record_type == 3: offset = address - (self.hart.ram & 0xffffffff) written_data = data[offset:offset+len(line_data)] highest_seen += len(line_data) if line_data != written_data: raise TestFailed( "Data mismatch at 0x%x (offset 0x%x); wrote %s but " "read %s" % ( self.hart.ram + offset, offset, readable_binary_string(written_data), readable_binary_string(line_data))) assertEqual(highest_seen, self.length)
def access_test(self, size, data_type): assertEqual(self.gdb.p("sizeof(%s)" % data_type), size) a = 0x86753095555aaaa & ((1<<(size*8))-1) b = 0xdeadbeef12345678 & ((1<<(size*8))-1) 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) assertEqual(self.gdb.p("*((%s*)0x%x)" % (data_type, addrB)), b)
def access_test(self, size, data_type): assertEqual(self.gdb.p("sizeof(%s)" % data_type), size) a = 0x86753095555aaaa & ((1<<(size*8))-1) b = 0xdeadbeef12345678 & ((1<<(size*8))-1) self.gdb.p("*((%s*)0x%x) = 0x%x" % (data_type, self.target.ram, a)) self.gdb.p("*((%s*)0x%x) = 0x%x" % (data_type, self.target.ram + size, b)) assertEqual(self.gdb.p("*((%s*)0x%x)" % (data_type, self.target.ram)), a) assertEqual(self.gdb.p("*((%s*)0x%x)" % ( data_type, self.target.ram + size)), b)
def test(self): self.write_nops(16) self.cli.command("bp 0x%x 4" % (self.target.ram + 12)) self.cli.command("bp 0x%x 4" % (self.target.ram + 24)) self.cli.command("resume 0x%x" % self.target.ram) assertEqual(self.cli.reg("pc"), self.target.ram + 12) self.cli.command("resume") assertEqual(self.cli.reg("pc"), self.target.ram + 24) self.cli.command("resume 0x%x" % self.target.ram) assertEqual(self.cli.reg("pc"), self.target.ram + 12)
def test(self): # Run to main for hart in self.target.harts: self.gdb.select_hart(hart) self.gdb.b("main") self.gdb.c() assertIn("main", self.gdb.where()) self.gdb.command("delete breakpoints") # Run through the entire loop. for hart in self.target.harts: self.gdb.select_hart(hart) self.gdb.b("main_end") self.gdb.c() assertIn("main_end", self.gdb.where()) hart_ids = [] for hart in self.target.harts: self.gdb.select_hart(hart) # Check register values. x1 = self.gdb.p("$x1") hart_id = self.gdb.p("$mhartid") assertEqual(x1, hart_id) assertNotIn(hart_id, hart_ids) hart_ids.append(hart_id) for n in range(2, 32): value = self.gdb.p("$x%d" % n) assertEqual(value, hart_ids[-1] + n - 1) # Confirmed that we read different register values for different harts. # Write a new value to x1, and run through the add sequence again. for hart in self.target.harts: self.gdb.select_hart(hart) self.gdb.p("$x1=0x%x" % (hart.index * 0x800)) self.gdb.p("$pc=main_post_csrr") self.gdb.c() for hart in self.target.harts: self.gdb.select_hart(hart) assertIn("main", self.gdb.where()) # Check register values. for n in range(1, 32): value = self.gdb.p("$x%d" % n) assertEqual(value, hart.index * 0x800 + n - 1)
def test(self): self.gdb.b("main:start") self.gdb.c() assertEqual(self.gdb.p('fib(6)'), 8) assertEqual(self.gdb.p('fib(7)'), 13) self.exit()
def test(self): self.gdb.load() self.gdb.command("b _exit") self.gdb.c(timeout=60) assertEqual(self.gdb.p("status"), self.crc) os.unlink(self.download_c.name)
def test(self): assertEqual(self.target.reset_vector, self.gdb.p("$pc")) # mcycle and minstret have no defined reset value. mstatus = self.gdb.p("$mstatus") assertEqual(mstatus & (MSTATUS_MIE | MSTATUS_MPRV | MSTATUS_VM), 0)
def test(self): self.gdb.load() self.gdb.command("b _exit") self.gdb.c() assertEqual(self.gdb.p("status"), self.crc)
def check_reg(self, name, alias): a = random.randrange(1 << self.hart.xlen) b = random.randrange(1 << self.hart.xlen) self.gdb.p("$%s=0x%x" % (name, a)) assertEqual(self.gdb.p("$%s" % alias), a) self.gdb.stepi() assertEqual(self.gdb.p("$%s" % name), a) assertEqual(self.gdb.p("$%s" % alias), a) self.gdb.p("$%s=0x%x" % (alias, b)) assertEqual(self.gdb.p("$%s" % name), b) self.gdb.stepi() assertEqual(self.gdb.p("$%s" % name), b) assertEqual(self.gdb.p("$%s" % alias), b)
def exit(self, expected_result=0xc86455d4): output = self.gdb.c() assertIn("Breakpoint", output) assertIn("_exit", output) assertEqual(self.gdb.p("status"), expected_result)
def test(self): main_address = self.gdb.p("$pc") self.gdb.command("hbreak *0x%x" % (main_address + 4)) self.gdb.c() assertEqual(self.gdb.p("$pc"), main_address + 4)