Skip to content

Commit

Permalink
target/riscv: Add support for external triggers
Browse files Browse the repository at this point in the history
Add support for associating a halt group with an external trigger via a
newly exposed configuration option "riscv set_external_trigger".

Change-Id: If10c67d2e14d8bc7cd6d59011b3215fda4ff4b02
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
  • Loading branch information
rbradford committed Dec 2, 2024
1 parent eb1ecd7 commit e9fef03
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 0 deletions.
5 changes: 5 additions & 0 deletions doc/openocd.texi
Original file line number Diff line number Diff line change
Expand Up @@ -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
Associate the supplied external trigger with the SMP 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
Expand Down
29 changes: 29 additions & 0 deletions src/target/riscv/riscv-013.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
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
Expand Down
27 changes: 27 additions & 0 deletions src/target/riscv/riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

return ERROR_OK;
}

static const struct command_registration riscv_exec_command_handlers[] = {
{
.name = "dump_sample_buf",
Expand Down Expand Up @@ -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
};

Expand Down
3 changes: 3 additions & 0 deletions src/target/riscv/riscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

bool triggers_enumerated;

/* Decremented every scan, and when it reaches 0 we clear the learned
Expand Down

0 comments on commit e9fef03

Please sign in to comment.