-
Notifications
You must be signed in to change notification settings - Fork 334
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
target/riscv: Add support for external triggers #1179
base: riscv
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11476,6 +11476,11 @@ The second argument configures how OpenOCD should use the selected trigger featu | |
With no parameters, prints current trigger features configuration. | ||
@end deffn | ||
|
||
@deffn {Command} {riscv set_external_trigger} value | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My initial idea was to create external triggers separately in the cfg file and list them in the
But there are a lot of changes required, so currently associating external trigger with a target seems like an easy enough way to start supporting it. Suppose we support it this way, then my suggestion is let this cmd support multiple external triggers instead of just one. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The design of this syntax looks really nice - i'm very happy to wait on this or if you prefer take a go at implementing that style myself? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I haven't started looking at the code yet, just a basic idea that needs further thought. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @zqb-all Thank you for your idea above. Still, I'd recommend to not abuse There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Agreed. Some concepts in debug spec are not explicitly represented in OpenOCD cfg file now. For example, |
||
Associate the supplied external trigger with the halt group for the harts. When | ||
the external trigger fires the harts in the halt group will be halted. | ||
@end deffn | ||
|
||
@subsection RISC-V Authentication Commands | ||
|
||
The following commands can be used to authenticate to a RISC-V system. Eg. a | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1703,6 +1703,32 @@ static void deinit_target(struct target *target) | |
info->version_specific = NULL; | ||
} | ||
|
||
static int set_external_trigger(struct target *target, unsigned int group, | ||
grouptype_t grouptype, unsigned int external_trigger) | ||
{ | ||
uint32_t write_val = DM_DMCS2_HGWRITE | DM_DMCS2_HGSELECT; | ||
assert(group <= 31); | ||
assert(external_trigger < 16); | ||
write_val = set_field(write_val, DM_DMCS2_GROUP, group); | ||
write_val = set_field(write_val, DM_DMCS2_GROUPTYPE, (grouptype == HALT_GROUP) ? 0 : 1); | ||
write_val = set_field(write_val, DM_DMCS2_DMEXTTRIGGER, external_trigger); | ||
if (dm_write(target, DM_DMCS2, write_val) != ERROR_OK) | ||
return ERROR_FAIL; | ||
uint32_t read_val; | ||
if (dm_read(target, &read_val, DM_DMCS2) != ERROR_OK) | ||
return ERROR_FAIL; | ||
if (get_field(read_val, DM_DMCS2_GROUP) == group && | ||
get_field(read_val, DM_DMCS2_DMEXTTRIGGER) == external_trigger && | ||
get_field(read_val, DM_DMCS2_HGSELECT) == 1) { | ||
LOG_TARGET_INFO(target, "External trigger %d added to group %d", external_trigger, | ||
group); | ||
} else { | ||
LOG_TARGET_ERROR(target, "External trigger %d not supported", external_trigger); | ||
} | ||
|
||
return ERROR_OK; | ||
} | ||
|
||
static int set_group(struct target *target, bool *supported, unsigned int group, | ||
grouptype_t grouptype) | ||
{ | ||
|
@@ -2051,6 +2077,9 @@ static int examine(struct target *target) | |
else | ||
LOG_TARGET_INFO(target, "Core %d could not be made part of halt group %d.", | ||
info->index, target->smp); | ||
if (r->external_trigger) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @aap-sc Thanks for taking the time to reply - some specific answers to your points
|
||
if (set_external_trigger(target, target->smp, HALT_GROUP, r->external_trigger) != ERROR_OK) | ||
return ERROR_FAIL; | ||
} | ||
|
||
/* Some regression suites rely on seeing 'Examined RISC-V core' to know | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5262,6 +5262,26 @@ COMMAND_HANDLER(handle_riscv_virt2phys_mode) | |
return ERROR_OK; | ||
} | ||
|
||
COMMAND_HANDLER(riscv_set_external_trigger) | ||
{ | ||
struct target *target = get_current_target(CMD_CTX); | ||
RISCV_INFO(r); | ||
|
||
if (CMD_ARGC != 1) { | ||
LOG_ERROR("Command takes exactly 1 parameter."); | ||
return ERROR_COMMAND_SYNTAX_ERROR; | ||
} | ||
int value = atoi(CMD_ARGV[0]); | ||
if (value <= 0 || value > 16) { | ||
LOG_ERROR("%s is not a valid integer argument for command.", CMD_ARGV[0]); | ||
return ERROR_FAIL; | ||
} | ||
|
||
r->external_trigger = value; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be safer to add some checks to prevent user from associating one trigger to multiple harts on same DM. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indeed this is a good point - the external trigger is logically associated with a halt group which will span multiple targets (assuming the one target per hart configuration method.) |
||
|
||
return ERROR_OK; | ||
} | ||
|
||
static const struct command_registration riscv_exec_command_handlers[] = { | ||
{ | ||
.name = "dump_sample_buf", | ||
|
@@ -5524,6 +5544,13 @@ static const struct command_registration riscv_exec_command_handlers[] = { | |
"When off, users need to take care of memory coherency themselves, for example by using " | ||
"`riscv exec_progbuf` to execute fence or CMO instructions." | ||
}, | ||
{ | ||
.name = "set_external_trigger", | ||
.handler = riscv_set_external_trigger, | ||
.mode = COMMAND_CONFIG, | ||
.usage = "value", | ||
.help = "Add the given external trigger to the halt group" | ||
}, | ||
COMMAND_REGISTRATION_DONE | ||
}; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -191,6 +191,9 @@ struct riscv_info { | |
/* The configured approach to translate virtual addresses to physical */ | ||
riscv_virt2phys_mode_t virt2phys_mode; | ||
|
||
/* Halt group may be associated with an external trigger */ | ||
unsigned int external_trigger; | ||
Comment on lines
+194
to
+195
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As pointed out in another comment, there can be multiple external triggers in a halt (or resume) group. The code, on the other hand, seems to force 1:1 relationship. |
||
|
||
bool triggers_enumerated; | ||
|
||
/* Decremented every scan, and when it reaches 0 we clear the learned | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RISC-V debug spec allows external triggers to be associated with halt and resume groups. I assume you are trying to add support for halt groups only. Looks like this command needs to be renamed, since resume groups are out of scope, or you should extend the interface to support resume groups too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed - my initial focus was only halt groups - this should be renamed if we go ahead with this very limited solution.