-
Notifications
You must be signed in to change notification settings - Fork 347
Add dcsr cetrig control #1255
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
base: riscv
Are you sure you want to change the base?
Add dcsr cetrig control #1255
Conversation
Ubuntu 20.04 is no longer available. See actions/runner-images#11101 Checkpatch-ignore: BAD_SIGN_OFF Change-Id: I0ec3e3342f9212a2a79d8dca6274e7db62ecedab Signed-off-by: Evgeniy Naydanov <[email protected]>
…-spec This pulls in some improvements from the riscv-debug-spec repo, and cleans up the licensing (riscv-debug-spec changed the license to dual CC-BY-4.0 and BSD-2-Clause specifically to make sure the generated debug_defines files don't conflict with OpenOCD licensing) Signed-off-by: Bernhard Rosenkränzer <[email protected]>
6b88574
to
605e820
Compare
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.
Thank you for the patch!
Overall it looks great, the only concern I have is with the new return from riscv013_halt_reason()
. I'm not sure RISCV_HALT_ERROR
is the proper return code. I'd suggest adding a new status and handling it differently at the callsite.
Also, how did you test the changes? Is this at all possible to extend riscv-tests
to include relevant tests?
src/target/riscv/riscv-013.c
Outdated
/* When false, we need to set dcsr.ebreak*, halting the target if that's | ||
* necessary. */ | ||
bool dcsr_ebreak_is_set; | ||
bool dcsr_configs_is_set; |
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.
Please, adjust the comment to drop the mention of ebreak
.
Also, this is a nitpick, but dcsr_configs_is_set
does not feel right (plural with is
). Maybe dcsr_config_is_set
?
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.
Addressed
src/target/riscv/riscv-013.c
Outdated
return ERROR_OK; | ||
} | ||
|
||
static int halt_set_dcsr_ebreak(struct target *target) | ||
static int halt_set_dcsr_configs(struct target *target) |
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.
static int halt_set_dcsr_configs(struct target *target) | |
static int halt_set_dcsr_config(struct target *target) |
For consistency with dcsr_config_is_set
(if you decide to adopt the suggestion).
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.
Addressed
src/target/riscv/riscv-013.c
Outdated
@@ -2939,13 +2940,13 @@ static int assert_reset(struct target *target) | |||
return riscv013_invalidate_cached_progbuf(target); | |||
} | |||
|
|||
static bool dcsr_ebreak_config_equals_reset_value(const struct target *target) | |||
static bool dcsr_configs_equals_reset_value(const struct target *target) |
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.
static bool dcsr_configs_equals_reset_value(const struct target *target) | |
static bool dcsr_config_equals_reset_value(const struct target *target) |
Same as above
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.
Addressed
src/target/riscv/riscv-013.c
Outdated
case CSR_DCSR_CAUSE_OTHER: | ||
if (get_field(dcsr, CSR_DCSR_EXTCAUSE) == 0) { | ||
LOG_TARGET_WARNING(target, "halted because of hart in a critical error state."); | ||
return RISCV_HALT_ERROR; |
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.
I believe this should be a separate entry in enum riscv_halt_reason
.
Also, AFAIU, RISCV_HALT_ERROR
is currently unused. Maybe a simple rename would suffice.
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.
Addressed
src/target/riscv/riscv-013.c
Outdated
@@ -5367,6 +5368,14 @@ static enum riscv_halt_reason riscv013_halt_reason(struct target *target) | |||
return RISCV_HALT_INTERRUPT; | |||
case CSR_DCSR_CAUSE_GROUP: | |||
return RISCV_HALT_GROUP; | |||
case CSR_DCSR_CAUSE_OTHER: | |||
if (get_field(dcsr, CSR_DCSR_EXTCAUSE) == 0) { | |||
LOG_TARGET_WARNING(target, "halted because of hart in a critical error state."); |
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.
LOG_TARGET_WARNING(target, "halted because of hart in a critical error state."); | |
LOG_TARGET_INFO(target, "halted because of hart in a critical error state."); |
I believe INFO
is more appropriate here, since this is completely normal from the debugger's point of view.
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.
Addressed
@@ -525,6 +527,15 @@ static struct jim_nvp nvp_ebreak_mode_opts[] = { | |||
{ .name = NULL, .value = RISCV_EBREAK_MODE_INVALID } | |||
}; | |||
|
|||
|
|||
#define RISCV_CETRIG_INVALID -1 |
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.
I believe this can be inlined.
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.
To be consistent with RISCV_EBREAK_MODE_INVALID
, should this be kept?
src/target/riscv/riscv.c
Outdated
{ | ||
if (goi->argc == 0) { | ||
Jim_WrongNumArgs(goi->interp, 1, goi->argv - 1, | ||
"?disable?or?enable?"); |
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.
"?disable?or?enable?"); | |
"?disable|enable?"); |
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.
Addressed
src/target/riscv/riscv.c
Outdated
static int jim_report_cetrig_config(const struct riscv_private_config *config, | ||
Jim_Interp *interp) | ||
{ | ||
const char * const cetrig_opt = jim_nvp_value2name_simple(nvp_cetrig_opts, |
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.
const char * const cetrig_opt = jim_nvp_value2name_simple(nvp_cetrig_opts, | |
const char *cetrig_opt = jim_nvp_value2name_simple(nvp_cetrig_opts, |
I'd suggest dropping this const
. AFAIU, the styleguide will be updated sometime to include this rule.
See https://review.openocd.org/c/openocd/+/8750/comment/984b8414_f6f804e4/
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.
Addressed
605e820
to
d1d2b0a
Compare
Introduce RISC-V-sepecific `configure` parameter `-cetrig`
d1d2b0a
to
aed2254
Compare
|
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.
Overall this looks good. I have managed a partial review and am sending my comments so far.
@@ -75,6 +75,7 @@ enum riscv_halt_reason { | |||
RISCV_HALT_TRIGGER, | |||
RISCV_HALT_UNKNOWN, | |||
RISCV_HALT_GROUP, | |||
RISCV_HALT_CRITERR, |
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.
If you like - this will be more clear to code readers:
RISCV_HALT_CRITERR, | |
RISCV_HALT_CRITICAL_ERROR, |
@@ -5367,6 +5368,14 @@ static enum riscv_halt_reason riscv013_halt_reason(struct target *target) | |||
return RISCV_HALT_INTERRUPT; | |||
case CSR_DCSR_CAUSE_GROUP: | |||
return RISCV_HALT_GROUP; | |||
case CSR_DCSR_CAUSE_OTHER: | |||
if (get_field(dcsr, CSR_DCSR_EXTCAUSE) == 0) { | |||
LOG_TARGET_INFO(target, "halted because of hart in a critical error state."); |
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.
Since this is an error condition of the target, I would use at least warning level. Perhaps even an error?
LOG_TARGET_INFO(target, "halted because of hart in a critical error state."); | |
LOG_TARGET_WARNING(target, "halted because of hart in a critical error state."); |
dcsr = set_field(dcsr, CSR_DCSR_EBREAKU, config->dcsr_ebreak_fields[RISCV_MODE_U]); | ||
dcsr = set_field(dcsr, CSR_DCSR_EBREAKVS, config->dcsr_ebreak_fields[RISCV_MODE_VS]); | ||
dcsr = set_field(dcsr, CSR_DCSR_EBREAKVU, config->dcsr_ebreak_fields[RISCV_MODE_VU]); | ||
dcsr = set_field(dcsr, CSR_DCSR_CETRIG, config->dcsr_cetrig); | ||
if (dcsr != original_dcsr && | ||
riscv_reg_set(target, GDB_REGNO_DCSR, dcsr) != ERROR_OK) | ||
return ERROR_FAIL; | ||
info->dcsr_ebreak_is_set = true; | ||
info->dcsr_config_is_set = true; | ||
return ERROR_OK; |
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.
Would it make sense to read DCSR back and see if these WARL bits were really set as the user wanted? If not, then a log info print could be made.
If you think this is a useful improvement, please open an issue or make a TODO comment into the code. I don't insist on making it in this PR. It'd better to do this separately.
if (get_field(dcsr, CSR_DCSR_EXTCAUSE) == 0) { | ||
LOG_TARGET_INFO(target, "halted because of hart in a critical error state."); | ||
return RISCV_HALT_CRITERR; | ||
} | ||
LOG_TARGET_ERROR(target, "Unknown DCSR extcause field: 0x%" | ||
PRIx64, get_field(dcsr, CSR_DCSR_EXTCAUSE)); | ||
return RISCV_HALT_UNKNOWN; |
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.
If you like, this could be a switch instead of if cascade.
This will encourage better coding style in future, when there are more EXTCAUSE values.
if (get_field(dcsr, CSR_DCSR_EXTCAUSE) == 0) { | |
LOG_TARGET_INFO(target, "halted because of hart in a critical error state."); | |
return RISCV_HALT_CRITERR; | |
} | |
LOG_TARGET_ERROR(target, "Unknown DCSR extcause field: 0x%" | |
PRIx64, get_field(dcsr, CSR_DCSR_EXTCAUSE)); | |
return RISCV_HALT_UNKNOWN; | |
switch (get_field(dcsr, CSR_DCSR_EXTCAUSE)) | |
{ | |
case 0: | |
/* ... */ | |
return RISCV_HALT_CRITICAL_ERROR; | |
default: | |
/* ... */ | |
return RISCV_HALT_UNKNOWN; | |
} |
* necessary. */ | ||
bool dcsr_ebreak_is_set; | ||
bool dcsr_config_is_set; |
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.
bool dcsr_config_is_set; | |
bool dcsr_register_is_set; |
/* When false, we need to set dcsr config, halting the target if that's | ||
* necessary. */ |
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.
/* When false, we need to set dcsr config, halting the target if that's | |
* necessary. */ | |
/* When false, we need to configure certain bits in the dcsr register. | |
* To do that, we may momentarily halt the target, if necessary. */ |
Introduce RISC-V-sepecific
configure
parameter-cetrig