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, see <http://www.gnu.org/licenses/>. *
19 ***************************************************************************/
25 #include "jtag/jtag.h"
27 #include "algorithm.h"
29 #include "breakpoints.h"
30 #include "target_type.h"
31 #include "avr32_jtag.h"
32 #include "avr32_mem.h"
33 #include "avr32_regs.h"
34 #include "avr32_ap7k.h"
36 static const char * const avr32_core_reg_list
[] = {
37 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8",
38 "r9", "r10", "r11", "r12", "sp", "lr", "pc", "sr"
41 static const struct avr32_core_reg
42 avr32_core_reg_list_arch_info
[AVR32NUMCOREREGS
] = {
63 static int avr32_read_core_reg(struct target
*target
, int num
);
64 static int avr32_write_core_reg(struct target
*target
, int num
);
66 int avr32_ap7k_save_context(struct target
*target
)
69 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
71 retval
= avr32_jtag_read_regs(&ap7k
->jtag
, ap7k
->core_regs
);
72 if (retval
!= ERROR_OK
)
75 for (i
= 0; i
< AVR32NUMCOREREGS
; i
++) {
76 if (!ap7k
->core_cache
->reg_list
[i
].valid
)
77 avr32_read_core_reg(target
, i
);
83 int avr32_ap7k_restore_context(struct target
*target
)
87 /* get pointers to arch-specific information */
88 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
90 for (i
= 0; i
< AVR32NUMCOREREGS
; i
++) {
91 if (ap7k
->core_cache
->reg_list
[i
].dirty
)
92 avr32_write_core_reg(target
, i
);
96 avr32_jtag_write_regs(&ap7k
->jtag
, ap7k
->core_regs
);
101 static int avr32_read_core_reg(struct target
*target
, int num
)
105 /* get pointers to arch-specific information */
106 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
108 if ((num
< 0) || (num
>= AVR32NUMCOREREGS
))
109 return ERROR_COMMAND_SYNTAX_ERROR
;
111 reg_value
= ap7k
->core_regs
[num
];
112 buf_set_u32(ap7k
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
113 ap7k
->core_cache
->reg_list
[num
].valid
= true;
114 ap7k
->core_cache
->reg_list
[num
].dirty
= false;
119 static int avr32_write_core_reg(struct target
*target
, int num
)
123 /* get pointers to arch-specific information */
124 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
126 if ((num
< 0) || (num
>= AVR32NUMCOREREGS
))
127 return ERROR_COMMAND_SYNTAX_ERROR
;
129 reg_value
= buf_get_u32(ap7k
->core_cache
->reg_list
[num
].value
, 0, 32);
130 ap7k
->core_regs
[num
] = reg_value
;
131 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", num
, reg_value
);
132 ap7k
->core_cache
->reg_list
[num
].valid
= true;
133 ap7k
->core_cache
->reg_list
[num
].dirty
= false;
138 static int avr32_get_core_reg(struct reg
*reg
)
141 struct avr32_core_reg
*avr32_reg
= reg
->arch_info
;
142 struct target
*target
= avr32_reg
->target
;
144 if (target
->state
!= TARGET_HALTED
)
145 return ERROR_TARGET_NOT_HALTED
;
147 retval
= avr32_read_core_reg(target
, avr32_reg
->num
);
152 static int avr32_set_core_reg(struct reg
*reg
, uint8_t *buf
)
154 struct avr32_core_reg
*avr32_reg
= reg
->arch_info
;
155 struct target
*target
= avr32_reg
->target
;
156 uint32_t value
= buf_get_u32(buf
, 0, 32);
158 if (target
->state
!= TARGET_HALTED
)
159 return ERROR_TARGET_NOT_HALTED
;
161 buf_set_u32(reg
->value
, 0, 32, value
);
168 static const struct reg_arch_type avr32_reg_type
= {
169 .get
= avr32_get_core_reg
,
170 .set
= avr32_set_core_reg
,
173 static struct reg_cache
*avr32_build_reg_cache(struct target
*target
)
175 int num_regs
= AVR32NUMCOREREGS
;
176 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
177 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
178 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
179 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
180 struct avr32_core_reg
*arch_info
=
181 malloc(sizeof(struct avr32_core_reg
) * num_regs
);
184 /* Build the process context cache */
185 cache
->name
= "avr32 registers";
187 cache
->reg_list
= reg_list
;
188 cache
->num_regs
= num_regs
;
190 ap7k
->core_cache
= cache
;
192 for (i
= 0; i
< num_regs
; i
++) {
193 arch_info
[i
] = avr32_core_reg_list_arch_info
[i
];
194 arch_info
[i
].target
= target
;
195 arch_info
[i
].avr32_common
= ap7k
;
196 reg_list
[i
].name
= avr32_core_reg_list
[i
];
197 reg_list
[i
].size
= 32;
198 reg_list
[i
].value
= calloc(1, 4);
199 reg_list
[i
].dirty
= false;
200 reg_list
[i
].valid
= false;
201 reg_list
[i
].type
= &avr32_reg_type
;
202 reg_list
[i
].arch_info
= &arch_info
[i
];
208 static int avr32_ap7k_debug_entry(struct target
*target
)
213 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
215 retval
= avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DPC
, &dpc
);
216 if (retval
!= ERROR_OK
)
219 retval
= avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DINST
, &dinst
);
220 if (retval
!= ERROR_OK
)
223 ap7k
->jtag
.dpc
= dpc
;
225 avr32_ap7k_save_context(target
);
231 static int avr32_ap7k_poll(struct target
*target
)
235 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
237 retval
= avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DS
, &ds
);
238 if (retval
!= ERROR_OK
)
241 /* check for processor halted */
242 if (ds
& OCDREG_DS_DBA
) {
243 if ((target
->state
== TARGET_RUNNING
) || (target
->state
== TARGET_RESET
)) {
244 target
->state
= TARGET_HALTED
;
246 retval
= avr32_ap7k_debug_entry(target
);
247 if (retval
!= ERROR_OK
)
250 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
251 } else if (target
->state
== TARGET_DEBUG_RUNNING
) {
252 target
->state
= TARGET_HALTED
;
254 retval
= avr32_ap7k_debug_entry(target
);
255 if (retval
!= ERROR_OK
)
258 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
261 target
->state
= TARGET_RUNNING
;
267 static int avr32_ap7k_halt(struct target
*target
)
269 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
271 LOG_DEBUG("target->state: %s",
272 target_state_name(target
));
274 if (target
->state
== TARGET_HALTED
) {
275 LOG_DEBUG("target was already halted");
279 if (target
->state
== TARGET_UNKNOWN
)
280 LOG_WARNING("target was in unknown state when halt was requested");
282 if (target
->state
== TARGET_RESET
) {
283 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst()) {
284 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
285 return ERROR_TARGET_FAILURE
;
287 target
->debug_reason
= DBG_REASON_DBGRQ
;
294 avr32_ocd_setbits(&ap7k
->jtag
, AVR32_OCDREG_DC
, OCDREG_DC_DBR
);
295 target
->debug_reason
= DBG_REASON_DBGRQ
;
300 static int avr32_ap7k_assert_reset(struct target
*target
)
302 LOG_ERROR("%s: implement me", __func__
);
307 static int avr32_ap7k_deassert_reset(struct target
*target
)
309 LOG_ERROR("%s: implement me", __func__
);
314 static int avr32_ap7k_resume(struct target
*target
, int current
,
315 target_addr_t address
, int handle_breakpoints
, int debug_execution
)
317 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
318 struct breakpoint
*breakpoint
= NULL
;
322 if (target
->state
!= TARGET_HALTED
) {
323 LOG_WARNING("target not halted");
324 return ERROR_TARGET_NOT_HALTED
;
327 if (!debug_execution
) {
328 target_free_all_working_areas(target
);
330 avr32_ap7k_enable_breakpoints(target);
331 avr32_ap7k_enable_watchpoints(target);
335 /* current = 1: continue on current pc, otherwise continue at <address> */
338 if (retval
!= ERROR_OK
)
343 resume_pc
= buf_get_u32(ap7k
->core_cache
->reg_list
[AVR32_REG_PC
].value
, 0, 32);
344 avr32_ap7k_restore_context(target
);
346 /* the front-end may request us not to handle breakpoints */
347 if (handle_breakpoints
) {
348 /* Single step past breakpoint at current address */
349 breakpoint
= breakpoint_find(target
, resume_pc
);
351 LOG_DEBUG("unset breakpoint at 0x%8.8" TARGET_PRIxADDR
"", breakpoint
->address
);
353 avr32_ap7k_unset_breakpoint(target
, breakpoint
);
354 avr32_ap7k_single_step_core(target
);
355 avr32_ap7k_set_breakpoint(target
, breakpoint
);
361 /* enable interrupts if we are running */
362 avr32_ap7k_enable_interrupts(target
, !debug_execution
);
364 /* exit debug mode */
365 mips_ejtag_exit_debug(ejtag_info
);
369 retval
= avr32_ocd_clearbits(&ap7k
->jtag
, AVR32_OCDREG_DC
,
371 if (retval
!= ERROR_OK
)
374 retval
= avr32_jtag_exec(&ap7k
->jtag
, RETD
);
375 if (retval
!= ERROR_OK
)
378 target
->debug_reason
= DBG_REASON_NOTHALTED
;
380 /* registers are now invalid */
381 register_cache_invalidate(ap7k
->core_cache
);
383 if (!debug_execution
) {
384 target
->state
= TARGET_RUNNING
;
385 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
386 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
388 target
->state
= TARGET_DEBUG_RUNNING
;
389 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
390 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
396 static int avr32_ap7k_step(struct target
*target
, int current
,
397 target_addr_t address
, int handle_breakpoints
)
399 LOG_ERROR("%s: implement me", __func__
);
404 static int avr32_ap7k_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
406 LOG_ERROR("%s: implement me", __func__
);
411 static int avr32_ap7k_remove_breakpoint(struct target
*target
,
412 struct breakpoint
*breakpoint
)
414 LOG_ERROR("%s: implement me", __func__
);
419 static int avr32_ap7k_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
421 LOG_ERROR("%s: implement me", __func__
);
426 static int avr32_ap7k_remove_watchpoint(struct target
*target
,
427 struct watchpoint
*watchpoint
)
429 LOG_ERROR("%s: implement me", __func__
);
434 static int avr32_ap7k_read_memory(struct target
*target
, target_addr_t address
,
435 uint32_t size
, uint32_t count
, uint8_t *buffer
)
437 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
439 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
444 if (target
->state
!= TARGET_HALTED
) {
445 LOG_WARNING("target not halted");
446 return ERROR_TARGET_NOT_HALTED
;
449 /* sanitize arguments */
450 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
451 return ERROR_COMMAND_SYNTAX_ERROR
;
453 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
454 return ERROR_TARGET_UNALIGNED_ACCESS
;
458 return avr32_jtag_read_memory32(&ap7k
->jtag
, address
, count
,
459 (uint32_t *)(void *)buffer
);
462 return avr32_jtag_read_memory16(&ap7k
->jtag
, address
, count
,
463 (uint16_t *)(void *)buffer
);
466 return avr32_jtag_read_memory8(&ap7k
->jtag
, address
, count
, buffer
);
475 static int avr32_ap7k_write_memory(struct target
*target
, target_addr_t address
,
476 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
478 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
480 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
485 if (target
->state
!= TARGET_HALTED
) {
486 LOG_WARNING("target not halted");
487 return ERROR_TARGET_NOT_HALTED
;
490 /* sanitize arguments */
491 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
492 return ERROR_COMMAND_SYNTAX_ERROR
;
494 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
495 return ERROR_TARGET_UNALIGNED_ACCESS
;
499 return avr32_jtag_write_memory32(&ap7k
->jtag
, address
, count
,
500 (uint32_t *)(void *)buffer
);
503 return avr32_jtag_write_memory16(&ap7k
->jtag
, address
, count
,
504 (uint16_t *)(void *)buffer
);
507 return avr32_jtag_write_memory8(&ap7k
->jtag
, address
, count
, buffer
);
516 static int avr32_ap7k_init_target(struct command_context
*cmd_ctx
,
517 struct target
*target
)
519 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
521 ap7k
->jtag
.tap
= target
->tap
;
522 avr32_build_reg_cache(target
);
526 static int avr32_ap7k_target_create(struct target
*target
, Jim_Interp
*interp
)
528 struct avr32_ap7k_common
*ap7k
= calloc(1, sizeof(struct
531 ap7k
->common_magic
= AP7k_COMMON_MAGIC
;
532 target
->arch_info
= ap7k
;
537 static int avr32_ap7k_examine(struct target
*target
)
540 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
542 if (!target_was_examined(target
)) {
543 target_set_examined(target
);
544 avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DID
, &devid
);
545 LOG_INFO("device id: %08" PRIx32
, devid
);
546 avr32_ocd_setbits(&ap7k
->jtag
, AVR32_OCDREG_DC
, OCDREG_DC_DBE
);
547 avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DS
, &ds
);
549 /* check for processor halted */
550 if (ds
& OCDREG_DS_DBA
) {
551 LOG_INFO("target is halted");
552 target
->state
= TARGET_HALTED
;
554 target
->state
= TARGET_RUNNING
;
560 int avr32_ap7k_arch_state(struct target
*target
)
562 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
564 LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32
"",
565 debug_reason_name(target
), ap7k
->jtag
.dpc
);
570 int avr32_ap7k_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[],
571 int *reg_list_size
, enum target_register_class reg_class
)
574 /* get pointers to arch-specific information */
577 /* include floating point registers */
578 *reg_list_size
= AVR32NUMCOREREGS
+ AVR32NUMFPREGS
;
579 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
581 for (i
= 0; i
< AVR32NUMCOREREGS
; i
++)
582 (*reg_list
)[i
] = &mips32
->core_cache
->reg_list
[i
];
584 /* add dummy floating points regs */
585 for (i
= AVR32NUMCOREREGS
; i
< (AVR32NUMCOREREGS
+ AVR32NUMFPREGS
); i
++)
586 (*reg_list
)[i
] = &avr32_ap7k_gdb_dummy_fp_reg
;
590 LOG_ERROR("%s: implement me", __func__
);
594 struct target_type avr32_ap7k_target
= {
595 .name
= "avr32_ap7k",
597 .poll
= avr32_ap7k_poll
,
598 .arch_state
= avr32_ap7k_arch_state
,
600 .halt
= avr32_ap7k_halt
,
601 .resume
= avr32_ap7k_resume
,
602 .step
= avr32_ap7k_step
,
604 .assert_reset
= avr32_ap7k_assert_reset
,
605 .deassert_reset
= avr32_ap7k_deassert_reset
,
607 .get_gdb_reg_list
= avr32_ap7k_get_gdb_reg_list
,
609 .read_memory
= avr32_ap7k_read_memory
,
610 .write_memory
= avr32_ap7k_write_memory
,
611 /* .checksum_memory = avr32_ap7k_checksum_memory, */
612 /* .blank_check_memory = avr32_ap7k_blank_check_memory, */
614 /* .run_algorithm = avr32_ap7k_run_algorithm, */
616 .add_breakpoint
= avr32_ap7k_add_breakpoint
,
617 .remove_breakpoint
= avr32_ap7k_remove_breakpoint
,
618 .add_watchpoint
= avr32_ap7k_add_watchpoint
,
619 .remove_watchpoint
= avr32_ap7k_remove_watchpoint
,
621 .target_create
= avr32_ap7k_target_create
,
622 .init_target
= avr32_ap7k_init_target
,
623 .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)