@@ -68,12 +68,8 @@ static int riscv013_access_memory(struct target *target, const riscv_mem_access_
68
68
static bool riscv013_get_impebreak (const struct target * target );
69
69
static unsigned int riscv013_get_progbufsize (const struct target * target );
70
70
71
- typedef enum {
72
- HALT_GROUP ,
73
- RESUME_GROUP
74
- } grouptype_t ;
75
71
static int set_group (struct target * target , bool * supported , unsigned int group ,
76
- grouptype_t grouptype );
72
+ enum grouptype grouptype , bool is_trigger , unsigned int trigger_num );
77
73
78
74
/**
79
75
* Since almost everything can be accomplish by scanning the dbus register, all
@@ -138,6 +134,8 @@ typedef struct {
138
134
* abstractcs.busy may have remained set. In that case we may need to
139
135
* re-check the busy state before executing these operations. */
140
136
bool abstract_cmd_maybe_busy ;
137
+
138
+ struct riscv_ext_trigger external_triggers [RISCV_MAX_EXTTRIGGERS ];
141
139
} dm013_info_t ;
142
140
143
141
typedef struct {
@@ -1732,7 +1730,7 @@ static int halt_set_dcsr_ebreak(struct target *target)
1732
1730
1733
1731
if (info -> haltgroup_supported ) {
1734
1732
bool supported ;
1735
- if (set_group (target , & supported , 0 , HALT_GROUP ) != ERROR_OK )
1733
+ if (set_group (target , & supported , 0 , HALT_GROUP , false, 0 ) != ERROR_OK )
1736
1734
return ERROR_FAIL ;
1737
1735
if (!supported )
1738
1736
LOG_TARGET_ERROR (target , "Couldn't place hart in halt group 0. "
@@ -1754,7 +1752,7 @@ static int halt_set_dcsr_ebreak(struct target *target)
1754
1752
/* Add it back to the halt group. */
1755
1753
if (info -> haltgroup_supported ) {
1756
1754
bool supported ;
1757
- if (set_group (target , & supported , target -> smp , HALT_GROUP ) != ERROR_OK )
1755
+ if (set_group (target , & supported , target -> smp , HALT_GROUP , false, 0 ) != ERROR_OK )
1758
1756
return ERROR_FAIL ;
1759
1757
if (!supported )
1760
1758
LOG_TARGET_ERROR (target , "Couldn't place hart back in halt group %d. "
@@ -1785,19 +1783,46 @@ static void deinit_target(struct target *target)
1785
1783
}
1786
1784
1787
1785
static int set_group (struct target * target , bool * supported , unsigned int group ,
1788
- grouptype_t grouptype )
1786
+ enum grouptype grouptype , bool is_trigger , unsigned int trigger_num )
1789
1787
{
1790
- uint32_t write_val = DM_DMCS2_HGWRITE ;
1791
1788
assert (group <= 31 );
1789
+ assert (trigger_num < 16 );
1790
+
1791
+ if (!is_trigger && dm013_select_target (target ) != ERROR_OK )
1792
+ return ERROR_FAIL ;
1793
+
1794
+ dm013_info_t * dm = get_dm (target );
1795
+ if (!dm )
1796
+ return ERROR_FAIL ;
1797
+ if (is_trigger && dm -> external_triggers [trigger_num ].haltgroup_was_set &&
1798
+ dm -> external_triggers [trigger_num ].haltgroup_num == group ) {
1799
+ LOG_TARGET_WARNING (target , "External trigger %d (at address dbgbase=0x%" PRIx32 ") "
1800
+ "for halt group %d has been set." , trigger_num , dm -> base , group );
1801
+ return ERROR_OK ;
1802
+ }
1803
+
1804
+ uint32_t write_val = DM_DMCS2_HGWRITE ;
1792
1805
write_val = set_field (write_val , DM_DMCS2_GROUP , group );
1793
1806
write_val = set_field (write_val , DM_DMCS2_GROUPTYPE , (grouptype == HALT_GROUP ) ? 0 : 1 );
1807
+ write_val = set_field (write_val , DM_DMCS2_DMEXTTRIGGER , trigger_num );
1808
+ write_val = set_field (write_val , DM_DMCS2_HGSELECT ,
1809
+ is_trigger ? DM_DMCS2_HGSELECT_TRIGGERS : DM_DMCS2_HGSELECT_HARTS );
1794
1810
if (dm_write (target , DM_DMCS2 , write_val ) != ERROR_OK )
1795
1811
return ERROR_FAIL ;
1796
1812
uint32_t read_val ;
1797
1813
if (dm_read (target , & read_val , DM_DMCS2 ) != ERROR_OK )
1798
1814
return ERROR_FAIL ;
1799
1815
if (supported )
1800
- * supported = (get_field (read_val , DM_DMCS2_GROUP ) == group );
1816
+ * supported = (get_field (read_val , DM_DMCS2_GROUP ) == group &&
1817
+ get_field (read_val , DM_DMCS2_GROUPTYPE ) == ((grouptype == HALT_GROUP ) ? 0 : 1 ) &&
1818
+ get_field (read_val , DM_DMCS2_HGSELECT ) ==
1819
+ (is_trigger ? DM_DMCS2_HGSELECT_TRIGGERS : DM_DMCS2_HGSELECT_HARTS ) &&
1820
+ get_field (read_val , DM_DMCS2_DMEXTTRIGGER ) == trigger_num );
1821
+ if (is_trigger && * supported ) {
1822
+ dm -> external_triggers [trigger_num ].haltgroup_was_set = true;
1823
+ dm -> external_triggers [trigger_num ].haltgroup_num = group ;
1824
+ }
1825
+
1801
1826
return ERROR_OK ;
1802
1827
}
1803
1828
@@ -2145,8 +2170,9 @@ static int examine(struct target *target)
2145
2170
}
2146
2171
2147
2172
if (target -> smp ) {
2148
- if (set_group (target , & info -> haltgroup_supported , target -> smp , HALT_GROUP ) != ERROR_OK )
2173
+ if (set_group (target , & info -> haltgroup_supported , target -> smp , HALT_GROUP , false, 0 ) != ERROR_OK )
2149
2174
return ERROR_FAIL ;
2175
+
2150
2176
if (info -> haltgroup_supported )
2151
2177
LOG_TARGET_INFO (target , "Core %d made part of halt group %d." , info -> index ,
2152
2178
target -> smp );
@@ -2881,6 +2907,8 @@ static int init_target(struct command_context *cmd_ctx,
2881
2907
generic_info -> handle_became_unavailable = & handle_became_unavailable ;
2882
2908
generic_info -> tick = & tick ;
2883
2909
2910
+ generic_info -> set_group = & set_group ;
2911
+
2884
2912
if (!generic_info -> version_specific ) {
2885
2913
generic_info -> version_specific = calloc (1 , sizeof (riscv013_info_t ));
2886
2914
if (!generic_info -> version_specific )
0 commit comments