Skip to content

Commit 2b852d6

Browse files
committed
target/riscv: access registers via reg->type
* `int riscv_reg_get()` and `int riscv_reg_set()` are implemented in terms of `reg->type->get/set` instead of the other way around. This makes it easier to support custom behavior for some registers. * Cacheability is determined by `reg->type` instead of `riscv_reg_impl_gdb_regno_cacheable()`. * Issues with redirection of `priv` -> `dcsr` and `pc` -> `dpc` are addressed at the "topmost" level. - `priv` and `pc` are always invalid. - Fixed some issues, e.g. the first `pc` write printed-out an uninitialized value: ``` > reg pc 0 pc (/64): 0x000075da6b33db20 ``` Change-Id: I514547f455d62b289fb5dee62753bf5d9aa3b8ae Signed-off-by: Evgeniy Naydanov <[email protected]>
1 parent d3f46bc commit 2b852d6

File tree

6 files changed

+502
-310
lines changed

6 files changed

+502
-310
lines changed

src/target/riscv/program.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ int riscv_program_write(struct riscv_program *program);
4141

4242
/* Executes a program, returning 0 if the program successfully executed. Note
4343
* that this may cause registers to be saved or restored, which could result to
44-
* calls to things like riscv013_reg_save which itself could require a
44+
* calls to things like riscv013_reg_save_gpr which itself could require a
4545
* program to execute. That's OK, just make sure this eventually terminates.
4646
* */
4747
int riscv_program_exec(struct riscv_program *p, struct target *t);

src/target/riscv/riscv-013.c

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -988,7 +988,7 @@ static int examine_progbuf(struct target *target)
988988
return ERROR_OK;
989989
}
990990

991-
if (riscv013_reg_save(target, GDB_REGNO_S0) != ERROR_OK)
991+
if (riscv013_reg_save_gpr(target, GDB_REGNO_S0) != ERROR_OK)
992992
return ERROR_FAIL;
993993

