arm_adi_v5: add ap refcount and add get/put around ap use
[openocd.git] / src / target / mem_ap.c
blob86bb29f2127faa583b5cce06864e972e9fb79d6b
1 /*****************************************************************************
2 * Copyright (C) 2016 by Matthias Welwarsky <matthias.welwarsky@sysgo.com> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 ****************************************************************************/
15 #ifdef HAVE_CONFIG_H
16 #include "config.h"
17 #endif
19 #include "target.h"
20 #include "target_type.h"
21 #include "arm_adi_v5.h"
22 #include "register.h"
24 #include <jtag/jtag.h>
26 #define MEM_AP_COMMON_MAGIC 0x4DE4DA50
28 struct mem_ap {
29 int common_magic;
30 struct adiv5_dap *dap;
31 struct adiv5_ap *ap;
32 int ap_num;
35 static int mem_ap_target_create(struct target *target, Jim_Interp *interp)
37 struct mem_ap *mem_ap;
38 struct adiv5_private_config *pc;
40 pc = (struct adiv5_private_config *)target->private_config;
41 if (!pc)
42 return ERROR_FAIL;
44 if (pc->ap_num == DP_APSEL_INVALID) {
45 LOG_ERROR("AP number not specified");
46 return ERROR_FAIL;
49 mem_ap = calloc(1, sizeof(struct mem_ap));
50 if (!mem_ap) {
51 LOG_ERROR("Out of memory");
52 return ERROR_FAIL;
55 mem_ap->ap_num = pc->ap_num;
56 mem_ap->common_magic = MEM_AP_COMMON_MAGIC;
57 mem_ap->dap = pc->dap;
59 target->arch_info = mem_ap;
61 if (!target->gdb_port_override)
62 target->gdb_port_override = strdup("disabled");
64 return ERROR_OK;
67 static int mem_ap_init_target(struct command_context *cmd_ctx, struct target *target)
69 LOG_DEBUG("%s", __func__);
70 target->state = TARGET_UNKNOWN;
71 target->debug_reason = DBG_REASON_UNDEFINED;
72 return ERROR_OK;
75 static void mem_ap_deinit_target(struct target *target)
77 struct mem_ap *mem_ap = target->arch_info;
79 LOG_DEBUG("%s", __func__);
81 if (mem_ap->ap)
82 dap_put_ap(mem_ap->ap);
84 free(target->private_config);
85 free(target->arch_info);
86 return;
89 static int mem_ap_arch_state(struct target *target)
91 LOG_DEBUG("%s", __func__);
92 return ERROR_OK;
95 static int mem_ap_poll(struct target *target)
97 if (target->state == TARGET_UNKNOWN) {
98 target->state = TARGET_RUNNING;
99 target->debug_reason = DBG_REASON_NOTHALTED;
102 return ERROR_OK;
105 static int mem_ap_halt(struct target *target)
107 LOG_DEBUG("%s", __func__);
108 target->state = TARGET_HALTED;
109 target->debug_reason = DBG_REASON_DBGRQ;
110 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
111 return ERROR_OK;
114 static int mem_ap_resume(struct target *target, int current, target_addr_t address,
115 int handle_breakpoints, int debug_execution)
117 LOG_DEBUG("%s", __func__);
118 target->state = TARGET_RUNNING;
119 target->debug_reason = DBG_REASON_NOTHALTED;
120 return ERROR_OK;
123 static int mem_ap_step(struct target *target, int current, target_addr_t address,
124 int handle_breakpoints)
126 LOG_DEBUG("%s", __func__);
127 target->state = TARGET_HALTED;
128 target->debug_reason = DBG_REASON_DBGRQ;
129 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
130 return ERROR_OK;
133 static int mem_ap_assert_reset(struct target *target)
135 target->state = TARGET_RESET;
136 target->debug_reason = DBG_REASON_UNDEFINED;
138 LOG_DEBUG("%s", __func__);
139 return ERROR_OK;
142 static int mem_ap_examine(struct target *target)
144 struct mem_ap *mem_ap = target->arch_info;
146 if (!target_was_examined(target)) {
147 if (mem_ap->ap) {
148 dap_put_ap(mem_ap->ap);
149 mem_ap->ap = NULL;
152 mem_ap->ap = dap_get_ap(mem_ap->dap, mem_ap->ap_num);
153 if (!mem_ap->ap) {
154 LOG_ERROR("Cannot get AP");
155 return ERROR_FAIL;
157 target_set_examined(target);
158 target->state = TARGET_UNKNOWN;
159 target->debug_reason = DBG_REASON_UNDEFINED;
160 return mem_ap_init(mem_ap->ap);
163 return ERROR_OK;
166 static int mem_ap_deassert_reset(struct target *target)
168 if (target->reset_halt) {
169 target->state = TARGET_HALTED;
170 target->debug_reason = DBG_REASON_DBGRQ;
171 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
172 } else {
173 target->state = TARGET_RUNNING;
174 target->debug_reason = DBG_REASON_NOTHALTED;
177 LOG_DEBUG("%s", __func__);
178 return ERROR_OK;
181 static int mem_ap_reg_get(struct reg *reg)
183 return ERROR_OK;
186 static int mem_ap_reg_set(struct reg *reg, uint8_t *buf)
188 return ERROR_OK;
191 static struct reg_arch_type mem_ap_reg_arch_type = {
192 .get = mem_ap_reg_get,
193 .set = mem_ap_reg_set,
196 const char *mem_ap_get_gdb_arch(struct target *target)
198 return "arm";
202 * Dummy ARM register emulation:
203 * reg[0..15]: 32 bits, r0~r12, sp, lr, pc
204 * reg[16..23]: 96 bits, f0~f7
205 * reg[24]: 32 bits, fps
206 * reg[25]: 32 bits, cpsr
208 * Set 'exist' only to reg[0..15], so initial response to GDB is correct
210 #define NUM_REGS 26
211 #define MAX_REG_SIZE 96
212 #define REG_EXIST(n) ((n) < 16)
213 #define REG_SIZE(n) ((((n) >= 16) && ((n) < 24)) ? 96 : 32)
215 struct mem_ap_alloc_reg_list {
216 /* reg_list must be the first field */
217 struct reg *reg_list[NUM_REGS];
218 struct reg regs[NUM_REGS];
219 uint8_t regs_value[MAX_REG_SIZE / 8];
222 static int mem_ap_get_gdb_reg_list(struct target *target, struct reg **reg_list[],
223 int *reg_list_size, enum target_register_class reg_class)
225 struct mem_ap_alloc_reg_list *mem_ap_alloc = calloc(1, sizeof(struct mem_ap_alloc_reg_list));
226 if (!mem_ap_alloc) {
227 LOG_ERROR("Out of memory");
228 return ERROR_FAIL;
231 *reg_list = mem_ap_alloc->reg_list;
232 *reg_list_size = NUM_REGS;
233 struct reg *regs = mem_ap_alloc->regs;
235 for (int i = 0; i < NUM_REGS; i++) {
236 regs[i].number = i;
237 regs[i].value = mem_ap_alloc->regs_value;
238 regs[i].size = REG_SIZE(i);
239 regs[i].exist = REG_EXIST(i);
240 regs[i].type = &mem_ap_reg_arch_type;
241 (*reg_list)[i] = &regs[i];
244 return ERROR_OK;
247 static int mem_ap_read_memory(struct target *target, target_addr_t address,
248 uint32_t size, uint32_t count, uint8_t *buffer)
250 struct mem_ap *mem_ap = target->arch_info;
252 LOG_DEBUG("Reading memory at physical address " TARGET_ADDR_FMT
253 "; size %" PRIu32 "; count %" PRIu32, address, size, count);
255 if (count == 0 || !buffer)
256 return ERROR_COMMAND_SYNTAX_ERROR;
258 return mem_ap_read_buf(mem_ap->ap, buffer, size, count, address);
261 static int mem_ap_write_memory(struct target *target, target_addr_t address,
262 uint32_t size, uint32_t count,
263 const uint8_t *buffer)
265 struct mem_ap *mem_ap = target->arch_info;
267 LOG_DEBUG("Writing memory at physical address " TARGET_ADDR_FMT
268 "; size %" PRIu32 "; count %" PRIu32, address, size, count);
270 if (count == 0 || !buffer)
271 return ERROR_COMMAND_SYNTAX_ERROR;
273 return mem_ap_write_buf(mem_ap->ap, buffer, size, count, address);
276 struct target_type mem_ap_target = {
277 .name = "mem_ap",
279 .target_create = mem_ap_target_create,
280 .init_target = mem_ap_init_target,
281 .deinit_target = mem_ap_deinit_target,
282 .examine = mem_ap_examine,
283 .target_jim_configure = adiv5_jim_configure,
285 .poll = mem_ap_poll,
286 .arch_state = mem_ap_arch_state,
288 .halt = mem_ap_halt,
289 .resume = mem_ap_resume,
290 .step = mem_ap_step,
292 .assert_reset = mem_ap_assert_reset,
293 .deassert_reset = mem_ap_deassert_reset,
295 .get_gdb_arch = mem_ap_get_gdb_arch,
296 .get_gdb_reg_list = mem_ap_get_gdb_reg_list,
298 .read_memory = mem_ap_read_memory,
299 .write_memory = mem_ap_write_memory,