1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2006 by Magnus Lundin *
8 * Copyright (C) 2008 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
11 * Copyright (C) 2007,2008 Øyvind Harboe *
12 * oyvind.harboe@zylin.com *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program; if not, write to the *
26 * Free Software Foundation, Inc., *
27 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
29 * ARMv7-M Architecture, Application Level Reference Manual *
30 * ARM DDI 0405C (September 2008) *
32 ***************************************************************************/
39 #define ARRAY_SIZE(x) ((int)(sizeof(x)/sizeof((x)[0])))
43 #define _DEBUG_INSTRUCTION_EXECUTION_
46 char* armv7m_mode_strings
[] =
48 "Thread", "Thread (User)", "Handler",
51 static char *armv7m_exception_strings
[] =
53 "", "Reset", "NMI", "HardFault",
54 "MemManage", "BusFault", "UsageFault", "RESERVED",
55 "RESERVED", "RESERVED", "RESERVED", "SVCall",
56 "DebugMonitor", "RESERVED", "PendSV", "SysTick"
59 uint8_t armv7m_gdb_dummy_fp_value
[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
61 reg_t armv7m_gdb_dummy_fp_reg
=
63 "GDB dummy floating-point register", armv7m_gdb_dummy_fp_value
, 0, 1, 96, NULL
, 0, NULL
, 0
66 uint8_t armv7m_gdb_dummy_fps_value
[] = {0, 0, 0, 0};
68 reg_t armv7m_gdb_dummy_fps_reg
=
70 "GDB dummy floating-point status register", armv7m_gdb_dummy_fps_value
, 0, 1, 32, NULL
, 0, NULL
, 0
73 #ifdef ARMV7_GDB_HACKS
74 uint8_t armv7m_gdb_dummy_cpsr_value
[] = {0, 0, 0, 0};
76 reg_t armv7m_gdb_dummy_cpsr_reg
=
78 "GDB dummy cpsr register", armv7m_gdb_dummy_cpsr_value
, 0, 1, 32, NULL
, 0, NULL
, 0
83 * These registers are not memory-mapped. The ARMv7-M profile includes
84 * memory mapped registers too, such as for the NVIC (interrupt controller)
85 * and SysTick (timer) modules; those can mostly be treated as peripherals.
92 { ARMV7M_R0
, "r0", 32 },
93 { ARMV7M_R1
, "r1", 32 },
94 { ARMV7M_R2
, "r2", 32 },
95 { ARMV7M_R3
, "r3", 32 },
97 { ARMV7M_R4
, "r4", 32 },
98 { ARMV7M_R5
, "r5", 32 },
99 { ARMV7M_R6
, "r6", 32 },
100 { ARMV7M_R7
, "r7", 32 },
102 { ARMV7M_R8
, "r8", 32 },
103 { ARMV7M_R9
, "r9", 32 },
104 { ARMV7M_R10
, "r10", 32 },
105 { ARMV7M_R11
, "r11", 32 },
107 { ARMV7M_R12
, "r12", 32 },
108 { ARMV7M_R13
, "sp", 32 },
109 { ARMV7M_R14
, "lr", 32 },
110 { ARMV7M_PC
, "pc", 32 },
112 { ARMV7M_xPSR
, "xPSR", 32 },
113 { ARMV7M_MSP
, "msp", 32 },
114 { ARMV7M_PSP
, "psp", 32 },
116 { ARMV7M_PRIMASK
, "primask", 1 },
117 { ARMV7M_BASEPRI
, "basepri", 8 },
118 { ARMV7M_FAULTMASK
, "faultmask", 1 },
119 { ARMV7M_CONTROL
, "control", 2 },
122 #define ARMV7M_NUM_REGS ARRAY_SIZE(armv7m_regs)
124 int armv7m_core_reg_arch_type
= -1;
125 int armv7m_dummy_core_reg_arch_type
= -1;
127 int armv7m_restore_context(target_t
*target
)
131 /* get pointers to arch-specific information */
132 armv7m_common_t
*armv7m
= target
->arch_info
;
136 if (armv7m
->pre_restore_context
)
137 armv7m
->pre_restore_context(target
);
139 for (i
= ARMV7M_NUM_REGS
- 1; i
>= 0; i
--)
141 if (armv7m
->core_cache
->reg_list
[i
].dirty
)
143 armv7m
->write_core_reg(target
, i
);
147 if (armv7m
->post_restore_context
)
148 armv7m
->post_restore_context(target
);
153 /* Core state functions */
154 char *armv7m_exception_string(int number
)
156 static char enamebuf
[32];
158 if ((number
< 0) | (number
> 511))
159 return "Invalid exception";
161 return armv7m_exception_strings
[number
];
162 sprintf(enamebuf
, "External Interrupt(%i)", number
- 16);
166 int armv7m_get_core_reg(reg_t
*reg
)
169 armv7m_core_reg_t
*armv7m_reg
= reg
->arch_info
;
170 target_t
*target
= armv7m_reg
->target
;
171 armv7m_common_t
*armv7m_target
= target
->arch_info
;
173 if (target
->state
!= TARGET_HALTED
)
175 return ERROR_TARGET_NOT_HALTED
;
178 retval
= armv7m_target
->read_core_reg(target
, armv7m_reg
->num
);
183 int armv7m_set_core_reg(reg_t
*reg
, uint8_t *buf
)
185 armv7m_core_reg_t
*armv7m_reg
= reg
->arch_info
;
186 target_t
*target
= armv7m_reg
->target
;
187 uint32_t value
= buf_get_u32(buf
, 0, 32);
189 if (target
->state
!= TARGET_HALTED
)
191 return ERROR_TARGET_NOT_HALTED
;
194 buf_set_u32(reg
->value
, 0, 32, value
);
201 int armv7m_read_core_reg(struct target_s
*target
, int num
)
205 armv7m_core_reg_t
* armv7m_core_reg
;
207 /* get pointers to arch-specific information */
208 armv7m_common_t
*armv7m
= target
->arch_info
;
210 if ((num
< 0) || (num
>= ARMV7M_NUM_REGS
))
211 return ERROR_INVALID_ARGUMENTS
;
213 armv7m_core_reg
= armv7m
->core_cache
->reg_list
[num
].arch_info
;
214 retval
= armv7m
->load_core_reg_u32(target
, armv7m_core_reg
->type
, armv7m_core_reg
->num
, ®_value
);
215 buf_set_u32(armv7m
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
216 armv7m
->core_cache
->reg_list
[num
].valid
= 1;
217 armv7m
->core_cache
->reg_list
[num
].dirty
= 0;
222 int armv7m_write_core_reg(struct target_s
*target
, int num
)
226 armv7m_core_reg_t
*armv7m_core_reg
;
228 /* get pointers to arch-specific information */
229 armv7m_common_t
*armv7m
= target
->arch_info
;
231 if ((num
< 0) || (num
>= ARMV7M_NUM_REGS
))
232 return ERROR_INVALID_ARGUMENTS
;
234 reg_value
= buf_get_u32(armv7m
->core_cache
->reg_list
[num
].value
, 0, 32);
235 armv7m_core_reg
= armv7m
->core_cache
->reg_list
[num
].arch_info
;
236 retval
= armv7m
->store_core_reg_u32(target
, armv7m_core_reg
->type
, armv7m_core_reg
->num
, reg_value
);
237 if (retval
!= ERROR_OK
)
239 LOG_ERROR("JTAG failure");
240 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
241 return ERROR_JTAG_DEVICE_ERROR
;
243 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", num
, reg_value
);
244 armv7m
->core_cache
->reg_list
[num
].valid
= 1;
245 armv7m
->core_cache
->reg_list
[num
].dirty
= 0;
250 int armv7m_invalidate_core_regs(target_t
*target
)
252 /* get pointers to arch-specific information */
253 armv7m_common_t
*armv7m
= target
->arch_info
;
256 for (i
= 0; i
< armv7m
->core_cache
->num_regs
; i
++)
258 armv7m
->core_cache
->reg_list
[i
].valid
= 0;
259 armv7m
->core_cache
->reg_list
[i
].dirty
= 0;
265 int armv7m_get_gdb_reg_list(target_t
*target
, reg_t
**reg_list
[], int *reg_list_size
)
267 /* get pointers to arch-specific information */
268 armv7m_common_t
*armv7m
= target
->arch_info
;
272 *reg_list
= malloc(sizeof(reg_t
*) * (*reg_list_size
));
275 * GDB register packet format for ARM:
276 * - the first 16 registers are r0..r15
277 * - (obsolete) 8 FPA registers
278 * - (obsolete) FPA status
281 for (i
= 0; i
< 16; i
++)
283 (*reg_list
)[i
] = &armv7m
->core_cache
->reg_list
[i
];
286 for (i
= 16; i
< 24; i
++)
288 (*reg_list
)[i
] = &armv7m_gdb_dummy_fp_reg
;
291 (*reg_list
)[24] = &armv7m_gdb_dummy_fps_reg
;
293 #ifdef ARMV7_GDB_HACKS
294 /* use dummy cpsr reg otherwise gdb may try and set the thumb bit */
295 (*reg_list
)[25] = &armv7m_gdb_dummy_cpsr_reg
;
297 /* ARMV7M is always in thumb mode, try to make GDB understand this
298 * if it does not support this arch */
299 *((char*)armv7m
->core_cache
->reg_list
[15].value
) |= 1;
301 (*reg_list
)[25] = &armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
];
307 /* run to exit point. return error if exit point was not reached. */
308 static int armv7m_run_and_wait(struct target_s
*target
, uint32_t entry_point
, int timeout_ms
, uint32_t exit_point
, armv7m_common_t
*armv7m
)
312 /* This code relies on the target specific resume() and poll()->debug_entry()
313 * sequence to write register values to the processor and the read them back */
314 if ((retval
= target_resume(target
, 0, entry_point
, 1, 1)) != ERROR_OK
)
319 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
320 /* If the target fails to halt due to the breakpoint, force a halt */
321 if (retval
!= ERROR_OK
|| target
->state
!= TARGET_HALTED
)
323 if ((retval
= target_halt(target
)) != ERROR_OK
)
325 if ((retval
= target_wait_state(target
, TARGET_HALTED
, 500)) != ERROR_OK
)
329 return ERROR_TARGET_TIMEOUT
;
332 armv7m
->load_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 15, &pc
);
333 if (pc
!= exit_point
)
335 LOG_DEBUG("failed algoritm halted at 0x%" PRIx32
" ", pc
);
336 return ERROR_TARGET_TIMEOUT
;
342 int armv7m_run_algorithm(struct target_s
*target
, int num_mem_params
, mem_param_t
*mem_params
, int num_reg_params
, reg_param_t
*reg_params
, uint32_t entry_point
, uint32_t exit_point
, int timeout_ms
, void *arch_info
)
344 /* get pointers to arch-specific information */
345 armv7m_common_t
*armv7m
= target
->arch_info
;
346 armv7m_algorithm_t
*armv7m_algorithm_info
= arch_info
;
347 enum armv7m_mode core_mode
= armv7m
->core_mode
;
348 int retval
= ERROR_OK
;
350 uint32_t context
[ARMV7M_NUM_REGS
];
352 if (armv7m_algorithm_info
->common_magic
!= ARMV7M_COMMON_MAGIC
)
354 LOG_ERROR("current target isn't an ARMV7M target");
355 return ERROR_TARGET_INVALID
;
358 if (target
->state
!= TARGET_HALTED
)
360 LOG_WARNING("target not halted");
361 return ERROR_TARGET_NOT_HALTED
;
364 /* refresh core register cache */
365 /* Not needed if core register cache is always consistent with target process state */
366 for (i
= 0; i
< ARMV7M_NUM_REGS
; i
++)
368 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
369 armv7m
->read_core_reg(target
, i
);
370 context
[i
] = buf_get_u32(armv7m
->core_cache
->reg_list
[i
].value
, 0, 32);
373 for (i
= 0; i
< num_mem_params
; i
++)
375 if ((retval
= target_write_buffer(target
, mem_params
[i
].address
, mem_params
[i
].size
, mem_params
[i
].value
)) != ERROR_OK
)
379 for (i
= 0; i
< num_reg_params
; i
++)
381 reg_t
*reg
= register_get_by_name(armv7m
->core_cache
, reg_params
[i
].reg_name
, 0);
382 // uint32_t regvalue;
386 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
390 if (reg
->size
!= reg_params
[i
].size
)
392 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params
[i
].reg_name
);
396 // regvalue = buf_get_u32(reg_params[i].value, 0, 32);
397 armv7m_set_core_reg(reg
, reg_params
[i
].value
);
400 if (armv7m_algorithm_info
->core_mode
!= ARMV7M_MODE_ANY
)
402 LOG_DEBUG("setting core_mode: 0x%2.2x", armv7m_algorithm_info
->core_mode
);
403 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_CONTROL
].value
,
404 0, 1, armv7m_algorithm_info
->core_mode
);
405 armv7m
->core_cache
->reg_list
[ARMV7M_CONTROL
].dirty
= 1;
406 armv7m
->core_cache
->reg_list
[ARMV7M_CONTROL
].valid
= 1;
409 /* ARMV7M always runs in Thumb state */
410 if ((retval
= breakpoint_add(target
, exit_point
, 2, BKPT_SOFT
)) != ERROR_OK
)
412 LOG_ERROR("can't add breakpoint to finish algorithm execution");
413 return ERROR_TARGET_FAILURE
;
416 retval
= armv7m_run_and_wait(target
, entry_point
, timeout_ms
, exit_point
, armv7m
);
418 breakpoint_remove(target
, exit_point
);
420 if (retval
!= ERROR_OK
)
425 /* Read memory values to mem_params[] */
426 for (i
= 0; i
< num_mem_params
; i
++)
428 if (mem_params
[i
].direction
!= PARAM_OUT
)
429 if ((retval
= target_read_buffer(target
, mem_params
[i
].address
, mem_params
[i
].size
, mem_params
[i
].value
)) != ERROR_OK
)
435 /* Copy core register values to reg_params[] */
436 for (i
= 0; i
< num_reg_params
; i
++)
438 if (reg_params
[i
].direction
!= PARAM_OUT
)
440 reg_t
*reg
= register_get_by_name(armv7m
->core_cache
, reg_params
[i
].reg_name
, 0);
444 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
448 if (reg
->size
!= reg_params
[i
].size
)
450 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params
[i
].reg_name
);
454 buf_set_u32(reg_params
[i
].value
, 0, 32, buf_get_u32(reg
->value
, 0, 32));
458 for (i
= ARMV7M_NUM_REGS
- 1; i
>= 0; i
--)
461 regvalue
= buf_get_u32(armv7m
->core_cache
->reg_list
[i
].value
, 0, 32);
462 if (regvalue
!= context
[i
])
464 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32
,
465 armv7m
->core_cache
->reg_list
[i
].name
, context
[i
]);
466 buf_set_u32(armv7m
->core_cache
->reg_list
[i
].value
,
468 armv7m
->core_cache
->reg_list
[i
].valid
= 1;
469 armv7m
->core_cache
->reg_list
[i
].dirty
= 1;
473 armv7m
->core_mode
= core_mode
;
478 int armv7m_arch_state(struct target_s
*target
)
480 /* get pointers to arch-specific information */
481 armv7m_common_t
*armv7m
= target
->arch_info
;
484 ctrl
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_CONTROL
].value
, 0, 32);
485 sp
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_R13
].value
, 0, 32);
487 LOG_USER("target halted due to %s, current mode: %s %s\n"
488 "xPSR: %#8.8" PRIx32
" pc: %#8.8" PRIx32
" %csp: %#8.8" PRIx32
,
489 Jim_Nvp_value2name_simple(nvp_target_debug_reason
,
490 target
->debug_reason
)->name
,
491 armv7m_mode_strings
[armv7m
->core_mode
],
492 armv7m_exception_string(armv7m
->exception_number
),
493 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32),
494 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PC
].value
, 0, 32),
495 (ctrl
& 0x02) ? 'p' : 'm',
501 reg_cache_t
*armv7m_build_reg_cache(target_t
*target
)
503 /* get pointers to arch-specific information */
504 armv7m_common_t
*armv7m
= target
->arch_info
;
506 int num_regs
= ARMV7M_NUM_REGS
;
507 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
508 reg_cache_t
*cache
= malloc(sizeof(reg_cache_t
));
509 reg_t
*reg_list
= calloc(num_regs
, sizeof(reg_t
));
510 armv7m_core_reg_t
*arch_info
= calloc(num_regs
, sizeof(armv7m_core_reg_t
));
513 if (armv7m_core_reg_arch_type
== -1)
515 armv7m_core_reg_arch_type
= register_reg_arch_type(armv7m_get_core_reg
, armv7m_set_core_reg
);
518 register_init_dummy(&armv7m_gdb_dummy_fps_reg
);
519 #ifdef ARMV7_GDB_HACKS
520 register_init_dummy(&armv7m_gdb_dummy_cpsr_reg
);
522 register_init_dummy(&armv7m_gdb_dummy_fp_reg
);
524 /* Build the process context cache */
525 cache
->name
= "arm v7m registers";
527 cache
->reg_list
= reg_list
;
528 cache
->num_regs
= num_regs
;
530 armv7m
->core_cache
= cache
;
532 for (i
= 0; i
< num_regs
; i
++)
534 arch_info
[i
].num
= armv7m_regs
[i
].id
;
535 arch_info
[i
].target
= target
;
536 arch_info
[i
].armv7m_common
= armv7m
;
537 reg_list
[i
].name
= armv7m_regs
[i
].name
;
538 reg_list
[i
].size
= armv7m_regs
[i
].bits
;
539 reg_list
[i
].value
= calloc(1, 4);
540 reg_list
[i
].dirty
= 0;
541 reg_list
[i
].valid
= 0;
542 reg_list
[i
].bitfield_desc
= NULL
;
543 reg_list
[i
].num_bitfields
= 0;
544 reg_list
[i
].arch_type
= armv7m_core_reg_arch_type
;
545 reg_list
[i
].arch_info
= &arch_info
[i
];
551 int armv7m_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
553 armv7m_build_reg_cache(target
);
558 int armv7m_init_arch_info(target_t
*target
, armv7m_common_t
*armv7m
)
560 /* register arch-specific functions */
562 target
->arch_info
= armv7m
;
563 armv7m
->read_core_reg
= armv7m_read_core_reg
;
564 armv7m
->write_core_reg
= armv7m_write_core_reg
;
569 int armv7m_checksum_memory(struct target_s
*target
, uint32_t address
, uint32_t count
, uint32_t* checksum
)
571 working_area_t
*crc_algorithm
;
572 armv7m_algorithm_t armv7m_info
;
573 reg_param_t reg_params
[2];
576 static const uint16_t cortex_m3_crc_code
[] = {
577 0x4602, /* mov r2, r0 */
578 0xF04F, 0x30FF, /* mov r0, #0xffffffff */
579 0x460B, /* mov r3, r1 */
580 0xF04F, 0x0400, /* mov r4, #0 */
581 0xE013, /* b ncomp */
583 0x5D11, /* ldrb r1, [r2, r4] */
584 0xF8DF, 0x7028, /* ldr r7, CRC32XOR */
585 0xEA80, 0x6001, /* eor r0, r0, r1, asl #24 */
587 0xF04F, 0x0500, /* mov r5, #0 */
589 0x2800, /* cmp r0, #0 */
590 0xEA4F, 0x0640, /* mov r6, r0, asl #1 */
591 0xF105, 0x0501, /* add r5, r5, #1 */
592 0x4630, /* mov r0, r6 */
594 0xEA86, 0x0007, /* eor r0, r6, r7 */
595 0x2D08, /* cmp r5, #8 */
596 0xD1F4, /* bne loop */
598 0xF104, 0x0401, /* add r4, r4, #1 */
600 0x429C, /* cmp r4, r3 */
601 0xD1E9, /* bne nbyte */
604 0x1DB7, 0x04C1 /* CRC32XOR: .word 0x04C11DB7 */
609 if (target_alloc_working_area(target
, sizeof(cortex_m3_crc_code
), &crc_algorithm
) != ERROR_OK
)
611 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
614 /* convert flash writing code into a buffer in target endianness */
615 for (i
= 0; i
< (sizeof(cortex_m3_crc_code
)/sizeof(uint16_t)); i
++)
616 if ((retval
= target_write_u16(target
, crc_algorithm
->address
+ i
*sizeof(uint16_t), cortex_m3_crc_code
[i
])) != ERROR_OK
)
621 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
622 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
624 init_reg_param(®_params
[0], "r0", 32, PARAM_IN_OUT
);
625 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
627 buf_set_u32(reg_params
[0].value
, 0, 32, address
);
628 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
630 if ((retval
= target_run_algorithm(target
, 0, NULL
, 2, reg_params
,
631 crc_algorithm
->address
, crc_algorithm
->address
+ (sizeof(cortex_m3_crc_code
)-6), 20000, &armv7m_info
)) != ERROR_OK
)
633 LOG_ERROR("error executing cortex_m3 crc algorithm");
634 destroy_reg_param(®_params
[0]);
635 destroy_reg_param(®_params
[1]);
636 target_free_working_area(target
, crc_algorithm
);
640 *checksum
= buf_get_u32(reg_params
[0].value
, 0, 32);
642 destroy_reg_param(®_params
[0]);
643 destroy_reg_param(®_params
[1]);
645 target_free_working_area(target
, crc_algorithm
);
650 int armv7m_blank_check_memory(struct target_s
*target
, uint32_t address
, uint32_t count
, uint32_t* blank
)
652 working_area_t
*erase_check_algorithm
;
653 reg_param_t reg_params
[3];
654 armv7m_algorithm_t armv7m_info
;
658 static const uint16_t erase_check_code
[] =
661 0xF810, 0x3B01, /* ldrb r3, [r0], #1 */
662 0xEA02, 0x0203, /* and r2, r2, r3 */
663 0x3901, /* subs r1, r1, #1 */
664 0xD1F9, /* bne loop */
669 /* make sure we have a working area */
670 if (target_alloc_working_area(target
, sizeof(erase_check_code
), &erase_check_algorithm
) != ERROR_OK
)
672 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
675 /* convert flash writing code into a buffer in target endianness */
676 for (i
= 0; i
< (sizeof(erase_check_code
)/sizeof(uint16_t)); i
++)
677 target_write_u16(target
, erase_check_algorithm
->address
+ i
*sizeof(uint16_t), erase_check_code
[i
]);
679 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
680 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
682 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
683 buf_set_u32(reg_params
[0].value
, 0, 32, address
);
685 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
686 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
688 init_reg_param(®_params
[2], "r2", 32, PARAM_IN_OUT
);
689 buf_set_u32(reg_params
[2].value
, 0, 32, 0xff);
691 if ((retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
,
692 erase_check_algorithm
->address
, erase_check_algorithm
->address
+ (sizeof(erase_check_code
)-2), 10000, &armv7m_info
)) != ERROR_OK
)
694 destroy_reg_param(®_params
[0]);
695 destroy_reg_param(®_params
[1]);
696 destroy_reg_param(®_params
[2]);
697 target_free_working_area(target
, erase_check_algorithm
);
701 *blank
= buf_get_u32(reg_params
[2].value
, 0, 32);
703 destroy_reg_param(®_params
[0]);
704 destroy_reg_param(®_params
[1]);
705 destroy_reg_param(®_params
[2]);
707 target_free_working_area(target
, erase_check_algorithm
);
713 * Return the debug ap baseaddress in hexadecimal;
714 * no extra output to simplify script processing
716 static int handle_dap_baseaddr_command(struct command_context_s
*cmd_ctx
,
717 char *cmd
, char **args
, int argc
)
719 target_t
*target
= get_current_target(cmd_ctx
);
720 armv7m_common_t
*armv7m
= target
->arch_info
;
721 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
722 uint32_t apsel
, apselsave
, baseaddr
;
725 apsel
= swjdp
->apsel
;
726 apselsave
= swjdp
->apsel
;
729 apsel
= strtoul(args
[0], NULL
, 0);
731 if (apselsave
!= apsel
)
733 dap_ap_select(swjdp
, apsel
);
736 dap_ap_read_reg_u32(swjdp
, 0xF8, &baseaddr
);
737 retval
= swjdp_transaction_endcheck(swjdp
);
738 command_print(cmd_ctx
, "0x%8.8" PRIx32
"", baseaddr
);
740 if (apselsave
!= apsel
)
742 dap_ap_select(swjdp
, apselsave
);
750 * Return the debug ap id in hexadecimal;
751 * no extra output to simplify script processing
753 extern int handle_dap_apid_command(struct command_context_s
*cmd_ctx
,
754 char *cmd
, char **args
, int argc
)
756 target_t
*target
= get_current_target(cmd_ctx
);
757 armv7m_common_t
*armv7m
= target
->arch_info
;
758 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
760 return dap_apid_command(cmd_ctx
, swjdp
, args
, argc
);
763 static int handle_dap_apsel_command(struct command_context_s
*cmd_ctx
,
764 char *cmd
, char **args
, int argc
)
766 target_t
*target
= get_current_target(cmd_ctx
);
767 armv7m_common_t
*armv7m
= target
->arch_info
;
768 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
770 return dap_apsel_command(cmd_ctx
, swjdp
, args
, argc
);
773 static int handle_dap_memaccess_command(struct command_context_s
*cmd_ctx
,
774 char *cmd
, char **args
, int argc
)
776 target_t
*target
= get_current_target(cmd_ctx
);
777 armv7m_common_t
*armv7m
= target
->arch_info
;
778 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
780 return dap_memaccess_command(cmd_ctx
, swjdp
, args
, argc
);
784 static int handle_dap_info_command(struct command_context_s
*cmd_ctx
,
785 char *cmd
, char **args
, int argc
)
787 target_t
*target
= get_current_target(cmd_ctx
);
788 armv7m_common_t
*armv7m
= target
->arch_info
;
789 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
792 apsel
= swjdp
->apsel
;
794 apsel
= strtoul(args
[0], NULL
, 0);
796 return dap_info_command(cmd_ctx
, swjdp
, apsel
);
799 int armv7m_register_commands(struct command_context_s
*cmd_ctx
)
801 command_t
*arm_adi_v5_dap_cmd
;
803 arm_adi_v5_dap_cmd
= register_command(cmd_ctx
, NULL
, "dap",
805 "cortex dap specific commands");
807 register_command(cmd_ctx
, arm_adi_v5_dap_cmd
, "info",
808 handle_dap_info_command
, COMMAND_EXEC
,
809 "Displays dap info for ap [num],"
810 "default currently selected AP");
811 register_command(cmd_ctx
, arm_adi_v5_dap_cmd
, "apsel",
812 handle_dap_apsel_command
, COMMAND_EXEC
,
813 "Select a different AP [num] (default 0)");
814 register_command(cmd_ctx
, arm_adi_v5_dap_cmd
, "apid",
815 handle_dap_apid_command
, COMMAND_EXEC
,
816 "Displays id reg from AP [num], "
817 "default currently selected AP");
818 register_command(cmd_ctx
, arm_adi_v5_dap_cmd
, "baseaddr",
819 handle_dap_baseaddr_command
, COMMAND_EXEC
,
820 "Displays debug base address from AP [num],"
821 "default currently selected AP");
822 register_command(cmd_ctx
, arm_adi_v5_dap_cmd
, "memaccess",
823 handle_dap_memaccess_command
, COMMAND_EXEC
,
824 "set/get number of extra tck for mem-ap "
825 "memory bus access [0-255]");
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)