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

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)