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
,
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)