Skip to content

Commit 4072fa4

Browse files
committed
Disable debugger-set triggers on connect
When first connecting to a target, have the debugger disable any hardware triggers that are set by a previously connected debugger. The 0.11 code already did this, but 0.13 did not. To achieve this I decided to share the code to enumerate triggers between 0.11 and 0.13, which required me to implement get_register() and set_register() for 0.11, which made the whole change a lot larger than you might have guessed. Hopefully this sets us up to in the future share the code to set/remove triggers as well.
1 parent 29b6271 commit 4072fa4

File tree

4 files changed

+135
-82
lines changed

4 files changed

+135
-82
lines changed

src/target/riscv/riscv-011.c

Lines changed: 74 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,6 @@ typedef struct {
216216
// unique_id of the breakpoint/watchpoint that is using it.
217217
int trigger_unique_id[MAX_HWBPS];
218218

219-
unsigned int trigger_count;
220-
221219
// Number of run-test/idle cycles the target requests we do after each dbus
222220
// access.
223221
unsigned int dtmcontrol_idle;
@@ -1045,7 +1043,7 @@ static int read_csr(struct target *target, uint64_t *value, uint32_t csr)
10451043

10461044
uint32_t exception = cache_get32(target, info->dramsize-1);
10471045
if (exception) {
1048-
LOG_ERROR("Got exception 0x%x when reading CSR 0x%x", exception, csr);
1046+
LOG_WARNING("Got exception 0x%x when reading CSR 0x%x", exception, csr);
10491047
*value = ~0;
10501048
return ERROR_FAIL;
10511049
}
@@ -1260,22 +1258,54 @@ static int update_mstatus_actual(struct target *target)
12601258

12611259
/*** OpenOCD target functions. ***/
12621260

1261+
static int register_read(struct target *target, riscv_reg_t *value, int regnum)
1262+
{
1263+
riscv011_info_t *info = get_info(target);
1264+
if (regnum >= REG_CSR0 && regnum <= REG_CSR4095) {
1265+
cache_set32(target, 0, csrr(S0, regnum - REG_CSR0));
1266+
cache_set_store(target, 1, S0, SLOT0);
1267+
cache_set_jump(target, 2);
1268+
} else {
1269+
LOG_ERROR("Don't know how to read register %d", regnum);
1270+
return ERROR_FAIL;
1271+
}
1272+
1273+
if (cache_write(target, 4, true) != ERROR_OK) {
1274+
return ERROR_FAIL;
1275+
}
1276+
1277+
uint32_t exception = cache_get32(target, info->dramsize-1);
1278+
if (exception) {
1279+
LOG_WARNING("Got exception 0x%x when reading register %d", exception,
1280+
regnum);
1281+
*value = ~0;
1282+
return ERROR_FAIL;
1283+
}
1284+
1285+
*value = cache_get(target, SLOT0);
1286+
LOG_DEBUG("reg[%d]=0x%" PRIx64, regnum, *value);
1287+
1288+
if (regnum == REG_MSTATUS) {
1289+
info->mstatus_actual = *value;
1290+
}
1291+
1292+
return ERROR_OK;
1293+
}
1294+
12631295
static int register_get(struct reg *reg)
12641296
{
12651297
struct target *target = (struct target *) reg->arch_info;
12661298
riscv011_info_t *info = get_info(target);
12671299

12681300
maybe_write_tselect(target);
1301+
riscv_reg_t value = ~0;
12691302

12701303
if (reg->number <= REG_XPR31) {
1271-
buf_set_u64(reg->value, 0, riscv_xlen(target), reg_cache_get(target, reg->number));
1304+
value = reg_cache_get(target, reg->number);
12721305
LOG_DEBUG("%s=0x%" PRIx64, reg->name, reg_cache_get(target, reg->number));
1273-
return ERROR_OK;
12741306
} else if (reg->number == REG_PC) {
1275-
buf_set_u32(reg->value, 0, 32, info->dpc);
1276-
reg->valid = true;
1307+
value = info->dpc;
12771308
LOG_DEBUG("%s=0x%" PRIx64 " (cached)", reg->name, info->dpc);
1278-
return ERROR_OK;
12791309
} else if (reg->number >= REG_FPR0 && reg->number <= REG_FPR31) {
12801310
int result = update_mstatus_actual(target);
12811311
if (result != ERROR_OK) {
@@ -1295,44 +1325,24 @@ static int register_get(struct reg *reg)
12951325
cache_set32(target, i++, fsd(reg->number - REG_FPR0, 0, DEBUG_RAM_START + 16));
12961326
}
12971327
cache_set_jump(target, i++);
1298-
} else if (reg->number >= REG_CSR0 && reg->number <= REG_CSR4095) {
1299-
cache_set32(target, 0, csrr(S0, reg->number - REG_CSR0));
1300-
cache_set_store(target, 1, S0, SLOT0);
1301-
cache_set_jump(target, 2);
1302-
} else if (reg->number == REG_PRIV) {
1303-
buf_set_u64(reg->value, 0, 8, get_field(info->dcsr, DCSR_PRV));
1304-
LOG_DEBUG("%s=%d (cached)", reg->name,
1305-
(int) get_field(info->dcsr, DCSR_PRV));
1306-
return ERROR_OK;
1307-
} else {
1308-
LOG_ERROR("Don't know how to read register %d (%s)", reg->number, reg->name);
1309-
return ERROR_FAIL;
1310-
}
1311-
1312-
if (cache_write(target, 4, true) != ERROR_OK) {
1313-
return ERROR_FAIL;
1314-
}
13151328

1316-
uint32_t exception = cache_get32(target, info->dramsize-1);
1317-
if (exception) {
1318-
LOG_ERROR("Got exception 0x%x when reading register %d", exception,
1319-
reg->number);
1320-
buf_set_u64(reg->value, 0, riscv_xlen(target), ~0);
1321-
return ERROR_FAIL;
1329+
if (cache_write(target, 4, true) != ERROR_OK) {
1330+
return ERROR_FAIL;
1331+
}
1332+
} else {
1333+
if (register_read(target, &value, reg->number) != ERROR_OK)
1334+
return ERROR_FAIL;
13221335
}
1323-
1324-
uint64_t value = cache_get(target, SLOT0);
1325-
LOG_DEBUG("%s=0x%" PRIx64, reg->name, value);
13261336
buf_set_u64(reg->value, 0, riscv_xlen(target), value);
13271337

13281338
if (reg->number == REG_MSTATUS) {
1329-
info->mstatus_actual = value;
13301339
reg->valid = true;
13311340
}
13321341

13331342
return ERROR_OK;
13341343
}
13351344

1345+
// Write the register. No caching or games.
13361346
static int register_write(struct target *target, unsigned int number,
13371347
uint64_t value)
13381348
{
@@ -1396,7 +1406,7 @@ static int register_write(struct target *target, unsigned int number,
13961406

13971407
uint32_t exception = cache_get32(target, info->dramsize-1);
13981408
if (exception) {
1399-
LOG_ERROR("Got exception 0x%x when writing register %d", exception,
1409+
LOG_WARNING("Got exception 0x%x when writing register %d", exception,
14001410
number);
14011411
return ERROR_FAIL;
14021412
}
@@ -1423,6 +1433,25 @@ static struct reg_arch_type riscv_reg_arch_type = {
14231433
.set = register_set
14241434
};
14251435

1436+
static riscv_reg_t get_register(struct target *target, int hartid, int regid)
1437+
{
1438+
assert(hartid == 0);
1439+
riscv_reg_t value;
1440+
if (register_read(target, &value, regid) != ERROR_OK) {
1441+
// TODO: propagate errors
1442+
value = ~0;
1443+
}
1444+
return value;
1445+
}
1446+
1447+
static void set_register(struct target *target, int hartid, int regid,
1448+
uint64_t value)
1449+
{
1450+
assert(hartid == 0);
1451+
// TODO: propagate errors
1452+
register_write(target, regid, value);
1453+
}
1454+
14261455
static int halt(struct target *target)
14271456
{
14281457
LOG_DEBUG("riscv_halt()");
@@ -1446,7 +1475,8 @@ static int init_target(struct command_context *cmd_ctx,
14461475
{
14471476
LOG_DEBUG("init");
14481477
riscv_info_t *generic_info = (riscv_info_t *) target->arch_info;
1449-
generic_info->get_register = NULL;
1478+
generic_info->get_register = get_register;
1479+
generic_info->set_register = set_register;
14501480
generic_info->version_specific = calloc(1, sizeof(riscv011_info_t));
14511481
if (!generic_info->version_specific)
14521482
return ERROR_FAIL;
@@ -1605,11 +1635,12 @@ static int maybe_add_trigger_t2(struct target *target, struct trigger *trigger,
16051635
static int add_trigger(struct target *target, struct trigger *trigger)
16061636
{
16071637
riscv011_info_t *info = get_info(target);
1638+
RISCV_INFO(r);
16081639

16091640
maybe_read_tselect(target);
16101641

16111642
unsigned int i;
1612-
for (i = 0; i < info->trigger_count; i++) {
1643+
for (i = 0; i < r->trigger_count[0]; i++) {
16131644
if (info->trigger_unique_id[i] != -1) {
16141645
continue;
16151646
}
@@ -1642,7 +1673,7 @@ static int add_trigger(struct target *target, struct trigger *trigger)
16421673
info->trigger_unique_id[i] = trigger->unique_id;
16431674
break;
16441675
}
1645-
if (i >= info->trigger_count) {
1676+
if (i >= r->trigger_count[0]) {
16461677
LOG_ERROR("Couldn't find an available hardware trigger.");
16471678
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
16481679
}
@@ -1652,17 +1683,18 @@ static int add_trigger(struct target *target, struct trigger *trigger)
16521683

16531684
static int remove_trigger(struct target *target, struct trigger *trigger)
16541685
{
1686+
RISCV_INFO(r);
16551687
riscv011_info_t *info = get_info(target);
16561688

16571689
maybe_read_tselect(target);
16581690

16591691
unsigned int i;
1660-
for (i = 0; i < info->trigger_count; i++) {
1692+
for (i = 0; i < r->trigger_count[0]; i++) {
16611693
if (info->trigger_unique_id[i] == trigger->unique_id) {
16621694
break;
16631695
}
16641696
}
1665-
if (i >= info->trigger_count) {
1697+
if (i >= r->trigger_count[0]) {
16661698
LOG_ERROR("Couldn't find the hardware resources used by hardware "
16671699
"trigger.");
16681700
return ERROR_FAIL;
@@ -2200,30 +2232,10 @@ static int handle_halt(struct target *target, bool announce)
22002232
if (info->never_halted) {
22012233
info->never_halted = false;
22022234

2203-
// Disable any hardware triggers that have dmode set. We can't have set
2204-
// them ourselves. Maybe they're left over from some killed debug
2205-
// session.
2206-
// Count the number of triggers while we're at it.
2207-
22082235
int result = maybe_read_tselect(target);
22092236
if (result != ERROR_OK)
22102237
return result;
2211-
for (info->trigger_count = 0; info->trigger_count < MAX_HWBPS; info->trigger_count++) {
2212-
write_csr(target, CSR_TSELECT, info->trigger_count);
2213-
uint64_t tselect_rb;
2214-
read_csr(target, &tselect_rb, CSR_TSELECT);
2215-
// Mask off the top bit, which is used as tdrmode in old
2216-
// implementations.
2217-
tselect_rb &= ~(1ULL << (riscv_xlen(target)-1));
2218-
if (info->trigger_count != tselect_rb)
2219-
break;
2220-
uint64_t tdata1;
2221-
read_csr(target, &tdata1, CSR_TDATA1);
2222-
if ((tdata1 & MCONTROL_DMODE(riscv_xlen(target))) &&
2223-
(tdata1 & (MCONTROL_EXECUTE | MCONTROL_STORE | MCONTROL_LOAD))) {
2224-
write_csr(target, CSR_TDATA1, 0);
2225-
}
2226-
}
2238+
riscv_enumerate_triggers(target);
22272239
}
22282240

22292241
if (announce) {

src/target/riscv/riscv-013.c

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,21 +1239,7 @@ static int examine(struct target *target)
12391239
}
12401240

12411241
/* Then we check the number of triggers availiable to each hart. */
1242-
for (int i = 0; i < riscv_count_harts(target); ++i) {
1243-
if (!riscv_hart_enabled(target, i))
1244-
continue;
1245-
1246-
for (uint32_t t = 0; t < RISCV_MAX_TRIGGERS; ++t) {
1247-
riscv_set_current_hartid(target, i);
1248-
1249-
r->trigger_count[i] = t;
1250-
register_write_direct(target, GDB_REGNO_TSELECT, t);
1251-
uint64_t tselect = t+1;
1252-
register_read_direct(target, &tselect, GDB_REGNO_TSELECT);
1253-
if (tselect != t)
1254-
break;
1255-
}
1256-
}
1242+
riscv_enumerate_triggers(target);
12571243

12581244
/* Resumes all the harts, so the debugger can later pause them. */
12591245
riscv_resume_all_harts(target);

src/target/riscv/riscv.c

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,10 +1103,12 @@ void riscv_set_register(struct target *target, enum gdb_regno r, riscv_reg_t v)
11031103
return riscv_set_register_on_hart(target, riscv_current_hartid(target), r, v);
11041104
}
11051105

1106-
void riscv_set_register_on_hart(struct target *target, int hartid, enum gdb_regno regid, uint64_t value)
1106+
void riscv_set_register_on_hart(struct target *target, int hartid,
1107+
enum gdb_regno regid, uint64_t value)
11071108
{
11081109
RISCV_INFO(r);
1109-
LOG_DEBUG("writing register %d on hart %d", regid, hartid);
1110+
LOG_DEBUG("[%d] reg[%d] <- %" PRIx64, hartid, regid, value);
1111+
assert(r->set_register);
11101112
return r->set_register(target, hartid, regid, value);
11111113
}
11121114

@@ -1243,3 +1245,53 @@ bool riscv_hart_enabled(struct target *target, int hartid)
12431245

12441246
return hartid == target->coreid;
12451247
}
1248+
1249+
/**
1250+
* Count triggers, and initialize trigger_count for each hart.
1251+
* trigger_count is initialized even if this function fails to discover
1252+
* something.
1253+
* Disable any hardware triggers that have dmode set. We can't have set them
1254+
* ourselves. Maybe they're left over from some killed debug session.
1255+
* */
1256+
int riscv_enumerate_triggers(struct target *target)
1257+
{
1258+
RISCV_INFO(r);
1259+
1260+
for (int hartid = 0; hartid < riscv_count_harts(target); ++hartid) {
1261+
if (!riscv_hart_enabled(target, hartid))
1262+
continue;
1263+
1264+
for (unsigned t = 0; t < RISCV_MAX_TRIGGERS; ++t) {
1265+
r->trigger_count[hartid] = t;
1266+
1267+
riscv_set_register_on_hart(target, hartid, GDB_REGNO_TSELECT, t);
1268+
uint64_t tselect = riscv_get_register_on_hart(target, hartid,
1269+
GDB_REGNO_TSELECT);
1270+
// Mask off the top bit, which is used as tdrmode in old
1271+
// implementations.
1272+
tselect &= ~(1ULL << (riscv_xlen(target)-1));
1273+
if (tselect != t)
1274+
break;
1275+
1276+
uint64_t tdata1 = riscv_get_register_on_hart(target, hartid,
1277+
GDB_REGNO_TDATA1);
1278+
int type = get_field(tdata1, MCONTROL_TYPE(riscv_xlen(target)));
1279+
switch (type) {
1280+
case 1:
1281+
// On these older cores we don't support software using
1282+
// triggers.
1283+
riscv_set_register_on_hart(target, hartid, GDB_REGNO_TDATA1, 0);
1284+
break;
1285+
case 2:
1286+
if (tdata1 & MCONTROL_DMODE(riscv_xlen(target))) {
1287+
riscv_set_register_on_hart(target, hartid, GDB_REGNO_TDATA1, 0);
1288+
}
1289+
break;
1290+
}
1291+
}
1292+
1293+
LOG_DEBUG("[%d] Found %d triggers", hartid, r->trigger_count[hartid]);
1294+
}
1295+
1296+
return ERROR_OK;
1297+
}

src/target/riscv/riscv.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ typedef struct {
5757
int xlen[RISCV_MAX_HARTS];
5858

5959
/* The number of triggers per hart. */
60-
int trigger_count[RISCV_MAX_HARTS];
60+
unsigned trigger_count[RISCV_MAX_HARTS];
6161

6262
/* The address of the debug RAM buffer. */
6363
riscv_addr_t debug_buffer_addr[RISCV_MAX_HARTS];
@@ -70,8 +70,9 @@ typedef struct {
7070

7171
/* Helper functions that target the various RISC-V debug spec
7272
* implementations. */
73-
riscv_reg_t (*get_register)(struct target *, int, int);
74-
void (*set_register)(struct target *, int, int, uint64_t);
73+
riscv_reg_t (*get_register)(struct target *, int hartid, int regid);
74+
void (*set_register)(struct target *, int hartid, int regid,
75+
uint64_t value);
7576
void (*select_current_hart)(struct target *);
7677
bool (*is_halted)(struct target *target);
7778
void (*halt_current_hart)(struct target *);
@@ -218,4 +219,6 @@ void riscv_invalidate_register_cache(struct target *target);
218219
/* Returns TRUE when a hart is enabled in this target. */
219220
bool riscv_hart_enabled(struct target *target, int hartid);
220221

222+
int riscv_enumerate_triggers(struct target *target);
223+
221224
#endif

0 commit comments

Comments
 (0)