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
)
114 /* get pointers to arch-specific information */
115 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
117 if ((num
< 0) || (num
>= AVR32NUMCOREREGS
))
118 return ERROR_INVALID_ARGUMENTS
;
120 reg_value
= ap7k
->core_regs
[num
];
121 buf_set_u32(ap7k
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
122 ap7k
->core_cache
->reg_list
[num
].valid
= 1;
123 ap7k
->core_cache
->reg_list
[num
].dirty
= 0;
128 static int avr32_write_core_reg(struct target
*target
, int num
)
132 /* get pointers to arch-specific information */
133 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
135 if ((num
< 0) || (num
>= AVR32NUMCOREREGS
))
136 return ERROR_INVALID_ARGUMENTS
;
138 reg_value
= buf_get_u32(ap7k
->core_cache
->reg_list
[num
].value
, 0, 32);
139 ap7k
->core_regs
[num
] = reg_value
;
140 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", num
, reg_value
);
141 ap7k
->core_cache
->reg_list
[num
].valid
= 1;
142 ap7k
->core_cache
->reg_list
[num
].dirty
= 0;
147 static int avr32_get_core_reg(struct reg
*reg
)
150 struct avr32_core_reg
*avr32_reg
= reg
->arch_info
;
151 struct target
*target
= avr32_reg
->target
;
153 if (target
->state
!= TARGET_HALTED
)
155 return ERROR_TARGET_NOT_HALTED
;
158 retval
= avr32_read_core_reg(target
, avr32_reg
->num
);
163 static int avr32_set_core_reg(struct reg
*reg
, uint8_t *buf
)
165 struct avr32_core_reg
*avr32_reg
= reg
->arch_info
;
166 struct target
*target
= avr32_reg
->target
;
167 uint32_t value
= buf_get_u32(buf
, 0, 32);
169 if (target
->state
!= TARGET_HALTED
)
171 return ERROR_TARGET_NOT_HALTED
;
174 buf_set_u32(reg
->value
, 0, 32, value
);
181 static const struct reg_arch_type avr32_reg_type
= {
182 .get
= avr32_get_core_reg
,
183 .set
= avr32_set_core_reg
,
186 static struct reg_cache
*avr32_build_reg_cache(struct target
*target
)
188 int num_regs
= AVR32NUMCOREREGS
;
189 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
190 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
191 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
192 struct reg
*reg_list
= malloc(sizeof(struct reg
) * num_regs
);
193 struct avr32_core_reg
*arch_info
=
194 malloc(sizeof(struct avr32_core_reg
) * num_regs
);
197 /* Build the process context cache */
198 cache
->name
= "avr32 registers";
200 cache
->reg_list
= reg_list
;
201 cache
->num_regs
= num_regs
;
203 ap7k
->core_cache
= cache
;
205 for (i
= 0; i
< num_regs
; i
++)
207 arch_info
[i
] = avr32_core_reg_list_arch_info
[i
];
208 arch_info
[i
].target
= target
;
209 arch_info
[i
].avr32_common
= ap7k
;
210 reg_list
[i
].name
= avr32_core_reg_list
[i
];
211 reg_list
[i
].size
= 32;
212 reg_list
[i
].value
= calloc(1, 4);
213 reg_list
[i
].dirty
= 0;
214 reg_list
[i
].valid
= 0;
215 reg_list
[i
].type
= &avr32_reg_type
;
216 reg_list
[i
].arch_info
= &arch_info
[i
];
222 static int avr32_ap7k_debug_entry(struct target
*target
)
227 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
229 retval
= avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DPC
, &dpc
);
230 if (retval
!= ERROR_OK
)
233 retval
= avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DINST
, &dinst
);
234 if (retval
!= ERROR_OK
)
237 ap7k
->jtag
.dpc
= dpc
;
239 avr32_ap7k_save_context(target
);
245 static int avr32_ap7k_poll(struct target
*target
)
249 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
251 retval
= avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DS
, &ds
);
252 if (retval
!= ERROR_OK
)
255 /* check for processor halted */
256 if (ds
& OCDREG_DS_DBA
)
258 if ((target
->state
== TARGET_RUNNING
) || (target
->state
== TARGET_RESET
))
260 target
->state
= TARGET_HALTED
;
262 if ((retval
= avr32_ap7k_debug_entry(target
)) != ERROR_OK
)
265 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
267 else if (target
->state
== TARGET_DEBUG_RUNNING
)
269 target
->state
= TARGET_HALTED
;
271 if ((retval
= avr32_ap7k_debug_entry(target
)) != ERROR_OK
)
274 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
279 target
->state
= TARGET_RUNNING
;
286 static int avr32_ap7k_halt(struct target
*target
)
288 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
290 LOG_DEBUG("target->state: %s",
291 target_state_name(target
));
293 if (target
->state
== TARGET_HALTED
)
295 LOG_DEBUG("target was already halted");
299 if (target
->state
== TARGET_UNKNOWN
)
301 LOG_WARNING("target was in unknown state when halt was requested");
304 if (target
->state
== TARGET_RESET
)
306 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst())
308 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
309 return ERROR_TARGET_FAILURE
;
313 target
->debug_reason
= DBG_REASON_DBGRQ
;
320 avr32_ocd_setbits(&ap7k
->jtag
, AVR32_OCDREG_DC
, OCDREG_DC_DBR
);
321 target
->debug_reason
= DBG_REASON_DBGRQ
;
326 static int avr32_ap7k_assert_reset(struct target
*target
)
328 LOG_ERROR("%s: implement me", __func__
);
333 static int avr32_ap7k_deassert_reset(struct target
*target
)
335 LOG_ERROR("%s: implement me", __func__
);
340 static int avr32_ap7k_soft_reset_halt(struct target
*target
)
342 LOG_ERROR("%s: implement me", __func__
);
347 static int avr32_ap7k_resume(struct target
*target
, int current
,
348 uint32_t address
, int handle_breakpoints
, int debug_execution
)
350 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
351 struct breakpoint
*breakpoint
= NULL
;
355 if (target
->state
!= TARGET_HALTED
)
357 LOG_WARNING("target not halted");
358 return ERROR_TARGET_NOT_HALTED
;
361 if (!debug_execution
)
363 target_free_all_working_areas(target
);
365 avr32_ap7k_enable_breakpoints(target);
366 avr32_ap7k_enable_watchpoints(target);
370 /* current = 1: continue on current pc, otherwise continue at <address> */
374 if (retval
!= ERROR_OK
)
380 buf_get_u32(ap7k
->core_cache
->reg_list
[AVR32_REG_PC
].value
, 0, 32);
381 avr32_ap7k_restore_context(target
);
383 /* the front-end may request us not to handle breakpoints */
384 if (handle_breakpoints
)
386 /* Single step past breakpoint at current address */
387 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
389 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
"", breakpoint
->address
);
391 avr32_ap7k_unset_breakpoint(target
, breakpoint
);
392 avr32_ap7k_single_step_core(target
);
393 avr32_ap7k_set_breakpoint(target
, breakpoint
);
399 /* enable interrupts if we are running */
400 avr32_ap7k_enable_interrupts(target
, !debug_execution
);
402 /* exit debug mode */
403 mips_ejtag_exit_debug(ejtag_info
);
407 retval
= avr32_ocd_clearbits(&ap7k
->jtag
, AVR32_OCDREG_DC
,
409 if (retval
!= ERROR_OK
)
412 retval
= avr32_jtag_exec(&ap7k
->jtag
, RETD
);
413 if (retval
!= ERROR_OK
)
416 target
->debug_reason
= DBG_REASON_NOTHALTED
;
418 /* registers are now invalid */
419 register_cache_invalidate(ap7k
->core_cache
);
421 if (!debug_execution
)
423 target
->state
= TARGET_RUNNING
;
424 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
425 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
429 target
->state
= TARGET_DEBUG_RUNNING
;
430 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
431 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
437 static int avr32_ap7k_step(struct target
*target
, int current
,
438 uint32_t address
, int handle_breakpoints
)
440 LOG_ERROR("%s: implement me", __func__
);
445 static int avr32_ap7k_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
447 LOG_ERROR("%s: implement me", __func__
);
452 static int avr32_ap7k_remove_breakpoint(struct target
*target
,
453 struct breakpoint
*breakpoint
)
455 LOG_ERROR("%s: implement me", __func__
);
460 static int avr32_ap7k_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
462 LOG_ERROR("%s: implement me", __func__
);
467 static int avr32_ap7k_remove_watchpoint(struct target
*target
,
468 struct watchpoint
*watchpoint
)
470 LOG_ERROR("%s: implement me", __func__
);
475 static int avr32_ap7k_read_memory(struct target
*target
, uint32_t address
,
476 uint32_t size
, uint32_t count
, uint8_t *buffer
)
478 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
480 LOG_DEBUG("address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"", address
, size
, count
);
482 if (target
->state
!= TARGET_HALTED
)
484 LOG_WARNING("target not halted");
485 return ERROR_TARGET_NOT_HALTED
;
488 /* sanitize arguments */
489 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
490 return ERROR_INVALID_ARGUMENTS
;
492 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
493 return ERROR_TARGET_UNALIGNED_ACCESS
;
498 return avr32_jtag_read_memory32(&ap7k
->jtag
, address
, count
, (uint32_t*)(void *)buffer
);
501 return avr32_jtag_read_memory16(&ap7k
->jtag
, address
, count
, (uint16_t*)(void *)buffer
);
504 return avr32_jtag_read_memory8(&ap7k
->jtag
, address
, count
, buffer
);
513 static int avr32_ap7k_write_memory(struct target
*target
, uint32_t address
,
514 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
516 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
518 LOG_DEBUG("address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"", address
, size
, count
);
520 if (target
->state
!= TARGET_HALTED
)
522 LOG_WARNING("target not halted");
523 return ERROR_TARGET_NOT_HALTED
;
526 /* sanitize arguments */
527 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
528 return ERROR_INVALID_ARGUMENTS
;
530 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
531 return ERROR_TARGET_UNALIGNED_ACCESS
;
536 return avr32_jtag_write_memory32(&ap7k
->jtag
, address
, count
, (uint32_t*)(void *)buffer
);
539 return avr32_jtag_write_memory16(&ap7k
->jtag
, address
, count
, (uint16_t*)(void *)buffer
);
542 return avr32_jtag_write_memory8(&ap7k
->jtag
, address
, count
, buffer
);
551 static int avr32_ap7k_init_target(struct command_context
*cmd_ctx
,
552 struct target
*target
)
554 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
556 ap7k
->jtag
.tap
= target
->tap
;
557 avr32_build_reg_cache(target
);
561 static int avr32_ap7k_target_create(struct target
*target
, Jim_Interp
*interp
)
563 struct avr32_ap7k_common
*ap7k
= calloc(1, sizeof(struct
566 ap7k
->common_magic
= AP7k_COMMON_MAGIC
;
567 target
->arch_info
= ap7k
;
572 static int avr32_ap7k_examine(struct target
*target
)
575 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
577 if (!target_was_examined(target
))
579 target_set_examined(target
);
580 avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DID
, &devid
);
581 LOG_INFO("device id: %08x", devid
);
582 avr32_ocd_setbits(&ap7k
->jtag
, AVR32_OCDREG_DC
,OCDREG_DC_DBE
);
583 avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DS
, &ds
);
585 /* check for processor halted */
586 if (ds
& OCDREG_DS_DBA
)
588 LOG_INFO("target is halted");
589 target
->state
= TARGET_HALTED
;
592 target
->state
= TARGET_RUNNING
;
598 static int avr32_ap7k_bulk_write_memory(struct target
*target
, uint32_t address
,
599 uint32_t count
, const uint8_t *buffer
)
601 LOG_ERROR("%s: implement me", __func__
);
607 int avr32_ap7k_arch_state(struct target
*target
)
609 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
611 LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32
"",
612 debug_reason_name(target
), ap7k
->jtag
.dpc
);
617 int avr32_ap7k_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[], int *reg_list_size
)
620 /* get pointers to arch-specific information */
623 /* include floating point registers */
624 *reg_list_size
= AVR32NUMCOREREGS
+ AVR32NUMFPREGS
;
625 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
627 for (i
= 0; i
< AVR32NUMCOREREGS
; i
++)
629 (*reg_list
)[i
] = &mips32
->core_cache
->reg_list
[i
];
632 /* add dummy floating points regs */
633 for (i
= AVR32NUMCOREREGS
; i
< (AVR32NUMCOREREGS
+ AVR32NUMFPREGS
); i
++)
635 (*reg_list
)[i
] = &avr32_ap7k_gdb_dummy_fp_reg
;
639 LOG_ERROR("%s: implement me", __func__
);
645 struct target_type avr32_ap7k_target
=
647 .name
= "avr32_ap7k",
649 .poll
= avr32_ap7k_poll
,
650 .arch_state
= avr32_ap7k_arch_state
,
652 .target_request_data
= NULL
,
654 .halt
= avr32_ap7k_halt
,
655 .resume
= avr32_ap7k_resume
,
656 .step
= avr32_ap7k_step
,
658 .assert_reset
= avr32_ap7k_assert_reset
,
659 .deassert_reset
= avr32_ap7k_deassert_reset
,
660 .soft_reset_halt
= avr32_ap7k_soft_reset_halt
,
662 .get_gdb_reg_list
= avr32_ap7k_get_gdb_reg_list
,
664 .read_memory
= avr32_ap7k_read_memory
,
665 .write_memory
= avr32_ap7k_write_memory
,
666 .bulk_write_memory
= avr32_ap7k_bulk_write_memory
,
667 // .checksum_memory = avr32_ap7k_checksum_memory,
668 // .blank_check_memory = avr32_ap7k_blank_check_memory,
670 // .run_algorithm = avr32_ap7k_run_algorithm,
672 .add_breakpoint
= avr32_ap7k_add_breakpoint
,
673 .remove_breakpoint
= avr32_ap7k_remove_breakpoint
,
674 .add_watchpoint
= avr32_ap7k_add_watchpoint
,
675 .remove_watchpoint
= avr32_ap7k_remove_watchpoint
,
677 .target_create
= avr32_ap7k_target_create
,
678 .init_target
= avr32_ap7k_init_target
,
679 .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)