1 // SPDX-License-Identifier: GPL-2.0-or-later
7 #include "target/target.h"
8 #include "target/register.h"
11 #include "helper/log.h"
16 /* Program interface. */
17 int riscv_program_init(struct riscv_program *p, struct target *target)
19 memset(p, 0, sizeof(*p));
21 p->instruction_count = 0;
22 p->target_xlen = riscv_xlen(target);
23 for (size_t i = 0; i < RISCV_REGISTER_COUNT; ++i)
24 p->writes_xreg[i] = 0;
26 for (size_t i = 0; i < RISCV_MAX_DEBUG_BUFFER_SIZE; ++i)
27 p->debug_buffer[i] = -1;
32 int riscv_program_write(struct riscv_program *program)
34 for (unsigned i = 0; i < program->instruction_count; ++i) {
35 LOG_DEBUG("debug_buffer[%02x] = DASM(0x%08x)", i, program->debug_buffer[i]);
36 if (riscv_write_debug_buffer(program->target, i,
37 program->debug_buffer[i]) != ERROR_OK)
43 /** Add ebreak and execute the program. */
44 int riscv_program_exec(struct riscv_program *p, struct target *t)
48 riscv_reg_t saved_registers[GDB_REGNO_XPR31 + 1];
49 for (size_t i = GDB_REGNO_ZERO + 1; i <= GDB_REGNO_XPR31; ++i) {
50 if (p->writes_xreg[i]) {
51 LOG_DEBUG("Saving register %d as used by program", (int)i);
52 int result = riscv_get_register(t, &saved_registers[i], i);
53 if (result != ERROR_OK)
58 if (riscv_program_ebreak(p) != ERROR_OK) {
59 LOG_ERROR("Unable to write ebreak");
60 for (size_t i = 0; i < riscv_debug_buffer_size(p->target); ++i)
61 LOG_ERROR("ram[%02x]: DASM(0x%08" PRIx32 ") [0x%08" PRIx32 "]",
62 (int)i, p->debug_buffer[i], p->debug_buffer[i]);
66 if (riscv_program_write(p) != ERROR_OK)
69 if (riscv_execute_debug_buffer(t) != ERROR_OK) {
70 LOG_DEBUG("Unable to execute program %p", p);
74 for (size_t i = 0; i < riscv_debug_buffer_size(p->target); ++i)
75 if (i >= riscv_debug_buffer_size(p->target))
76 p->debug_buffer[i] = riscv_read_debug_buffer(t, i);
78 for (size_t i = GDB_REGNO_ZERO; i <= GDB_REGNO_XPR31; ++i)
79 if (p->writes_xreg[i])
80 riscv_set_register(t, i, saved_registers[i]);
85 int riscv_program_sdr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
87 return riscv_program_insert(p, sd(d, b, offset));
90 int riscv_program_swr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
92 return riscv_program_insert(p, sw(d, b, offset));
95 int riscv_program_shr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
97 return riscv_program_insert(p, sh(d, b, offset));
100 int riscv_program_sbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
102 return riscv_program_insert(p, sb(d, b, offset));
105 int riscv_program_ldr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
107 return riscv_program_insert(p, ld(d, b, offset));
110 int riscv_program_lwr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
112 return riscv_program_insert(p, lw(d, b, offset));
115 int riscv_program_lhr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
117 return riscv_program_insert(p, lh(d, b, offset));
120 int riscv_program_lbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
122 return riscv_program_insert(p, lb(d, b, offset));
125 int riscv_program_csrrsi(struct riscv_program *p, enum gdb_regno d, unsigned int z, enum gdb_regno csr)
127 assert(csr >= GDB_REGNO_CSR0 && csr <= GDB_REGNO_CSR4095);
128 return riscv_program_insert(p, csrrsi(d, z, csr - GDB_REGNO_CSR0));
131 int riscv_program_csrrci(struct riscv_program *p, enum gdb_regno d, unsigned int z, enum gdb_regno csr)
133 assert(csr >= GDB_REGNO_CSR0 && csr <= GDB_REGNO_CSR4095);
134 return riscv_program_insert(p, csrrci(d, z, csr - GDB_REGNO_CSR0));
137 int riscv_program_csrr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno csr)
139 assert(csr >= GDB_REGNO_CSR0 && csr <= GDB_REGNO_CSR4095);
140 return riscv_program_insert(p, csrrs(d, GDB_REGNO_ZERO, csr - GDB_REGNO_CSR0));
143 int riscv_program_csrw(struct riscv_program *p, enum gdb_regno s, enum gdb_regno csr)
145 assert(csr >= GDB_REGNO_CSR0);
146 return riscv_program_insert(p, csrrw(GDB_REGNO_ZERO, s, csr - GDB_REGNO_CSR0));
149 int riscv_program_fence_i(struct riscv_program *p)
151 return riscv_program_insert(p, fence_i());
154 int riscv_program_fence(struct riscv_program *p)
156 return riscv_program_insert(p, fence());
159 int riscv_program_ebreak(struct riscv_program *p)
161 struct target *target = p->target;
163 if (p->instruction_count == riscv_debug_buffer_size(p->target) &&
167 return riscv_program_insert(p, ebreak());
170 int riscv_program_addi(struct riscv_program *p, enum gdb_regno d, enum gdb_regno s, int16_t u)
172 return riscv_program_insert(p, addi(d, s, u));
175 int riscv_program_insert(struct riscv_program *p, riscv_insn_t i)
177 if (p->instruction_count >= riscv_debug_buffer_size(p->target)) {
178 LOG_ERROR("Unable to insert instruction:");
179 LOG_ERROR(" instruction_count=%d", (int)p->instruction_count);
180 LOG_ERROR(" buffer size =%d", (int)riscv_debug_buffer_size(p->target));
184 p->debug_buffer[p->instruction_count] = i;
185 p->instruction_count++;