1 /*****************************************************************************
2 * Copyright (C) 2016 by Matthias Welwarsky <matthias.welwarsky@sysgo.com> *
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. *
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 ****************************************************************************/
20 #include "target_type.h"
22 #include "arm_adi_v5.h"
25 #include <jtag/jtag.h>
33 static int mem_ap_target_create(struct target *target, Jim_Interp *interp)
35 struct mem_ap *mem_ap;
36 struct adiv5_private_config *pc;
38 pc = (struct adiv5_private_config *)target->private_config;
42 if (pc->ap_num == DP_APSEL_INVALID) {
43 LOG_ERROR("AP number not specified");
47 mem_ap = calloc(1, sizeof(struct mem_ap));
49 LOG_ERROR("Out of memory");
53 mem_ap->ap_num = pc->ap_num;
54 mem_ap->arm.common_magic = ARM_COMMON_MAGIC;
55 mem_ap->arm.dap = pc->dap;
57 target->arch_info = mem_ap;
59 if (!target->gdb_port_override)
60 target->gdb_port_override = strdup("disabled");
65 static int mem_ap_init_target(struct command_context *cmd_ctx, struct target *target)
67 LOG_DEBUG("%s", __func__);
68 target->state = TARGET_UNKNOWN;
69 target->debug_reason = DBG_REASON_UNDEFINED;
73 static void mem_ap_deinit_target(struct target *target)
75 LOG_DEBUG("%s", __func__);
77 free(target->private_config);
78 free(target->arch_info);
82 static int mem_ap_arch_state(struct target *target)
84 LOG_DEBUG("%s", __func__);
88 static int mem_ap_poll(struct target *target)
90 if (target->state == TARGET_UNKNOWN) {
91 target->state = TARGET_RUNNING;
92 target->debug_reason = DBG_REASON_NOTHALTED;
98 static int mem_ap_halt(struct target *target)
100 LOG_DEBUG("%s", __func__);
101 target->state = TARGET_HALTED;
102 target->debug_reason = DBG_REASON_DBGRQ;
103 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
107 static int mem_ap_resume(struct target *target, int current, target_addr_t address,
108 int handle_breakpoints, int debug_execution)
110 LOG_DEBUG("%s", __func__);
111 target->state = TARGET_RUNNING;
112 target->debug_reason = DBG_REASON_NOTHALTED;
116 static int mem_ap_step(struct target *target, int current, target_addr_t address,
117 int handle_breakpoints)
119 LOG_DEBUG("%s", __func__);
120 target->state = TARGET_HALTED;
121 target->debug_reason = DBG_REASON_DBGRQ;
122 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
126 static int mem_ap_assert_reset(struct target *target)
128 target->state = TARGET_RESET;
129 target->debug_reason = DBG_REASON_UNDEFINED;
131 LOG_DEBUG("%s", __func__);
135 static int mem_ap_examine(struct target *target)
137 struct mem_ap *mem_ap = target->arch_info;
139 if (!target_was_examined(target)) {
140 mem_ap->ap = dap_ap(mem_ap->arm.dap, mem_ap->ap_num);
141 target_set_examined(target);
142 target->state = TARGET_UNKNOWN;
143 target->debug_reason = DBG_REASON_UNDEFINED;
144 return mem_ap_init(mem_ap->ap);
150 static int mem_ap_deassert_reset(struct target *target)
152 if (target->reset_halt) {
153 target->state = TARGET_HALTED;
154 target->debug_reason = DBG_REASON_DBGRQ;
155 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
157 target->state = TARGET_RUNNING;
158 target->debug_reason = DBG_REASON_NOTHALTED;
161 LOG_DEBUG("%s", __func__);
165 static int mem_ap_reg_get(struct reg *reg)
170 static int mem_ap_reg_set(struct reg *reg, uint8_t *buf)
175 static struct reg_arch_type mem_ap_reg_arch_type = {
176 .get = mem_ap_reg_get,
177 .set = mem_ap_reg_set,
180 const char *mem_ap_get_gdb_arch(struct target *target)
186 * Dummy ARM register emulation:
187 * reg[0..15]: 32 bits, r0~r12, sp, lr, pc
188 * reg[16..23]: 96 bits, f0~f7
189 * reg[24]: 32 bits, fps
190 * reg[25]: 32 bits, cpsr
192 * Set 'exist' only to reg[0..15], so initial response to GDB is correct
195 #define MAX_REG_SIZE 96
196 #define REG_EXIST(n) ((n) < 16)
197 #define REG_SIZE(n) ((((n) >= 16) && ((n) < 24)) ? 96 : 32)
199 struct mem_ap_alloc_reg_list {
200 /* reg_list must be the first field */
201 struct reg *reg_list[NUM_REGS];
202 struct reg regs[NUM_REGS];
203 uint8_t regs_value[MAX_REG_SIZE / 8];
206 static int mem_ap_get_gdb_reg_list(struct target *target, struct reg **reg_list[],
207 int *reg_list_size, enum target_register_class reg_class)
209 struct mem_ap_alloc_reg_list *mem_ap_alloc = calloc(1, sizeof(struct mem_ap_alloc_reg_list));
211 LOG_ERROR("Out of memory");
215 *reg_list = mem_ap_alloc->reg_list;
216 *reg_list_size = NUM_REGS;
217 struct reg *regs = mem_ap_alloc->regs;
219 for (int i = 0; i < NUM_REGS; i++) {
221 regs[i].value = mem_ap_alloc->regs_value;
222 regs[i].size = REG_SIZE(i);
223 regs[i].exist = REG_EXIST(i);
224 regs[i].type = &mem_ap_reg_arch_type;
225 (*reg_list)[i] = ®s[i];
231 static int mem_ap_read_memory(struct target *target, target_addr_t address,
232 uint32_t size, uint32_t count, uint8_t *buffer)
234 struct mem_ap *mem_ap = target->arch_info;
236 LOG_DEBUG("Reading memory at physical address " TARGET_ADDR_FMT
237 "; size %" PRIu32 "; count %" PRIu32, address, size, count);
239 if (count == 0 || buffer == NULL)
240 return ERROR_COMMAND_SYNTAX_ERROR;
242 return mem_ap_read_buf(mem_ap->ap, buffer, size, count, address);
245 static int mem_ap_write_memory(struct target *target, target_addr_t address,
246 uint32_t size, uint32_t count,
247 const uint8_t *buffer)
249 struct mem_ap *mem_ap = target->arch_info;
251 LOG_DEBUG("Writing memory at physical address " TARGET_ADDR_FMT
252 "; size %" PRIu32 "; count %" PRIu32, address, size, count);
254 if (count == 0 || buffer == NULL)
255 return ERROR_COMMAND_SYNTAX_ERROR;
257 return mem_ap_write_buf(mem_ap->ap, buffer, size, count, address);
260 struct target_type mem_ap_target = {
263 .target_create = mem_ap_target_create,
264 .init_target = mem_ap_init_target,
265 .deinit_target = mem_ap_deinit_target,
266 .examine = mem_ap_examine,
267 .target_jim_configure = adiv5_jim_configure,
270 .arch_state = mem_ap_arch_state,
273 .resume = mem_ap_resume,
276 .assert_reset = mem_ap_assert_reset,
277 .deassert_reset = mem_ap_deassert_reset,
279 .get_gdb_arch = mem_ap_get_gdb_arch,
280 .get_gdb_reg_list = mem_ap_get_gdb_reg_list,
282 .read_memory = mem_ap_read_memory,
283 .write_memory = mem_ap_write_memory,