Determine the trigger count dynamically

This commit is contained in:
Palmer Dabbelt 2017-04-07 15:26:24 -07:00
parent dd4677c3df
commit a4d3a8d415
3 changed files with 39 additions and 9 deletions

View File

@ -139,8 +139,6 @@ typedef struct {
// unique_id of the breakpoint/watchpoint that is using it.
int trigger_unique_id[MAX_HWBPS];
unsigned int trigger_count;
// Number of run-test/idle cycles the target requests we do after each dbus
// access.
unsigned int dtmcontrol_idle;
@ -929,11 +927,12 @@ static void deinit_target(struct target *target)
static int add_trigger(struct target *target, struct trigger *trigger)
{
riscv013_info_t *info = get_info(target);
RISCV_INFO(r);
maybe_read_tselect(target);
unsigned int i;
for (i = 0; i < info->trigger_count; i++) {
for (i = 0; i < riscv_count_triggers(target); i++) {
if (info->trigger_unique_id[i] != -1) {
continue;
}
@ -994,7 +993,7 @@ static int add_trigger(struct target *target, struct trigger *trigger)
info->trigger_unique_id[i] = trigger->unique_id;
break;
}
if (i >= info->trigger_count) {
if (i >= riscv_count_triggers(target)) {
LOG_ERROR("Couldn't find an available hardware trigger.");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
@ -1009,12 +1008,12 @@ static int remove_trigger(struct target *target, struct trigger *trigger)
maybe_read_tselect(target);
unsigned int i;
for (i = 0; i < info->trigger_count; i++) {
for (i = 0; i < riscv_count_triggers(target); i++) {
if (info->trigger_unique_id[i] == trigger->unique_id) {
break;
}
}
if (i >= info->trigger_count) {
if (i >= riscv_count_triggers(target)) {
LOG_ERROR("Couldn't find the hardware resources used by hardware "
"trigger.");
return ERROR_FAIL;
@ -1239,7 +1238,6 @@ static int examine(struct target *target)
/* Examines every hart, first checking XLEN. */
for (int i = 0; i < riscv_count_harts(target); ++i) {
RISCV_INFO(r);
riscv_set_current_hartid(target, i);
if (abstract_read_register(target, NULL, S0, 128) == ERROR_OK) {
@ -1254,8 +1252,19 @@ static int examine(struct target *target)
}
}
/* FIXME: Are there 2 triggers? */
info->trigger_count = 2;
/* Then we check the number of triggers availiable to each hart. */
for (int i = 0; i < riscv_count_harts(target); ++i) {
for (int t = 0; t < RISCV_MAX_TRIGGERS; ++t) {
riscv_set_current_hartid(target, i);
r->trigger_count[i] = t;
register_write_direct(target, GDB_REGNO_TSELECT, t);
uint64_t tselect = t+1;
register_read_direct(target, &tselect, GDB_REGNO_TSELECT);
if (tselect != t)
break;
}
}
/* Resumes all the harts, so the debugger can later pause them. */
riscv_resume_all_harts(target);

View File

@ -1008,3 +1008,15 @@ enum riscv_halt_reason riscv_halt_reason(struct target *target, int hartid)
assert(riscv_is_halted(target));
return r->halt_reason(target);
}
int riscv_count_triggers(struct target *target)
{
return riscv_count_triggers_of_hart(target, riscv_current_hartid(target));
}
int riscv_count_triggers_of_hart(struct target *target, int hartid)
{
RISCV_INFO(r);
assert(hartid < riscv_count_harts(target));
return r->trigger_count[hartid];
}

View File

@ -7,6 +7,7 @@
/* The register cache is staticly allocated. */
#define RISCV_MAX_HARTS 32
#define RISCV_MAX_REGISTERS 5000
#define RISCV_MAX_TRIGGERS 32
extern struct target_type riscv011_target;
extern struct target_type riscv013_target;
@ -64,6 +65,9 @@ typedef struct {
/* The state of every hart. */
enum riscv_hart_state hart_state[RISCV_MAX_HARTS];
/* The number of triggers per hart. */
int trigger_count[RISCV_MAX_HARTS];
/* Helper functions that target the various RISC-V debug spec
* implementations. */
riscv_reg_t (*get_register)(struct target *, int, int);
@ -177,4 +181,9 @@ bool riscv_is_halted(struct target *target);
bool riscv_was_halted(struct target *target);
enum riscv_halt_reason riscv_halt_reason(struct target *target, int hartid);
/* Returns the number of triggers availiable to either the current hart or to
* the given hart. */
int riscv_count_triggers(struct target *target);
int riscv_count_triggers_of_hart(struct target *target, int hartid);
#endif