Skip to content

Commit

Permalink
debug: Add Openocd.set_available()
Browse files Browse the repository at this point in the history
This helper uses dmi_write commands to mark harts
available/unavailable.
  • Loading branch information
timsifive committed Sep 29, 2023
1 parent d4eaa5b commit 903ec82
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 7 deletions.
13 changes: 6 additions & 7 deletions debug/gdbserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -1830,8 +1830,7 @@ def test(self):
# Other hart should have become unavailable.
if self.target.support_unavailable_control:
self.server.wait_until_running(self.target.harts)
self.server.command(
f"riscv dmi_write 0x1f 0x{(1<<self.hart.id)&0x3:x}")
self.server.set_available([self.hart])
self.gdb.expect(r"\S+ became unavailable.")
self.gdb.interrupt()

Expand Down Expand Up @@ -1901,8 +1900,8 @@ def test(self):
self.gdb.c(wait=False)
if self.target.support_unavailable_control:
self.server.wait_until_running([self.hart])
self.server.command(
f"riscv dmi_write 0x1f 0x{(~(1<<self.hart.id))&0x3:x}")
self.server.set_available(
[h for h in self.target.harts if h != self.hart])
self.gdb.expect(r"\S+ became unavailable.")
self.gdb.interrupt()
# gdb might automatically switch to the available hart.
Expand Down Expand Up @@ -1933,14 +1932,14 @@ def test(self):
self.gdb.p("$pc=loop_forever")
self.gdb.c(wait=False)
self.server.wait_until_running([self.hart])
self.server.command(
f"riscv dmi_write 0x1f 0x{(~(1<<self.hart.id))&0x3:x}")
self.server.set_available(
[h for h in self.target.harts if h != self.hart])
self.gdb.expect(r"\S+ became unavailable.")

# Now send a DMI command through OpenOCD to make the hart available
# again.

self.server.command("riscv dmi_write 0x1f 0x3")
self.server.set_available(self.target.harts)
self.gdb.expect(r"\S+ became available")
self.gdb.interrupt()
self.gdb.p("$pc")
Expand Down
24 changes: 24 additions & 0 deletions debug/testlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,30 @@ def wait_until_running(self, harts):
if time.time() - start > self.timeout:
raise TestLibError("Timed out waiting for targets to run.")

def set_available(self, harts):
"""Set the given harts to available, and any others to be unavailable.
This uses a custom DMI register (0x1f) that is only implemented in
spike."""
available_mask = 0
for hart in harts:
available_mask |= 1 << hart.id
self.command(f"riscv dmi_write 0x1f 0x{available_mask:x}")

# Wait until it happened.
start = time.time()
while True:
currently_available = set()
currently_unavailable = set()
for i, target in enumerate(self.targets()):
if target["State"] == "unavailable":
currently_unavailable.add(i)
else:
currently_available.add(i)
if currently_available == set(hart.id for hart in harts):
return
if time.time() - start > self.timeout:
raise TestLibError("Timed out waiting for hart availability.")

class OpenocdCli:
def __init__(self, port=4444):
self.child = pexpect.spawn(
Expand Down

0 comments on commit 903ec82

Please sign in to comment.