Skip to content

Commit 49f4f2e

Browse files
committed
[debug] Support mcontrol and mcontrol6 based on HwbpManual
1 parent 988c2ce commit 49f4f2e

File tree

1 file changed

+67
-23
lines changed

1 file changed

+67
-23
lines changed

debug/gdbserver.py

Lines changed: 67 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -651,12 +651,16 @@ def test(self):
651651
self.gdb.b("_exit")
652652
self.exit()
653653

654-
def MCONTROL_TYPE(xlen):
654+
def TDATA1_TYPE(xlen):
655655
return 0xf<<((xlen)-4)
656-
def MCONTROL_DMODE(xlen):
656+
def TDATA1_DMODE(xlen):
657657
return 1<<((xlen)-5)
658658
def MCONTROL_MASKMAX(xlen):
659-
return 0x3<<((xlen)-11)
659+
return 0x3f<<((xlen)-11)
660+
661+
TDATA1_TYPE_NONE = 0
662+
TDATA1_TYPE_MATCH = 2
663+
TDATA1_TYPE_MATCH6 = 6
660664

661665
MCONTROL_SELECT = 1<<19
662666
MCONTROL_TIMING = 1<<18
@@ -671,8 +675,23 @@ def MCONTROL_MASKMAX(xlen):
671675
MCONTROL_STORE = 1<<1
672676
MCONTROL_LOAD = 1<<0
673677

674-
MCONTROL_TYPE_NONE = 0
675-
MCONTROL_TYPE_MATCH = 2
678+
MCONTROL6_UNCERTAIN = 1<<26
679+
MCONTROL6_HIT1 = 1<<25
680+
MCONTROL6_VS = 1<<24
681+
MCONTROL6_VU = 1<<23
682+
MCONTROL6_HIT0 = 1<<22
683+
MCONTROL6_SELECT = 1<<21
684+
MCONTROL6_SIZE = 0x7<<16
685+
MCONTROL6_ACTION = 0xf<<12
686+
MCONTROL6_CHAIN = 1<<11
687+
MCONTROL6_MATCH = 0xf<<7
688+
MCONTROL6_M = 1<<6
689+
MCONTROL6_UNCERTAINEN = 1<<5
690+
MCONTROL6_S = 1<<4
691+
MCONTROL6_U = 1<<3
692+
MCONTROL6_EXECUTE = 1<<2
693+
MCONTROL6_STORE = 1<<1
694+
MCONTROL6_LOAD = 1<<0
676695

677696
MCONTROL_ACTION_DEBUG_EXCEPTION = 0
678697
MCONTROL_ACTION_DEBUG_MODE = 1
@@ -707,7 +726,7 @@ def check_reserve_trigger_support(self):
707726
not_supp_msg + "}").splitlines():
708727
raise TestNotApplicable
709728

710-
def set_manual_trigger(self, tdata1, tdata2):
729+
def set_manual_trigger(self, tdata1, tdata2, maskmax_mask):
711730
for tselect in itertools.count(0):
712731
self.gdb.p(f"$tselect={tselect}")
713732
if self.gdb.p("$tselect") != tselect:
@@ -724,21 +743,23 @@ def set_manual_trigger(self, tdata1, tdata2):
724743

725744
tdata2_rb = self.gdb.p("$tdata2")
726745
tdata1_rb = self.gdb.p("$tdata1")
727-
if tdata1_rb == tdata1 and tdata2_rb == tdata2:
728-
return tselect
729746

730-
type_rb = tdata1_rb & MCONTROL_TYPE(self.hart.xlen)
731-
type_none = set_field(0, MCONTROL_TYPE(self.hart.xlen),
732-
MCONTROL_TYPE_NONE)
747+
type_rb = tdata1_rb & TDATA1_TYPE(self.hart.xlen)
748+
type_none = set_field(0, TDATA1_TYPE(self.hart.xlen),
749+
TDATA1_TYPE_NONE)
733750
if type_rb == type_none:
734751
raise TestNotApplicable
735752

