OpenOCD
mem_ap.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /*
4  * Copyright (C) 2016 by Matthias Welwarsky <matthias.welwarsky@sysgo.com>
5  */
6 
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10 
11 #include "target.h"
12 #include "target_type.h"
13 #include "arm_adi_v5.h"
14 #include "register.h"
15 
16 #include <jtag/jtag.h>
17 
18 #define MEM_AP_COMMON_MAGIC 0x4DE4DA50
19 
20 struct mem_ap {
22  struct adiv5_dap *dap;
23  struct adiv5_ap *ap;
24  uint64_t ap_num;
25 };
26 
27 static int mem_ap_target_create(struct target *target, Jim_Interp *interp)
28 {
29  struct mem_ap *mem_ap;
30  struct adiv5_private_config *pc;
31 
33  if (!pc)
34  return ERROR_FAIL;
35 
36  if (pc->ap_num == DP_APSEL_INVALID) {
37  LOG_ERROR("AP number not specified");
38  return ERROR_FAIL;
39  }
40 
41  mem_ap = calloc(1, sizeof(struct mem_ap));
42  if (!mem_ap) {
43  LOG_ERROR("Out of memory");
44  return ERROR_FAIL;
45  }
46 
47  mem_ap->ap_num = pc->ap_num;
49  mem_ap->dap = pc->dap;
50 
52 
54  target->gdb_port_override = strdup("disabled");
55 
56  return ERROR_OK;
57 }
58 
59 static int mem_ap_init_target(struct command_context *cmd_ctx, struct target *target)
60 {
61  LOG_DEBUG("%s", __func__);
64  return ERROR_OK;
65 }
66 
67 static void mem_ap_deinit_target(struct target *target)
68 {
69  struct mem_ap *mem_ap = target->arch_info;
70 
71  LOG_DEBUG("%s", __func__);
72 
73  if (mem_ap->ap)
75 
76  free(target->private_config);
77  free(target->arch_info);
78  return;
79 }
80 
81 static int mem_ap_arch_state(struct target *target)
82 {
83  LOG_DEBUG("%s", __func__);
84  return ERROR_OK;
85 }
86 
87 static int mem_ap_poll(struct target *target)
88 {
89  if (target->state == TARGET_UNKNOWN) {
92  }
93 
94  return ERROR_OK;
95 }
96 
97 static int mem_ap_halt(struct target *target)
98 {
99  LOG_DEBUG("%s", __func__);
103  return ERROR_OK;
104 }
105 
106 static int mem_ap_resume(struct target *target, int current, target_addr_t address,
107  int handle_breakpoints, int debug_execution)
108 {
109  LOG_DEBUG("%s", __func__);
112  return ERROR_OK;
113 }
114 
115 static int mem_ap_step(struct target *target, int current, target_addr_t address,
116  int handle_breakpoints)
117 {
118  LOG_DEBUG("%s", __func__);
122  return ERROR_OK;
123 }
124 
125 static int mem_ap_assert_reset(struct target *target)
126 {
129 
130  LOG_DEBUG("%s", __func__);
131  return ERROR_OK;
132 }
133 
134 static int mem_ap_examine(struct target *target)
135 {
136  struct mem_ap *mem_ap = target->arch_info;
137 
138  if (!target_was_examined(target)) {
139  if (!mem_ap->ap) {
141  if (!mem_ap->ap) {
142  LOG_ERROR("Cannot get AP");
143  return ERROR_FAIL;
144  }
145  }
149  return mem_ap_init(mem_ap->ap);
150  }
151 
152  return ERROR_OK;
153 }
154 
156 {
157  if (target->reset_halt) {
161  } else {
164  }
165 
166  LOG_DEBUG("%s", __func__);
167  return ERROR_OK;
168 }
169 
170 static int mem_ap_reg_get(struct reg *reg)
171 {
172  return ERROR_OK;
173 }
174 
175 static int mem_ap_reg_set(struct reg *reg, uint8_t *buf)
176 {
177  return ERROR_OK;
178 }
179 
180 static struct reg_arch_type mem_ap_reg_arch_type = {
181  .get = mem_ap_reg_get,
182  .set = mem_ap_reg_set,
183 };
184 
185 static const char *mem_ap_get_gdb_arch(const struct target *target)
186 {
187  return "arm";
188 }
189 
190 /*
191  * Dummy ARM register emulation:
192  * reg[0..15]: 32 bits, r0~r12, sp, lr, pc
193  * reg[16..23]: 96 bits, f0~f7
194  * reg[24]: 32 bits, fps
195  * reg[25]: 32 bits, cpsr
196  *
197  * GDB requires only reg[0..15]
198  */
199 #define NUM_REGS 26
200 #define NUM_GDB_REGS 16
201 #define MAX_REG_SIZE 96
202 #define REG_SIZE(n) ((((n) >= 16) && ((n) < 24)) ? 96 : 32)
203 
205  /* reg_list must be the first field */
207  struct reg regs[NUM_REGS];
208  uint8_t regs_value[MAX_REG_SIZE / 8];
209 };
210 
211 static int mem_ap_get_gdb_reg_list(struct target *target, struct reg **reg_list[],
212  int *reg_list_size, enum target_register_class reg_class)
213 {
214  struct mem_ap_alloc_reg_list *mem_ap_alloc = calloc(1, sizeof(struct mem_ap_alloc_reg_list));
215  if (!mem_ap_alloc) {
216  LOG_ERROR("Out of memory");
217  return ERROR_FAIL;
218  }
219 
220  *reg_list = mem_ap_alloc->reg_list;
221  *reg_list_size = (reg_class == REG_CLASS_ALL) ? NUM_REGS : NUM_GDB_REGS;
222  struct reg *regs = mem_ap_alloc->regs;
223 
224  for (int i = 0; i < NUM_REGS; i++) {
225  regs[i].number = i;
226  regs[i].value = mem_ap_alloc->regs_value;
227  regs[i].size = REG_SIZE(i);
228  regs[i].exist = true;
229  regs[i].type = &mem_ap_reg_arch_type;
230  (*reg_list)[i] = &regs[i];
231  }
232 
233  return ERROR_OK;
234 }
235 
236 static int mem_ap_read_memory(struct target *target, target_addr_t address,
237  uint32_t size, uint32_t count, uint8_t *buffer)
238 {
239  struct mem_ap *mem_ap = target->arch_info;
240 
241  LOG_DEBUG("Reading memory at physical address " TARGET_ADDR_FMT
242  "; size %" PRIu32 "; count %" PRIu32, address, size, count);
243 
244  if (count == 0 || !buffer)
246 
247  return mem_ap_read_buf(mem_ap->ap, buffer, size, count, address);
248 }
249 
250 static int mem_ap_write_memory(struct target *target, target_addr_t address,
251  uint32_t size, uint32_t count,
252  const uint8_t *buffer)
253 {
254  struct mem_ap *mem_ap = target->arch_info;
255 
256  LOG_DEBUG("Writing memory at physical address " TARGET_ADDR_FMT
257  "; size %" PRIu32 "; count %" PRIu32, address, size, count);
258 
259  if (count == 0 || !buffer)
261 
262  return mem_ap_write_buf(mem_ap->ap, buffer, size, count, address);
263 }
264 
265 struct target_type mem_ap_target = {
266  .name = "mem_ap",
267 
268  .target_create = mem_ap_target_create,
269  .init_target = mem_ap_init_target,
270  .deinit_target = mem_ap_deinit_target,
271  .examine = mem_ap_examine,
272  .target_jim_configure = adiv5_jim_configure,
273 
274  .poll = mem_ap_poll,
275  .arch_state = mem_ap_arch_state,
276 
277  .halt = mem_ap_halt,
278  .resume = mem_ap_resume,
279  .step = mem_ap_step,
280 
281  .assert_reset = mem_ap_assert_reset,
282  .deassert_reset = mem_ap_deassert_reset,
283 
284  .get_gdb_arch = mem_ap_get_gdb_arch,
285  .get_gdb_reg_list = mem_ap_get_gdb_reg_list,
286 
287  .read_memory = mem_ap_read_memory,
288  .write_memory = mem_ap_write_memory,
289 };
int mem_ap_read_buf(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint32_t count, target_addr_t address)
Definition: arm_adi_v5.c:722
int adiv5_jim_configure(struct target *target, struct jim_getopt_info *goi)
Definition: arm_adi_v5.c:2467
struct adiv5_ap * dap_get_ap(struct adiv5_dap *dap, uint64_t ap_num)
Definition: arm_adi_v5.c:1188
int dap_put_ap(struct adiv5_ap *ap)
Definition: arm_adi_v5.c:1208
int mem_ap_init(struct adiv5_ap *ap)
Initialize a DAP.
Definition: arm_adi_v5.c:887
int mem_ap_write_buf(struct adiv5_ap *ap, const uint8_t *buffer, uint32_t size, uint32_t count, target_addr_t address)
Definition: arm_adi_v5.c:728
This defines formats and data structures used to talk to ADIv5 entities.
#define DP_APSEL_INVALID
Definition: arm_adi_v5.h:110
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:402
The JTAG interface can be implemented with a software or hardware fifo.
static const struct @108 regs[]
#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 int mem_ap_assert_reset(struct target *target)
Definition: mem_ap.c:125
static int mem_ap_poll(struct target *target)
Definition: mem_ap.c:87
static const char * mem_ap_get_gdb_arch(const struct target *target)
Definition: mem_ap.c:185
static int mem_ap_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size, enum target_register_class reg_class)
Definition: mem_ap.c:211
static int mem_ap_target_create(struct target *target, Jim_Interp *interp)
Definition: mem_ap.c:27
#define NUM_REGS
Definition: mem_ap.c:199
struct target_type mem_ap_target
Definition: mem_ap.c:265
static int mem_ap_reg_get(struct reg *reg)
Definition: mem_ap.c:170
static int mem_ap_examine(struct target *target)
Definition: mem_ap.c:134
static int mem_ap_halt(struct target *target)
Definition: mem_ap.c:97
#define MEM_AP_COMMON_MAGIC
Definition: mem_ap.c:18
static int mem_ap_write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
Definition: mem_ap.c:250
static int mem_ap_deassert_reset(struct target *target)
Definition: mem_ap.c:155
#define MAX_REG_SIZE
Definition: mem_ap.c:201
static int mem_ap_resume(struct target *target, int current, target_addr_t address, int handle_breakpoints, int debug_execution)
Definition: mem_ap.c:106
static int mem_ap_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
Definition: mem_ap.c:236
#define REG_SIZE(n)
Definition: mem_ap.c:202
static int mem_ap_arch_state(struct target *target)
Definition: mem_ap.c:81
static struct reg_arch_type mem_ap_reg_arch_type
Definition: mem_ap.c:180
static int mem_ap_reg_set(struct reg *reg, uint8_t *buf)
Definition: mem_ap.c:175
static void mem_ap_deinit_target(struct target *target)
Definition: mem_ap.c:67
static int mem_ap_step(struct target *target, int current, target_addr_t address, int handle_breakpoints)
Definition: mem_ap.c:115
#define NUM_GDB_REGS
Definition: mem_ap.c:200
static int mem_ap_init_target(struct command_context *cmd_ctx, struct target *target)
Definition: mem_ap.c:59
size_t size
Size of the control block search area.
Definition: rtt/rtt.c:30
This represents an ARM Debug Interface (v5) Access Port (AP).
Definition: arm_adi_v5.h:250
This represents an ARM Debug Interface (v5) Debug Access Port (DAP).
Definition: arm_adi_v5.h:348
struct adiv5_dap * dap
Definition: arm_adi_v5.h:787
struct reg regs[NUM_REGS]
Definition: mem_ap.c:207
uint8_t regs_value[MAX_REG_SIZE/8]
Definition: mem_ap.c:208
struct reg * reg_list[NUM_REGS]
Definition: mem_ap.c:206
Definition: mem_ap.c:20
int common_magic
Definition: mem_ap.c:21
struct adiv5_dap * dap
Definition: mem_ap.c:22
struct adiv5_ap * ap
Definition: mem_ap.c:23
uint64_t ap_num
Definition: mem_ap.c:24
int(* get)(struct reg *reg)
Definition: register.h:152
Definition: register.h:111
This holds methods shared between all instances of a given target type.
Definition: target_type.h:26
const char * name
Name of this type of target.
Definition: target_type.h:31
Definition: target.h:116
enum target_debug_reason debug_reason
Definition: target.h:154
enum target_state state
Definition: target.h:157
void * private_config
Definition: target.h:165
char * gdb_port_override
Definition: target.h:204
void * arch_info
Definition: target.h:164
bool reset_halt
Definition: target.h:144
int target_call_event_callbacks(struct target *target, enum target_event event)
Definition: target.c:1764
@ DBG_REASON_UNDEFINED
Definition: target.h:77
@ DBG_REASON_NOTHALTED
Definition: target.h:74
@ DBG_REASON_DBGRQ
Definition: target.h:69
target_register_class
Definition: target.h:110
@ REG_CLASS_ALL
Definition: target.h:111
static bool target_was_examined(const struct target *target)
Definition: target.h:436
@ TARGET_EVENT_HALTED
Definition: target.h:252
@ TARGET_RESET
Definition: target.h:57
@ TARGET_UNKNOWN
Definition: target.h:54
@ TARGET_HALTED
Definition: target.h:56
@ TARGET_RUNNING
Definition: target.h:55
static void target_set_examined(struct target *target)
Sets the examined flag for the given target.
Definition: target.h:443
#define TARGET_ADDR_FMT
Definition: types.h:342
uint64_t target_addr_t
Definition: types.h:335
uint8_t count[4]
Definition: vdebug.c:22