Lots of RISC-V improvements.
[fw/openocd] / src / target / riscv / program.h
1 #ifndef TARGET__RISCV__PROGRAM_H
2 #define TARGET__RISCV__PROGRAM_H
3
4 #include "riscv.h"
5
6 #define RISCV_MAX_DEBUG_BUFFER_SIZE 32
7 #define RISCV_REGISTER_COUNT 32
8 #define RISCV_DSCRATCH_COUNT 2
9
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;
15
16         uint32_t debug_buffer[RISCV_MAX_DEBUG_BUFFER_SIZE];
17
18         /* Number of 32-bit instructions in the program. */
19         size_t instruction_count;
20
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];
24
25         /* XLEN on the target. */
26         int target_xlen;
27 };
28
29 /* Initializes a program with the header. */
30 int riscv_program_init(struct riscv_program *p, struct target *t);
31
32 /* Write the program to the program buffer. */
33 int riscv_program_write(struct riscv_program *program);
34
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.
39  * */
40 int riscv_program_exec(struct riscv_program *p, struct target *t);
41 int riscv_program_load(struct riscv_program *p, struct target *t);
42
43 /* Clears a program, removing all the state associated with it. */
44 int riscv_program_clear(struct riscv_program *p, struct target *t);
45
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);
48
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
52  * memory. */
53 int riscv_program_save_to_dscratch(struct riscv_program *p, enum gdb_regno to_save);
54
55 /* Helpers to assemble various instructions.  Return 0 on success.  These might
56  * assemble 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);
61
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);
65
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);
68
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);
72
73 int riscv_program_addi(struct riscv_program *p, enum gdb_regno d, enum gdb_regno s, int16_t i);
74
75 #endif