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 *
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. *
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. *
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 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 ***************************************************************************/
26 #include "jtag/jtag.h"
28 #include "algorithm.h"
30 #include "breakpoints.h"
31 #include "target_type.h"
32 #include "avr32_jtag.h"
33 #include "avr32_mem.h"
34 #include "avr32_regs.h"
35 #include "avr32_ap7k.h"
37 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"
43 static struct avr32_core_reg
44 avr32_core_reg_list_arch_info
[AVR32NUMCOREREGS
] =
66 static int avr32_read_core_reg(struct target
*target
, int num
);
67 static int avr32_write_core_reg(struct target
*target
, int num
);
69 int avr32_ap7k_save_context(struct target
*target
)
72 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
74 retval
= avr32_jtag_read_regs(&ap7k
->jtag
, ap7k
->core_regs
);
75 if (retval
!= ERROR_OK
)
78 for (i
= 0; i
< AVR32NUMCOREREGS
; i
++)
80 if (!ap7k
->core_cache
->reg_list
[i
].valid
)
82 avr32_read_core_reg(target
, i
);
89 int avr32_ap7k_restore_context(struct target
*target
)
93 /* get pointers to arch-specific information */
94 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
96 for (i
= 0; i
< AVR32NUMCOREREGS
; i
++)
98 if (ap7k
->core_cache
->reg_list
[i
].dirty
)
100 avr32_write_core_reg(target
, i
);
104 /* write core regs */
105 avr32_jtag_write_regs(&ap7k
->jtag
, ap7k
->core_regs
);
110 static int avr32_read_core_reg(struct target
*target
, int num
)
113 struct avr32_core_reg
*mips_core_reg
;
115 /* get pointers to arch-specific information */
116 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
118 if ((num
< 0) || (num
>= AVR32NUMCOREREGS
))
119 return ERROR_INVALID_ARGUMENTS
;
121 mips_core_reg
= ap7k
->core_cache
->reg_list
[num
].arch_info
;
122 reg_value
= ap7k
->core_regs
[num
];
123 buf_set_u32(ap7k
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
124 ap7k
->core_cache
->reg_list
[num
].valid
= 1;
125 ap7k
->core_cache
->reg_list
[num
].dirty
= 0;
130 static int avr32_write_core_reg(struct target
*target
, int num
)
133 struct avr32_core_reg
*mips_core_reg
;
135 /* get pointers to arch-specific information */
136 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
138 if ((num
< 0) || (num
>= AVR32NUMCOREREGS
))
139 return ERROR_INVALID_ARGUMENTS
;
141 reg_value
= buf_get_u32(ap7k
->core_cache
->reg_list
[num
].value
, 0, 32);
142 mips_core_reg
= ap7k
->core_cache
->reg_list
[num
].arch_info
;
143 ap7k
->core_regs
[num
] = reg_value
;
144 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", num
, reg_value
);
145 ap7k
->core_cache
->reg_list
[num
].valid
= 1;
146 ap7k
->core_cache
->reg_list
[num
].dirty
= 0;
151 static int avr32_get_core_reg(struct reg
*reg
)
154 struct avr32_core_reg
*avr32_reg
= reg
->arch_info
;
155 struct target
*target
= avr32_reg
->target
;
157 if (target
->state
!= TARGET_HALTED
)
159 return ERROR_TARGET_NOT_HALTED
;
162 retval
= avr32_read_core_reg(target
, avr32_reg
->num
);
167 static int avr32_set_core_reg(struct reg
*reg
, uint8_t *buf
)
169 struct avr32_core_reg
*avr32_reg
= reg
->arch_info
;
170 struct target
*target
= avr32_reg
->target
;
171 uint32_t value
= buf_get_u32(buf
, 0, 32);
173 if (target
->state
!= TARGET_HALTED
)
175 return ERROR_TARGET_NOT_HALTED
;
178 buf_set_u32(reg
->value
, 0, 32, value
);
185 static const struct reg_arch_type avr32_reg_type
= {
186 .get
= avr32_get_core_reg
,
187 .set
= avr32_set_core_reg
,
190 static struct reg_cache
*avr32_build_reg_cache(struct target
*target
)
192 int num_regs
= AVR32NUMCOREREGS
;
193 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
194 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
195 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
196 struct reg
*reg_list
= malloc(sizeof(struct reg
) * num_regs
);
197 struct avr32_core_reg
*arch_info
=
198 malloc(sizeof(struct avr32_core_reg
) * num_regs
);
201 /* Build the process context cache */
202 cache
->name
= "avr32 registers";
204 cache
->reg_list
= reg_list
;
205 cache
->num_regs
= num_regs
;
207 ap7k
->core_cache
= cache
;
209 for (i
= 0; i
< num_regs
; i
++)
211 arch_info
[i
] = avr32_core_reg_list_arch_info
[i
];
212 arch_info
[i
].target
= target
;
213 arch_info
[i
].avr32_common
= ap7k
;
214 reg_list
[i
].name
= avr32_core_reg_list
[i
];
215 reg_list
[i
].size
= 32;
216 reg_list
[i
].value
= calloc(1, 4);
217 reg_list
[i
].dirty
= 0;
218 reg_list
[i
].valid
= 0;
219 reg_list
[i
].type
= &avr32_reg_type
;
220 reg_list
[i
].arch_info
= &arch_info
[i
];
226 static int avr32_ap7k_debug_entry(struct target
*target
)
231 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
233 retval
= avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DPC
, &dpc
);
234 if (retval
!= ERROR_OK
)
237 retval
= avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DINST
, &dinst
);
238 if (retval
!= ERROR_OK
)
241 ap7k
->jtag
.dpc
= dpc
;
243 avr32_ap7k_save_context(target
);
249 static int avr32_ap7k_poll(struct target
*target
)
253 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
255 retval
= avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DS
, &ds
);
256 if (retval
!= ERROR_OK
)
259 /* check for processor halted */
260 if (ds
& OCDREG_DS_DBA
)
262 if ((target
->state
== TARGET_RUNNING
) || (target
->state
== TARGET_RESET
))
264 target
->state
= TARGET_HALTED
;
266 if ((retval
= avr32_ap7k_debug_entry(target
)) != ERROR_OK
)
269 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
271 else if (target
->state
== TARGET_DEBUG_RUNNING
)
273 target
->state
= TARGET_HALTED
;
275 if ((retval
= avr32_ap7k_debug_entry(target
)) != ERROR_OK
)
278 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
283 target
->state
= TARGET_RUNNING
;
290 static int avr32_ap7k_halt(struct target
*target
)
292 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
294 LOG_DEBUG("target->state: %s",
295 target_state_name(target
));
297 if (target
->state
== TARGET_HALTED
)
299 LOG_DEBUG("target was already halted");
303 if (target
->state
== TARGET_UNKNOWN
)
305 LOG_WARNING("target was in unknown state when halt was requested");
308 if (target
->state
== TARGET_RESET
)
310 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst())
312 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
313 return ERROR_TARGET_FAILURE
;
317 target
->debug_reason
= DBG_REASON_DBGRQ
;
324 avr32_ocd_setbits(&ap7k
->jtag
, AVR32_OCDREG_DC
, OCDREG_DC_DBR
);
325 target
->debug_reason
= DBG_REASON_DBGRQ
;
330 static int avr32_ap7k_assert_reset(struct target
*target
)
332 LOG_ERROR("%s: implement me", __func__
);
337 static int avr32_ap7k_deassert_reset(struct target
*target
)
339 LOG_ERROR("%s: implement me", __func__
);
344 static int avr32_ap7k_soft_reset_halt(struct target
*target
)
346 LOG_ERROR("%s: implement me", __func__
);
351 static int avr32_ap7k_resume(struct target
*target
, int current
,
352 uint32_t address
, int handle_breakpoints
, int debug_execution
)
354 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
355 struct breakpoint
*breakpoint
= NULL
;
359 if (target
->state
!= TARGET_HALTED
)
361 LOG_WARNING("target not halted");
362 return ERROR_TARGET_NOT_HALTED
;
365 if (!debug_execution
)
367 target_free_all_working_areas(target
);
369 avr32_ap7k_enable_breakpoints(target);
370 avr32_ap7k_enable_watchpoints(target);
374 /* current = 1: continue on current pc, otherwise continue at <address> */
378 if (retval
!= ERROR_OK
)
384 buf_get_u32(ap7k
->core_cache
->reg_list
[AVR32_REG_PC
].value
, 0, 32);
385 avr32_ap7k_restore_context(target
);
387 /* the front-end may request us not to handle breakpoints */
388 if (handle_breakpoints
)
390 /* Single step past breakpoint at current address */
391 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
393 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
"", breakpoint
->address
);
395 avr32_ap7k_unset_breakpoint(target
, breakpoint
);
396 avr32_ap7k_single_step_core(target
);
397 avr32_ap7k_set_breakpoint(target
, breakpoint
);
403 /* enable interrupts if we are running */
404 avr32_ap7k_enable_interrupts(target
, !debug_execution
);
406 /* exit debug mode */
407 mips_ejtag_exit_debug(ejtag_info
);
411 retval
= avr32_ocd_clearbits(&ap7k
->jtag
, AVR32_OCDREG_DC
,
413 if (retval
!= ERROR_OK
)
416 retval
= avr32_jtag_exec(&ap7k
->jtag
, RETD
);
417 if (retval
!= ERROR_OK
)
420 target
->debug_reason
= DBG_REASON_NOTHALTED
;
422 /* registers are now invalid */
423 register_cache_invalidate(ap7k
->core_cache
);
425 if (!debug_execution
)
427 target
->state
= TARGET_RUNNING
;
428 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
429 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
433 target
->state
= TARGET_DEBUG_RUNNING
;
434 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
435 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
441 static int avr32_ap7k_step(struct target
*target
, int current
,
442 uint32_t address
, int handle_breakpoints
)
444 LOG_ERROR("%s: implement me", __func__
);
449 static int avr32_ap7k_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
451 LOG_ERROR("%s: implement me", __func__
);
456 static int avr32_ap7k_remove_breakpoint(struct target
*target
,
457 struct breakpoint
*breakpoint
)
459 LOG_ERROR("%s: implement me", __func__
);
464 static int avr32_ap7k_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
466 LOG_ERROR("%s: implement me", __func__
);
471 static int avr32_ap7k_remove_watchpoint(struct target
*target
,
472 struct watchpoint
*watchpoint
)
474 LOG_ERROR("%s: implement me", __func__
);
479 static int avr32_ap7k_read_memory(struct target
*target
, uint32_t address
,
480 uint32_t size
, uint32_t count
, uint8_t *buffer
)
482 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
484 LOG_DEBUG("address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"", address
, size
, count
);
486 if (target
->state
!= TARGET_HALTED
)
488 LOG_WARNING("target not halted");
489 return ERROR_TARGET_NOT_HALTED
;
492 /* sanitize arguments */
493 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
494 return ERROR_INVALID_ARGUMENTS
;
496 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
497 return ERROR_TARGET_UNALIGNED_ACCESS
;
502 return avr32_jtag_read_memory32(&ap7k
->jtag
, address
, count
, (uint32_t*)(void *)buffer
);
505 return avr32_jtag_read_memory16(&ap7k
->jtag
, address
, count
, (uint16_t*)(void *)buffer
);
508 return avr32_jtag_read_memory8(&ap7k
->jtag
, address
, count
, buffer
);
517 static int avr32_ap7k_write_memory(struct target
*target
, uint32_t address
,
518 uint32_t size
, uint32_t count
, uint8_t *buffer
)
520 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
522 LOG_DEBUG("address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"", address
, size
, count
);
524 if (target
->state
!= TARGET_HALTED
)
526 LOG_WARNING("target not halted");
527 return ERROR_TARGET_NOT_HALTED
;
530 /* sanitize arguments */
531 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
532 return ERROR_INVALID_ARGUMENTS
;
534 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
535 return ERROR_TARGET_UNALIGNED_ACCESS
;
540 return avr32_jtag_write_memory32(&ap7k
->jtag
, address
, count
, (uint32_t*)(void *)buffer
);
543 return avr32_jtag_write_memory16(&ap7k
->jtag
, address
, count
, (uint16_t*)(void *)buffer
);
546 return avr32_jtag_write_memory8(&ap7k
->jtag
, address
, count
, buffer
);
555 static int avr32_ap7k_init_target(struct command_context
*cmd_ctx
,
556 struct target
*target
)
558 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
560 ap7k
->jtag
.tap
= target
->tap
;
561 avr32_build_reg_cache(target
);
565 static int avr32_ap7k_target_create(struct target
*target
, Jim_Interp
*interp
)
567 struct avr32_ap7k_common
*ap7k
= calloc(1, sizeof(struct
570 ap7k
->common_magic
= AP7k_COMMON_MAGIC
;
571 target
->arch_info
= ap7k
;
576 static int avr32_ap7k_examine(struct target
*target
)
579 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
581 if (!target_was_examined(target
))
583 target_set_examined(target
);
584 avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DID
, &devid
);
585 LOG_INFO("device id: %08x", devid
);
586 avr32_ocd_setbits(&ap7k
->jtag
, AVR32_OCDREG_DC
,OCDREG_DC_DBE
);
587 avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DS
, &ds
);
589 /* check for processor halted */
590 if (ds
& OCDREG_DS_DBA
)
592 LOG_INFO("target is halted");
593 target
->state
= TARGET_HALTED
;
596 target
->state
= TARGET_RUNNING
;
602 static int avr32_ap7k_bulk_write_memory(struct target
*target
, uint32_t address
,
603 uint32_t count
, uint8_t *buffer
)
605 LOG_ERROR("%s: implement me", __func__
);
611 int avr32_ap7k_arch_state(struct target
*target
)
613 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
615 LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32
"",
616 debug_reason_name(target
), ap7k
->jtag
.dpc
);
621 int avr32_ap7k_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[], int *reg_list_size
)
624 /* get pointers to arch-specific information */
627 /* include floating point registers */
628 *reg_list_size
= AVR32NUMCOREREGS
+ AVR32NUMFPREGS
;
629 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
631 for (i
= 0; i
< AVR32NUMCOREREGS
; i
++)
633 (*reg_list
)[i
] = &mips32
->core_cache
->reg_list
[i
];
636 /* add dummy floating points regs */
637 for (i
= AVR32NUMCOREREGS
; i
< (AVR32NUMCOREREGS
+ AVR32NUMFPREGS
); i
++)
639 (*reg_list
)[i
] = &avr32_ap7k_gdb_dummy_fp_reg
;
643 LOG_ERROR("%s: implement me", __func__
);
649 struct target_type avr32_ap7k_target
=
651 .name
= "avr32_ap7k",
653 .poll
= avr32_ap7k_poll
,
654 .arch_state
= avr32_ap7k_arch_state
,
656 .target_request_data
= NULL
,
658 .halt
= avr32_ap7k_halt
,
659 .resume
= avr32_ap7k_resume
,
660 .step
= avr32_ap7k_step
,
662 .assert_reset
= avr32_ap7k_assert_reset
,
663 .deassert_reset
= avr32_ap7k_deassert_reset
,
664 .soft_reset_halt
= avr32_ap7k_soft_reset_halt
,
666 .get_gdb_reg_list
= avr32_ap7k_get_gdb_reg_list
,
668 .read_memory
= avr32_ap7k_read_memory
,
669 .write_memory
= avr32_ap7k_write_memory
,
670 .bulk_write_memory
= avr32_ap7k_bulk_write_memory
,
671 // .checksum_memory = avr32_ap7k_checksum_memory,
672 // .blank_check_memory = avr32_ap7k_blank_check_memory,
674 // .run_algorithm = avr32_ap7k_run_algorithm,
676 .add_breakpoint
= avr32_ap7k_add_breakpoint
,
677 .remove_breakpoint
= avr32_ap7k_remove_breakpoint
,
678 .add_watchpoint
= avr32_ap7k_add_watchpoint
,
679 .remove_watchpoint
= avr32_ap7k_remove_watchpoint
,
681 .target_create
= avr32_ap7k_target_create
,
682 .init_target
= avr32_ap7k_init_target
,
683 .examine
= avr32_ap7k_examine
,
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)