@@ -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 )
658658def 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
661665MCONTROL_SELECT = 1 << 19
662666MCONTROL_TIMING = 1 << 18
@@ -671,8 +675,23 @@ def MCONTROL_MASKMAX(xlen):
671675MCONTROL_STORE = 1 << 1
672676MCONTROL_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
677696MCONTROL_ACTION_DEBUG_EXCEPTION = 0
678697MCONTROL_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
806850class Hwbp2 (DebugTest ):
807851 def early_applicable (self ):
0 commit comments