Skip to content

Commit 3cff421

Browse files
Merge pull request #69 from riscv/multi-gdb
Fix the multi-GDB mode bugs
2 parents ce48a5d + f18fd83 commit 3cff421

File tree

3 files changed

+66
-43
lines changed

3 files changed

+66
-43
lines changed

src/target/riscv/riscv-013.c

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,7 @@ static int init_target(struct command_context *cmd_ctx,
706706
LOG_DEBUG("init");
707707
riscv_info_t *generic_info = (riscv_info_t *) target->arch_info;
708708

709-
riscv_info_init(generic_info);
709+
riscv_info_init(target, generic_info);
710710
generic_info->get_register = &riscv013_get_register;
711711
generic_info->set_register = &riscv013_set_register;
712712
generic_info->select_current_hart = &riscv013_select_current_hart;
@@ -832,6 +832,9 @@ static int add_trigger(struct target *target, struct trigger *trigger)
832832

833833
uint64_t tdata1_rb;
834834
for (int hartid = 0; hartid < riscv_count_harts(target); ++hartid) {
835+
if (!riscv_hart_enabled(target, hartid))
836+
continue;
837+
835838
riscv_set_current_hartid(target, hartid);
836839

837840
if (hartid > 0) {
@@ -918,6 +921,9 @@ static int remove_trigger(struct target *target, struct trigger *trigger)
918921
}
919922
LOG_DEBUG("Stop using resource %d for bp %d", i, trigger->unique_id);
920923
for (int hartid = 0; hartid < riscv_count_harts(target); ++hartid) {
924+
if (!riscv_hart_enabled(target, hartid))
925+
continue;
926+
921927
riscv_set_current_hartid(target, hartid);
922928
register_write_direct(target, GDB_REGNO_TSELECT, i);
923929
register_write_direct(target, GDB_REGNO_TDATA1, 0);
@@ -1123,17 +1129,23 @@ static int examine(struct target *target)
11231129

11241130
/* Before doing anything else we must first enumerate the harts. */
11251131
RISCV_INFO(r);
1126-
if (riscv_rtos_enabled(target)) {
1127-
for (int i = 0; i < RISCV_MAX_HARTS; ++i) {
1128-
riscv_set_current_hartid(target, i);
1129-
uint32_t s = dmi_read(target, DMI_DMSTATUS);
1130-
if (get_field(s, DMI_DMSTATUS_ANYNONEXISTENT))
1131-
break;
1132-
r->hart_count = i + 1;
1132+
int original_coreid = target->coreid;
1133+
for (int i = 0; i < RISCV_MAX_HARTS; ++i) {
1134+
/* Fake being a non-RTOS targeted to this core so we can see if
1135+
* it exists. This avoids the assertion in
1136+
* riscv_set_current_hartid() that ensures non-RTOS targets
1137+
* don't touch the harts they're not assigned to. */
1138+
target->coreid = i;
1139+
r->hart_count = i + 1;
1140+
riscv_set_current_hartid(target, i);
1141+
1142+
uint32_t s = dmi_read(target, DMI_DMSTATUS);
1143+
if (get_field(s, DMI_DMSTATUS_ANYNONEXISTENT)) {
1144+
r->hart_count--;
1145+
break;
11331146
}
1134-
} else {
1135-
r->hart_count = 1;
11361147
}
1148+
target->coreid = original_coreid;
11371149

11381150
LOG_DEBUG("Enumerated %d harts", r->hart_count);
11391151

@@ -1143,6 +1155,9 @@ static int examine(struct target *target)
11431155
/* Find the address of the program buffer, which must be done without
11441156
* knowing anything about the target. */
11451157
for (int i = 0; i < riscv_count_harts(target); ++i) {
1158+
if (!riscv_hart_enabled(target, i))
1159+
continue;
1160+
11461161
riscv_set_current_hartid(target, i);
11471162

11481163
/* Without knowing anything else we can at least mess with the
@@ -1225,6 +1240,9 @@ static int examine(struct target *target)
12251240

12261241
/* Then we check the number of triggers availiable to each hart. */
12271242
for (int i = 0; i < riscv_count_harts(target); ++i) {
1243+
if (!riscv_hart_enabled(target, i))
1244+
continue;
1245+
12281246
for (uint32_t t = 0; t < RISCV_MAX_TRIGGERS; ++t) {
12291247
riscv_set_current_hartid(target, i);
12301248

@@ -1239,6 +1257,7 @@ static int examine(struct target *target)
12391257

12401258
/* Resumes all the harts, so the debugger can later pause them. */
12411259
riscv_resume_all_harts(target);
1260+
target->state = TARGET_RUNNING;
12421261
target_set_examined(target);
12431262

12441263
if (target->rtos) {
@@ -1333,9 +1352,6 @@ static int read_memory(struct target *target, target_addr_t address,
13331352
size, address);
13341353

13351354
select_dmi(target);
1336-
/* There was a bug in the memory system and only accesses from hart 0 actually
1337-
* worked correctly. This should be obselete now. -palmer */
1338-
riscv_set_current_hartid(target, 0);
13391355

13401356
/* This program uses two temporary registers. A word of data and the
13411357
* associated address are stored at some location in memory. The
@@ -1531,9 +1547,6 @@ static int write_memory(struct target *target, target_addr_t address,
15311547
LOG_DEBUG("writing %d words of %d bytes to 0x%08lx", count, size, (long)address);
15321548

15331549
select_dmi(target);
1534-
/* There was a bug in the memory system and only accesses from hart 0 actually
1535-
* worked correctly. This should be obselete now. -palmer */
1536-
riscv_set_current_hartid(target, 0);
15371550

15381551
/* This program uses two temporary registers. A word of data and the
15391552
* associated address are stored at some location in memory. The

src/target/riscv/riscv.c

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -448,11 +448,12 @@ static int riscv_get_gdb_reg_list(struct target *target,
448448
{
449449
RISCV_INFO(r);
450450
LOG_DEBUG("reg_class=%d", reg_class);
451-
LOG_DEBUG("riscv_get_gdb_reg_list: rtos_hartid=%d current_hartid=%d", r->rtos_hartid, r->current_hartid);
452-
if (r->rtos_hartid != -1)
451+
LOG_DEBUG("rtos_hartid=%d current_hartid=%d", r->rtos_hartid, r->current_hartid);
452+
453+
if (r->rtos_hartid != -1 && riscv_rtos_enabled(target))
453454
riscv_set_current_hartid(target, r->rtos_hartid);
454455
else
455-
riscv_set_current_hartid(target, 0);
456+
riscv_set_current_hartid(target, target->coreid);
456457

457458
switch (reg_class) {
458459
case REG_CLASS_GENERAL:
@@ -872,11 +873,12 @@ struct target_type riscv_target =
872873

873874
/*** RISC-V Interface ***/
874875

875-
void riscv_info_init(riscv_info_t *r)
876+
void riscv_info_init(struct target *target, riscv_info_t *r)
876877
{
877878
memset(r, 0, sizeof(*r));
878879
r->dtm_version = 1;
879880
r->registers_initialized = false;
881+
r->current_hartid = target->coreid;
880882

881883
for (size_t h = 0; h < RISCV_MAX_HARTS; ++h) {
882884
r->xlen[h] = -1;
@@ -889,11 +891,11 @@ void riscv_info_init(riscv_info_t *r)
889891

890892
int riscv_halt_all_harts(struct target *target)
891893
{
892-
if (riscv_rtos_enabled(target)) {
893-
for (int i = 0; i < riscv_count_harts(target); ++i)
894-
riscv_halt_one_hart(target, i);
895-
} else {
896-
riscv_halt_one_hart(target, riscv_current_hartid(target));
894+
for (int i = 0; i < riscv_count_harts(target); ++i) {
895+
if (!riscv_hart_enabled(target, i))
896+
continue;
897+
898+
riscv_halt_one_hart(target, i);
897899
}
898900

899901
return ERROR_OK;
@@ -915,11 +917,11 @@ int riscv_halt_one_hart(struct target *target, int hartid)
915917

916918
int riscv_resume_all_harts(struct target *target)
917919
{
918-
if (riscv_rtos_enabled(target)) {
919-
for (int i = 0; i < riscv_count_harts(target); ++i)
920-
riscv_resume_one_hart(target, i);
921-
} else {
922-
riscv_resume_one_hart(target, riscv_current_hartid(target));
920+
for (int i = 0; i < riscv_count_harts(target); ++i) {
921+
if (!riscv_hart_enabled(target, i))
922+
continue;
923+
924+
riscv_resume_one_hart(target, i);
923925
}
924926

925927
riscv_invalidate_register_cache(target);
@@ -943,11 +945,11 @@ int riscv_resume_one_hart(struct target *target, int hartid)
943945

944946
int riscv_reset_all_harts(struct target *target)
945947
{
946-
if (riscv_rtos_enabled(target)) {
947-
for (int i = 0; i < riscv_count_harts(target); ++i)
948-
riscv_reset_one_hart(target, i);
949-
} else {
950-
riscv_reset_one_hart(target, riscv_current_hartid(target));
948+
for (int i = 0; i < riscv_count_harts(target); ++i) {
949+
if (!riscv_hart_enabled(target, i))
950+
continue;
951+
952+
riscv_reset_one_hart(target, i);
951953
}
952954

953955
riscv_invalidate_register_cache(target);
@@ -1017,10 +1019,9 @@ void riscv_set_current_hartid(struct target *target, int hartid)
10171019

10181020
int previous_hartid = riscv_current_hartid(target);
10191021
r->current_hartid = hartid;
1020-
assert(riscv_rtos_enabled(target) || target->coreid == hartid);
1022+
assert(riscv_hart_enabled(target, hartid));
10211023
LOG_DEBUG("setting hartid to %d, was %d", hartid, previous_hartid);
1022-
if (riscv_rtos_enabled(target))
1023-
r->select_current_hart(target);
1024+
r->select_current_hart(target);
10241025

10251026
/* This might get called during init, in which case we shouldn't be
10261027
* setting up the register cache. */
@@ -1068,10 +1069,7 @@ void riscv_invalidate_register_cache(struct target *target)
10681069
int riscv_current_hartid(const struct target *target)
10691070
{
10701071
RISCV_INFO(r);
1071-
if (riscv_rtos_enabled(target))
1072-
return r->current_hartid;
1073-
else
1074-
return target->coreid;
1072+
return r->current_hartid;
10751073
}
10761074

10771075
void riscv_set_all_rtos_harts(struct target *target)
@@ -1236,3 +1234,12 @@ int riscv_dmi_write_u64_bits(struct target *target)
12361234
RISCV_INFO(r);
12371235
return r->dmi_write_u64_bits(target);
12381236
}
1237+
1238+
bool riscv_hart_enabled(struct target *target, int hartid)
1239+
{
1240+
/* FIXME: Add a hart mask to the RTOS. */
1241+
if (riscv_rtos_enabled(target))
1242+
return hartid < riscv_count_harts(target);
1243+
1244+
return hartid == target->coreid;
1245+
}

src/target/riscv/riscv.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ int riscv_openocd_deassert_reset(struct target *target);
134134
/*** RISC-V Interface ***/
135135

136136
/* Initializes the shared RISC-V structure. */
137-
void riscv_info_init(riscv_info_t *r);
137+
void riscv_info_init(struct target *target, riscv_info_t *r);
138138

139139
/* Run control, possibly for multiple harts. The _all_harts versions resume
140140
* all the enabled harts, which when running in RTOS mode is all the harts on
@@ -215,4 +215,7 @@ int riscv_dmi_write_u64_bits(struct target *target);
215215
/* Invalidates the register cache. */
216216
void riscv_invalidate_register_cache(struct target *target);
217217

218+
/* Returns TRUE when a hart is enabled in this target. */
219+
bool riscv_hart_enabled(struct target *target, int hartid);
220+
218221
#endif

0 commit comments

Comments
 (0)