753+
tdata1 = set_field(tdata1, maskmax_mask, tdata1_rb & maskmax_mask)
754+
if tdata1_rb == tdata1 and tdata2_rb == tdata2:
755+
return tselect
756+
736757
self.gdb.p("$tdata1=0")
737758
self.gdb.command(
738759
f"monitor riscv reserve_trigger {tselect} off")
739760
assert False
740761

741-
def test(self):
762+
def run_test(self, tdata1, maskmax_mask):
742763
if not self.hart.honors_tdata1_dmode:
743764
# Run to main before setting the breakpoint, because startup code
744765
# will otherwise clear the trigger that we set.
@@ -753,20 +774,10 @@ def test(self):
753774
self.check_reserve_trigger_support()
754775

755776
#self.gdb.hbreak("rot13")
756-
tdata1 = MCONTROL_DMODE(self.hart.xlen)
757-
tdata1 = set_field(tdata1, MCONTROL_TYPE(self.hart.xlen),
758-
MCONTROL_TYPE_MATCH)
759-
tdata1 = set_field(tdata1, MCONTROL_ACTION, MCONTROL_ACTION_DEBUG_MODE)
760-
tdata1 = set_field(tdata1, MCONTROL_MATCH, MCONTROL_MATCH_EQUAL)
761-
tdata1 |= MCONTROL_M | MCONTROL_EXECUTE
762-
if self.hart.extensionSupported("S"):
763-
tdata1 |= MCONTROL_S
764-
if self.hart.extensionSupported("U"):
765-
tdata1 |= MCONTROL_U
766777

767778
tdata2 = self.gdb.p("&rot13")
768779

769-
tselect = self.set_manual_trigger(tdata1, tdata2)
780+
tselect = self.set_manual_trigger(tdata1, tdata2, maskmax_mask)
770781

771782
# The breakpoint should be hit exactly 2 times.
772783
for _ in range(2):
@@ -802,6 +813,39 @@ def test(self):
802813
self.gdb.b("_exit")
803814
self.exit()
804815

816+
class McontrolManual(HwbpManual):
817+
def test(self):
818+
if not self.target.support_mcontrol:
819+
raise TestNotApplicable
820+
821+
tdata1 = TDATA1_DMODE(self.hart.xlen)
822+
tdata1 = set_field(tdata1, TDATA1_TYPE(self.hart.xlen),
823+
TDATA1_TYPE_MATCH)
824+
tdata1 = set_field(tdata1, MCONTROL_ACTION, MCONTROL_ACTION_DEBUG_MODE)
825+
tdata1 = set_field(tdata1, MCONTROL_MATCH, MCONTROL_MATCH_EQUAL)
826+
tdata1 |= MCONTROL_M | MCONTROL_EXECUTE
827+
if self.hart.extensionSupported("S"):
828+
tdata1 |= MCONTROL_S
829+
if self.hart.extensionSupported("U"):
830+
tdata1 |= MCONTROL_U
831+
self.run_test(tdata1, MCONTROL_MASKMAX(self.hart.xlen))
832+
833+
class Mcontrol6Manual(HwbpManual):
834+
def test(self):
835+
if not self.target.support_mcontrol6:
836+
raise TestNotApplicable
837+
838+
tdata1 = TDATA1_DMODE(self.hart.xlen)
839+
tdata1 = set_field(tdata1, TDATA1_TYPE(self.hart.xlen),
840+
TDATA1_TYPE_MATCH6)
841+
tdata1 = set_field(tdata1, MCONTROL6_ACTION, MCONTROL_ACTION_DEBUG_MODE)
842+
tdata1 = set_field(tdata1, MCONTROL6_MATCH, MCONTROL_MATCH_EQUAL)
843+
tdata1 |= MCONTROL6_M | MCONTROL6_EXECUTE
844+
if self.hart.extensionSupported("S"):
845+
tdata1 |= MCONTROL_S
846+
if self.hart.extensionSupported("U"):
847+
tdata1 |= MCONTROL_U
848+
self.run_test(tdata1, 0)
805849

806850
class Hwbp2(DebugTest):
807851
def early_applicable(self):

0 commit comments

Comments
 (0)