Skip to content

Commit d1d2b0a

Browse files
committed
target/riscv: add cetrig control
Introduce RISC-V-sepecific `configure` parameter `-cetrig`
1 parent 6a30484 commit d1d2b0a

File tree

4 files changed

+79
-15
lines changed

4 files changed

+79
-15
lines changed

doc/openocd.texi

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11437,6 +11437,13 @@ action pairs.
1143711437
@end itemize
1143811438
@end itemize
1143911439

11440+
@itemize
11441+
@item @code{-cetrig} @option{disable}|@option{enable} -- sets the @code{cetrig}
11442+
field for dcsr. Defaults to @option{disable}.
11443+
11444+
@item @code{cget} return a @code{cetrig} state.
11445+
@end itemize
11446+
1144011447
@subsection RISC-V Debug Configuration Commands
1144111448

1144211449
@deffn {Command} {riscv dump_sample_buf} [base64]

src/target/riscv/riscv-013.c

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,9 @@ typedef struct {
251251
/* This target was selected using hasel. */
252252
bool selected;
253253

254-
/* When false, we need to set dcsr.ebreak*, halting the target if that's
254+
/* When false, we need to set dcsr config, halting the target if that's
255255
* necessary. */
256-
bool dcsr_ebreak_is_set;
256+
bool dcsr_config_is_set;
257257

258258
/* This hart was placed into a halt group in examine(). */
259259
bool haltgroup_supported;
@@ -1674,7 +1674,7 @@ static int wait_for_authbusy(struct target *target, uint32_t *dmstatus)
16741674
return ERROR_OK;
16751675
}
16761676

1677-
static int set_dcsr_ebreak(struct target *target, bool step)
1677+
static int set_dcsr_config(struct target *target, bool step)
16781678
{
16791679
LOG_TARGET_DEBUG(target, "Set dcsr.ebreak*");
16801680

@@ -1694,14 +1694,15 @@ static int set_dcsr_ebreak(struct target *target, bool step)
16941694
dcsr = set_field(dcsr, CSR_DCSR_EBREAKU, config->dcsr_ebreak_fields[RISCV_MODE_U]);
16951695
dcsr = set_field(dcsr, CSR_DCSR_EBREAKVS, config->dcsr_ebreak_fields[RISCV_MODE_VS]);
16961696
dcsr = set_field(dcsr, CSR_DCSR_EBREAKVU, config->dcsr_ebreak_fields[RISCV_MODE_VU]);
1697+
dcsr = set_field(dcsr, CSR_DCSR_CETRIG, config->dcsr_cetrig);
16971698
if (dcsr != original_dcsr &&
16981699
riscv_reg_set(target, GDB_REGNO_DCSR, dcsr) != ERROR_OK)
16991700
return ERROR_FAIL;
1700-
info->dcsr_ebreak_is_set = true;
1701+
info->dcsr_config_is_set = true;
17011702
return ERROR_OK;
17021703
}
17031704

