OpenOCD
program.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
6 
7 #include "target/target.h"
8 #include "target/register.h"
9 #include "riscv.h"
10 #include "program.h"
11 #include "helper/log.h"
12 
13 #include "asm.h"
14 #include "encoding.h"
15 
16 /* Program interface. */
18 {
19  memset(p, 0, sizeof(*p));
20  p->target = target;
21  p->instruction_count = 0;
23  for (size_t i = 0; i < RISCV_REGISTER_COUNT; ++i)
24  p->writes_xreg[i] = 0;
25 
26  for (size_t i = 0; i < RISCV_MAX_DEBUG_BUFFER_SIZE; ++i)
27  p->debug_buffer[i] = -1;
28 
29  return ERROR_OK;
30 }
31 
32 int riscv_program_write(struct riscv_program *program)
33 {
34  for (unsigned int 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)
38  return ERROR_FAIL;
39  }
40  return ERROR_OK;
41 }
42 
44 int riscv_program_exec(struct riscv_program *p, struct target *t)
45 {
46  keep_alive();
47 
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)
54  return result;
55  }
56  }
57 
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]);
63  return ERROR_FAIL;
64  }
65 
66  if (riscv_program_write(p) != ERROR_OK)
67  return ERROR_FAIL;
68 
70  LOG_DEBUG("Unable to execute program %p", p);
71  return ERROR_FAIL;
72  }
73 
74  for (size_t i = 0; i < riscv_debug_buffer_size(p->target); ++i)
75  if (i >= riscv_debug_buffer_size(p->target))
77 
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]);
81 
82  return ERROR_OK;
83 }
84 
85 int riscv_program_sdr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
86 {
87  return riscv_program_insert(p, sd(d, b, offset));
88 }
89 
90 int riscv_program_swr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
91 {
92  return riscv_program_insert(p, sw(d, b, offset));
93 }
94 
95 int riscv_program_shr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
96 {
97  return riscv_program_insert(p, sh(d, b, offset));
98 }
99 
100 int riscv_program_sbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
101 {
102  return riscv_program_insert(p, sb(d, b, offset));
103 }
104 
105 int riscv_program_ldr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
106 {
107  return riscv_program_insert(p, ld(d, b, offset));
108 }
109 
110 int riscv_program_lwr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
111 {
112  return riscv_program_insert(p, lw(d, b, offset));
113 }
114 
115 int riscv_program_lhr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
116 {
117  return riscv_program_insert(p, lh(d, b, offset));
118 }
119 
120 int riscv_program_lbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
121 {
122  return riscv_program_insert(p, lb(d, b, offset));
123 }
124 
125 int riscv_program_csrrsi(struct riscv_program *p, enum gdb_regno d, unsigned int z, enum gdb_regno csr)
126 {
127  assert(csr >= GDB_REGNO_CSR0 && csr <= GDB_REGNO_CSR4095);
128  return riscv_program_insert(p, csrrsi(d, z, csr - GDB_REGNO_CSR0));
129 }
130 
131 int riscv_program_csrrci(struct riscv_program *p, enum gdb_regno d, unsigned int z, enum gdb_regno csr)
132 {
133  assert(csr >= GDB_REGNO_CSR0 && csr <= GDB_REGNO_CSR4095);
134  return riscv_program_insert(p, csrrci(d, z, csr - GDB_REGNO_CSR0));
135 }
136 
138 {
139  assert(csr >= GDB_REGNO_CSR0 && csr <= GDB_REGNO_CSR4095);
141 }
142 
144 {
145  assert(csr >= GDB_REGNO_CSR0);
147 }
148 
150 {
151  return riscv_program_insert(p, fence_i());
152 }
153 
155 {
156  return riscv_program_insert(p, fence());
157 }
158 
160 {
161  struct target *target = p->target;
162  RISCV_INFO(r);
164  r->impebreak) {
165  return ERROR_OK;
166  }
167  return riscv_program_insert(p, ebreak());
168 }
169 
170 int riscv_program_addi(struct riscv_program *p, enum gdb_regno d, enum gdb_regno s, int16_t u)
171 {
172  return riscv_program_insert(p, addi(d, s, u));
173 }
174 
176 {
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));
181  return ERROR_FAIL;
182  }
183 
184  p->debug_buffer[p->instruction_count] = i;
185  p->instruction_count++;
186  return ERROR_OK;
187 }
uint8_t csr
Definition: esirisc.c:136
gdb_regno
Definition: gdb_regs.h:8
@ GDB_REGNO_CSR0
Definition: gdb_regs.h:80
@ GDB_REGNO_ZERO
Definition: gdb_regs.h:9
@ GDB_REGNO_XPR31
Definition: gdb_regs.h:43
@ GDB_REGNO_CSR4095
Definition: gdb_regs.h:98
void keep_alive(void)
Definition: log.c:415
#define ERROR_FAIL
Definition: log.h:170
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:164
static uint32_t csrrw(unsigned int rd, unsigned int rs, unsigned int csr) __attribute__((unused))
Definition: opcodes.h:153
static uint32_t lb(unsigned int rd, unsigned int base, uint16_t offset) __attribute__((unused))
Definition: opcodes.h:123
static uint32_t csrrs(unsigned int rd, unsigned int rs, unsigned int csr) __attribute__((unused))
Definition: opcodes.h:147
static uint32_t fence(void) __attribute__((unused))
Definition: opcodes.h:298
static uint32_t fence_i(void) __attribute__((unused))
Definition: opcodes.h:233
static uint32_t lh(unsigned int rd, unsigned int base, uint16_t offset) __attribute__((unused))
Definition: opcodes.h:117
static uint32_t csrrci(unsigned int rd, unsigned int zimm, unsigned int csr) __attribute__((unused))
Definition: opcodes.h:159
static uint32_t sh(unsigned int src, unsigned int base, uint16_t offset) __attribute__((unused))
Definition: opcodes.h:93
static uint32_t sw(unsigned int src, unsigned int base, uint16_t offset) __attribute__((unused))
Definition: opcodes.h:81
static uint32_t ebreak(void) __attribute__((unused))
Definition: opcodes.h:219
static uint32_t csrrsi(unsigned int rd, unsigned int zimm, unsigned int csr) __attribute__((unused))
Definition: opcodes.h:165
static uint32_t ld(unsigned int rd, unsigned int base, uint16_t offset) __attribute__((unused))
Definition: opcodes.h:105
static uint32_t sd(unsigned int src, unsigned int base, uint16_t offset) __attribute__((unused))
Definition: opcodes.h:87
static uint32_t sb(unsigned int src, unsigned int base, uint16_t offset) __attribute__((unused))
Definition: opcodes.h:99
static uint32_t lw(unsigned int rd, unsigned int base, uint16_t offset) __attribute__((unused))
Definition: opcodes.h:111
static uint32_t addi(unsigned int dest, unsigned int src, uint16_t imm) __attribute__((unused))
Definition: opcodes.h:135
int riscv_program_fence_i(struct riscv_program *p)
Definition: program.c:149
int riscv_program_lbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
Definition: program.c:120
int riscv_program_write(struct riscv_program *program)
Definition: program.c:32
int riscv_program_fence(struct riscv_program *p)
Definition: program.c:154
int riscv_program_csrrsi(struct riscv_program *p, enum gdb_regno d, unsigned int z, enum gdb_regno csr)
Definition: program.c:125
int riscv_program_addi(struct riscv_program *p, enum gdb_regno d, enum gdb_regno s, int16_t u)
Definition: program.c:170
int riscv_program_ldr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
Definition: program.c:105
int riscv_program_insert(struct riscv_program *p, riscv_insn_t i)
Definition: program.c:175
int riscv_program_csrr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno csr)
Definition: program.c:137
int riscv_program_init(struct riscv_program *p, struct target *target)
Definition: program.c:17
int riscv_program_csrw(struct riscv_program *p, enum gdb_regno s, enum gdb_regno csr)
Definition: program.c:143
int riscv_program_lhr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
Definition: program.c:115
int riscv_program_ebreak(struct riscv_program *p)
Definition: program.c:159
int riscv_program_swr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
Definition: program.c:90
int riscv_program_lwr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
Definition: program.c:110
int riscv_program_sdr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
Definition: program.c:85
int riscv_program_shr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
Definition: program.c:95
int riscv_program_exec(struct riscv_program *p, struct target *t)
Add ebreak and execute the program.
Definition: program.c:44
int riscv_program_csrrci(struct riscv_program *p, enum gdb_regno d, unsigned int z, enum gdb_regno csr)
Definition: program.c:131
int riscv_program_sbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
Definition: program.c:100
#define RISCV_MAX_DEBUG_BUFFER_SIZE
Definition: program.h:8
#define RISCV_REGISTER_COUNT
Definition: program.h:9
unsigned int riscv_xlen(const struct target *target)
Definition: riscv.c:3207
int riscv_set_register(struct target *target, enum gdb_regno regid, riscv_reg_t value)
This function is called when the debug user wants to change the value of a register.
Definition: riscv.c:3308
int riscv_write_debug_buffer(struct target *target, int index, riscv_insn_t insn)
Definition: riscv.c:3397
int riscv_execute_debug_buffer(struct target *target)
Definition: riscv.c:3410
size_t riscv_debug_buffer_size(struct target *target)
Definition: riscv.c:3391
int riscv_get_register(struct target *target, riscv_reg_t *value, enum gdb_regno regid)
Get register, from the cache if it's in there.
Definition: riscv.c:3334
riscv_insn_t riscv_read_debug_buffer(struct target *target, int index)
Definition: riscv.c:3404
#define RISCV_INFO(R)
Definition: riscv.h:271
uint64_t riscv_reg_t
Definition: riscv.h:41
uint32_t riscv_insn_t
Definition: riscv.h:42
struct target * target
Definition: rtt/rtt.c:26
int target_xlen
Definition: program.h:28
struct target * target
Definition: program.h:16
uint32_t debug_buffer[RISCV_MAX_DEBUG_BUFFER_SIZE]
Definition: program.h:18
bool writes_xreg[RISCV_REGISTER_COUNT]
Definition: program.h:25
size_t instruction_count
Definition: program.h:21
Definition: target.h:116
uint8_t offset[4]
Definition: vdebug.c:9