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 "debug_defines.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;
22 
23  for (unsigned int i = 0; i < RISCV013_MAX_PROGBUF_SIZE; ++i)
24  p->progbuf[i] = (uint32_t)(-1);
25 
27  return ERROR_OK;
28 }
29 
30 int riscv_program_write(struct riscv_program *program)
31 {
32  for (unsigned int i = 0; i < program->instruction_count; ++i) {
33  LOG_TARGET_DEBUG(program->target, "progbuf[%02x] = DASM(0x%08x)",
34  i, program->progbuf[i]);
35  if (riscv_write_progbuf(program->target, i, program->progbuf[i]) != ERROR_OK)
36  return ERROR_FAIL;
37  }
38  return ERROR_OK;
39 }
40 
42 int riscv_program_exec(struct riscv_program *p, struct target *t)
43 {
44  keep_alive();
45 
47 
48  if (riscv_program_ebreak(p) != ERROR_OK) {
49  LOG_TARGET_ERROR(t, "Unable to insert ebreak into program buffer");
50  for (unsigned int i = 0; i < riscv_progbuf_size(p->target); ++i)
51  LOG_TARGET_ERROR(t, "progbuf[%02x]: DASM(0x%08" PRIx32 ") [0x%08" PRIx32 "]",
52  i, p->progbuf[i], p->progbuf[i]);
53  return ERROR_FAIL;
54  }
55 
56  if (riscv_program_write(p) != ERROR_OK)
57  return ERROR_FAIL;
58 
59  uint32_t cmderr;
60  if (riscv_execute_progbuf(t, &cmderr) != ERROR_OK) {
64  /* TODO: what happens if we fail here, but need to restore registers? */
65  LOG_TARGET_DEBUG(t, "Unable to execute program %p", p);
66  return ERROR_FAIL;
67  }
69 
70  return ERROR_OK;
71 }
72 
73 int riscv_program_sdr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
74 {
75  return riscv_program_insert(p, sd(d, b, offset));
76 }
77 
78 int riscv_program_swr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
79 {
80  return riscv_program_insert(p, sw(d, b, offset));
81 }
82 
83 int riscv_program_shr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
84 {
85  return riscv_program_insert(p, sh(d, b, offset));
86 }
87 
88 int riscv_program_sbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
89 {
90  return riscv_program_insert(p, sb(d, b, offset));
91 }
92 
93 int riscv_program_store(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset,
94  unsigned int size)
95 {
96  switch (size) {
97  case 1:
98  return riscv_program_sbr(p, d, b, offset);
99  case 2:
100  return riscv_program_shr(p, d, b, offset);
101  case 4:
102  return riscv_program_swr(p, d, b, offset);
103  case 8:
104  return riscv_program_sdr(p, d, b, offset);
105  }
106  assert(false && "Unsupported size");
107  return ERROR_FAIL;
108 }
109 
110 int riscv_program_ldr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
111 {
112  return riscv_program_insert(p, ld(d, b, offset));
113 }
114 
115 int riscv_program_lwr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
116 {
117  return riscv_program_insert(p, lw(d, b, offset));
118 }
119 
120 int riscv_program_lhr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
121 {
122  return riscv_program_insert(p, lh(d, b, offset));
123 }
124 
125 int riscv_program_lbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
126 {
127  return riscv_program_insert(p, lb(d, b, offset));
128 }
129 
130 int riscv_program_load(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset,
131  unsigned int size)
132 {
133  switch (size) {
134  case 1:
135  return riscv_program_lbr(p, d, b, offset);
136  case 2:
137  return riscv_program_lhr(p, d, b, offset);
138  case 4:
139  return riscv_program_lwr(p, d, b, offset);
140  case 8:
141  return riscv_program_ldr(p, d, b, offset);
142  }
143  assert(false && "Unsupported size");
144  return ERROR_FAIL;
145 }
146 
147 int riscv_program_csrrsi(struct riscv_program *p, enum gdb_regno d, uint8_t z, enum gdb_regno csr)
148 {
149  assert(csr >= GDB_REGNO_CSR0 && csr <= GDB_REGNO_CSR4095);
150  return riscv_program_insert(p, csrrsi(d, z, csr - GDB_REGNO_CSR0));
151 }
152 
153 int riscv_program_csrrci(struct riscv_program *p, enum gdb_regno d, uint8_t z, enum gdb_regno csr)
154 {
155  assert(csr >= GDB_REGNO_CSR0 && csr <= GDB_REGNO_CSR4095);
156  return riscv_program_insert(p, csrrci(d, z, csr - GDB_REGNO_CSR0));
157 }
158 
160 {
161  assert(csr >= GDB_REGNO_CSR0 && csr <= GDB_REGNO_CSR4095);
163 }
164 
166 {
167  assert(csr >= GDB_REGNO_CSR0 && csr <= GDB_REGNO_CSR4095);
169 }
170 
172 {
173  return riscv_program_insert(p, fence_i());
174 }
175 
177 {
178  return riscv_program_insert(p, fence_rw_rw());
179 }
180 
182 {
183  struct target *target = p->target;
184  RISCV_INFO(r);
186  r->get_impebreak(target)) {
187  return ERROR_OK;
188  }
189  return riscv_program_insert(p, ebreak());
190 }
191 
192 int riscv_program_addi(struct riscv_program *p, enum gdb_regno d, enum gdb_regno s, int16_t u)
193 {
194  return riscv_program_insert(p, addi(d, s, u));
195 }
196 
198 {
200  LOG_TARGET_ERROR(p->target, "Unable to insert program into progbuf, "
201  "capacity would be exceeded (progbufsize=%u).",
203  return ERROR_FAIL;
204  }
205 
206  p->progbuf[p->instruction_count] = i;
207  p->instruction_count++;
208  return ERROR_OK;
209 }
#define DM_ABSTRACTCS_CMDERR_EXCEPTION
uint32_t size
Size of dw_spi_transaction::buffer.
Definition: dw-spi-helper.h:4
uint8_t csr
Definition: esirisc.c:136
gdb_regno
Definition: gdb_regs.h:10
@ GDB_REGNO_CSR0
Definition: gdb_regs.h:82
@ GDB_REGNO_ZERO
Definition: gdb_regs.h:11
@ GDB_REGNO_CSR4095
Definition: gdb_regs.h:111
void keep_alive(void)
Definition: log.c:429
#define ERROR_FAIL
Definition: log.h:175
#define LOG_TARGET_ERROR(target, fmt_str,...)
Definition: log.h:163
#define LOG_TARGET_DEBUG(target, fmt_str,...)
Definition: log.h:151
#define ERROR_OK
Definition: log.h:169
static uint32_t fence_rw_rw(void) __attribute__((unused))
Definition: opcodes.h:385
static uint32_t csrrw(unsigned int rd, unsigned int rs, unsigned int csr) __attribute__((unused))
Definition: opcodes.h:230
static uint32_t sb(unsigned int src, unsigned int base, int16_t offset) __attribute__((unused))
Definition: opcodes.h:142
static uint32_t sd(unsigned int src, unsigned int base, int16_t offset) __attribute__((unused))
Definition: opcodes.h:122
static uint32_t csrrs(unsigned int rd, unsigned int rs, unsigned int csr) __attribute__((unused))
Definition: opcodes.h:220
static uint32_t ld(unsigned int rd, unsigned int base, int16_t offset) __attribute__((unused))
Definition: opcodes.h:152
static uint32_t fence_i(void) __attribute__((unused))
Definition: opcodes.h:350
static uint32_t lw(unsigned int rd, unsigned int base, int16_t offset) __attribute__((unused))
Definition: opcodes.h:162
static uint32_t lh(unsigned int rd, unsigned int base, int16_t offset) __attribute__((unused))
Definition: opcodes.h:172
static uint32_t ebreak(void) __attribute__((unused))
Definition: opcodes.h:336
static uint32_t csrrsi(unsigned int rd, uint8_t zimm, unsigned int csr) __attribute__((unused))
Definition: opcodes.h:250
static uint32_t csrrci(unsigned int rd, uint8_t zimm, unsigned int csr) __attribute__((unused))
Definition: opcodes.h:240
static uint32_t sh(unsigned int src, unsigned int base, int16_t offset) __attribute__((unused))
Definition: opcodes.h:132
static uint32_t addi(unsigned int dest, unsigned int src, int16_t imm) __attribute__((unused))
Definition: opcodes.h:201
static uint32_t sw(unsigned int src, unsigned int base, int16_t offset) __attribute__((unused))
Definition: opcodes.h:112
static uint32_t lb(unsigned int rd, unsigned int base, int16_t offset) __attribute__((unused))
Definition: opcodes.h:182
int riscv_program_fence_i(struct riscv_program *p)
Definition: program.c:171
int riscv_program_swr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
Definition: program.c:78
int riscv_program_lbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
Definition: program.c:125
int riscv_program_write(struct riscv_program *program)
Definition: program.c:30
int riscv_program_shr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
Definition: program.c:83
int riscv_program_fence_rw_rw(struct riscv_program *p)
Definition: program.c:176
int riscv_program_store(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset, unsigned int size)
Definition: program.c:93
int riscv_program_csrrsi(struct riscv_program *p, enum gdb_regno d, uint8_t z, enum gdb_regno csr)
Definition: program.c:147
int riscv_program_addi(struct riscv_program *p, enum gdb_regno d, enum gdb_regno s, int16_t u)
Definition: program.c:192
int riscv_program_csrrci(struct riscv_program *p, enum gdb_regno d, uint8_t z, enum gdb_regno csr)
Definition: program.c:153
int riscv_program_insert(struct riscv_program *p, riscv_insn_t i)
Definition: program.c:197
int riscv_program_load(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset, unsigned int size)
Definition: program.c:130
int riscv_program_csrr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno csr)
Definition: program.c:159
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:165
int riscv_program_ldr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
Definition: program.c:110
int riscv_program_ebreak(struct riscv_program *p)
Definition: program.c:181
int riscv_program_sdr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
Definition: program.c:73
int riscv_program_exec(struct riscv_program *p, struct target *t)
Add ebreak and execute the program.
Definition: program.c:42
int riscv_program_lwr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
Definition: program.c:115
int riscv_program_lhr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
Definition: program.c:120
int riscv_program_sbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
Definition: program.c:88
#define RISCV013_MAX_PROGBUF_SIZE
Definition: program.h:8
@ RISCV_PROGBUF_EXEC_RESULT_EXCEPTION
Definition: program.h:13
@ RISCV_PROGBUF_EXEC_RESULT_UNKNOWN
Definition: program.h:12
@ RISCV_PROGBUF_EXEC_RESULT_SUCCESS
Definition: program.h:15
@ RISCV_PROGBUF_EXEC_RESULT_NOT_EXECUTED
Definition: program.h:11
@ RISCV_PROGBUF_EXEC_RESULT_UNKNOWN_ERROR
Definition: program.h:14
unsigned int riscv_progbuf_size(struct target *target)
Definition: riscv.c:6089
int riscv_write_progbuf(struct target *target, unsigned int index, riscv_insn_t insn)
Definition: riscv.c:6095
int riscv_execute_progbuf(struct target *target, uint32_t *cmderr)
Definition: riscv.c:6107
#define RISCV_INFO(R)
Definition: riscv.h:426
uint32_t riscv_insn_t
Definition: riscv.h:47
struct target * target
Definition: rtt/rtt.c:26
enum riscv_progbuf_exec_result execution_result
Definition: program.h:31
struct target * target
Definition: program.h:22
uint32_t progbuf[RISCV013_MAX_PROGBUF_SIZE]
Definition: program.h:24
unsigned int instruction_count
Definition: program.h:27
Definition: target.h:119
uint8_t offset[4]
Definition: vdebug.c:9