08a188324a368945ffae7f69b33bb52202d0ac5e
[fw/openocd] / src / target / mem_ap.c
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 {
21         int common_magic;
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
32         pc = (struct adiv5_private_config *)target->private_config;
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;
48         mem_ap->common_magic = MEM_AP_COMMON_MAGIC;
49         mem_ap->dap = pc->dap;
50
51         target->arch_info = mem_ap;
52
53         if (!target->gdb_port_override)
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__);
62         target->state = TARGET_UNKNOWN;
63         target->debug_reason = DBG_REASON_UNDEFINED;
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)
74                 dap_put_ap(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) {
90                 target->state = TARGET_RUNNING;
91                 target->debug_reason = DBG_REASON_NOTHALTED;
92         }
93
94         return ERROR_OK;
95 }
96
97 static int mem_ap_halt(struct target *target)
98 {
99         LOG_DEBUG("%s", __func__);
100         target->state = TARGET_HALTED;
101         target->debug_reason = DBG_REASON_DBGRQ;
102         target_call_event_callbacks(target, TARGET_EVENT_HALTED);
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__);
110         target->state = TARGET_RUNNING;
111         target->debug_reason = DBG_REASON_NOTHALTED;
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__);
119         target->state = TARGET_HALTED;
120         target->debug_reason = DBG_REASON_DBGRQ;
121         target_call_event_callbacks(target, TARGET_EVENT_HALTED);
122         return ERROR_OK;
123 }
124
125 static int mem_ap_assert_reset(struct target *target)
126 {
127         target->state = TARGET_RESET;
128         target->debug_reason = DBG_REASON_UNDEFINED;
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) {
140                         dap_put_ap(mem_ap->ap);
141                         mem_ap->ap = NULL;
142                 }
143
144                 mem_ap->ap = dap_get_ap(mem_ap->dap, mem_ap->ap_num);
145                 if (!mem_ap->ap) {
146                         LOG_ERROR("Cannot get AP");
147                         return ERROR_FAIL;
148                 }
149                 target_set_examined(target);
150                 target->state = TARGET_UNKNOWN;
151                 target->debug_reason = DBG_REASON_UNDEFINED;
152                 return mem_ap_init(mem_ap->ap);
153         }
154
155         return ERROR_OK;
156 }
157
158 static int mem_ap_deassert_reset(struct target *target)
159 {
160         if (target->reset_halt) {
161                 target->state = TARGET_HALTED;
162                 target->debug_reason = DBG_REASON_DBGRQ;
163                 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
164         } else {
165                 target->state = TARGET_RUNNING;
166                 target->debug_reason = DBG_REASON_NOTHALTED;
167         }
168
169         LOG_DEBUG("%s", __func__);
170         return ERROR_OK;
171 }
172
173 static int mem_ap_reg_get(struct reg *reg)
174 {
175         return ERROR_OK;
176 }
177
178 static int mem_ap_reg_set(struct reg *reg, uint8_t *buf)
179 {
180         return ERROR_OK;
181 }
182
183 static struct reg_arch_type mem_ap_reg_arch_type = {
184         .get = mem_ap_reg_get,
185         .set = mem_ap_reg_set,
186 };
187
188 static const char *mem_ap_get_gdb_arch(struct target *target)
189 {
190         return "arm";
191 }
192
193 /*
194  * Dummy ARM register emulation:
195  * reg[0..15]:  32 bits, r0~r12, sp, lr, pc
196  * reg[16..23]: 96 bits, f0~f7
197  * reg[24]:     32 bits, fps
198  * reg[25]:     32 bits, cpsr
199  *
200  * Set 'exist' only to reg[0..15], so initial response to GDB is correct
201  */
202 #define NUM_REGS     26
203 #define MAX_REG_SIZE 96
204 #define REG_EXIST(n) ((n) < 16)
205 #define REG_SIZE(n)  ((((n) >= 16) && ((n) < 24)) ? 96 : 32)
206
207 struct mem_ap_alloc_reg_list {
208         /* reg_list must be the first field */
209         struct reg *reg_list[NUM_REGS];
210         struct reg regs[NUM_REGS];
211         uint8_t regs_value[MAX_REG_SIZE / 8];
212 };
213
214 static int mem_ap_get_gdb_reg_list(struct target *target, struct reg **reg_list[],
215                                 int *reg_list_size, enum target_register_class reg_class)
216 {
217         struct mem_ap_alloc_reg_list *mem_ap_alloc = calloc(1, sizeof(struct mem_ap_alloc_reg_list));
218         if (!mem_ap_alloc) {
219                 LOG_ERROR("Out of memory");
220                 return ERROR_FAIL;
221         }
222
223         *reg_list = mem_ap_alloc->reg_list;
224         *reg_list_size = NUM_REGS;
225         struct reg *regs = mem_ap_alloc->regs;
226
227         for (int i = 0; i < NUM_REGS; i++) {
228                 regs[i].number = i;
229                 regs[i].value = mem_ap_alloc->regs_value;
230                 regs[i].size = REG_SIZE(i);
231                 regs[i].exist = REG_EXIST(i);
232                 regs[i].type = &mem_ap_reg_arch_type;
233                 (*reg_list)[i] = &regs[i];
234         }
235
236         return ERROR_OK;
237 }
238
239 static int mem_ap_read_memory(struct target *target, target_addr_t address,
240                                uint32_t size, uint32_t count, uint8_t *buffer)
241 {
242         struct mem_ap *mem_ap = target->arch_info;
243
244         LOG_DEBUG("Reading memory at physical address " TARGET_ADDR_FMT
245                   "; size %" PRIu32 "; count %" PRIu32, address, size, count);
246
247         if (count == 0 || !buffer)
248                 return ERROR_COMMAND_SYNTAX_ERROR;
249
250         return mem_ap_read_buf(mem_ap->ap, buffer, size, count, address);
251 }
252
253 static int mem_ap_write_memory(struct target *target, target_addr_t address,
254                                 uint32_t size, uint32_t count,
255                                 const uint8_t *buffer)
256 {
257         struct mem_ap *mem_ap = target->arch_info;
258
259         LOG_DEBUG("Writing memory at physical address " TARGET_ADDR_FMT
260                   "; size %" PRIu32 "; count %" PRIu32, address, size, count);
261
262         if (count == 0 || !buffer)
263                 return ERROR_COMMAND_SYNTAX_ERROR;
264
265         return mem_ap_write_buf(mem_ap->ap, buffer, size, count, address);
266 }
267
268 struct target_type mem_ap_target = {
269         .name = "mem_ap",
270
271         .target_create = mem_ap_target_create,
272         .init_target = mem_ap_init_target,
273         .deinit_target = mem_ap_deinit_target,
274         .examine = mem_ap_examine,
275         .target_jim_configure = adiv5_jim_configure,
276
277         .poll = mem_ap_poll,
278         .arch_state = mem_ap_arch_state,
279
280         .halt = mem_ap_halt,
281         .resume = mem_ap_resume,
282         .step = mem_ap_step,
283
284         .assert_reset = mem_ap_assert_reset,
285         .deassert_reset = mem_ap_deassert_reset,
286
287         .get_gdb_arch = mem_ap_get_gdb_arch,
288         .get_gdb_reg_list = mem_ap_get_gdb_reg_list,
289
290         .read_memory = mem_ap_read_memory,
291         .write_memory = mem_ap_write_memory,
292 };