jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / target / avr32_ap7k.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com> *
5 * Based on mips_m4k code: *
6 * Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> *
7 * Copyright (C) 2008 by David T.L. Wong *
8 ***************************************************************************/
9
10 #ifdef HAVE_CONFIG_H
11 #include "config.h"
12 #endif
13
14 #include "jtag/jtag.h"
15 #include "register.h"
16 #include "algorithm.h"
17 #include "target.h"
18 #include "breakpoints.h"
19 #include "target_type.h"
20 #include "avr32_jtag.h"
21 #include "avr32_mem.h"
22 #include "avr32_regs.h"
23 #include "avr32_ap7k.h"
24
25 static const char * const avr32_core_reg_list[] = {
26 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8",
27 "r9", "r10", "r11", "r12", "sp", "lr", "pc", "sr"
28 };
29
30 static const struct avr32_core_reg
31 avr32_core_reg_list_arch_info[AVR32NUMCOREREGS] = {
32 {0, NULL, NULL},
33 {1, NULL, NULL},
34 {2, NULL, NULL},
35 {3, NULL, NULL},
36 {4, NULL, NULL},
37 {5, NULL, NULL},
38 {6, NULL, NULL},
39 {7, NULL, NULL},
40 {8, NULL, NULL},
41 {9, NULL, NULL},
42 {10, NULL, NULL},
43 {11, NULL, NULL},
44 {12, NULL, NULL},
45 {13, NULL, NULL},
46 {14, NULL, NULL},
47 {15, NULL, NULL},
48 {16, NULL, NULL},
49 };
50
51
52 static int avr32_read_core_reg(struct target *target, int num);
53 static int avr32_write_core_reg(struct target *target, int num);
54
55 static int avr32_ap7k_save_context(struct target *target)
56 {
57 int retval, i;
58 struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
59
60 retval = avr32_jtag_read_regs(&ap7k->jtag, ap7k->core_regs);
61 if (retval != ERROR_OK)
62 return retval;
63
64 for (i = 0; i < AVR32NUMCOREREGS; i++) {
65 if (!ap7k->core_cache->reg_list[i].valid)
66 avr32_read_core_reg(target, i);
67 }
68
69 return ERROR_OK;
70 }
71
72 static int avr32_ap7k_restore_context(struct target *target)
73 {
74 int i;
75
76 /* get pointers to arch-specific information */
77 struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
78
79 for (i = 0; i < AVR32NUMCOREREGS; i++) {
80 if (ap7k->core_cache->reg_list[i].dirty)
81 avr32_write_core_reg(target, i);
82 }
83
84 /* write core regs */
85 avr32_jtag_write_regs(&ap7k->jtag, ap7k->core_regs);
86
87 return ERROR_OK;
88 }
89
90 static int avr32_read_core_reg(struct target *target, int num)
91 {
92 uint32_t reg_value;
93
94 /* get pointers to arch-specific information */
95 struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
96
97 if ((num < 0) || (num >= AVR32NUMCOREREGS))
98 return ERROR_COMMAND_SYNTAX_ERROR;
99
100 reg_value = ap7k->core_regs[num];
101 buf_set_u32(ap7k->core_cache->reg_list[num].value, 0, 32, reg_value);
102 ap7k->core_cache->reg_list[num].valid = true;
103 ap7k->core_cache->reg_list[num].dirty = false;
104
105 return ERROR_OK;
106 }
107
108 static int avr32_write_core_reg(struct target *target, int num)
109 {
110 uint32_t reg_value;
111
112 /* get pointers to arch-specific information */
113 struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
114
115 if ((num < 0) || (num >= AVR32NUMCOREREGS))
116 return ERROR_COMMAND_SYNTAX_ERROR;
117
118 reg_value = buf_get_u32(ap7k->core_cache->reg_list[num].value, 0, 32);
119 ap7k->core_regs[num] = reg_value;
120 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num, reg_value);
121 ap7k->core_cache->reg_list[num].valid = true;
122 ap7k->core_cache->reg_list[num].dirty = false;
123
124 return ERROR_OK;
125 }
126
127 static int avr32_get_core_reg(struct reg *reg)
128 {
129 int retval;
130 struct avr32_core_reg *avr32_reg = reg->arch_info;
131 struct target *target = avr32_reg->target;
132
133 if (target->state != TARGET_HALTED)
134 return ERROR_TARGET_NOT_HALTED;
135
136 retval = avr32_read_core_reg(target, avr32_reg->num);
137
138 return retval;
139 }
140
141 static int avr32_set_core_reg(struct reg *reg, uint8_t *buf)
142 {
143 struct avr32_core_reg *avr32_reg = reg->arch_info;
144 struct target *target = avr32_reg->target;
145 uint32_t value = buf_get_u32(buf, 0, 32);
146
147 if (target->state != TARGET_HALTED)
148 return ERROR_TARGET_NOT_HALTED;
149
150 buf_set_u32(reg->value, 0, 32, value);
151 reg->dirty = true;
152 reg->valid = true;
153
154 return ERROR_OK;
155 }
156
157 static const struct reg_arch_type avr32_reg_type = {
158 .get = avr32_get_core_reg,
159 .set = avr32_set_core_reg,
160 };
161
162 static struct reg_cache *avr32_build_reg_cache(struct target *target)
163 {
164 int num_regs = AVR32NUMCOREREGS;
165 struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
166 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
167 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
168 struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
169 struct avr32_core_reg *arch_info =
170 malloc(sizeof(struct avr32_core_reg) * num_regs);
171 int i;
172
173 /* Build the process context cache */
174 cache->name = "avr32 registers";
175 cache->next = NULL;
176 cache->reg_list = reg_list;
177 cache->num_regs = num_regs;
178 (*cache_p) = cache;
179 ap7k->core_cache = cache;
180
181 for (i = 0; i < num_regs; i++) {
182 arch_info[i] = avr32_core_reg_list_arch_info[i];
183 arch_info[i].target = target;
184 arch_info[i].avr32_common = ap7k;
185 reg_list[i].name = avr32_core_reg_list[i];
186 reg_list[i].size = 32;
187 reg_list[i].value = calloc(1, 4);
188 reg_list[i].dirty = false;
189 reg_list[i].valid = false;
190 reg_list[i].type = &avr32_reg_type;
191 reg_list[i].arch_info = &arch_info[i];
192 }
193
194 return cache;
195 }
196
197 static int avr32_ap7k_debug_entry(struct target *target)
198 {
199
200 uint32_t dpc, dinst;
201 int retval;
202 struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
203
204 retval = avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DPC, &dpc);
205 if (retval != ERROR_OK)
206 return retval;
207
208 retval = avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DINST, &dinst);
209 if (retval != ERROR_OK)
210 return retval;
211
212 ap7k->jtag.dpc = dpc;
213
214 avr32_ap7k_save_context(target);
215
216 return ERROR_OK;
217 }
218
219
220 static int avr32_ap7k_poll(struct target *target)
221 {
222 uint32_t ds;
223 int retval;
224 struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
225
226 retval = avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DS, &ds);
227 if (retval != ERROR_OK)
228 return retval;
229
230 /* check for processor halted */
231 if (ds & OCDREG_DS_DBA) {
232 if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET)) {
233 target->state = TARGET_HALTED;
234
235 retval = avr32_ap7k_debug_entry(target);
236 if (retval != ERROR_OK)
237 return retval;
238
239 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
240 } else if (target->state == TARGET_DEBUG_RUNNING) {
241 target->state = TARGET_HALTED;
242
243 retval = avr32_ap7k_debug_entry(target);
244 if (retval != ERROR_OK)
245 return retval;
246
247 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
248 }
249 } else
250 target->state = TARGET_RUNNING;
251
252
253 return ERROR_OK;
254 }
255
256 static int avr32_ap7k_halt(struct target *target)
257 {
258 struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
259
260 LOG_DEBUG("target->state: %s",
261 target_state_name(target));
262
263 if (target->state == TARGET_HALTED) {
264 LOG_DEBUG("target was already halted");
265 return ERROR_OK;
266 }
267
268 if (target->state == TARGET_UNKNOWN)
269 LOG_WARNING("target was in unknown state when halt was requested");
270
271 if (target->state == TARGET_RESET) {
272 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst()) {
273 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
274 return ERROR_TARGET_FAILURE;
275 } else {
276 target->debug_reason = DBG_REASON_DBGRQ;
277
278 return ERROR_OK;
279 }
280 }
281
282
283 avr32_ocd_setbits(&ap7k->jtag, AVR32_OCDREG_DC, OCDREG_DC_DBR);
284 target->debug_reason = DBG_REASON_DBGRQ;
285
286 return ERROR_OK;
287 }
288
289 static int avr32_ap7k_assert_reset(struct target *target)
290 {
291 LOG_ERROR("%s: implement me", __func__);
292
293 return ERROR_OK;
294 }
295
296 static int avr32_ap7k_deassert_reset(struct target *target)
297 {
298 LOG_ERROR("%s: implement me", __func__);
299
300 return ERROR_OK;
301 }
302
303 static int avr32_ap7k_resume(struct target *target, int current,
304 target_addr_t address, int handle_breakpoints, int debug_execution)
305 {
306 struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
307 struct breakpoint *breakpoint = NULL;
308 uint32_t resume_pc;
309 int retval;
310
311 if (target->state != TARGET_HALTED) {
312 LOG_TARGET_ERROR(target, "not halted");
313 return ERROR_TARGET_NOT_HALTED;
314 }
315
316 if (!debug_execution) {
317 target_free_all_working_areas(target);
318 /*
319 avr32_ap7k_enable_breakpoints(target);
320 avr32_ap7k_enable_watchpoints(target);
321 */
322 }
323
324 /* current = 1: continue on current pc, otherwise continue at <address> */
325 if (!current) {
326 #if 0
327 if (retval != ERROR_OK)
328 return retval;
329 #endif
330 }
331
332 resume_pc = buf_get_u32(ap7k->core_cache->reg_list[AVR32_REG_PC].value, 0, 32);
333 avr32_ap7k_restore_context(target);
334
335 /* the front-end may request us not to handle breakpoints */
336 if (handle_breakpoints) {
337 /* Single step past breakpoint at current address */
338 breakpoint = breakpoint_find(target, resume_pc);
339 if (breakpoint) {
340 LOG_DEBUG("unset breakpoint at 0x%8.8" TARGET_PRIxADDR "", breakpoint->address);
341 #if 0
342 avr32_ap7k_unset_breakpoint(target, breakpoint);
343 avr32_ap7k_single_step_core(target);
344 avr32_ap7k_set_breakpoint(target, breakpoint);
345 #endif
346 }
347 }
348
349 #if 0
350 /* enable interrupts if we are running */
351 avr32_ap7k_enable_interrupts(target, !debug_execution);
352
353 /* exit debug mode */
354 mips_ejtag_exit_debug(ejtag_info);
355 #endif
356
357
358 retval = avr32_ocd_clearbits(&ap7k->jtag, AVR32_OCDREG_DC,
359 OCDREG_DC_DBR);
360 if (retval != ERROR_OK)
361 return retval;
362
363 retval = avr32_jtag_exec(&ap7k->jtag, RETD);
364 if (retval != ERROR_OK)
365 return retval;
366
367 target->debug_reason = DBG_REASON_NOTHALTED;
368
369 /* registers are now invalid */
370 register_cache_invalidate(ap7k->core_cache);
371
372 if (!debug_execution) {
373 target->state = TARGET_RUNNING;
374 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
375 LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc);
376 } else {
377 target->state = TARGET_DEBUG_RUNNING;
378 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
379 LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc);
380 }
381
382 return ERROR_OK;
383 }
384
385 static int avr32_ap7k_step(struct target *target, int current,
386 target_addr_t address, int handle_breakpoints)
387 {
388 LOG_ERROR("%s: implement me", __func__);
389
390 return ERROR_OK;
391 }
392
393 static int avr32_ap7k_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
394 {
395 LOG_ERROR("%s: implement me", __func__);
396
397 return ERROR_OK;
398 }
399
400 static int avr32_ap7k_remove_breakpoint(struct target *target,
401 struct breakpoint *breakpoint)
402 {
403 LOG_ERROR("%s: implement me", __func__);
404
405 return ERROR_OK;
406 }
407
408 static int avr32_ap7k_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
409 {
410 LOG_ERROR("%s: implement me", __func__);
411
412 return ERROR_OK;
413 }
414
415 static int avr32_ap7k_remove_watchpoint(struct target *target,
416 struct watchpoint *watchpoint)
417 {
418 LOG_ERROR("%s: implement me", __func__);
419
420 return ERROR_OK;
421 }
422
423 static int avr32_ap7k_read_memory(struct target *target, target_addr_t address,
424 uint32_t size, uint32_t count, uint8_t *buffer)
425 {
426 struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
427
428 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
429 address,
430 size,
431 count);
432
433 if (target->state != TARGET_HALTED) {
434 LOG_TARGET_ERROR(target, "not halted");
435 return ERROR_TARGET_NOT_HALTED;
436 }
437
438 /* sanitize arguments */
439 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
440 return ERROR_COMMAND_SYNTAX_ERROR;
441
442 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
443 return ERROR_TARGET_UNALIGNED_ACCESS;
444
445 switch (size) {
446 case 4:
447 return avr32_jtag_read_memory32(&ap7k->jtag, address, count,
448 (uint32_t *)(void *)buffer);
449 break;
450 case 2:
451 return avr32_jtag_read_memory16(&ap7k->jtag, address, count,
452 (uint16_t *)(void *)buffer);
453 break;
454 case 1:
455 return avr32_jtag_read_memory8(&ap7k->jtag, address, count, buffer);
456 default:
457 break;
458 }
459
460 return ERROR_OK;
461 }
462
463 static int avr32_ap7k_write_memory(struct target *target, target_addr_t address,
464 uint32_t size, uint32_t count, const uint8_t *buffer)
465 {
466 struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
467
468 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
469 address,
470 size,
471 count);
472
473 if (target->state != TARGET_HALTED) {
474 LOG_TARGET_ERROR(target, "not halted");
475 return ERROR_TARGET_NOT_HALTED;
476 }
477
478 /* sanitize arguments */
479 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
480 return ERROR_COMMAND_SYNTAX_ERROR;
481
482 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
483 return ERROR_TARGET_UNALIGNED_ACCESS;
484
485 switch (size) {
486 case 4:
487 return avr32_jtag_write_memory32(&ap7k->jtag, address, count,
488 (uint32_t *)(void *)buffer);
489 break;
490 case 2:
491 return avr32_jtag_write_memory16(&ap7k->jtag, address, count,
492 (uint16_t *)(void *)buffer);
493 break;
494 case 1:
495 return avr32_jtag_write_memory8(&ap7k->jtag, address, count, buffer);
496 default:
497 break;
498 }
499
500 return ERROR_OK;
501 }
502
503 static int avr32_ap7k_init_target(struct command_context *cmd_ctx,
504 struct target *target)
505 {
506 struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
507
508 ap7k->jtag.tap = target->tap;
509 avr32_build_reg_cache(target);
510 return ERROR_OK;
511 }
512
513 static int avr32_ap7k_target_create(struct target *target, Jim_Interp *interp)
514 {
515 struct avr32_ap7k_common *ap7k = calloc(1, sizeof(struct
516 avr32_ap7k_common));
517
518 ap7k->common_magic = AP7K_COMMON_MAGIC;
519 target->arch_info = ap7k;
520
521 return ERROR_OK;
522 }
523
524 static int avr32_ap7k_examine(struct target *target)
525 {
526 uint32_t devid, ds;
527 struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
528
529 if (!target_was_examined(target)) {
530 target_set_examined(target);
531 avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DID, &devid);
532 LOG_INFO("device id: %08" PRIx32, devid);
533 avr32_ocd_setbits(&ap7k->jtag, AVR32_OCDREG_DC, OCDREG_DC_DBE);
534 avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DS, &ds);
535
536 /* check for processor halted */
537 if (ds & OCDREG_DS_DBA) {
538 LOG_INFO("target is halted");
539 target->state = TARGET_HALTED;
540 } else
541 target->state = TARGET_RUNNING;
542 }
543
544 return ERROR_OK;
545 }
546
547 static int avr32_ap7k_arch_state(struct target *target)
548 {
549 struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
550
551 LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32 "",
552 debug_reason_name(target), ap7k->jtag.dpc);
553
554 return ERROR_OK;
555 }
556
557 static int avr32_ap7k_get_gdb_reg_list(struct target *target, struct reg **reg_list[],
558 int *reg_list_size, enum target_register_class reg_class)
559 {
560 #if 0
561 /* get pointers to arch-specific information */
562 int i;
563
564 /* include floating point registers */
565 *reg_list_size = AVR32NUMCOREREGS + AVR32NUMFPREGS;
566 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
567
568 for (i = 0; i < AVR32NUMCOREREGS; i++)
569 (*reg_list)[i] = &mips32->core_cache->reg_list[i];
570
571 /* add dummy floating points regs */
572 for (i = AVR32NUMCOREREGS; i < (AVR32NUMCOREREGS + AVR32NUMFPREGS); i++)
573 (*reg_list)[i] = &avr32_ap7k_gdb_dummy_fp_reg;
574
575 #endif
576
577 LOG_ERROR("%s: implement me", __func__);
578 return ERROR_FAIL;
579 }
580
581 struct target_type avr32_ap7k_target = {
582 .name = "avr32_ap7k",
583
584 .poll = avr32_ap7k_poll,
585 .arch_state = avr32_ap7k_arch_state,
586
587 .halt = avr32_ap7k_halt,
588 .resume = avr32_ap7k_resume,
589 .step = avr32_ap7k_step,
590
591 .assert_reset = avr32_ap7k_assert_reset,
592 .deassert_reset = avr32_ap7k_deassert_reset,
593
594 .get_gdb_reg_list = avr32_ap7k_get_gdb_reg_list,
595
596 .read_memory = avr32_ap7k_read_memory,
597 .write_memory = avr32_ap7k_write_memory,
598 /* .checksum_memory = avr32_ap7k_checksum_memory, */
599 /* .blank_check_memory = avr32_ap7k_blank_check_memory, */
600
601 /* .run_algorithm = avr32_ap7k_run_algorithm, */
602
603 .add_breakpoint = avr32_ap7k_add_breakpoint,
604 .remove_breakpoint = avr32_ap7k_remove_breakpoint,
605 .add_watchpoint = avr32_ap7k_add_watchpoint,
606 .remove_watchpoint = avr32_ap7k_remove_watchpoint,
607
608 .target_create = avr32_ap7k_target_create,
609 .init_target = avr32_ap7k_init_target,
610 .examine = avr32_ap7k_examine,
611 };

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)