Skip to content

Commit

Permalink
target/riscv: cleanup riscv_enumerate_triggers()
Browse files Browse the repository at this point in the history
1. Propagate error codes.
2. Disable leftover triggers in case `tinfo` is supported.

Change-Id: Ie20edb4d8b9245e13ac8757bf6afe549ac99c4f1
Signed-off-by: Evgeniy Naydanov <[email protected]>
  • Loading branch information
en-sc committed Aug 25, 2023
1 parent 928f2b3 commit 4069033
Showing 1 changed file with 55 additions and 50 deletions.
105 changes: 55 additions & 50 deletions src/target/riscv/riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -4179,10 +4179,10 @@ COMMAND_HANDLER(handle_info)
/* This output format can be fed directly into TCL's "array set". */

riscv_print_info_line(CMD, "hart", "xlen", riscv_xlen(target));
riscv_enumerate_triggers(target);
riscv_print_info_line(CMD, "hart", "trigger_count",
r->trigger_count);

if (riscv_enumerate_triggers(target) == ERROR_OK)
riscv_print_info_line(CMD, "hart", "trigger_count",
r->trigger_count);
if (r->print_info)
return CALL_COMMAND_HANDLER(r->print_info, target);

Expand Down Expand Up @@ -5043,8 +5043,6 @@ int riscv_enumerate_triggers(struct target *target)
if (r->triggers_enumerated)
return ERROR_OK;

r->triggers_enumerated = true; /* At the very least we tried. */

riscv_reg_t tselect;
int result = riscv_get_register(target, &tselect, GDB_REGNO_TSELECT);
/* If tselect is not readable, the trigger module is likely not
Expand All @@ -5057,13 +5055,14 @@ int riscv_enumerate_triggers(struct target *target)
return ERROR_OK;
}

for (unsigned int t = 0; t < RISCV_MAX_TRIGGERS; ++t) {
r->trigger_count = t;
unsigned int t = 0;
unsigned int trigger_tinfo[ARRAY_SIZE(r->trigger_tinfo)];
for (; t < ARRAY_SIZE(r->trigger_tinfo); ++t) {

/* If we can't write tselect, then this hart does not support triggers. */
if (riscv_set_register(target, GDB_REGNO_TSELECT, t) != ERROR_OK)
break;
uint64_t tselect_rb;
riscv_reg_t tselect_rb;
result = riscv_get_register(target, &tselect_rb, GDB_REGNO_TSELECT);
if (result != ERROR_OK)
return result;
Expand All @@ -5073,59 +5072,65 @@ int riscv_enumerate_triggers(struct target *target)
if (tselect_rb != t)
break;

uint64_t tinfo;
result = riscv_get_register(target, &tinfo, GDB_REGNO_TINFO);
if (result == ERROR_OK) {
riscv_reg_t tinfo;
const bool may_support_multiple_trigger_types =
riscv_get_register(target, &tinfo, GDB_REGNO_TINFO) == ERROR_OK;
if (may_support_multiple_trigger_types) {
/* tinfo == 0 invalid tinfo
* tinfo == 1 trigger doesn’t exist */
if (tinfo == 0 || tinfo == 1)
break;
r->trigger_tinfo[t] = tinfo;
} else {
uint64_t tdata1;
result = riscv_get_register(target, &tdata1, GDB_REGNO_TDATA1);
if (result != ERROR_OK)
return result;
trigger_tinfo[t] = tinfo;
}

int type = get_field(tdata1, CSR_TDATA1_TYPE(riscv_xlen(target)));
riscv_reg_t tdata1;
if (riscv_get_register(target, &tdata1, GDB_REGNO_TDATA1) != ERROR_OK)
return ERROR_FAIL;

const int type = get_field(tdata1, CSR_TDATA1_TYPE(riscv_xlen(target)));
if (!may_support_multiple_trigger_types) {
if (type == 0)
break;
switch (type) {
case CSR_TDATA1_TYPE_LEGACY:
/* On these older cores we don't support software using
* triggers. */
riscv_set_register(target, GDB_REGNO_TDATA1, 0);
break;
case CSR_TDATA1_TYPE_MCONTROL:
if (tdata1 & CSR_MCONTROL_DMODE(riscv_xlen(target)))
riscv_set_register(target, GDB_REGNO_TDATA1, 0);
break;
case CSR_TDATA1_TYPE_MCONTROL6:
if (tdata1 & CSR_MCONTROL6_DMODE(riscv_xlen(target)))
riscv_set_register(target, GDB_REGNO_TDATA1, 0);
break;
case CSR_TDATA1_TYPE_ICOUNT:
if (tdata1 & CSR_ICOUNT_DMODE(riscv_xlen(target)))
riscv_set_register(target, GDB_REGNO_TDATA1, 0);
break;
case CSR_TDATA1_TYPE_ITRIGGER:
if (tdata1 & CSR_ITRIGGER_DMODE(riscv_xlen(target)))
riscv_set_register(target, GDB_REGNO_TDATA1, 0);
break;
case CSR_TDATA1_TYPE_ETRIGGER:
if (tdata1 & CSR_ETRIGGER_DMODE(riscv_xlen(target)))
riscv_set_register(target, GDB_REGNO_TDATA1, 0);
break;
}
r->trigger_tinfo[t] = 1 << type;
trigger_tinfo[t] = 1 << type;
}
LOG_TARGET_DEBUG(target, "Trigger %u: supported types (mask) = 0x%08x", t, r->trigger_tinfo[t]);
}
/* Disable leftover triggers */
bool is_leftover;
switch (type) {
case CSR_TDATA1_TYPE_LEGACY:
/* On these older cores we don't support software using
* triggers. */
is_leftover = true;
break;
case CSR_TDATA1_TYPE_MCONTROL:
is_leftover = tdata1 & CSR_MCONTROL_DMODE(riscv_xlen(target));
break;
case CSR_TDATA1_TYPE_MCONTROL6:
is_leftover = tdata1 & CSR_MCONTROL6_DMODE(riscv_xlen(target));
break;
case CSR_TDATA1_TYPE_ICOUNT:
is_leftover = tdata1 & CSR_ICOUNT_DMODE(riscv_xlen(target));
break;
case CSR_TDATA1_TYPE_ITRIGGER:
is_leftover = tdata1 & CSR_ITRIGGER_DMODE(riscv_xlen(target));
break;
case CSR_TDATA1_TYPE_ETRIGGER:
is_leftover = tdata1 & CSR_ETRIGGER_DMODE(riscv_xlen(target));
break;
}
if (is_leftover && riscv_set_register(target, GDB_REGNO_TDATA1, 0) != ERROR_OK)
return ERROR_FAIL;

riscv_set_register(target, GDB_REGNO_TSELECT, tselect);
LOG_TARGET_DEBUG(target, "Trigger %u: supported types (mask) = 0x%08x",
t, trigger_tinfo[t]);
}

LOG_TARGET_INFO(target, "Found %d triggers.", r->trigger_count);
if (riscv_set_register(target, GDB_REGNO_TSELECT, tselect) != ERROR_OK)
return ERROR_FAIL;

r->triggers_enumerated = true;
r->trigger_count = t + 1;
LOG_TARGET_INFO(target, "Found %d triggers", r->trigger_count);
memcpy(r->trigger_tinfo, trigger_tinfo, r->trigger_count);
return ERROR_OK;
}

Expand Down

0 comments on commit 4069033

Please sign in to comment.