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 ***************************************************************************/
27 #include "jtag/jtag.h"
29 #include "algorithm.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"
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"
43 static struct avr32_core_reg
44 avr32_core_reg_list_arch_info
[AVR32NUMCOREREGS
] = {
65 static int avr32_read_core_reg(struct target
*target
, int num
);
66 static int avr32_write_core_reg(struct target
*target
, int num
);
68 int avr32_ap7k_save_context(struct target
*target
)
71 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
73 retval
= avr32_jtag_read_regs(&ap7k
->jtag
, ap7k
->core_regs
);
74 if (retval
!= ERROR_OK
)
77 for (i
= 0; i
< AVR32NUMCOREREGS
; i
++) {
78 if (!ap7k
->core_cache
->reg_list
[i
].valid
)
79 avr32_read_core_reg(target
, i
);
85 int avr32_ap7k_restore_context(struct target
*target
)
89 /* get pointers to arch-specific information */
90 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
92 for (i
= 0; i
< AVR32NUMCOREREGS
; i
++) {
93 if (ap7k
->core_cache
->reg_list
[i
].dirty
)
94 avr32_write_core_reg(target
, i
);
98 avr32_jtag_write_regs(&ap7k
->jtag
, ap7k
->core_regs
);
103 static int avr32_read_core_reg(struct target
*target
, int num
)
107 /* get pointers to arch-specific information */
108 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
110 if ((num
< 0) || (num
>= AVR32NUMCOREREGS
))
111 return ERROR_COMMAND_SYNTAX_ERROR
;
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;
121 static int avr32_write_core_reg(struct target
*target
, int num
)
125 /* get pointers to arch-specific information */
126 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
128 if ((num
< 0) || (num
>= AVR32NUMCOREREGS
))
129 return ERROR_COMMAND_SYNTAX_ERROR
;
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;
140 static int avr32_get_core_reg(struct reg
*reg
)
143 struct avr32_core_reg
*avr32_reg
= reg
->arch_info
;
144 struct target
*target
= avr32_reg
->target
;
146 if (target
->state
!= TARGET_HALTED
)
147 return ERROR_TARGET_NOT_HALTED
;
149 retval
= avr32_read_core_reg(target
, avr32_reg
->num
);
154 static int avr32_set_core_reg(struct reg
*reg
, uint8_t *buf
)
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);
160 if (target
->state
!= TARGET_HALTED
)
161 return ERROR_TARGET_NOT_HALTED
;
163 buf_set_u32(reg
->value
, 0, 32, value
);
170 static const struct reg_arch_type avr32_reg_type
= {
171 .get
= avr32_get_core_reg
,
172 .set
= avr32_set_core_reg
,
175 static struct reg_cache
*avr32_build_reg_cache(struct target
*target
)
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
= malloc(sizeof(struct reg
) * num_regs
);
182 struct avr32_core_reg
*arch_info
=
183 malloc(sizeof(struct avr32_core_reg
) * num_regs
);
186 /* Build the process context cache */
187 cache
->name
= "avr32 registers";
189 cache
->reg_list
= reg_list
;
190 cache
->num_regs
= num_regs
;
192 ap7k
->core_cache
= cache
;
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
];
210 static int avr32_ap7k_debug_entry(struct target
*target
)
215 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
217 retval
= avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DPC
, &dpc
);
218 if (retval
!= ERROR_OK
)
221 retval
= avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DINST
, &dinst
);
222 if (retval
!= ERROR_OK
)
225 ap7k
->jtag
.dpc
= dpc
;
227 avr32_ap7k_save_context(target
);
233 static int avr32_ap7k_poll(struct target
*target
)
237 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
239 retval
= avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DS
, &ds
);
240 if (retval
!= ERROR_OK
)
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
;
248 retval
= avr32_ap7k_debug_entry(target
);
249 if (retval
!= ERROR_OK
)
252 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
253 } else if (target
->state
== TARGET_DEBUG_RUNNING
) {
254 target
->state
= TARGET_HALTED
;
256 retval
= avr32_ap7k_debug_entry(target
);
257 if (retval
!= ERROR_OK
)
260 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
263 target
->state
= TARGET_RUNNING
;
269 static int avr32_ap7k_halt(struct target
*target
)
271 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
273 LOG_DEBUG("target->state: %s",
274 target_state_name(target
));
276 if (target
->state
== TARGET_HALTED
) {
277 LOG_DEBUG("target was already halted");
281 if (target
->state
== TARGET_UNKNOWN
)
282 LOG_WARNING("target was in unknown state when halt was requested");
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
;
289 target
->debug_reason
= DBG_REASON_DBGRQ
;
296 avr32_ocd_setbits(&ap7k
->jtag
, AVR32_OCDREG_DC
, OCDREG_DC_DBR
);
297 target
->debug_reason
= DBG_REASON_DBGRQ
;
302 static int avr32_ap7k_assert_reset(struct target
*target
)
304 LOG_ERROR("%s: implement me", __func__
);
309 static int avr32_ap7k_deassert_reset(struct target
*target
)
311 LOG_ERROR("%s: implement me", __func__
);
316 static int avr32_ap7k_soft_reset_halt(struct target
*target
)
318 LOG_ERROR("%s: implement me", __func__
);
323 static int avr32_ap7k_resume(struct target
*target
, int current
,
324 uint32_t address
, int handle_breakpoints
, int debug_execution
)
326 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
327 struct breakpoint
*breakpoint
= NULL
;
331 if (target
->state
!= TARGET_HALTED
) {
332 LOG_WARNING("target not halted");
333 return ERROR_TARGET_NOT_HALTED
;
336 if (!debug_execution
) {
337 target_free_all_working_areas(target
);
339 avr32_ap7k_enable_breakpoints(target);
340 avr32_ap7k_enable_watchpoints(target);
344 /* current = 1: continue on current pc, otherwise continue at <address> */
347 if (retval
!= ERROR_OK
)
352 resume_pc
= buf_get_u32(ap7k
->core_cache
->reg_list
[AVR32_REG_PC
].value
, 0, 32);
353 avr32_ap7k_restore_context(target
);
355 /* the front-end may request us not to handle breakpoints */
356 if (handle_breakpoints
) {
357 /* Single step past breakpoint at current address */
358 breakpoint
= breakpoint_find(target
, resume_pc
);
360 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
"", breakpoint
->address
);
362 avr32_ap7k_unset_breakpoint(target
, breakpoint
);
363 avr32_ap7k_single_step_core(target
);
364 avr32_ap7k_set_breakpoint(target
, breakpoint
);
370 /* enable interrupts if we are running */
371 avr32_ap7k_enable_interrupts(target
, !debug_execution
);
373 /* exit debug mode */
374 mips_ejtag_exit_debug(ejtag_info
);
378 retval
= avr32_ocd_clearbits(&ap7k
->jtag
, AVR32_OCDREG_DC
,
380 if (retval
!= ERROR_OK
)
383 retval
= avr32_jtag_exec(&ap7k
->jtag
, RETD
);
384 if (retval
!= ERROR_OK
)
387 target
->debug_reason
= DBG_REASON_NOTHALTED
;
389 /* registers are now invalid */
390 register_cache_invalidate(ap7k
->core_cache
);
392 if (!debug_execution
) {
393 target
->state
= TARGET_RUNNING
;
394 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
395 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
397 target
->state
= TARGET_DEBUG_RUNNING
;
398 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
399 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
405 static int avr32_ap7k_step(struct target
*target
, int current
,
406 uint32_t address
, int handle_breakpoints
)
408 LOG_ERROR("%s: implement me", __func__
);
413 static int avr32_ap7k_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
415 LOG_ERROR("%s: implement me", __func__
);
420 static int avr32_ap7k_remove_breakpoint(struct target
*target
,
421 struct breakpoint
*breakpoint
)
423 LOG_ERROR("%s: implement me", __func__
);
428 static int avr32_ap7k_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
430 LOG_ERROR("%s: implement me", __func__
);
435 static int avr32_ap7k_remove_watchpoint(struct target
*target
,
436 struct watchpoint
*watchpoint
)
438 LOG_ERROR("%s: implement me", __func__
);
443 static int avr32_ap7k_read_memory(struct target
*target
, uint32_t address
,
444 uint32_t size
, uint32_t count
, uint8_t *buffer
)
446 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
448 LOG_DEBUG("address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
453 if (target
->state
!= TARGET_HALTED
) {
454 LOG_WARNING("target not halted");
455 return ERROR_TARGET_NOT_HALTED
;
458 /* sanitize arguments */
459 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
460 return ERROR_COMMAND_SYNTAX_ERROR
;
462 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
463 return ERROR_TARGET_UNALIGNED_ACCESS
;
467 return avr32_jtag_read_memory32(&ap7k
->jtag
, address
, count
,
468 (uint32_t *)(void *)buffer
);
471 return avr32_jtag_read_memory16(&ap7k
->jtag
, address
, count
,
472 (uint16_t *)(void *)buffer
);
475 return avr32_jtag_read_memory8(&ap7k
->jtag
, address
, count
, buffer
);
484 static int avr32_ap7k_write_memory(struct target
*target
, uint32_t address
,
485 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
487 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
489 LOG_DEBUG("address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
494 if (target
->state
!= TARGET_HALTED
) {
495 LOG_WARNING("target not halted");
496 return ERROR_TARGET_NOT_HALTED
;
499 /* sanitize arguments */
500 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
501 return ERROR_COMMAND_SYNTAX_ERROR
;
503 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
504 return ERROR_TARGET_UNALIGNED_ACCESS
;
508 return avr32_jtag_write_memory32(&ap7k
->jtag
, address
, count
,
509 (uint32_t *)(void *)buffer
);
512 return avr32_jtag_write_memory16(&ap7k
->jtag
, address
, count
,
513 (uint16_t *)(void *)buffer
);
516 return avr32_jtag_write_memory8(&ap7k
->jtag
, address
, count
, buffer
);
525 static int avr32_ap7k_init_target(struct command_context
*cmd_ctx
,
526 struct target
*target
)
528 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
530 ap7k
->jtag
.tap
= target
->tap
;
531 avr32_build_reg_cache(target
);
535 static int avr32_ap7k_target_create(struct target
*target
, Jim_Interp
*interp
)
537 struct avr32_ap7k_common
*ap7k
= calloc(1, sizeof(struct
540 ap7k
->common_magic
= AP7k_COMMON_MAGIC
;
541 target
->arch_info
= ap7k
;
546 static int avr32_ap7k_examine(struct target
*target
)
549 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
551 if (!target_was_examined(target
)) {
552 target_set_examined(target
);
553 avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DID
, &devid
);
554 LOG_INFO("device id: %08x", devid
);
555 avr32_ocd_setbits(&ap7k
->jtag
, AVR32_OCDREG_DC
, OCDREG_DC_DBE
);
556 avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DS
, &ds
);
558 /* check for processor halted */
559 if (ds
& OCDREG_DS_DBA
) {
560 LOG_INFO("target is halted");
561 target
->state
= TARGET_HALTED
;
563 target
->state
= TARGET_RUNNING
;
569 int avr32_ap7k_arch_state(struct target
*target
)
571 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
573 LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32
"",
574 debug_reason_name(target
), ap7k
->jtag
.dpc
);
579 int avr32_ap7k_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[], int *reg_list_size
)
582 /* get pointers to arch-specific information */
585 /* include floating point registers */
586 *reg_list_size
= AVR32NUMCOREREGS
+ AVR32NUMFPREGS
;
587 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
589 for (i
= 0; i
< AVR32NUMCOREREGS
; i
++)
590 (*reg_list
)[i
] = &mips32
->core_cache
->reg_list
[i
];
592 /* add dummy floating points regs */
593 for (i
= AVR32NUMCOREREGS
; i
< (AVR32NUMCOREREGS
+ AVR32NUMFPREGS
); i
++)
594 (*reg_list
)[i
] = &avr32_ap7k_gdb_dummy_fp_reg
;
598 LOG_ERROR("%s: implement me", __func__
);
604 struct target_type avr32_ap7k_target
= {
605 .name
= "avr32_ap7k",
607 .poll
= avr32_ap7k_poll
,
608 .arch_state
= avr32_ap7k_arch_state
,
610 .target_request_data
= NULL
,
612 .halt
= avr32_ap7k_halt
,
613 .resume
= avr32_ap7k_resume
,
614 .step
= avr32_ap7k_step
,
616 .assert_reset
= avr32_ap7k_assert_reset
,
617 .deassert_reset
= avr32_ap7k_deassert_reset
,
618 .soft_reset_halt
= avr32_ap7k_soft_reset_halt
,
620 .get_gdb_reg_list
= avr32_ap7k_get_gdb_reg_list
,
622 .read_memory
= avr32_ap7k_read_memory
,
623 .write_memory
= avr32_ap7k_write_memory
,
624 /* .checksum_memory = avr32_ap7k_checksum_memory, */
625 /* .blank_check_memory = avr32_ap7k_blank_check_memory, */
627 /* .run_algorithm = avr32_ap7k_run_algorithm, */
629 .add_breakpoint
= avr32_ap7k_add_breakpoint
,
630 .remove_breakpoint
= avr32_ap7k_remove_breakpoint
,
631 .add_watchpoint
= avr32_ap7k_add_watchpoint
,
632 .remove_watchpoint
= avr32_ap7k_remove_watchpoint
,
634 .target_create
= avr32_ap7k_target_create
,
635 .init_target
= avr32_ap7k_init_target
,
636 .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)