994994
struct riscv_program program;
@@ -1320,7 +1320,7 @@ static int fpr_read_progbuf(struct target *target, uint64_t *value,
13201320

13211321
const unsigned int freg = number - GDB_REGNO_FPR0;
13221322

1323-
if (riscv013_reg_save(target, GDB_REGNO_S0) != ERROR_OK)
1323+
if (riscv013_reg_save_gpr(target, GDB_REGNO_S0) != ERROR_OK)
13241324
return ERROR_FAIL;
13251325

13261326
struct riscv_program program;
@@ -1350,7 +1350,7 @@ static int csr_read_progbuf(struct target *target, uint64_t *value,
13501350
assert(target->state == TARGET_HALTED);
13511351
assert(number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095);
13521352

1353-
if (riscv013_reg_save(target, GDB_REGNO_S0) != ERROR_OK)
1353+
if (riscv013_reg_save_gpr(target, GDB_REGNO_S0) != ERROR_OK)
13541354
return ERROR_FAIL;
13551355

13561356
struct riscv_program program;
@@ -1418,7 +1418,7 @@ static int fpr_write_progbuf(struct target *target, enum gdb_regno number,
14181418
assert(number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31);
14191419
const unsigned int freg = number - GDB_REGNO_FPR0;
14201420

1421-
if (riscv013_reg_save(target, GDB_REGNO_S0) != ERROR_OK)
1421+
if (riscv013_reg_save_gpr(target, GDB_REGNO_S0) != ERROR_OK)
14221422
return ERROR_FAIL;
14231423

14241424
struct riscv_program program;
@@ -1448,11 +1448,11 @@ static int vtype_write_progbuf(struct target *target, riscv_reg_t value)
14481448
{
14491449
assert(target->state == TARGET_HALTED);
14501450

1451-
if (riscv013_reg_save(target, GDB_REGNO_S0) != ERROR_OK)
1451+
if (riscv013_reg_save_gpr(target, GDB_REGNO_S0) != ERROR_OK)
14521452
return ERROR_FAIL;
14531453
if (register_write_abstract(target, GDB_REGNO_S0, value) != ERROR_OK)
14541454
return ERROR_FAIL;
1455-
if (riscv013_reg_save(target, GDB_REGNO_S1) != ERROR_OK)
1455+
if (riscv013_reg_save_gpr(target, GDB_REGNO_S1) != ERROR_OK)
14561456
return ERROR_FAIL;
14571457

14581458
struct riscv_program program;
@@ -1469,11 +1469,11 @@ static int vl_write_progbuf(struct target *target, riscv_reg_t value)
14691469
{
14701470
assert(target->state == TARGET_HALTED);
14711471

1472-
if (riscv013_reg_save(target, GDB_REGNO_S0) != ERROR_OK)
1472+
if (riscv013_reg_save_gpr(target, GDB_REGNO_S0) != ERROR_OK)
14731473
return ERROR_FAIL;
14741474
if (register_write_abstract(target, GDB_REGNO_S0, value) != ERROR_OK)
14751475
return ERROR_FAIL;
1476-
if (riscv013_reg_save(target, GDB_REGNO_S1) != ERROR_OK)
1476+
if (riscv013_reg_save_gpr(target, GDB_REGNO_S1) != ERROR_OK)
14771477
return ERROR_FAIL;
14781478

14791479
struct riscv_program program;
@@ -1492,7 +1492,7 @@ static int csr_write_progbuf(struct target *target, enum gdb_regno number,
14921492
assert(target->state == TARGET_HALTED);
14931493
assert(number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095);
14941494

1495-
if (riscv013_reg_save(target, GDB_REGNO_S0) != ERROR_OK)
1495+
if (riscv013_reg_save_gpr(target, GDB_REGNO_S0) != ERROR_OK)
14961496
return ERROR_FAIL;
14971497
if (register_write_abstract(target, GDB_REGNO_S0, value) != ERROR_OK)
14981498
return ERROR_FAIL;
@@ -2298,7 +2298,7 @@ int riscv013_get_register_buf(struct target *target, uint8_t *value,
22982298
&debug_vl, &debug_vsew) != ERROR_OK)
22992299
return ERROR_FAIL;
23002300

2301-
if (riscv013_reg_save(target, GDB_REGNO_S0) != ERROR_OK)
2301+
if (riscv013_reg_save_gpr(target, GDB_REGNO_S0) != ERROR_OK)
23022302
return ERROR_FAIL;
23032303

23042304
unsigned int vnum = regno - GDB_REGNO_V0;
@@ -2353,7 +2353,7 @@ int riscv013_set_register_buf(struct target *target, enum gdb_regno regno,
23532353
&debug_vl, &debug_vsew) != ERROR_OK)
23542354
return ERROR_FAIL;
23552355

2356-
if (riscv013_reg_save(target, GDB_REGNO_S0) != ERROR_OK)
2356+
if (riscv013_reg_save_gpr(target, GDB_REGNO_S0) != ERROR_OK)
23572357
return ERROR_FAIL;
23582358

23592359
unsigned int vnum = regno - GDB_REGNO_V0;
@@ -4242,11 +4242,11 @@ static int read_memory_progbuf_inner_fill_progbuf(struct target *target,
42424242
{
42434243
const bool is_repeated_read = increment == 0;
42444244

4245-
if (riscv013_reg_save(target, GDB_REGNO_S0) != ERROR_OK)
4245+
if (riscv013_reg_save_gpr(target, GDB_REGNO_S0) != ERROR_OK)
42464246
return ERROR_FAIL;
4247-
if (riscv013_reg_save(target, GDB_REGNO_S1) != ERROR_OK)
4247+
if (riscv013_reg_save_gpr(target, GDB_REGNO_S1) != ERROR_OK)
42484248
return ERROR_FAIL;
4249-
if (is_repeated_read && riscv013_reg_save(target, GDB_REGNO_A0) != ERROR_OK)
4249+
if (is_repeated_read && riscv013_reg_save_gpr(target, GDB_REGNO_A0) != ERROR_OK)
42504250
return ERROR_FAIL;
42514251

42524252
struct riscv_program program;
@@ -4338,7 +4338,7 @@ static int read_memory_progbuf_inner_one(struct target *target, const riscv_mem_
43384338
{
43394339
assert(riscv_mem_access_is_read(args));
43404340

4341-
if (riscv013_reg_save(target, GDB_REGNO_S1) != ERROR_OK)
4341+
if (riscv013_reg_save_gpr(target, GDB_REGNO_S1) != ERROR_OK)
43424342
return ERROR_FAIL;
43434343

43444344
struct riscv_program program;
@@ -4861,9 +4861,9 @@ static int write_memory_progbuf_try_to_write(struct target *target,
48614861

48624862
static int write_memory_progbuf_fill_progbuf(struct target *target, uint32_t size)
48634863
{
4864-
if (riscv013_reg_save(target, GDB_REGNO_S0) != ERROR_OK)
4864+
if (riscv013_reg_save_gpr(target, GDB_REGNO_S0) != ERROR_OK)
48654865
return ERROR_FAIL;
4866-
if (riscv013_reg_save(target, GDB_REGNO_S1) != ERROR_OK)
4866+
if (riscv013_reg_save_gpr(target, GDB_REGNO_S1) != ERROR_OK)
48674867
return ERROR_FAIL;
48684868

48694869
struct riscv_program program;
@@ -5067,19 +5067,8 @@ struct target_type riscv013_target = {
50675067
int riscv013_get_register(struct target *target,
50685068
riscv_reg_t *value, enum gdb_regno rid)
50695069
{
5070-
/* It would be beneficial to move this redirection to the
5071-
* version-independent section, but there is a conflict:
5072-
* `dcsr[5]` is `dcsr.v` in current spec, but it is `dcsr.debugint` in 0.11.
5073-
*/
5074-
if (rid == GDB_REGNO_PRIV) {
5075-
uint64_t dcsr;
5076-
if (riscv_reg_get(target, &dcsr, GDB_REGNO_DCSR) != ERROR_OK)
5077-
return ERROR_FAIL;
5078-
*value = set_field(0, VIRT_PRIV_V, get_field(dcsr, CSR_DCSR_V));
5079-
*value = set_field(*value, VIRT_PRIV_PRV, get_field(dcsr, CSR_DCSR_PRV));
5080-
return ERROR_OK;
5081-
}
5082-
5070+
assert(rid != GDB_REGNO_PC && "'pc' should be read through 'dpc'");
5071+
assert(rid != GDB_REGNO_PRIV && "'priv' should be read through 'dcsr'");
50835072
LOG_TARGET_DEBUG(target, "reading register %s", riscv_reg_gdb_regno_name(target, rid));
50845073

50855074
if (dm013_select_target(target) != ERROR_OK)
@@ -5096,6 +5085,8 @@ int riscv013_get_register(struct target *target,
50965085
int riscv013_set_register(struct target *target, enum gdb_regno rid,
50975086
riscv_reg_t value)
50985087
{
5088+
assert(rid != GDB_REGNO_PC && "'pc' should be written through 'dpc'");
5089+
assert(rid != GDB_REGNO_PRIV && "'priv' should be written through 'dcsr'");
50995090
LOG_TARGET_DEBUG(target, "writing 0x%" PRIx64 " to register %s",
51005091
value, riscv_reg_gdb_regno_name(target, rid));
51015092

0 commit comments

Comments
 (0)