mem_ap: allow GDB connections
[fw/openocd] / src / target / mem_ap.c
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  ****************************************************************************/
14
15 #ifdef HAVE_CONFIG_H
16 #include "config.h"
17 #endif
18
19 #include "target.h"
20 #include "target_type.h"
21 #include "arm.h"
22 #include "arm_adi_v5.h"
23 #include "register.h"
24
25 #include <jtag/jtag.h>
26
27 struct mem_ap {
28         struct arm arm;
29         struct adiv5_ap *ap;
30         int ap_num;
31 };
32
33 static int mem_ap_target_create(struct target *target, Jim_Interp *interp)
34 {
35         struct mem_ap *mem_ap;
36         struct adiv5_private_config *pc;
37
38         pc = (struct adiv5_private_config *)target->private_config;
39         if (pc == NULL)
40                 return ERROR_FAIL;
41
42         if (pc->ap_num == DP_APSEL_INVALID) {
43                 LOG_ERROR("AP number not specified");
44                 return ERROR_FAIL;
45         }
46
47         mem_ap = calloc(1, sizeof(struct mem_ap));
48         if (mem_ap == NULL) {
49                 LOG_ERROR("Out of memory");
50                 return ERROR_FAIL;
51         }
52
53         mem_ap->ap_num = pc->ap_num;
54         mem_ap->arm.common_magic = ARM_COMMON_MAGIC;
55         mem_ap->arm.dap = pc->dap;
56
57         target->arch_info = mem_ap;
58
59         if (!target->gdb_port_override)
60                 target->gdb_port_override = strdup("disabled");
61
62         return ERROR_OK;
63 }
64
65 static int mem_ap_init_target(struct command_context *cmd_ctx, struct target *target)
66 {
67         LOG_DEBUG("%s", __func__);
68         target->state = TARGET_UNKNOWN;
69         target->debug_reason = DBG_REASON_UNDEFINED;
70         return ERROR_OK;
71 }
72
73 static void mem_ap_deinit_target(struct target *target)
74 {
75         LOG_DEBUG("%s", __func__);
76
77         free(target->private_config);
78         free(target->arch_info);
79         return;
80 }
81
82 static int mem_ap_arch_state(struct target *target)
83 {
84         LOG_DEBUG("%s", __func__);
85         return ERROR_OK;
86 }
87
88 static int mem_ap_poll(struct target *target)
89 {
90         if (target->state == TARGET_UNKNOWN) {
91                 target->state = TARGET_RUNNING;
92                 target->debug_reason = DBG_REASON_NOTHALTED;
93         }
94
95         return ERROR_OK;
96 }
97
98 static int mem_ap_halt(struct target *target)
99 {
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);
104         return ERROR_OK;
105 }
106
107 static int mem_ap_resume(struct target *target, int current, target_addr_t address,
108                 int handle_breakpoints, int debug_execution)
109 {
110         LOG_DEBUG("%s", __func__);
111         target->state = TARGET_RUNNING;
112         target->debug_reason = DBG_REASON_NOTHALTED;
113         return ERROR_OK;
114 }
115
116 static int mem_ap_step(struct target *target, int current, target_addr_t address,
117                                 int handle_breakpoints)
118 {
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);
123         return ERROR_OK;
124 }
125
126 static int mem_ap_assert_reset(struct target *target)
127 {
128         target->state = TARGET_RESET;
129         target->debug_reason = DBG_REASON_UNDEFINED;
130
131         LOG_DEBUG("%s", __func__);
132         return ERROR_OK;
133 }
134
135 static int mem_ap_examine(struct target *target)
136 {
137         struct mem_ap *mem_ap = target->arch_info;
138
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);
145         }
146
147         return ERROR_OK;
148 }
149
150 static int mem_ap_deassert_reset(struct target *target)
151 {
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);
156         } else {
157                 target->state = TARGET_RUNNING;
158                 target->debug_reason = DBG_REASON_NOTHALTED;
159         }
160
161         LOG_DEBUG("%s", __func__);
162         return ERROR_OK;
163 }
164
165 static int mem_ap_reg_get(struct reg *reg)
166 {
167         return ERROR_OK;
168 }
169
170 static int mem_ap_reg_set(struct reg *reg, uint8_t *buf)
171 {
172         return ERROR_OK;
173 }
174
175 static struct reg_arch_type mem_ap_reg_arch_type = {
176         .get = mem_ap_reg_get,
177         .set = mem_ap_reg_set,
178 };
179
180 const char *mem_ap_get_gdb_arch(struct target *target)
181 {
182         return "arm";
183 }
184
185 /*
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
191  *
192  * Set 'exist' only to reg[0..15], so initial response to GDB is correct
193  */
194 #define NUM_REGS     26
195 #define MAX_REG_SIZE 96
196 #define REG_EXIST(n) ((n) < 16)
197 #define REG_SIZE(n)  ((((n) >= 16) && ((n) < 24)) ? 96 : 32)
198
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];
204 };
205
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)
208 {
209         struct mem_ap_alloc_reg_list *mem_ap_alloc = calloc(1, sizeof(struct mem_ap_alloc_reg_list));
210         if (!mem_ap_alloc) {
211                 LOG_ERROR("Out of memory");
212                 return ERROR_FAIL;
213         }
214
215         *reg_list = mem_ap_alloc->reg_list;
216         *reg_list_size = NUM_REGS;
217         struct reg *regs = mem_ap_alloc->regs;
218
219         for (int i = 0; i < NUM_REGS; i++) {
220                 regs[i].number = 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] = &regs[i];
226         }
227
228         return ERROR_OK;
229 }
230
231 static int mem_ap_read_memory(struct target *target, target_addr_t address,
232                                uint32_t size, uint32_t count, uint8_t *buffer)
233 {
234         struct mem_ap *mem_ap = target->arch_info;
235
236         LOG_DEBUG("Reading memory at physical address " TARGET_ADDR_FMT
237                   "; size %" PRIu32 "; count %" PRIu32, address, size, count);
238
239         if (count == 0 || buffer == NULL)
240                 return ERROR_COMMAND_SYNTAX_ERROR;
241
242         return mem_ap_read_buf(mem_ap->ap, buffer, size, count, address);
243 }
244
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)
248 {
249         struct mem_ap *mem_ap = target->arch_info;
250
251         LOG_DEBUG("Writing memory at physical address " TARGET_ADDR_FMT
252                   "; size %" PRIu32 "; count %" PRIu32, address, size, count);
253
254         if (count == 0 || buffer == NULL)
255                 return ERROR_COMMAND_SYNTAX_ERROR;
256
257         return mem_ap_write_buf(mem_ap->ap, buffer, size, count, address);
258 }
259
260 struct target_type mem_ap_target = {
261         .name = "mem_ap",
262
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,
268
269         .poll = mem_ap_poll,
270         .arch_state = mem_ap_arch_state,
271
272         .halt = mem_ap_halt,
273         .resume = mem_ap_resume,
274         .step = mem_ap_step,
275
276         .assert_reset = mem_ap_assert_reset,
277         .deassert_reset = mem_ap_deassert_reset,
278
279         .get_gdb_arch = mem_ap_get_gdb_arch,
280         .get_gdb_reg_list = mem_ap_get_gdb_reg_list,
281
282         .read_memory = mem_ap_read_memory,
283         .write_memory = mem_ap_write_memory,
284 };