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

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)