1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com> *
5 * Based on mips_m4k code: *
6 * Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> *
7 * Copyright (C) 2008 by David T.L. Wong *
8 ***************************************************************************/
14 #include "jtag/jtag.h"
16 #include "algorithm.h"
18 #include "breakpoints.h"
19 #include "target_type.h"
20 #include "avr32_jtag.h"
21 #include "avr32_mem.h"
22 #include "avr32_regs.h"
23 #include "avr32_ap7k.h"
25 static const char * const avr32_core_reg_list
[] = {
26 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8",
27 "r9", "r10", "r11", "r12", "sp", "lr", "pc", "sr"
30 static const struct avr32_core_reg
31 avr32_core_reg_list_arch_info
[AVR32NUMCOREREGS
] = {
52 static int avr32_read_core_reg(struct target
*target
, int num
);
53 static int avr32_write_core_reg(struct target
*target
, int num
);
55 static int avr32_ap7k_save_context(struct target
*target
)
58 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
60 retval
= avr32_jtag_read_regs(&ap7k
->jtag
, ap7k
->core_regs
);
61 if (retval
!= ERROR_OK
)
64 for (i
= 0; i
< AVR32NUMCOREREGS
; i
++) {
65 if (!ap7k
->core_cache
->reg_list
[i
].valid
)
66 avr32_read_core_reg(target
, i
);
72 static int avr32_ap7k_restore_context(struct target
*target
)
76 /* get pointers to arch-specific information */
77 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
79 for (i
= 0; i
< AVR32NUMCOREREGS
; i
++) {
80 if (ap7k
->core_cache
->reg_list
[i
].dirty
)
81 avr32_write_core_reg(target
, i
);
85 avr32_jtag_write_regs(&ap7k
->jtag
, ap7k
->core_regs
);
90 static int avr32_read_core_reg(struct target
*target
, int num
)
94 /* get pointers to arch-specific information */
95 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
97 if ((num
< 0) || (num
>= AVR32NUMCOREREGS
))
98 return ERROR_COMMAND_SYNTAX_ERROR
;
100 reg_value
= ap7k
->core_regs
[num
];
101 buf_set_u32(ap7k
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
102 ap7k
->core_cache
->reg_list
[num
].valid
= true;
103 ap7k
->core_cache
->reg_list
[num
].dirty
= false;
108 static int avr32_write_core_reg(struct target
*target
, int num
)
112 /* get pointers to arch-specific information */
113 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
115 if ((num
< 0) || (num
>= AVR32NUMCOREREGS
))
116 return ERROR_COMMAND_SYNTAX_ERROR
;
118 reg_value
= buf_get_u32(ap7k
->core_cache
->reg_list
[num
].value
, 0, 32);
119 ap7k
->core_regs
[num
] = reg_value
;
120 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", num
, reg_value
);
121 ap7k
->core_cache
->reg_list
[num
].valid
= true;
122 ap7k
->core_cache
->reg_list
[num
].dirty
= false;
127 static int avr32_get_core_reg(struct reg
*reg
)
130 struct avr32_core_reg
*avr32_reg
= reg
->arch_info
;
131 struct target
*target
= avr32_reg
->target
;
133 if (target
->state
!= TARGET_HALTED
)
134 return ERROR_TARGET_NOT_HALTED
;
136 retval
= avr32_read_core_reg(target
, avr32_reg
->num
);
141 static int avr32_set_core_reg(struct reg
*reg
, uint8_t *buf
)
143 struct avr32_core_reg
*avr32_reg
= reg
->arch_info
;
144 struct target
*target
= avr32_reg
->target
;
145 uint32_t value
= buf_get_u32(buf
, 0, 32);
147 if (target
->state
!= TARGET_HALTED
)
148 return ERROR_TARGET_NOT_HALTED
;
150 buf_set_u32(reg
->value
, 0, 32, value
);
157 static const struct reg_arch_type avr32_reg_type
= {
158 .get
= avr32_get_core_reg
,
159 .set
= avr32_set_core_reg
,
162 static struct reg_cache
*avr32_build_reg_cache(struct target
*target
)
164 int num_regs
= AVR32NUMCOREREGS
;
165 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
166 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
167 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
168 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
169 struct avr32_core_reg
*arch_info
=
170 malloc(sizeof(struct avr32_core_reg
) * num_regs
);
173 /* Build the process context cache */
174 cache
->name
= "avr32 registers";
176 cache
->reg_list
= reg_list
;
177 cache
->num_regs
= num_regs
;
179 ap7k
->core_cache
= cache
;
181 for (i
= 0; i
< num_regs
; i
++) {
182 arch_info
[i
] = avr32_core_reg_list_arch_info
[i
];
183 arch_info
[i
].target
= target
;
184 arch_info
[i
].avr32_common
= ap7k
;
185 reg_list
[i
].name
= avr32_core_reg_list
[i
];
186 reg_list
[i
].size
= 32;
187 reg_list
[i
].value
= calloc(1, 4);
188 reg_list
[i
].dirty
= false;
189 reg_list
[i
].valid
= false;
190 reg_list
[i
].type
= &avr32_reg_type
;
191 reg_list
[i
].arch_info
= &arch_info
[i
];
197 static int avr32_ap7k_debug_entry(struct target
*target
)
202 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
204 retval
= avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DPC
, &dpc
);
205 if (retval
!= ERROR_OK
)
208 retval
= avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DINST
, &dinst
);
209 if (retval
!= ERROR_OK
)
212 ap7k
->jtag
.dpc
= dpc
;
214 avr32_ap7k_save_context(target
);
220 static int avr32_ap7k_poll(struct target
*target
)
224 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
226 retval
= avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DS
, &ds
);
227 if (retval
!= ERROR_OK
)
230 /* check for processor halted */
231 if (ds
& OCDREG_DS_DBA
) {
232 if ((target
->state
== TARGET_RUNNING
) || (target
->state
== TARGET_RESET
)) {
233 target
->state
= TARGET_HALTED
;
235 retval
= avr32_ap7k_debug_entry(target
);
236 if (retval
!= ERROR_OK
)
239 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
240 } else if (target
->state
== TARGET_DEBUG_RUNNING
) {
241 target
->state
= TARGET_HALTED
;
243 retval
= avr32_ap7k_debug_entry(target
);
244 if (retval
!= ERROR_OK
)
247 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
250 target
->state
= TARGET_RUNNING
;
256 static int avr32_ap7k_halt(struct target
*target
)
258 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
260 LOG_DEBUG("target->state: %s",
261 target_state_name(target
));
263 if (target
->state
== TARGET_HALTED
) {
264 LOG_DEBUG("target was already halted");
268 if (target
->state
== TARGET_UNKNOWN
)
269 LOG_WARNING("target was in unknown state when halt was requested");
271 if (target
->state
== TARGET_RESET
) {
272 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst()) {
273 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
274 return ERROR_TARGET_FAILURE
;
276 target
->debug_reason
= DBG_REASON_DBGRQ
;
283 avr32_ocd_setbits(&ap7k
->jtag
, AVR32_OCDREG_DC
, OCDREG_DC_DBR
);
284 target
->debug_reason
= DBG_REASON_DBGRQ
;
289 static int avr32_ap7k_assert_reset(struct target
*target
)
291 LOG_ERROR("%s: implement me", __func__
);
296 static int avr32_ap7k_deassert_reset(struct target
*target
)
298 LOG_ERROR("%s: implement me", __func__
);
303 static int avr32_ap7k_resume(struct target
*target
, int current
,
304 target_addr_t address
, int handle_breakpoints
, int debug_execution
)
306 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
307 struct breakpoint
*breakpoint
= NULL
;
311 if (target
->state
!= TARGET_HALTED
) {
312 LOG_WARNING("target not halted");
313 return ERROR_TARGET_NOT_HALTED
;
316 if (!debug_execution
) {
317 target_free_all_working_areas(target
);
319 avr32_ap7k_enable_breakpoints(target);
320 avr32_ap7k_enable_watchpoints(target);
324 /* current = 1: continue on current pc, otherwise continue at <address> */
327 if (retval
!= ERROR_OK
)
332 resume_pc
= buf_get_u32(ap7k
->core_cache
->reg_list
[AVR32_REG_PC
].value
, 0, 32);
333 avr32_ap7k_restore_context(target
);
335 /* the front-end may request us not to handle breakpoints */
336 if (handle_breakpoints
) {
337 /* Single step past breakpoint at current address */
338 breakpoint
= breakpoint_find(target
, resume_pc
);
340 LOG_DEBUG("unset breakpoint at 0x%8.8" TARGET_PRIxADDR
"", breakpoint
->address
);
342 avr32_ap7k_unset_breakpoint(target
, breakpoint
);
343 avr32_ap7k_single_step_core(target
);
344 avr32_ap7k_set_breakpoint(target
, breakpoint
);
350 /* enable interrupts if we are running */
351 avr32_ap7k_enable_interrupts(target
, !debug_execution
);
353 /* exit debug mode */
354 mips_ejtag_exit_debug(ejtag_info
);
358 retval
= avr32_ocd_clearbits(&ap7k
->jtag
, AVR32_OCDREG_DC
,
360 if (retval
!= ERROR_OK
)
363 retval
= avr32_jtag_exec(&ap7k
->jtag
, RETD
);
364 if (retval
!= ERROR_OK
)
367 target
->debug_reason
= DBG_REASON_NOTHALTED
;
369 /* registers are now invalid */
370 register_cache_invalidate(ap7k
->core_cache
);
372 if (!debug_execution
) {
373 target
->state
= TARGET_RUNNING
;
374 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
375 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
377 target
->state
= TARGET_DEBUG_RUNNING
;
378 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
379 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
385 static int avr32_ap7k_step(struct target
*target
, int current
,
386 target_addr_t address
, int handle_breakpoints
)
388 LOG_ERROR("%s: implement me", __func__
);
393 static int avr32_ap7k_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
395 LOG_ERROR("%s: implement me", __func__
);
400 static int avr32_ap7k_remove_breakpoint(struct target
*target
,
401 struct breakpoint
*breakpoint
)
403 LOG_ERROR("%s: implement me", __func__
);
408 static int avr32_ap7k_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
410 LOG_ERROR("%s: implement me", __func__
);
415 static int avr32_ap7k_remove_watchpoint(struct target
*target
,
416 struct watchpoint
*watchpoint
)
418 LOG_ERROR("%s: implement me", __func__
);
423 static int avr32_ap7k_read_memory(struct target
*target
, target_addr_t address
,
424 uint32_t size
, uint32_t count
, uint8_t *buffer
)
426 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
428 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
433 if (target
->state
!= TARGET_HALTED
) {
434 LOG_WARNING("target not halted");
435 return ERROR_TARGET_NOT_HALTED
;
438 /* sanitize arguments */
439 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
440 return ERROR_COMMAND_SYNTAX_ERROR
;
442 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
443 return ERROR_TARGET_UNALIGNED_ACCESS
;
447 return avr32_jtag_read_memory32(&ap7k
->jtag
, address
, count
,
448 (uint32_t *)(void *)buffer
);
451 return avr32_jtag_read_memory16(&ap7k
->jtag
, address
, count
,
452 (uint16_t *)(void *)buffer
);
455 return avr32_jtag_read_memory8(&ap7k
->jtag
, address
, count
, buffer
);
463 static int avr32_ap7k_write_memory(struct target
*target
, target_addr_t address
,
464 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
466 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
468 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
473 if (target
->state
!= TARGET_HALTED
) {
474 LOG_WARNING("target not halted");
475 return ERROR_TARGET_NOT_HALTED
;
478 /* sanitize arguments */
479 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
480 return ERROR_COMMAND_SYNTAX_ERROR
;
482 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
483 return ERROR_TARGET_UNALIGNED_ACCESS
;
487 return avr32_jtag_write_memory32(&ap7k
->jtag
, address
, count
,
488 (uint32_t *)(void *)buffer
);
491 return avr32_jtag_write_memory16(&ap7k
->jtag
, address
, count
,
492 (uint16_t *)(void *)buffer
);
495 return avr32_jtag_write_memory8(&ap7k
->jtag
, address
, count
, buffer
);
503 static int avr32_ap7k_init_target(struct command_context
*cmd_ctx
,
504 struct target
*target
)
506 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
508 ap7k
->jtag
.tap
= target
->tap
;
509 avr32_build_reg_cache(target
);
513 static int avr32_ap7k_target_create(struct target
*target
, Jim_Interp
*interp
)
515 struct avr32_ap7k_common
*ap7k
= calloc(1, sizeof(struct
518 ap7k
->common_magic
= AP7K_COMMON_MAGIC
;
519 target
->arch_info
= ap7k
;
524 static int avr32_ap7k_examine(struct target
*target
)
527 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
529 if (!target_was_examined(target
)) {
530 target_set_examined(target
);
531 avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DID
, &devid
);
532 LOG_INFO("device id: %08" PRIx32
, devid
);
533 avr32_ocd_setbits(&ap7k
->jtag
, AVR32_OCDREG_DC
, OCDREG_DC_DBE
);
534 avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DS
, &ds
);
536 /* check for processor halted */
537 if (ds
& OCDREG_DS_DBA
) {
538 LOG_INFO("target is halted");
539 target
->state
= TARGET_HALTED
;
541 target
->state
= TARGET_RUNNING
;
547 static int avr32_ap7k_arch_state(struct target
*target
)
549 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
551 LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32
"",
552 debug_reason_name(target
), ap7k
->jtag
.dpc
);
557 static int avr32_ap7k_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[],
558 int *reg_list_size
, enum target_register_class reg_class
)
561 /* get pointers to arch-specific information */
564 /* include floating point registers */
565 *reg_list_size
= AVR32NUMCOREREGS
+ AVR32NUMFPREGS
;
566 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
568 for (i
= 0; i
< AVR32NUMCOREREGS
; i
++)
569 (*reg_list
)[i
] = &mips32
->core_cache
->reg_list
[i
];
571 /* add dummy floating points regs */
572 for (i
= AVR32NUMCOREREGS
; i
< (AVR32NUMCOREREGS
+ AVR32NUMFPREGS
); i
++)
573 (*reg_list
)[i
] = &avr32_ap7k_gdb_dummy_fp_reg
;
577 LOG_ERROR("%s: implement me", __func__
);
581 struct target_type avr32_ap7k_target
= {
582 .name
= "avr32_ap7k",
584 .poll
= avr32_ap7k_poll
,
585 .arch_state
= avr32_ap7k_arch_state
,
587 .halt
= avr32_ap7k_halt
,
588 .resume
= avr32_ap7k_resume
,
589 .step
= avr32_ap7k_step
,
591 .assert_reset
= avr32_ap7k_assert_reset
,
592 .deassert_reset
= avr32_ap7k_deassert_reset
,
594 .get_gdb_reg_list
= avr32_ap7k_get_gdb_reg_list
,
596 .read_memory
= avr32_ap7k_read_memory
,
597 .write_memory
= avr32_ap7k_write_memory
,
598 /* .checksum_memory = avr32_ap7k_checksum_memory, */
599 /* .blank_check_memory = avr32_ap7k_blank_check_memory, */
601 /* .run_algorithm = avr32_ap7k_run_algorithm, */
603 .add_breakpoint
= avr32_ap7k_add_breakpoint
,
604 .remove_breakpoint
= avr32_ap7k_remove_breakpoint
,
605 .add_watchpoint
= avr32_ap7k_add_watchpoint
,
606 .remove_watchpoint
= avr32_ap7k_remove_watchpoint
,
608 .target_create
= avr32_ap7k_target_create
,
609 .init_target
= avr32_ap7k_init_target
,
610 .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)