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 static 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 static 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
);
474 static int avr32_ap7k_write_memory(struct target
*target
, target_addr_t address
,
475 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
477 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
479 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
484 if (target
->state
!= TARGET_HALTED
) {
485 LOG_WARNING("target not halted");
486 return ERROR_TARGET_NOT_HALTED
;
489 /* sanitize arguments */
490 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
491 return ERROR_COMMAND_SYNTAX_ERROR
;
493 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
494 return ERROR_TARGET_UNALIGNED_ACCESS
;
498 return avr32_jtag_write_memory32(&ap7k
->jtag
, address
, count
,
499 (uint32_t *)(void *)buffer
);
502 return avr32_jtag_write_memory16(&ap7k
->jtag
, address
, count
,
503 (uint16_t *)(void *)buffer
);
506 return avr32_jtag_write_memory8(&ap7k
->jtag
, address
, count
, buffer
);
514 static int avr32_ap7k_init_target(struct command_context
*cmd_ctx
,
515 struct target
*target
)
517 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
519 ap7k
->jtag
.tap
= target
->tap
;
520 avr32_build_reg_cache(target
);
524 static int avr32_ap7k_target_create(struct target
*target
, Jim_Interp
*interp
)
526 struct avr32_ap7k_common
*ap7k
= calloc(1, sizeof(struct
529 ap7k
->common_magic
= AP7K_COMMON_MAGIC
;
530 target
->arch_info
= ap7k
;
535 static int avr32_ap7k_examine(struct target
*target
)
538 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
540 if (!target_was_examined(target
)) {
541 target_set_examined(target
);
542 avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DID
, &devid
);
543 LOG_INFO("device id: %08" PRIx32
, devid
);
544 avr32_ocd_setbits(&ap7k
->jtag
, AVR32_OCDREG_DC
, OCDREG_DC_DBE
);
545 avr32_jtag_nexus_read(&ap7k
->jtag
, AVR32_OCDREG_DS
, &ds
);
547 /* check for processor halted */
548 if (ds
& OCDREG_DS_DBA
) {
549 LOG_INFO("target is halted");
550 target
->state
= TARGET_HALTED
;
552 target
->state
= TARGET_RUNNING
;
558 static int avr32_ap7k_arch_state(struct target
*target
)
560 struct avr32_ap7k_common
*ap7k
= target_to_ap7k(target
);
562 LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32
"",
563 debug_reason_name(target
), ap7k
->jtag
.dpc
);
568 static int avr32_ap7k_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[],
569 int *reg_list_size
, enum target_register_class reg_class
)
572 /* get pointers to arch-specific information */
575 /* include floating point registers */
576 *reg_list_size
= AVR32NUMCOREREGS
+ AVR32NUMFPREGS
;
577 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
579 for (i
= 0; i
< AVR32NUMCOREREGS
; i
++)
580 (*reg_list
)[i
] = &mips32
->core_cache
->reg_list
[i
];
582 /* add dummy floating points regs */
583 for (i
= AVR32NUMCOREREGS
; i
< (AVR32NUMCOREREGS
+ AVR32NUMFPREGS
); i
++)
584 (*reg_list
)[i
] = &avr32_ap7k_gdb_dummy_fp_reg
;
588 LOG_ERROR("%s: implement me", __func__
);
592 struct target_type avr32_ap7k_target
= {
593 .name
= "avr32_ap7k",
595 .poll
= avr32_ap7k_poll
,
596 .arch_state
= avr32_ap7k_arch_state
,
598 .halt
= avr32_ap7k_halt
,
599 .resume
= avr32_ap7k_resume
,
600 .step
= avr32_ap7k_step
,
602 .assert_reset
= avr32_ap7k_assert_reset
,
603 .deassert_reset
= avr32_ap7k_deassert_reset
,
605 .get_gdb_reg_list
= avr32_ap7k_get_gdb_reg_list
,
607 .read_memory
= avr32_ap7k_read_memory
,
608 .write_memory
= avr32_ap7k_write_memory
,
609 /* .checksum_memory = avr32_ap7k_checksum_memory, */
610 /* .blank_check_memory = avr32_ap7k_blank_check_memory, */
612 /* .run_algorithm = avr32_ap7k_run_algorithm, */
614 .add_breakpoint
= avr32_ap7k_add_breakpoint
,
615 .remove_breakpoint
= avr32_ap7k_remove_breakpoint
,
616 .add_watchpoint
= avr32_ap7k_add_watchpoint
,
617 .remove_watchpoint
= avr32_ap7k_remove_watchpoint
,
619 .target_create
= avr32_ap7k_target_create
,
620 .init_target
= avr32_ap7k_init_target
,
621 .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)