Determine the trigger count dynamically
This commit is contained in:
parent
dd4677c3df
commit
a4d3a8d415
|
@ -139,8 +139,6 @@ typedef struct {
|
||||||
// unique_id of the breakpoint/watchpoint that is using it.
|
// unique_id of the breakpoint/watchpoint that is using it.
|
||||||
int trigger_unique_id[MAX_HWBPS];
|
int trigger_unique_id[MAX_HWBPS];
|
||||||
|
|
||||||
unsigned int trigger_count;
|
|
||||||
|
|
||||||
// Number of run-test/idle cycles the target requests we do after each dbus
|
// Number of run-test/idle cycles the target requests we do after each dbus
|
||||||
// access.
|
// access.
|
||||||
unsigned int dtmcontrol_idle;
|
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)
|
static int add_trigger(struct target *target, struct trigger *trigger)
|
||||||
{
|
{
|
||||||
riscv013_info_t *info = get_info(target);
|
riscv013_info_t *info = get_info(target);
|
||||||
|
RISCV_INFO(r);
|
||||||
|
|
||||||
maybe_read_tselect(target);
|
maybe_read_tselect(target);
|
||||||
|
|
||||||
unsigned int i;
|
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) {
|
if (info->trigger_unique_id[i] != -1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -994,7 +993,7 @@ static int add_trigger(struct target *target, struct trigger *trigger)
|
||||||
info->trigger_unique_id[i] = trigger->unique_id;
|
info->trigger_unique_id[i] = trigger->unique_id;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i >= info->trigger_count) {
|
if (i >= riscv_count_triggers(target)) {
|
||||||
LOG_ERROR("Couldn't find an available hardware trigger.");
|
LOG_ERROR("Couldn't find an available hardware trigger.");
|
||||||
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
|
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
@ -1009,12 +1008,12 @@ static int remove_trigger(struct target *target, struct trigger *trigger)
|
||||||
maybe_read_tselect(target);
|
maybe_read_tselect(target);
|
||||||
|
|
||||||
unsigned int i;
|
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) {
|
if (info->trigger_unique_id[i] == trigger->unique_id) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i >= info->trigger_count) {
|
if (i >= riscv_count_triggers(target)) {
|
||||||
LOG_ERROR("Couldn't find the hardware resources used by hardware "
|
LOG_ERROR("Couldn't find the hardware resources used by hardware "
|
||||||
"trigger.");
|
"trigger.");
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
|
@ -1239,7 +1238,6 @@ static int examine(struct target *target)
|
||||||
|
|
||||||
/* Examines every hart, first checking XLEN. */
|
/* Examines every hart, first checking XLEN. */
|
||||||
for (int i = 0; i < riscv_count_harts(target); ++i) {
|
for (int i = 0; i < riscv_count_harts(target); ++i) {
|
||||||
RISCV_INFO(r);
|
|
||||||
riscv_set_current_hartid(target, i);
|
riscv_set_current_hartid(target, i);
|
||||||
|
|
||||||
if (abstract_read_register(target, NULL, S0, 128) == ERROR_OK) {
|
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? */
|
/* Then we check the number of triggers availiable to each hart. */
|
||||||
info->trigger_count = 2;
|
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. */
|
/* Resumes all the harts, so the debugger can later pause them. */
|
||||||
riscv_resume_all_harts(target);
|
riscv_resume_all_harts(target);
|
||||||
|
|
|
@ -1008,3 +1008,15 @@ enum riscv_halt_reason riscv_halt_reason(struct target *target, int hartid)
|
||||||
assert(riscv_is_halted(target));
|
assert(riscv_is_halted(target));
|
||||||
return r->halt_reason(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];
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
/* The register cache is staticly allocated. */
|
/* The register cache is staticly allocated. */
|
||||||
#define RISCV_MAX_HARTS 32
|
#define RISCV_MAX_HARTS 32
|
||||||
#define RISCV_MAX_REGISTERS 5000
|
#define RISCV_MAX_REGISTERS 5000
|
||||||
|
#define RISCV_MAX_TRIGGERS 32
|
||||||
|
|
||||||
extern struct target_type riscv011_target;
|
extern struct target_type riscv011_target;
|
||||||
extern struct target_type riscv013_target;
|
extern struct target_type riscv013_target;
|
||||||
|
@ -64,6 +65,9 @@ typedef struct {
|
||||||
/* The state of every hart. */
|
/* The state of every hart. */
|
||||||
enum riscv_hart_state hart_state[RISCV_MAX_HARTS];
|
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
|
/* Helper functions that target the various RISC-V debug spec
|
||||||
* implementations. */
|
* implementations. */
|
||||||
riscv_reg_t (*get_register)(struct target *, int, int);
|
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);
|
bool riscv_was_halted(struct target *target);
|
||||||
enum riscv_halt_reason riscv_halt_reason(struct target *target, int hartid);
|
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
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue