@@ -68,10 +68,6 @@ 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
72
grouptype_t grouptype );
77
73
@@ -1784,6 +1780,37 @@ static void deinit_target(struct target *target)
1784
1780
info -> version_specific = NULL ;
1785
1781
}
1786
1782
1783
+ static int smp_add_ext_trigger (struct target * target , unsigned int group ,
1784
+ riscv_ext_trigger_t external_trigger )
1785
+ {
1786
+ uint32_t write_val = DM_DMCS2_HGSELECT ;
1787
+ assert (group <= 31 );
1788
+ assert (external_trigger .dmexttrigger < 16 );
1789
+ write_val = set_field (write_val , DM_DMCS2_GROUP , group );
1790
+ write_val = set_field (write_val , DM_DMCS2_GROUPTYPE , external_trigger .grouptype );
1791
+ write_val = set_field (write_val , DM_DMCS2_DMEXTTRIGGER , external_trigger .dmexttrigger );
1792
+ if (dm_write (target , DM_DMCS2 , write_val ) != ERROR_OK )
1793
+ return ERROR_FAIL ;
1794
+ write_val = set_field (write_val , DM_DMCS2_HGWRITE , 1 );
1795
+ if (dm_write (target , DM_DMCS2 , write_val ) != ERROR_OK )
1796
+ return ERROR_FAIL ;
1797
+
1798
+ uint32_t read_val ;
1799
+ if (dm_read (target , & read_val , DM_DMCS2 ) != ERROR_OK )
1800
+ return ERROR_FAIL ;
1801
+ if (get_field (read_val , DM_DMCS2_GROUP ) == group &&
1802
+ get_field (read_val , DM_DMCS2_DMEXTTRIGGER ) == external_trigger .dmexttrigger &&
1803
+ get_field (read_val , DM_DMCS2_HGSELECT ) == 1 ) {
1804
+ LOG_TARGET_INFO (target , "External trigger %d added to %s group %d" , external_trigger .dmexttrigger ,
1805
+ external_trigger .grouptype ? "resume" : "halt" , group );
1806
+ } else {
1807
+ LOG_TARGET_ERROR (target , "External trigger %d not supported %s group %d" , external_trigger .dmexttrigger ,
1808
+ external_trigger .grouptype ? "resume" : "halt" , group );
1809
+ }
1810
+
1811
+ return ERROR_OK ;
1812
+ }
1813
+
1787
1814
static int set_group (struct target * target , bool * supported , unsigned int group ,
1788
1815
grouptype_t grouptype )
1789
1816
{
@@ -2153,6 +2180,20 @@ static int examine(struct target *target)
2153
2180
else
2154
2181
LOG_TARGET_INFO (target , "Core %d could not be made part of halt group %d." ,
2155
2182
info -> index , target -> smp );
2183
+
2184
+ /* TODO: Resume groups with external input triggers look to be very problematic.
2185
+ * Neither OpenOCD nor GDB is ready for the case when a target suddenly
2186
+ * resumes (due to the trigger), without an explicit resume request and
2187
+ * at arbitrary moment in time. */
2188
+
2189
+ for (unsigned int i = 0 ; i < RISCV_MAX_EXTTRIGGERS ; i ++ ) {
2190
+ if (r -> external_triggers [i ].is_set ) {
2191
+ if (smp_add_ext_trigger (target , target -> smp , r -> external_triggers [i ]) != ERROR_OK )
2192
+ return ERROR_FAIL ;
2193
+ } else {
2194
+ break ;
2195
+ }
2196
+ }
2156
2197
}
2157
2198
2158
2199
/* Some regression suites rely on seeing 'Examined RISC-V core' to know
0 commit comments