5 #include "target/target.h"
6 #include "target/register.h"
9 #include "helper/log.h"
14 /* Program interface. */
15 int riscv_program_init(struct riscv_program *p, struct target *target)
17 memset(p, 0, sizeof(*p));
19 p->instruction_count = 0;
20 p->target_xlen = riscv_xlen(target);
21 for (size_t i = 0; i < RISCV_REGISTER_COUNT; ++i)
22 p->writes_xreg[i] = 0;
24 for (size_t i = 0; i < RISCV_MAX_DEBUG_BUFFER_SIZE; ++i)
25 p->debug_buffer[i] = -1;
30 int riscv_program_write(struct riscv_program *program)
32 for (unsigned i = 0; i < program->instruction_count; ++i) {
33 LOG_DEBUG("%p: debug_buffer[%02x] = DASM(0x%08x)", program, i, program->debug_buffer[i]);
34 if (riscv_write_debug_buffer(program->target, i,
35 program->debug_buffer[i]) != ERROR_OK)
41 /** Add ebreak and execute the program. */
42 int riscv_program_exec(struct riscv_program *p, struct target *t)
46 riscv_reg_t saved_registers[GDB_REGNO_XPR31 + 1];
47 for (size_t i = GDB_REGNO_ZERO + 1; i <= GDB_REGNO_XPR31; ++i) {
48 if (p->writes_xreg[i]) {
49 LOG_DEBUG("Saving register %d as used by program", (int)i);
50 int result = riscv_get_register(t, &saved_registers[i], i);
51 if (result != ERROR_OK)
56 if (riscv_program_ebreak(p) != ERROR_OK) {
57 LOG_ERROR("Unable to write ebreak");
58 for (size_t i = 0; i < riscv_debug_buffer_size(p->target); ++i)
59 LOG_ERROR("ram[%02x]: DASM(0x%08lx) [0x%08lx]", (int)i, (long)p->debug_buffer[i], (long)p->debug_buffer[i]);
63 if (riscv_program_write(p) != ERROR_OK)
66 if (riscv_execute_debug_buffer(t) != ERROR_OK) {
67 LOG_DEBUG("Unable to execute program %p", p);
71 for (size_t i = 0; i < riscv_debug_buffer_size(p->target); ++i)
72 if (i >= riscv_debug_buffer_size(p->target))
73 p->debug_buffer[i] = riscv_read_debug_buffer(t, i);
75 for (size_t i = GDB_REGNO_ZERO; i <= GDB_REGNO_XPR31; ++i)
76 if (p->writes_xreg[i])
77 riscv_set_register(t, i, saved_registers[i]);
82 int riscv_program_swr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
84 return riscv_program_insert(p, sw(d, b, offset));
87 int riscv_program_shr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
89 return riscv_program_insert(p, sh(d, b, offset));
92 int riscv_program_sbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
94 return riscv_program_insert(p, sb(d, b, offset));
97 int riscv_program_lwr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
99 return riscv_program_insert(p, lw(d, b, offset));
102 int riscv_program_lhr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
104 return riscv_program_insert(p, lh(d, b, offset));
107 int riscv_program_lbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
109 return riscv_program_insert(p, lb(d, b, offset));
112 int riscv_program_csrr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno csr)
114 assert(csr >= GDB_REGNO_CSR0 && csr <= GDB_REGNO_CSR4095);
115 return riscv_program_insert(p, csrrs(d, GDB_REGNO_ZERO, csr - GDB_REGNO_CSR0));
118 int riscv_program_csrw(struct riscv_program *p, enum gdb_regno s, enum gdb_regno csr)
120 assert(csr >= GDB_REGNO_CSR0);
121 return riscv_program_insert(p, csrrw(GDB_REGNO_ZERO, s, csr - GDB_REGNO_CSR0));
124 int riscv_program_fence_i(struct riscv_program *p)
126 return riscv_program_insert(p, fence_i());
129 int riscv_program_fence(struct riscv_program *p)
131 return riscv_program_insert(p, fence());
134 int riscv_program_ebreak(struct riscv_program *p)
136 struct target *target = p->target;
138 if (p->instruction_count == riscv_debug_buffer_size(p->target) &&
142 return riscv_program_insert(p, ebreak());
145 int riscv_program_addi(struct riscv_program *p, enum gdb_regno d, enum gdb_regno s, int16_t u)
147 return riscv_program_insert(p, addi(d, s, u));
150 int riscv_program_insert(struct riscv_program *p, riscv_insn_t i)
152 if (p->instruction_count >= riscv_debug_buffer_size(p->target)) {
153 LOG_ERROR("Unable to insert instruction:");
154 LOG_ERROR(" instruction_count=%d", (int)p->instruction_count);
155 LOG_ERROR(" buffer size =%d", (int)riscv_debug_buffer_size(p->target));
159 p->debug_buffer[p->instruction_count] = i;
160 p->instruction_count++;