@@ -68,10 +68,6 @@ static int riscv013_access_memory(struct target *target, const riscv_mem_access_
6868static bool riscv013_get_impebreak(const struct target *target);
6969static unsigned int riscv013_get_progbufsize(const struct target *target);
7070
71- typedef enum {
72- HALT_GROUP,
73- RESUME_GROUP
74- } grouptype_t;
7571static int set_group(struct target *target, bool *supported, unsigned int group,
7672 grouptype_t grouptype);
7773
@@ -1784,6 +1780,37 @@ static void deinit_target(struct target *target)
17841780 info->version_specific = NULL;
17851781}
17861782
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+
17871814static int set_group(struct target *target, bool *supported, unsigned int group,
17881815 grouptype_t grouptype)
17891816{
@@ -2153,6 +2180,20 @@ static int examine(struct target *target)
21532180 else
21542181 LOG_TARGET_INFO(target, "Core %d could not be made part of halt group %d.",
21552182 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+ }
21562197 }
21572198
21582199 /* Some regression suites rely on seeing 'Examined RISC-V core' to know
0 commit comments