Skip to content

Commit

Permalink
target/riscv: Improve riscv controls that manage the set of available…
Browse files Browse the repository at this point in the history
… triggers for watchpoints

Add more debug messages connected with triggers.
Update names for internal flags to make them more clarified.

Change-Id: I5642346ce4a1e9bf79b22cdbf36bd757a7beffa8
Signed-off-by: Kirill Radkin <kirill.radkin@syntacore.com>
  • Loading branch information
kr-sc committed Feb 5, 2024
1 parent 87331a8 commit a114e7f
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 83 deletions.
12 changes: 2 additions & 10 deletions doc/openocd.texi
Original file line number Diff line number Diff line change
Expand Up @@ -11369,16 +11369,8 @@ OpenOCD. When off, they generate a breakpoint exception handled internally.
The commands below can be used to prevent OpenOCD from using certain RISC-V trigger features.
For example in cases when there are known issues in the target hardware.

@deffn {Command} {riscv set_enable_eq_match_trigger} [on|off]
When on (default), allow OpenOCD to use exact-match triggers in watchpoints.
@end deffn

@deffn {Command} {riscv set_enable_napot_trigger} [on|off]
When on (default), allow OpenOCD to use NAPOT trigger in watchpoints.
@end deffn

@deffn {Command} {riscv set_enable_ge_lt_trigger} [on|off]
When on (default), allow OpenOCD to use a pair of chained less-than & greater-than triggers in watchpoints.
@deffn {Command} {riscv set_enable_trigger_type} [eq|napot|ge_lt] [wp|none]
Control usage of triggers in wp by OpenOCD. All trigger types are enabled by default.
@end deffn

