1 #ifndef TARGET__RISCV__PROGRAM_H
2 #define TARGET__RISCV__PROGRAM_H
6 #define RISCV_MAX_DEBUG_BUFFER_SIZE 32
7 #define RISCV_REGISTER_COUNT 32
8 #define RISCV_DSCRATCH_COUNT 2
10 /* The various RISC-V debug specifications all revolve around setting up
11 * program buffers and executing them on the target. This structure contains a
12 * single program, which can then be executed on targets. */
13 struct riscv_program {
14 struct target *target;
16 uint32_t debug_buffer[RISCV_MAX_DEBUG_BUFFER_SIZE];
18 /* Number of 32-bit instructions in the program. */
19 size_t instruction_count;
21 /* Side effects of executing this program. These must be accounted for
22 * in order to maintain correct executing of the target system. */
23 bool writes_xreg[RISCV_REGISTER_COUNT];
25 /* XLEN on the target. */
29 /* Initializes a program with the header. */
30 int riscv_program_init(struct riscv_program *p, struct target *t);
32 /* Write the program to the program buffer. */
33 int riscv_program_write(struct riscv_program *program);
35 /* Executes a program, returning 0 if the program successfully executed. Note
36 * that this may cause registers to be saved or restored, which could result to
37 * calls to things like riscv_save_register which itself could require a
38 * program to execute. That's OK, just make sure this eventually terminates.
40 int riscv_program_exec(struct riscv_program *p, struct target *t);
41 int riscv_program_load(struct riscv_program *p, struct target *t);
43 /* Clears a program, removing all the state associated with it. */
44 int riscv_program_clear(struct riscv_program *p, struct target *t);
46 /* A lower level interface, you shouldn't use this unless you have a reason. */
47 int riscv_program_insert(struct riscv_program *p, riscv_insn_t i);
49 /* There is hardware support for saving at least one register. This register
50 * doesn't need to be saved/restored the usual way, which is useful during
51 * early initialization when we can't save/restore arbitrary registerrs to host
53 int riscv_program_save_to_dscratch(struct riscv_program *p, enum gdb_regno to_save);
55 /* Helpers to assembly various instructions. Return 0 on success. These might
56 * assembly into a multi-instruction sequence that overwrites some other
57 * register, but those will be properly saved and restored. */
58 int riscv_program_lwr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno a, int o);
59 int riscv_program_lhr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno a, int o);
60 int riscv_program_lbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno a, int o);
62 int riscv_program_swr(struct riscv_program *p, enum gdb_regno s, enum gdb_regno a, int o);
63 int riscv_program_shr(struct riscv_program *p, enum gdb_regno s, enum gdb_regno a, int o);
64 int riscv_program_sbr(struct riscv_program *p, enum gdb_regno s, enum gdb_regno a, int o);
66 int riscv_program_csrr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno csr);
67 int riscv_program_csrw(struct riscv_program *p, enum gdb_regno s, enum gdb_regno csr);
69 int riscv_program_fence_i(struct riscv_program *p);
70 int riscv_program_fence(struct riscv_program *p);
71 int riscv_program_ebreak(struct riscv_program *p);
73 int riscv_program_addi(struct riscv_program *p, enum gdb_regno d, enum gdb_regno s, int16_t i);