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 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 const char * const 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 const 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
= calloc(num_regs
, sizeof(struct reg
));
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_resume(struct target
*target
, int current
,
317 uint32_t address
, int handle_breakpoints
, int debug_execution
)
319 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
320 struct breakpoint
*breakpoint
= NULL
;
324 if (target
->state
!= TARGET_HALTED
) {
325 LOG_WARNING("target not halted");
326 return ERROR_TARGET_NOT_HALTED
;
329 if (!debug_execution
) {
330 target_free_all_working_areas(target
);
332 avr32_ap7k_enable_breakpoints(target);
333 avr32_ap7k_enable_watchpoints(target);
337 /* current = 1: continue on current pc, otherwise continue at <address> */
340 if (retval
!= ERROR_OK
)
345 resume_pc
= buf_get_u32(ap7k
->core_cache
->reg_list
[AVR32_REG_PC
].value
, 0, 32);
346 avr32_ap7k_restore_context(target
);
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
);
353 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
"", breakpoint
->address
);
355 avr32_ap7k_unset_breakpoint(target
, breakpoint
);
356 avr32_ap7k_single_step_core(target
);
357 avr32_ap7k_set_breakpoint(target
, breakpoint
);
363 /* enable interrupts if we are running */
364 avr32_ap7k_enable_interrupts(target
, !debug_execution
);
366 /* exit debug mode */
367 mips_ejtag_exit_debug(ejtag_info
);
371 retval
= avr32_ocd_clearbits(&ap7k
->jtag
, AVR32_OCDREG_DC
,
373 if (retval
!= ERROR_OK
)
376 retval
= avr32_jtag_exec(&ap7k
->jtag
, RETD
);
377 if (retval
!= ERROR_OK
)
380 target
->debug_reason
= DBG_REASON_NOTHALTED
;
382 /* registers are now invalid */
383 register_cache_invalidate(ap7k
->core_cache
);
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
);
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
);
398 static int avr32_ap7k_step(struct target
*target
, int current
,
399 uint32_t address
, int handle_breakpoints
)
401 LOG_ERROR("%s: implement me", __func__
);
406 static int avr32_ap7k_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
408 LOG_ERROR("%s: implement me", __func__
);
413 static int avr32_ap7k_remove_breakpoint(struct target
*target
,
414 struct breakpoint
*breakpoint
)
416 LOG_ERROR("%s: implement me", __func__
);
421 static int avr32_ap7k_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
423 LOG_ERROR("%s: implement me", __func__
);
428 static int avr32_ap7k_remove_watchpoint(struct target
*target
,
429 struct watchpoint
*watchpoint
)
431 LOG_ERROR("%s: implement me", __func__
);
436 static int avr32_ap7k_read_memory(struct target
*target
, uint32_t address
,
437 uint32_t size
, uint32_t count
, uint8_t *buffer
)
439 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
441 LOG_DEBUG("address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
446 if (target
->state
!= TARGET_HALTED
) {
447 LOG_WARNING("target not halted");
448 return ERROR_TARGET_NOT_HALTED
;
451 /* sanitize arguments */
452 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
453 return ERROR_COMMAND_SYNTAX_ERROR
;
455 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
456 return ERROR_TARGET_UNALIGNED_ACCESS
;
460 return avr32_jtag_read_memory32(&ap7k
->jtag
, address
, count
,
461 (uint32_t *)(void *)buffer
);
464 return avr32_jtag_read_memory16(&ap7k
->jtag
, address
, count
,
465 (uint16_t *)(void *)buffer
);
468 return avr32_jtag_read_memory8(&ap7k
->jtag
, address
, count
, buffer
);
477 static int avr32_ap7k_write_memory(struct target
*target
, uint32_t address
,
478 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
480 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
482 LOG_DEBUG("address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
487 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_COMMAND_SYNTAX_ERROR
;
496 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
497 return ERROR_TARGET_UNALIGNED_ACCESS
;
501 return avr32_jtag_write_memory32(&ap7k
->jtag
, address
, count
,
502 (uint32_t *)(void *)buffer
);
505 return avr32_jtag_write_memory16(&ap7k
->jtag
, address
, count
,
506 (uint16_t *)(void *)buffer
);
509 return avr32_jtag_write_memory8(&ap7k
->jtag
, address
, count
, buffer
);
518 static int avr32_ap7k_init_target(struct command_context
*cmd_ctx
,
519 struct target
*target
)
521 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
523 ap7k
->jtag
.tap
= target
->tap
;
524 avr32_build_reg_cache(target
);
528 static int avr32_ap7k_target_create(struct target
*target
, Jim_Interp
*interp
)
530 struct avr32_ap7k_common
*ap7k
= calloc(1, sizeof(struct
533 ap7k
->common_magic
= AP7k_COMMON_MAGIC
;
534 target
->arch_info
= ap7k
;
539 static int avr32_ap7k_examine(struct target
*target
)
542 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
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
);
551 /* check for processor halted */
552 if (ds
& OCDREG_DS_DBA
) {
553 LOG_INFO("target is halted");
554 target
->state
= TARGET_HALTED
;
556 target
->state
= TARGET_RUNNING
;
562 int avr32_ap7k_arch_state(struct target
*target
)
564 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
566 LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32
"",
567 debug_reason_name(target
), ap7k
->jtag
.dpc
);
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
)
576 /* get pointers to arch-specific information */
579 /* include floating point registers */
580 *reg_list_size
= AVR32NUMCOREREGS
+ AVR32NUMFPREGS
;
581 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
583 for (i
= 0; i
< AVR32NUMCOREREGS
; i
++)
584 (*reg_list
)[i
] = &mips32
->core_cache
->reg_list
[i
];
586 /* add dummy floating points regs */
587 for (i
= AVR32NUMCOREREGS
; i
< (AVR32NUMCOREREGS
+ AVR32NUMFPREGS
); i
++)
588 (*reg_list
)[i
] = &avr32_ap7k_gdb_dummy_fp_reg
;
592 LOG_ERROR("%s: implement me", __func__
);
596 struct target_type avr32_ap7k_target
= {
597 .name
= "avr32_ap7k",
599 .poll
= avr32_ap7k_poll
,
600 .arch_state
= avr32_ap7k_arch_state
,
602 .halt
= avr32_ap7k_halt
,
603 .resume
= avr32_ap7k_resume
,
604 .step
= avr32_ap7k_step
,
606 .assert_reset
= avr32_ap7k_assert_reset
,
607 .deassert_reset
= avr32_ap7k_deassert_reset
,
609 .get_gdb_reg_list
= avr32_ap7k_get_gdb_reg_list
,
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, */
616 /* .run_algorithm = avr32_ap7k_run_algorithm, */
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
,
623 .target_create
= avr32_ap7k_target_create
,
624 .init_target
= avr32_ap7k_init_target
,
625 .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)