@subsection RISC-V Authentication Commands
Expand Down
139 changes: 69 additions & 70 deletions src/target/riscv/riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1011,25 +1011,29 @@ static int maybe_add_trigger_t2_t6_for_wp(struct target *target,
struct trigger *trigger, struct match_triggers_tdata1_fields fields)
{
RISCV_INFO(r);
int ret = ERROR_FAIL;
int ret = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;

if (trigger->length > 0) {
/* Setting a load/store trigger ("watchpoint") on a range of addresses */

if (r->enable_napot_trigger && can_use_napot_match(trigger)) {
LOG_TARGET_DEBUG(target, "trying to setup NAPOT match trigger");
struct trigger_request_info napot = {
.tdata1 = fields.common | fields.size.any |
fields.chain.disable | fields.match.napot,
.tdata2 = trigger->address | ((trigger->length - 1) >> 1),
.tdata1_ignore_mask = fields.tdata1_ignore_mask
};
ret = try_setup_single_match_trigger(target, trigger, napot);
if (ret != ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
return ret;
if (can_use_napot_match(trigger)) {
if (r->wp_enable_napot_trigger) {
LOG_TARGET_DEBUG(target, "trying to setup NAPOT match trigger");
struct trigger_request_info napot = {
.tdata1 = fields.common | fields.size.any |
fields.chain.disable | fields.match.napot,
.tdata2 = trigger->address | ((trigger->length - 1) >> 1),
.tdata1_ignore_mask = fields.tdata1_ignore_mask
};
ret = try_setup_single_match_trigger(target, trigger, napot);
if (ret != ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
return ret;
} else {
LOG_TARGET_DEBUG(target, "NAPOT match triggers are disabled for watchpoints. "
"Use set_wp_enable_napot_trigger to enable it.");
}
}

if (r->enable_ge_lt_trigger) {
if (r->wp_enable_ge_lt_trigger) {
LOG_TARGET_DEBUG(target, "trying to setup GE+LT chained match trigger pair");
struct trigger_request_info ge_1 = {
.tdata1 = fields.common | fields.size.any | fields.chain.enable |
Expand Down Expand Up @@ -1063,10 +1067,13 @@ static int maybe_add_trigger_t2_t6_for_wp(struct target *target,
ret = try_setup_chained_match_triggers(target, trigger, lt_1, ge_2);
if (ret != ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
return ret;
} else {
LOG_TARGET_DEBUG(target, "LT+GE chained match triggers are disabled for watchpoints. "
"Use set_wp_enable_ge_lt_trigger to enable it.");
}
}

if (r->enable_equality_match_trigger) {
if (r->wp_enable_equality_match_trigger) {
LOG_TARGET_DEBUG(target, "trying to setup equality match trigger");
struct trigger_request_info eq = {
.tdata1 = fields.common | fields.size.any | fields.chain.disable |
Expand All @@ -1077,6 +1084,9 @@ static int maybe_add_trigger_t2_t6_for_wp(struct target *target,
ret = try_setup_single_match_trigger(target, trigger, eq);
if (ret != ERROR_OK)
return ret;
} else {
LOG_TARGET_DEBUG(target, "equality match triggers are disabled for watchpoints. "
"Use set_wp_enable_eq_match_trigger to enable it.");
}

if (ret == ERROR_OK && trigger->length > 1) {
Expand Down Expand Up @@ -4499,54 +4509,57 @@ COMMAND_HANDLER(riscv_exec_progbuf)
return ERROR_OK;
}

COMMAND_HANDLER(riscv_set_enable_eq_match_trigger)
COMMAND_HANDLER(riscv_set_enable_trigger_type)
{
struct target *target = get_current_target(CMD_CTX);
RISCV_INFO(r);

if (CMD_ARGC == 0) {
command_print(CMD, "equality match trigger enabled: %s", r->enable_equality_match_trigger ? "on" : "off");
return ERROR_OK;
} else if (CMD_ARGC == 1) {
COMMAND_PARSE_ON_OFF(CMD_ARGV[0], r->enable_equality_match_trigger);
return ERROR_OK;
}
command_print(CMD, "Triggers enabled:\n"
"Equality match trigger: for wp (%s)\n"
"NAPOT trigger: for wp (%s)\n"
"ge-lt chained triggers: for wp (%s)",
r->wp_enable_equality_match_trigger ? "on" : "off",
r->wp_enable_napot_trigger ? "on" : "off",
r->wp_enable_ge_lt_trigger ? "on" : "off");

LOG_ERROR("Command takes 0 or 1 parameters");
return ERROR_COMMAND_SYNTAX_ERROR;
}

COMMAND_HANDLER(riscv_set_enable_napot_trigger)
{
struct target *target = get_current_target(CMD_CTX);
RISCV_INFO(r);

if (CMD_ARGC == 0) {
command_print(CMD, "NAPOT trigger enabled: %s", r->enable_napot_trigger ? "on" : "off");
return ERROR_OK;
} else if (CMD_ARGC == 1) {
COMMAND_PARSE_ON_OFF(CMD_ARGV[0], r->enable_napot_trigger);
if (!strcmp(CMD_ARGV[0], "wp")) {
r->wp_enable_equality_match_trigger = true;
r->wp_enable_napot_trigger = true;
r->wp_enable_ge_lt_trigger = true;
} else if (!strcmp(CMD_ARGV[0], "none")) {
r->wp_enable_equality_match_trigger = false;
r->wp_enable_napot_trigger = false;
r->wp_enable_ge_lt_trigger = false;
} else {
return ERROR_COMMAND_SYNTAX_ERROR;
}

return ERROR_OK;
}
} else if (CMD_ARGC == 2) {
bool enable_for_wp = true;

LOG_ERROR("Command takes 0 or 1 parameters");
return ERROR_COMMAND_SYNTAX_ERROR;
}
if (!strcmp(CMD_ARGV[1], "wp"))
enable_for_wp = true;
else if (!strcmp(CMD_ARGV[1], "none"))
enable_for_wp = false;
else
return ERROR_COMMAND_SYNTAX_ERROR;

COMMAND_HANDLER(riscv_set_enable_ge_lt_trigger)
{
struct target *target = get_current_target(CMD_CTX);
RISCV_INFO(r);
if (!strcmp(CMD_ARGV[0], "eq"))
r->wp_enable_equality_match_trigger = enable_for_wp;
else if (!strcmp(CMD_ARGV[0], "napot"))
r->wp_enable_napot_trigger = enable_for_wp;
else if (!strcmp(CMD_ARGV[0], "ge_lt"))
r->wp_enable_ge_lt_trigger = enable_for_wp;
else
return ERROR_COMMAND_SYNTAX_ERROR;

if (CMD_ARGC == 0) {
command_print(CMD, "ge-lt triggers enabled: %s", r->enable_ge_lt_trigger ? "on" : "off");
return ERROR_OK;
} else if (CMD_ARGC == 1) {
COMMAND_PARSE_ON_OFF(CMD_ARGV[0], r->enable_ge_lt_trigger);
return ERROR_OK;
}

LOG_ERROR("Command takes 0 or 1 parameters");
return ERROR_COMMAND_SYNTAX_ERROR;
}

Expand Down Expand Up @@ -4800,25 +4813,11 @@ static const struct command_registration riscv_exec_command_handlers[] = {
"The final ebreak instruction is added automatically, if needed."
},
{
.name = "set_enable_eq_match_trigger",
.handler = riscv_set_enable_eq_match_trigger,
.mode = COMMAND_CONFIG,
.usage = "[on|off]",
.help = "When on, allow OpenOCD to use equality match trigger in wp."
},
{
.name = "set_enable_napot_trigger",
.handler = riscv_set_enable_napot_trigger,
.mode = COMMAND_CONFIG,
.usage = "[on|off]",
.help = "When on, allow OpenOCD to use NAPOT trigger in wp."
},
{
.name = "set_enable_ge_lt_trigger",
.handler = riscv_set_enable_ge_lt_trigger,
.mode = COMMAND_CONFIG,
.usage = "[on|off]",
.help = "When on, allow OpenOCD to use GE/LT triggers in wp."
.name = "set_enable_trigger_type",
.handler = riscv_set_enable_trigger_type,
.mode = COMMAND_ANY,
.usage = "[eq|napot|ge_lt] [wp|none]",
.help = "Control usage of triggers in wp by OpenOCD"
},
COMMAND_REGISTRATION_DONE
};
Expand Down Expand Up @@ -4956,9 +4955,9 @@ static void riscv_info_init(struct target *target, struct riscv_info *r)
r->riscv_ebreaks = true;
r->riscv_ebreaku = true;

r->enable_equality_match_trigger = true;
r->enable_ge_lt_trigger = true;
r->enable_napot_trigger = true;
r->wp_enable_equality_match_trigger = true;
r->wp_enable_ge_lt_trigger = true;
r->wp_enable_napot_trigger = true;
}

static int riscv_resume_go_all_harts(struct target *target)
Expand Down
6 changes: 3 additions & 3 deletions src/target/riscv/riscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -314,9 +314,9 @@ struct riscv_info {
bool riscv_ebreaks;
bool riscv_ebreaku;

bool enable_equality_match_trigger;
bool enable_napot_trigger;
bool enable_ge_lt_trigger;
bool wp_enable_equality_match_trigger;
bool wp_enable_napot_trigger;
bool wp_enable_ge_lt_trigger;
};

COMMAND_HELPER(riscv_print_info_line, const char *section, const char *key,
Expand Down

0 comments on commit a114e7f

Please sign in to comment.