Merge pull request #918 from kr-sc/kr-sc/allow-to-query-status-dcsr-ebreak
openocd does not allow to query status of dcsr.ebreak{u,s,m}
This commit is contained in:
commit
75b5de67df
|
@ -10856,17 +10856,17 @@ Keep in mind, disabling the option does not guarantee that single stepping will
|
||||||
To make that happen, dcsr.stepie would have to be written to 1 as well.
|
To make that happen, dcsr.stepie would have to be written to 1 as well.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Command} {riscv set_ebreakm} on|off
|
@deffn {Command} {riscv set_ebreakm} [on|off]
|
||||||
Control dcsr.ebreakm. When on (default), M-mode ebreak instructions trap to
|
Control dcsr.ebreakm. When on (default), M-mode ebreak instructions trap to
|
||||||
OpenOCD. When off, they generate a breakpoint exception handled internally.
|
OpenOCD. When off, they generate a breakpoint exception handled internally.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Command} {riscv set_ebreaks} on|off
|
@deffn {Command} {riscv set_ebreaks} [on|off]
|
||||||
Control dcsr.ebreaks. When on (default), S-mode ebreak instructions trap to
|
Control dcsr.ebreaks. When on (default), S-mode ebreak instructions trap to
|
||||||
OpenOCD. When off, they generate a breakpoint exception handled internally.
|
OpenOCD. When off, they generate a breakpoint exception handled internally.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Command} {riscv set_ebreaku} on|off
|
@deffn {Command} {riscv set_ebreaku} [on|off]
|
||||||
Control dcsr.ebreaku. When on (default), U-mode ebreak instructions trap to
|
Control dcsr.ebreaku. When on (default), U-mode ebreak instructions trap to
|
||||||
OpenOCD. When off, they generate a breakpoint exception handled internally.
|
OpenOCD. When off, they generate a breakpoint exception handled internally.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
|
@ -1104,6 +1104,7 @@ static int maybe_write_tselect(struct target *target)
|
||||||
|
|
||||||
static int execute_resume(struct target *target, bool step)
|
static int execute_resume(struct target *target, bool step)
|
||||||
{
|
{
|
||||||
|
RISCV_INFO(r);
|
||||||
riscv011_info_t *info = get_info(target);
|
riscv011_info_t *info = get_info(target);
|
||||||
|
|
||||||
LOG_DEBUG("step=%d", step);
|
LOG_DEBUG("step=%d", step);
|
||||||
|
@ -1135,9 +1136,9 @@ static int execute_resume(struct target *target, bool step)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
info->dcsr = set_field(info->dcsr, DCSR_EBREAKM, riscv_ebreakm);
|
info->dcsr = set_field(info->dcsr, DCSR_EBREAKM, r->riscv_ebreakm);
|
||||||
info->dcsr = set_field(info->dcsr, DCSR_EBREAKS, riscv_ebreaks);
|
info->dcsr = set_field(info->dcsr, DCSR_EBREAKS, r->riscv_ebreaks);
|
||||||
info->dcsr = set_field(info->dcsr, DCSR_EBREAKU, riscv_ebreaku);
|
info->dcsr = set_field(info->dcsr, DCSR_EBREAKU, r->riscv_ebreaku);
|
||||||
info->dcsr = set_field(info->dcsr, DCSR_EBREAKH, 1);
|
info->dcsr = set_field(info->dcsr, DCSR_EBREAKH, 1);
|
||||||
info->dcsr &= ~DCSR_HALT;
|
info->dcsr &= ~DCSR_HALT;
|
||||||
|
|
||||||
|
@ -1936,6 +1937,7 @@ static int riscv011_resume(struct target *target, int current,
|
||||||
|
|
||||||
static int assert_reset(struct target *target)
|
static int assert_reset(struct target *target)
|
||||||
{
|
{
|
||||||
|
RISCV_INFO(r);
|
||||||
riscv011_info_t *info = get_info(target);
|
riscv011_info_t *info = get_info(target);
|
||||||
/* TODO: Maybe what I implemented here is more like soft_reset_halt()? */
|
/* TODO: Maybe what I implemented here is more like soft_reset_halt()? */
|
||||||
|
|
||||||
|
@ -1949,9 +1951,9 @@ static int assert_reset(struct target *target)
|
||||||
|
|
||||||
/* Not sure what we should do when there are multiple cores.
|
/* Not sure what we should do when there are multiple cores.
|
||||||
* Here just reset the single hart we're talking to. */
|
* Here just reset the single hart we're talking to. */
|
||||||
info->dcsr = set_field(info->dcsr, DCSR_EBREAKM, riscv_ebreakm);
|
info->dcsr = set_field(info->dcsr, DCSR_EBREAKM, r->riscv_ebreakm);
|
||||||
info->dcsr = set_field(info->dcsr, DCSR_EBREAKS, riscv_ebreaks);
|
info->dcsr = set_field(info->dcsr, DCSR_EBREAKS, r->riscv_ebreaks);
|
||||||
info->dcsr = set_field(info->dcsr, DCSR_EBREAKU, riscv_ebreaku);
|
info->dcsr = set_field(info->dcsr, DCSR_EBREAKU, r->riscv_ebreaku);
|
||||||
info->dcsr = set_field(info->dcsr, DCSR_EBREAKH, 1);
|
info->dcsr = set_field(info->dcsr, DCSR_EBREAKH, 1);
|
||||||
info->dcsr |= DCSR_HALT;
|
info->dcsr |= DCSR_HALT;
|
||||||
if (target->reset_halt)
|
if (target->reset_halt)
|
||||||
|
|
|
@ -1721,6 +1721,7 @@ static int set_dcsr_ebreak(struct target *target, bool step)
|
||||||
if (dm013_select_target(target) != ERROR_OK)
|
if (dm013_select_target(target) != ERROR_OK)
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
|
|
||||||
|
RISCV_INFO(r);
|
||||||
RISCV013_INFO(info);
|
RISCV013_INFO(info);
|
||||||
riscv_reg_t original_dcsr, dcsr;
|
riscv_reg_t original_dcsr, dcsr;
|
||||||
/* We want to twiddle some bits in the debug CSR so debugging works. */
|
/* We want to twiddle some bits in the debug CSR so debugging works. */
|
||||||
|
@ -1728,11 +1729,11 @@ static int set_dcsr_ebreak(struct target *target, bool step)
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
original_dcsr = dcsr;
|
original_dcsr = dcsr;
|
||||||
dcsr = set_field(dcsr, CSR_DCSR_STEP, step);
|
dcsr = set_field(dcsr, CSR_DCSR_STEP, step);
|
||||||
dcsr = set_field(dcsr, CSR_DCSR_EBREAKM, riscv_ebreakm);
|
dcsr = set_field(dcsr, CSR_DCSR_EBREAKM, r->riscv_ebreakm);
|
||||||
dcsr = set_field(dcsr, CSR_DCSR_EBREAKS, riscv_ebreaks && riscv_supports_extension(target, 'S'));
|
dcsr = set_field(dcsr, CSR_DCSR_EBREAKS, r->riscv_ebreaks && riscv_supports_extension(target, 'S'));
|
||||||
dcsr = set_field(dcsr, CSR_DCSR_EBREAKU, riscv_ebreaku && riscv_supports_extension(target, 'U'));
|
dcsr = set_field(dcsr, CSR_DCSR_EBREAKU, r->riscv_ebreaku && riscv_supports_extension(target, 'U'));
|
||||||
dcsr = set_field(dcsr, CSR_DCSR_EBREAKVS, riscv_ebreaku && riscv_supports_extension(target, 'H'));
|
dcsr = set_field(dcsr, CSR_DCSR_EBREAKVS, r->riscv_ebreaku && riscv_supports_extension(target, 'H'));
|
||||||
dcsr = set_field(dcsr, CSR_DCSR_EBREAKVU, riscv_ebreaku && riscv_supports_extension(target, 'H'));
|
dcsr = set_field(dcsr, CSR_DCSR_EBREAKVU, r->riscv_ebreaku && riscv_supports_extension(target, 'H'));
|
||||||
if (dcsr != original_dcsr &&
|
if (dcsr != original_dcsr &&
|
||||||
riscv_set_register(target, GDB_REGNO_DCSR, dcsr) != ERROR_OK)
|
riscv_set_register(target, GDB_REGNO_DCSR, dcsr) != ERROR_OK)
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
|
|
|
@ -135,9 +135,6 @@ int riscv_command_timeout_sec = DEFAULT_COMMAND_TIMEOUT_SEC;
|
||||||
int riscv_reset_timeout_sec = DEFAULT_RESET_TIMEOUT_SEC;
|
int riscv_reset_timeout_sec = DEFAULT_RESET_TIMEOUT_SEC;
|
||||||
|
|
||||||
static bool riscv_enable_virt2phys = true;
|
static bool riscv_enable_virt2phys = true;
|
||||||
bool riscv_ebreakm = true;
|
|
||||||
bool riscv_ebreaks = true;
|
|
||||||
bool riscv_ebreaku = true;
|
|
||||||
|
|
||||||
bool riscv_enable_virtual;
|
bool riscv_enable_virtual;
|
||||||
|
|
||||||
|
@ -3748,32 +3745,53 @@ COMMAND_HANDLER(riscv_set_enable_virt2phys)
|
||||||
|
|
||||||
COMMAND_HANDLER(riscv_set_ebreakm)
|
COMMAND_HANDLER(riscv_set_ebreakm)
|
||||||
{
|
{
|
||||||
if (CMD_ARGC != 1) {
|
struct target *target = get_current_target(CMD_CTX);
|
||||||
LOG_ERROR("Command takes exactly 1 parameter");
|
RISCV_INFO(r);
|
||||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
|
||||||
|
if (CMD_ARGC == 0) {
|
||||||
|
command_print(CMD, "riscv_ebreakm enabled: %s", r->riscv_ebreakm ? "on" : "off");
|
||||||
|
return ERROR_OK;
|
||||||
|
} else if (CMD_ARGC == 1) {
|
||||||
|
COMMAND_PARSE_ON_OFF(CMD_ARGV[0], r->riscv_ebreakm);
|
||||||
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
COMMAND_PARSE_ON_OFF(CMD_ARGV[0], riscv_ebreakm);
|
|
||||||
return ERROR_OK;
|
LOG_ERROR("Command takes 0 or 1 parameters");
|
||||||
|
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
COMMAND_HANDLER(riscv_set_ebreaks)
|
COMMAND_HANDLER(riscv_set_ebreaks)
|
||||||
{
|
{
|
||||||
if (CMD_ARGC != 1) {
|
struct target *target = get_current_target(CMD_CTX);
|
||||||
LOG_ERROR("Command takes exactly 1 parameter");
|
RISCV_INFO(r);
|
||||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
|
||||||
|
if (CMD_ARGC == 0) {
|
||||||
|
command_print(CMD, "riscv_ebreaks enabled: %s", r->riscv_ebreaks ? "on" : "off");
|
||||||
|
return ERROR_OK;
|
||||||
|
} else if (CMD_ARGC == 1) {
|
||||||
|
COMMAND_PARSE_ON_OFF(CMD_ARGV[0], r->riscv_ebreaks);
|
||||||
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
COMMAND_PARSE_ON_OFF(CMD_ARGV[0], riscv_ebreaks);
|
|
||||||
return ERROR_OK;
|
LOG_ERROR("Command takes 0 or 1 parameters");
|
||||||
|
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
COMMAND_HANDLER(riscv_set_ebreaku)
|
COMMAND_HANDLER(riscv_set_ebreaku)
|
||||||
{
|
{
|
||||||
if (CMD_ARGC != 1) {
|
struct target *target = get_current_target(CMD_CTX);
|
||||||
LOG_ERROR("Command takes exactly 1 parameter");
|
RISCV_INFO(r);
|
||||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
|
||||||
|
if (CMD_ARGC == 0) {
|
||||||
|
command_print(CMD, "riscv_ebreaku enabled: %s", r->riscv_ebreaku ? "on" : "off");
|
||||||
|
return ERROR_OK;
|
||||||
|
} else if (CMD_ARGC == 1) {
|
||||||
|
COMMAND_PARSE_ON_OFF(CMD_ARGV[0], r->riscv_ebreaku);
|
||||||
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
COMMAND_PARSE_ON_OFF(CMD_ARGV[0], riscv_ebreaku);
|
|
||||||
return ERROR_OK;
|
LOG_ERROR("Command takes 0 or 1 parameters");
|
||||||
|
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
COMMAND_HELPER(riscv_clear_trigger, int trigger_id, const char *name)
|
COMMAND_HELPER(riscv_clear_trigger, int trigger_id, const char *name)
|
||||||
|
@ -4452,7 +4470,7 @@ static const struct command_registration riscv_exec_command_handlers[] = {
|
||||||
.name = "set_ebreakm",
|
.name = "set_ebreakm",
|
||||||
.handler = riscv_set_ebreakm,
|
.handler = riscv_set_ebreakm,
|
||||||
.mode = COMMAND_ANY,
|
.mode = COMMAND_ANY,
|
||||||
.usage = "on|off",
|
.usage = "[on|off]",
|
||||||
.help = "Control dcsr.ebreakm. When off, M-mode ebreak instructions "
|
.help = "Control dcsr.ebreakm. When off, M-mode ebreak instructions "
|
||||||
"don't trap to OpenOCD. Defaults to on."
|
"don't trap to OpenOCD. Defaults to on."
|
||||||
},
|
},
|
||||||
|
@ -4460,7 +4478,7 @@ static const struct command_registration riscv_exec_command_handlers[] = {
|
||||||
.name = "set_ebreaks",
|
.name = "set_ebreaks",
|
||||||
.handler = riscv_set_ebreaks,
|
.handler = riscv_set_ebreaks,
|
||||||
.mode = COMMAND_ANY,
|
.mode = COMMAND_ANY,
|
||||||
.usage = "on|off",
|
.usage = "[on|off]",
|
||||||
.help = "Control dcsr.ebreaks. When off, S-mode ebreak instructions "
|
.help = "Control dcsr.ebreaks. When off, S-mode ebreak instructions "
|
||||||
"don't trap to OpenOCD. Defaults to on."
|
"don't trap to OpenOCD. Defaults to on."
|
||||||
},
|
},
|
||||||
|
@ -4468,7 +4486,7 @@ static const struct command_registration riscv_exec_command_handlers[] = {
|
||||||
.name = "set_ebreaku",
|
.name = "set_ebreaku",
|
||||||
.handler = riscv_set_ebreaku,
|
.handler = riscv_set_ebreaku,
|
||||||
.mode = COMMAND_ANY,
|
.mode = COMMAND_ANY,
|
||||||
.usage = "on|off",
|
.usage = "[on|off]",
|
||||||
.help = "Control dcsr.ebreaku. When off, U-mode ebreak instructions "
|
.help = "Control dcsr.ebreaku. When off, U-mode ebreak instructions "
|
||||||
"don't trap to OpenOCD. Defaults to on."
|
"don't trap to OpenOCD. Defaults to on."
|
||||||
},
|
},
|
||||||
|
@ -4632,6 +4650,10 @@ static void riscv_info_init(struct target *target, struct riscv_info *r)
|
||||||
INIT_LIST_HEAD(&r->hide_csr);
|
INIT_LIST_HEAD(&r->hide_csr);
|
||||||
|
|
||||||
r->vsew64_supported = YNM_MAYBE;
|
r->vsew64_supported = YNM_MAYBE;
|
||||||
|
|
||||||
|
r->riscv_ebreakm = true;
|
||||||
|
r->riscv_ebreaks = true;
|
||||||
|
r->riscv_ebreaku = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int riscv_resume_go_all_harts(struct target *target)
|
static int riscv_resume_go_all_harts(struct target *target)
|
||||||
|
|
|
@ -297,6 +297,10 @@ struct riscv_info {
|
||||||
yes_no_maybe_t vsew64_supported;
|
yes_no_maybe_t vsew64_supported;
|
||||||
|
|
||||||
bool range_trigger_fallback_encountered;
|
bool range_trigger_fallback_encountered;
|
||||||
|
|
||||||
|
bool riscv_ebreakm;
|
||||||
|
bool riscv_ebreaks;
|
||||||
|
bool riscv_ebreaku;
|
||||||
};
|
};
|
||||||
|
|
||||||
COMMAND_HELPER(riscv_print_info_line, const char *section, const char *key,
|
COMMAND_HELPER(riscv_print_info_line, const char *section, const char *key,
|
||||||
|
@ -328,9 +332,6 @@ extern int riscv_command_timeout_sec;
|
||||||
extern int riscv_reset_timeout_sec;
|
extern int riscv_reset_timeout_sec;
|
||||||
|
|
||||||
extern bool riscv_enable_virtual;
|
extern bool riscv_enable_virtual;
|
||||||
extern bool riscv_ebreakm;
|
|
||||||
extern bool riscv_ebreaks;
|
|
||||||
extern bool riscv_ebreaku;
|
|
||||||
|
|
||||||
/* Everything needs the RISC-V specific info structure, so here's a nice macro
|
/* Everything needs the RISC-V specific info structure, so here's a nice macro
|
||||||
* that provides that. */
|
* that provides that. */
|
||||||
|
|
Loading…
Reference in New Issue