1704-
static int halt_set_dcsr_ebreak(struct target *target)
1705+
static int halt_set_dcsr_config(struct target *target)
17051706
{
17061707
RISCV_INFO(r);
17071708
RISCV013_INFO(info);
@@ -1743,7 +1744,7 @@ static int halt_set_dcsr_ebreak(struct target *target)
17431744

17441745
r->prepped = true;
17451746
if (riscv013_halt_go(target) != ERROR_OK ||
1746-
set_dcsr_ebreak(target, false) != ERROR_OK ||
1747+
set_dcsr_config(target, false) != ERROR_OK ||
17471748
riscv013_step_or_resume_current_hart(target, false) != ERROR_OK) {
17481749
result = ERROR_FAIL;
17491750
} else {
@@ -2132,7 +2133,7 @@ static int examine(struct target *target)
21322133
if (result != ERROR_OK)
21332134
return result;
21342135

2135-
if (set_dcsr_ebreak(target, false) != ERROR_OK)
2136+
if (set_dcsr_config(target, false) != ERROR_OK)
21362137
return ERROR_FAIL;
21372138

21382139
if (state_at_examine_start == RISCV_STATE_RUNNING) {
@@ -2779,7 +2780,7 @@ static int riscv013_get_hart_state(struct target *target, enum riscv_hart_state
27792780
return ERROR_FAIL;
27802781
if (get_field(dmstatus, DM_DMSTATUS_ANYHAVERESET)) {
27812782
LOG_TARGET_INFO(target, "Hart unexpectedly reset!");
2782-
info->dcsr_ebreak_is_set = false;
2783+
info->dcsr_config_is_set = false;
27832784
/* TODO: Can we make this more obvious to eg. a gdb user? */
27842785
uint32_t dmcontrol = DM_DMCONTROL_DMACTIVE |
27852786
DM_DMCONTROL_ACKHAVERESET;
@@ -2830,17 +2831,17 @@ static int handle_became_unavailable(struct target *target,
28302831

28312832
riscv_reg_cache_invalidate_all(target);
28322833

2833-
info->dcsr_ebreak_is_set = false;
2834+
info->dcsr_config_is_set = false;
28342835
return ERROR_OK;
28352836
}
28362837

28372838
static int tick(struct target *target)
28382839
{
28392840
RISCV013_INFO(info);
2840-
if (!info->dcsr_ebreak_is_set &&
2841+
if (!info->dcsr_config_is_set &&
28412842
target->state == TARGET_RUNNING &&
28422843
target_was_examined(target))
2843-
return halt_set_dcsr_ebreak(target);
2844+
return halt_set_dcsr_config(target);
28442845
return ERROR_OK;
28452846
}
28462847

@@ -2939,13 +2940,13 @@ static int assert_reset(struct target *target)
29392940
return riscv013_invalidate_cached_progbuf(target);
29402941
}
29412942

2942-
static bool dcsr_ebreak_config_equals_reset_value(const struct target *target)
2943+
static bool dcsr_config_equals_reset_value(const struct target *target)
29432944
{
29442945
const struct riscv_private_config * const config = riscv_private_config(target);
29452946
for (int i = 0; i < N_RISCV_MODE; ++i)
29462947
if (config->dcsr_ebreak_fields[i])
29472948
return false;
2948-
return true;
2949+
return !config->dcsr_cetrig;
29492950
}
29502951

29512952
static int deassert_reset(struct target *target)
@@ -3023,7 +3024,7 @@ static int deassert_reset(struct target *target)
30233024
target->state = TARGET_RUNNING;
30243025
target->debug_reason = DBG_REASON_NOTHALTED;
30253026
}
3026-
info->dcsr_ebreak_is_set = dcsr_ebreak_config_equals_reset_value(target);
3027+
info->dcsr_config_is_set = dcsr_config_equals_reset_value(target);
30273028
return ERROR_OK;
30283029
}
30293030

@@ -5367,6 +5368,14 @@ static enum riscv_halt_reason riscv013_halt_reason(struct target *target)
53675368
return RISCV_HALT_INTERRUPT;
53685369
case CSR_DCSR_CAUSE_GROUP:
53695370
return RISCV_HALT_GROUP;
5371+
case CSR_DCSR_CAUSE_OTHER:
5372+
if (get_field(dcsr, CSR_DCSR_EXTCAUSE) == 0) {
5373+
LOG_TARGET_INFO(target, "halted because of hart in a critical error state.");
5374+
return RISCV_HALT_CRITERR;
5375+
}
5376+
LOG_TARGET_ERROR(target, "Unknown DCSR extcause field: 0x%"
5377+
PRIx64, get_field(dcsr, CSR_DCSR_EXTCAUSE));
5378+
return RISCV_HALT_UNKNOWN;
53705379
}
53715380

53725381
LOG_TARGET_ERROR(target, "Unknown DCSR cause field: 0x%" PRIx64, get_field(dcsr, CSR_DCSR_CAUSE));
@@ -5462,7 +5471,7 @@ static int riscv013_on_step_or_resume(struct target *target, bool step)
54625471
if (execute_autofence(target) != ERROR_OK)
54635472
return ERROR_FAIL;
54645473

5465-
if (set_dcsr_ebreak(target, step) != ERROR_OK)
5474+
if (set_dcsr_config(target, step) != ERROR_OK)
54665475
return ERROR_FAIL;
54675476

54685477
if (riscv_reg_flush_all(target) != ERROR_OK)

src/target/riscv/riscv.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,8 @@ static struct riscv_private_config *alloc_default_riscv_private_config(void)
486486
for (unsigned int i = 0; i < ARRAY_SIZE(config->dcsr_ebreak_fields); ++i)
487487
config->dcsr_ebreak_fields[i] = true;
488488

489+
config->dcsr_cetrig = true;
490+
489491
return config;
490492
}
491493

@@ -525,6 +527,15 @@ static struct jim_nvp nvp_ebreak_mode_opts[] = {
525527
{ .name = NULL, .value = RISCV_EBREAK_MODE_INVALID }
526528
};
527529

530+
531+
#define RISCV_CETRIG_INVALID -1
532+
533+
static struct jim_nvp nvp_cetrig_opts[] = {
534+
{ .name = "disable", .value = false },
535+
{ .name = "enable", .value = true },
536+
{ .name = NULL, .value = RISCV_CETRIG_INVALID }
537+
};
538+
528539
static int jim_configure_ebreak(struct riscv_private_config *config, struct jim_getopt_info *goi)
529540
{
530541
if (goi->argc == 0) {
@@ -611,13 +622,43 @@ static int jim_report_ebreak_config(const struct riscv_private_config *config,
611622
return JIM_OK;
612623
}
613624

625+
static int jim_configure_cetrig(struct riscv_private_config *config,
626+
struct jim_getopt_info *goi)
627+
{
628+
if (goi->argc == 0) {
629+
Jim_WrongNumArgs(goi->interp, 1, goi->argv - 1,
630+
"?disable|enable?");
631+
return JIM_ERR;
632+
}
633+
634+
/* Here a dcsr field is processed, e.g: riscv.cpu configure -mprven enable" */
635+
struct jim_nvp *opt_nvp;
636+
if (jim_getopt_nvp(goi, nvp_cetrig_opts, &opt_nvp) != JIM_OK) {
637+
jim_getopt_nvp_unknown(goi, nvp_cetrig_opts, /*hadprefix*/ true);
638+
return JIM_ERR;
639+
}
640+
config->dcsr_cetrig = opt_nvp->value;
641+
return JIM_OK;
642+
}
643+
644+
static int jim_report_cetrig_config(const struct riscv_private_config *config,
645+
Jim_Interp *interp)
646+
{
647+
const char * cetrig_opt = jim_nvp_value2name_simple(nvp_cetrig_opts,
648+
config->dcsr_cetrig)->name;
649+
Jim_SetResultString(interp, cetrig_opt, strlen(cetrig_opt));
650+
return JIM_OK;
651+
}
652+
614653
enum riscv_cfg_opts {
615654
RISCV_CFG_EBREAK,
655+
RISCV_CFG_CETRIG,
616656
RISCV_CFG_INVALID = -1
617657
};
618658

619659
static struct jim_nvp nvp_config_opts[] = {
620660
{ .name = "-ebreak", .value = RISCV_CFG_EBREAK },
661+
{ .name = "-cetrig", .value = RISCV_CFG_CETRIG },
621662
{ .name = NULL, .value = RISCV_CFG_INVALID }
622663
};
623664

@@ -654,6 +695,10 @@ static int riscv_jim_configure(struct target *target,
654695
return goi->is_configure
655696
? jim_configure_ebreak(config, goi)
656697
: jim_report_ebreak_config(config, goi->interp);
698+
case RISCV_CFG_CETRIG:
699+
return goi->is_configure
700+
? jim_configure_cetrig(config, goi)
701+
: jim_report_cetrig_config(config, goi->interp);
657702
default:
658703
assert(false && "'jim_getopt_nvp' should have returned an error.");
659704
}
@@ -2617,6 +2662,7 @@ static int set_debug_reason(struct target *target, enum riscv_halt_reason halt_r
26172662
break;
26182663
case RISCV_HALT_INTERRUPT:
26192664
case RISCV_HALT_GROUP:
2665+
case RISCV_HALT_CRITERR:
26202666
target->debug_reason = DBG_REASON_DBGRQ;
26212667
break;
26222668
case RISCV_HALT_SINGLESTEP:

src/target/riscv/riscv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ enum riscv_halt_reason {
7575
RISCV_HALT_TRIGGER,
7676
RISCV_HALT_UNKNOWN,
7777
RISCV_HALT_GROUP,
78+
RISCV_HALT_CRITERR,
7879
RISCV_HALT_ERROR
7980
};
8081

@@ -378,6 +379,7 @@ enum riscv_priv_mode {
378379

379380
struct riscv_private_config {
380381
bool dcsr_ebreak_fields[N_RISCV_MODE];
382+
bool dcsr_cetrig;
381383
};
382384

383385
static inline struct riscv_private_config

0 commit comments

Comments
 (0)