1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2006 by Magnus Lundin *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
27 #include "replacements.h"
40 #define _DEBUG_INSTRUCTION_EXECUTION_
43 char* armv7m_mode_strings
[] =
48 char* armv7m_state_strings
[] =
53 char* armv7m_exception_strings
[] =
55 "", "Reset", "NMI", "HardFault", "MemManage", "BusFault", "UsageFault", "RESERVED", "RESERVED", "RESERVED", "RESERVED",
56 "SVCall", "DebugMonitor", "RESERVED", "PendSV", "SysTick"
59 char* armv7m_core_reg_list
[] =
61 /* Registers accessed through core debug */
62 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12",
65 /* Registers accessed through MSR instructions */
66 /* "apsr", "iapsr", "ipsr", "epsr", */
67 "primask", "basepri", "faultmask", "control"
70 char* armv7m_core_dbgreg_list
[] =
72 /* Registers accessed through core debug */
73 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12",
76 /* Registers accessed through MSR instructions */
77 /* "dbg_apsr", "iapsr", "ipsr", "epsr", */
78 "primask", "basepri", "faultmask", "dbg_control"
81 u8 armv7m_gdb_dummy_fp_value
[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
83 reg_t armv7m_gdb_dummy_fp_reg
=
85 "GDB dummy floating-point register", armv7m_gdb_dummy_fp_value
, 0, 1, 96, NULL
, 0, NULL
, 0
88 u8 armv7m_gdb_dummy_fps_value
[] = {0, 0, 0, 0};
90 reg_t armv7m_gdb_dummy_fps_reg
=
92 "GDB dummy floating-point status register", armv7m_gdb_dummy_fps_value
, 0, 1, 32, NULL
, 0, NULL
, 0
95 armv7m_core_reg_t armv7m_core_reg_list_arch_info
[] =
97 /* CORE_GP are accesible using the core debug registers */
98 {0, ARMV7M_REGISTER_CORE_GP
, ARMV7M_MODE_ANY
, NULL
, NULL
},
99 {1, ARMV7M_REGISTER_CORE_GP
, ARMV7M_MODE_ANY
, NULL
, NULL
},
100 {2, ARMV7M_REGISTER_CORE_GP
, ARMV7M_MODE_ANY
, NULL
, NULL
},
101 {3, ARMV7M_REGISTER_CORE_GP
, ARMV7M_MODE_ANY
, NULL
, NULL
},
102 {4, ARMV7M_REGISTER_CORE_GP
, ARMV7M_MODE_ANY
, NULL
, NULL
},
103 {5, ARMV7M_REGISTER_CORE_GP
, ARMV7M_MODE_ANY
, NULL
, NULL
},
104 {6, ARMV7M_REGISTER_CORE_GP
, ARMV7M_MODE_ANY
, NULL
, NULL
},
105 {7, ARMV7M_REGISTER_CORE_GP
, ARMV7M_MODE_ANY
, NULL
, NULL
},
106 {8, ARMV7M_REGISTER_CORE_GP
, ARMV7M_MODE_ANY
, NULL
, NULL
},
107 {9, ARMV7M_REGISTER_CORE_GP
, ARMV7M_MODE_ANY
, NULL
, NULL
},
108 {10, ARMV7M_REGISTER_CORE_GP
, ARMV7M_MODE_ANY
, NULL
, NULL
},
109 {11, ARMV7M_REGISTER_CORE_GP
, ARMV7M_MODE_ANY
, NULL
, NULL
},
110 {12, ARMV7M_REGISTER_CORE_GP
, ARMV7M_MODE_ANY
, NULL
, NULL
},
111 {13, ARMV7M_REGISTER_CORE_GP
, ARMV7M_MODE_ANY
, NULL
, NULL
},
112 {14, ARMV7M_REGISTER_CORE_GP
, ARMV7M_MODE_ANY
, NULL
, NULL
},
113 {15, ARMV7M_REGISTER_CORE_GP
, ARMV7M_MODE_ANY
, NULL
, NULL
},
115 {16, ARMV7M_REGISTER_CORE_GP
, ARMV7M_MODE_ANY
, NULL
, NULL
}, /* xPSR */
116 {17, ARMV7M_REGISTER_CORE_GP
, ARMV7M_MODE_ANY
, NULL
, NULL
}, /* MSP */
117 {18, ARMV7M_REGISTER_CORE_GP
, ARMV7M_MODE_ANY
, NULL
, NULL
}, /* PSP */
119 /* CORE_SP are accesible using MSR and MRS instructions */
121 {0x00, ARMV7M_REGISTER_CORE_SP
, ARMV7M_MODE_ANY
, NULL
, NULL
}, /* APSR */
122 {0x01, ARMV7M_REGISTER_CORE_SP
, ARMV7M_MODE_ANY
, NULL
, NULL
}, /* IAPSR */
123 {0x05, ARMV7M_REGISTER_CORE_SP
, ARMV7M_MODE_ANY
, NULL
, NULL
}, /* IPSR */
124 {0x06, ARMV7M_REGISTER_CORE_SP
, ARMV7M_MODE_ANY
, NULL
, NULL
}, /* EPSR */
127 {0x10, ARMV7M_REGISTER_CORE_SP
, ARMV7M_MODE_ANY
, NULL
, NULL
}, /* PRIMASK */
128 {0x11, ARMV7M_REGISTER_CORE_SP
, ARMV7M_MODE_ANY
, NULL
, NULL
}, /* BASEPRI */
129 {0x13, ARMV7M_REGISTER_CORE_SP
, ARMV7M_MODE_ANY
, NULL
, NULL
}, /* FAULTMASK */
130 {0x14, ARMV7M_REGISTER_CORE_SP
, ARMV7M_MODE_ANY
, NULL
, NULL
} /* CONTROL */
133 int armv7m_core_reg_arch_type
= -1;
135 /* Keep different contexts for the process being debugged and debug algorithms */
136 enum armv7m_runcontext
armv7m_get_context(target_t
*target
)
138 /* get pointers to arch-specific information */
139 armv7m_common_t
*armv7m
= target
->arch_info
;
141 if (armv7m
->process_context
== armv7m
->core_cache
)
142 return ARMV7M_PROCESS_CONTEXT
;
143 if (armv7m
->debug_context
== armv7m
->core_cache
)
144 return ARMV7M_DEBUG_CONTEXT
;
146 LOG_ERROR("Invalid runcontext");
150 int armv7m_use_context(target_t
*target
, enum armv7m_runcontext new_ctx
)
153 /* get pointers to arch-specific information */
154 armv7m_common_t
*armv7m
= target
->arch_info
;
156 if ((target
->state
!= TARGET_HALTED
) && (target
->state
!= TARGET_RESET
))
158 LOG_WARNING("target not halted, switch context ");
159 return ERROR_TARGET_NOT_HALTED
;
162 if (new_ctx
== armv7m_get_context(target
))
167 case ARMV7M_PROCESS_CONTEXT
:
168 armv7m
->core_cache
= armv7m
->process_context
;
170 case ARMV7M_DEBUG_CONTEXT
:
171 armv7m
->core_cache
= armv7m
->debug_context
;
174 LOG_ERROR("Invalid runcontext");
177 /* Mark registers in new context as dirty to force reload when run */
179 for (i
= 0; i
< armv7m
->core_cache
->num_regs
; i
++)
181 armv7m
->core_cache
->reg_list
[i
].dirty
= 1;
187 int armv7m_restore_context(target_t
*target
)
191 /* get pointers to arch-specific information */
192 armv7m_common_t
*armv7m
= target
->arch_info
;
196 if (armv7m
->pre_restore_context
)
197 armv7m
->pre_restore_context(target
);
199 for (i
= ARMV7NUMCOREREGS
-1; i
>= 0; i
--)
201 if (armv7m
->core_cache
->reg_list
[i
].dirty
)
203 armv7m
->write_core_reg(target
, i
);
207 if (armv7m
->post_restore_context
)
208 armv7m
->post_restore_context(target
);
213 /* Core state functions */
214 char *armv7m_exception_string(int number
)
216 static char enamebuf
[32];
218 if ((number
< 0) | (number
> 511))
219 return "Invalid exception";
221 return armv7m_exception_strings
[number
];
222 sprintf(enamebuf
, "External Interrupt(%i)", number
- 16);
226 int armv7m_get_core_reg(reg_t
*reg
)
229 armv7m_core_reg_t
*armv7m_reg
= reg
->arch_info
;
230 target_t
*target
= armv7m_reg
->target
;
231 armv7m_common_t
*armv7m_target
= target
->arch_info
;
233 if (target
->state
!= TARGET_HALTED
)
235 return ERROR_TARGET_NOT_HALTED
;
238 retval
= armv7m_target
->read_core_reg(target
, armv7m_reg
->num
);
243 int armv7m_set_core_reg(reg_t
*reg
, u8
*buf
)
245 armv7m_core_reg_t
*armv7m_reg
= reg
->arch_info
;
246 target_t
*target
= armv7m_reg
->target
;
247 u32 value
= buf_get_u32(buf
, 0, 32);
249 if (target
->state
!= TARGET_HALTED
)
251 return ERROR_TARGET_NOT_HALTED
;
254 buf_set_u32(reg
->value
, 0, 32, value
);
261 int armv7m_read_core_reg(struct target_s
*target
, int num
)
265 armv7m_core_reg_t
* armv7m_core_reg
;
267 /* get pointers to arch-specific information */
268 armv7m_common_t
*armv7m
= target
->arch_info
;
270 if ((num
< 0) || (num
>= ARMV7NUMCOREREGS
))
271 return ERROR_INVALID_ARGUMENTS
;
273 armv7m_core_reg
= armv7m
->core_cache
->reg_list
[num
].arch_info
;
274 retval
= armv7m
->load_core_reg_u32(target
, armv7m_core_reg
->type
, armv7m_core_reg
->num
, ®_value
);
275 buf_set_u32(armv7m
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
276 armv7m
->core_cache
->reg_list
[num
].valid
= 1;
277 armv7m
->core_cache
->reg_list
[num
].dirty
= 0;
282 int armv7m_write_core_reg(struct target_s
*target
, int num
)
286 armv7m_core_reg_t
*armv7m_core_reg
;
288 /* get pointers to arch-specific information */
289 armv7m_common_t
*armv7m
= target
->arch_info
;
291 if ((num
< 0) || (num
>= ARMV7NUMCOREREGS
))
292 return ERROR_INVALID_ARGUMENTS
;
294 reg_value
= buf_get_u32(armv7m
->core_cache
->reg_list
[num
].value
, 0, 32);
295 armv7m_core_reg
= armv7m
->core_cache
->reg_list
[num
].arch_info
;
296 retval
= armv7m
->store_core_reg_u32(target
, armv7m_core_reg
->type
, armv7m_core_reg
->num
, reg_value
);
297 if (retval
!= ERROR_OK
)
299 LOG_ERROR("JTAG failure");
300 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
301 return ERROR_JTAG_DEVICE_ERROR
;
303 LOG_DEBUG("write core reg %i value 0x%x", num
, reg_value
);
304 armv7m
->core_cache
->reg_list
[num
].valid
= 1;
305 armv7m
->core_cache
->reg_list
[num
].dirty
= 0;
310 int armv7m_invalidate_core_regs(target_t
*target
)
312 /* get pointers to arch-specific information */
313 armv7m_common_t
*armv7m
= target
->arch_info
;
316 for (i
= 0; i
< armv7m
->core_cache
->num_regs
; i
++)
318 armv7m
->core_cache
->reg_list
[i
].valid
= 0;
319 armv7m
->core_cache
->reg_list
[i
].dirty
= 0;
325 int armv7m_get_gdb_reg_list(target_t
*target
, reg_t
**reg_list
[], int *reg_list_size
)
327 /* get pointers to arch-specific information */
328 armv7m_common_t
*armv7m
= target
->arch_info
;
332 *reg_list
= malloc(sizeof(reg_t
*) * (*reg_list_size
));
334 for (i
= 0; i
< 16; i
++)
336 (*reg_list
)[i
] = &armv7m
->process_context
->reg_list
[i
];
339 for (i
= 16; i
< 24; i
++)
341 (*reg_list
)[i
] = &armv7m_gdb_dummy_fp_reg
;
344 (*reg_list
)[24] = &armv7m_gdb_dummy_fps_reg
;
346 /* ARMV7M is always in thumb mode, try to make GDB understand this
347 * if it does not support this arch */
348 armv7m
->process_context
->reg_list
[15].value
[0] |= 1;
349 (*reg_list
)[25] = &armv7m
->process_context
->reg_list
[ARMV7M_xPSR
];
353 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
, u32 entry_point
, u32 exit_point
, int timeout_ms
, void *arch_info
)
355 /* get pointers to arch-specific information */
356 armv7m_common_t
*armv7m
= target
->arch_info
;
357 armv7m_algorithm_t
*armv7m_algorithm_info
= arch_info
;
358 int retval
= ERROR_OK
;
362 if (armv7m_algorithm_info
->common_magic
!= ARMV7M_COMMON_MAGIC
)
364 LOG_ERROR("current target isn't an ARMV7M target");
365 return ERROR_TARGET_INVALID
;
368 if (target
->state
!= TARGET_HALTED
)
370 LOG_WARNING("target not halted");
371 return ERROR_TARGET_NOT_HALTED
;
374 /* refresh core register cache */
375 /* Not needed if core register cache is always consistent with target process state */
376 armv7m_use_context(target
, ARMV7M_DEBUG_CONTEXT
);
378 for (i
= 0; i
< num_mem_params
; i
++)
380 target_write_buffer(target
, mem_params
[i
].address
, mem_params
[i
].size
, mem_params
[i
].value
);
383 for (i
= 0; i
< num_reg_params
; i
++)
385 reg_t
*reg
= register_get_by_name(armv7m
->core_cache
, reg_params
[i
].reg_name
, 0);
390 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
394 if (reg
->size
!= reg_params
[i
].size
)
396 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params
[i
].reg_name
);
400 regvalue
= buf_get_u32(reg_params
[i
].value
, 0, 32);
401 armv7m_set_core_reg(reg
, reg_params
[i
].value
);
404 /* ARMV7M always runs in Thumb state */
405 if ((retval
= breakpoint_add(target
, exit_point
, 2, BKPT_SOFT
)) != ERROR_OK
)
407 LOG_ERROR("can't add breakpoint to finish algorithm execution");
408 return ERROR_TARGET_FAILURE
;
411 /* This code relies on the target specific resume() and poll()->debug_entry()
412 sequence to write register values to the processor and the read them back */
413 target
->type
->resume(target
, 0, entry_point
, 1, 1);
414 target
->type
->poll(target
);
416 while (target
->state
!= TARGET_HALTED
)
419 target
->type
->poll(target
);
420 if ((timeout_ms
-= 5) <= 0)
422 LOG_ERROR("timeout waiting for algorithm to complete, trying to halt target");
423 target
->type
->halt(target
);
425 while (target
->state
!= TARGET_HALTED
)
428 target
->type
->poll(target
);
429 if ((timeout_ms
-= 10) <= 0)
431 LOG_ERROR("target didn't reenter debug state, exiting");
435 armv7m
->load_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 15, &pc
);
436 LOG_DEBUG("failed algoritm halted at 0x%x ", pc
);
437 retval
= ERROR_TARGET_TIMEOUT
;
441 breakpoint_remove(target
, exit_point
);
443 /* Read memory values to mem_params[] */
444 for (i
= 0; i
< num_mem_params
; i
++)
446 if (mem_params
[i
].direction
!= PARAM_OUT
)
447 target_read_buffer(target
, mem_params
[i
].address
, mem_params
[i
].size
, mem_params
[i
].value
);
450 /* Copy core register values to reg_params[] */
451 for (i
= 0; i
< num_reg_params
; i
++)
453 if (reg_params
[i
].direction
!= PARAM_OUT
)
455 reg_t
*reg
= register_get_by_name(armv7m
->debug_context
, reg_params
[i
].reg_name
, 0);
459 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
463 if (reg
->size
!= reg_params
[i
].size
)
465 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params
[i
].reg_name
);
469 buf_set_u32(reg_params
[i
].value
, 0, 32, buf_get_u32(reg
->value
, 0, 32));
476 int armv7m_arch_state(struct target_s
*target
)
478 /* get pointers to arch-specific information */
479 armv7m_common_t
*armv7m
= target
->arch_info
;
481 LOG_USER("target halted in %s state due to %s, current mode: %s %s\nxPSR: 0x%8.8x pc: 0x%8.8x",
482 armv7m_state_strings
[armv7m
->core_state
],
483 target_debug_reason_strings
[target
->debug_reason
],
484 armv7m_mode_strings
[armv7m
->core_mode
],
485 armv7m_exception_string(armv7m
->exception_number
),
486 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32),
487 buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32));
492 reg_cache_t
*armv7m_build_reg_cache(target_t
*target
)
494 /* get pointers to arch-specific information */
495 armv7m_common_t
*armv7m
= target
->arch_info
;
497 int num_regs
= ARMV7NUMCOREREGS
;
498 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
499 reg_cache_t
*cache
= malloc(sizeof(reg_cache_t
));
500 reg_t
*reg_list
= malloc(sizeof(reg_t
) * num_regs
);
501 armv7m_core_reg_t
*arch_info
= malloc(sizeof(armv7m_core_reg_t
) * num_regs
);
504 if (armv7m_core_reg_arch_type
== -1)
505 armv7m_core_reg_arch_type
= register_reg_arch_type(armv7m_get_core_reg
, armv7m_set_core_reg
);
507 /* Build the process context cache */
508 cache
->name
= "arm v7m registers";
510 cache
->reg_list
= reg_list
;
511 cache
->num_regs
= num_regs
;
513 armv7m
->core_cache
= cache
;
514 armv7m
->process_context
= cache
;
516 for (i
= 0; i
< num_regs
; i
++)
518 arch_info
[i
] = armv7m_core_reg_list_arch_info
[i
];
519 arch_info
[i
].target
= target
;
520 arch_info
[i
].armv7m_common
= armv7m
;
521 reg_list
[i
].name
= armv7m_core_reg_list
[i
];
522 reg_list
[i
].size
= 32;
523 reg_list
[i
].value
= calloc(1, 4);
524 reg_list
[i
].dirty
= 0;
525 reg_list
[i
].valid
= 0;
526 reg_list
[i
].bitfield_desc
= NULL
;
527 reg_list
[i
].num_bitfields
= 0;
528 reg_list
[i
].arch_type
= armv7m_core_reg_arch_type
;
529 reg_list
[i
].arch_info
= &arch_info
[i
];
532 /* Build the debug context cache*/
533 cache
= malloc(sizeof(reg_cache_t
));
534 reg_list
= malloc(sizeof(reg_t
) * num_regs
);
536 cache
->name
= "arm v7m debug registers";
538 cache
->reg_list
= reg_list
;
539 cache
->num_regs
= num_regs
;
540 armv7m
->debug_context
= cache
;
541 armv7m
->process_context
->next
= cache
;
543 for (i
= 0; i
< num_regs
; i
++)
545 reg_list
[i
].name
= armv7m_core_dbgreg_list
[i
];
546 reg_list
[i
].size
= 32;
547 reg_list
[i
].value
= calloc(1, 4);
548 reg_list
[i
].dirty
= 0;
549 reg_list
[i
].valid
= 0;
550 reg_list
[i
].bitfield_desc
= NULL
;
551 reg_list
[i
].num_bitfields
= 0;
552 reg_list
[i
].arch_type
= armv7m_core_reg_arch_type
;
553 reg_list
[i
].arch_info
= &arch_info
[i
];
559 int armv7m_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
561 armv7m_build_reg_cache(target
);
566 int armv7m_init_arch_info(target_t
*target
, armv7m_common_t
*armv7m
)
568 /* register arch-specific functions */
570 target
->arch_info
= armv7m
;
571 armv7m
->core_state
= ARMV7M_STATE_THUMB
;
572 armv7m
->read_core_reg
= armv7m_read_core_reg
;
573 armv7m
->write_core_reg
= armv7m_write_core_reg
;
578 int armv7m_register_commands(struct command_context_s
*cmd_ctx
)
583 int armv7m_checksum_memory(struct target_s
*target
, u32 address
, u32 count
, u32
* checksum
)
585 working_area_t
*crc_algorithm
;
586 armv7m_algorithm_t armv7m_info
;
587 reg_param_t reg_params
[2];
590 u16 cortex_m3_crc_code
[] = {
591 0x4602, /* mov r2, r0 */
592 0xF04F, 0x30FF, /* mov r0, #0xffffffff */
593 0x460B, /* mov r3, r1 */
594 0xF04F, 0x0400, /* mov r4, #0 */
595 0xE013, /* b ncomp */
597 0x5D11, /* ldrb r1, [r2, r4] */
598 0xF8DF, 0x7028, /* ldr r7, CRC32XOR */
599 0xEA80, 0x6001, /* eor r0, r0, r1, asl #24 */
601 0xF04F, 0x0500, /* mov r5, #0 */
603 0x2800, /* cmp r0, #0 */
604 0xEA4F, 0x0640, /* mov r6, r0, asl #1 */
605 0xF105, 0x0501, /* add r5, r5, #1 */
606 0x4630, /* mov r0, r6 */
608 0xEA86, 0x0007, /* eor r0, r6, r7 */
609 0x2D08, /* cmp r5, #8 */
610 0xD1F4, /* bne loop */
612 0xF104, 0x0401, /* add r4, r4, #1 */
614 0x429C, /* cmp r4, r3 */
615 0xD1E9, /* bne nbyte */
618 0x1DB7, 0x04C1 /* CRC32XOR: .word 0x04C11DB7 */
623 if (target_alloc_working_area(target
, sizeof(cortex_m3_crc_code
), &crc_algorithm
) != ERROR_OK
)
625 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
628 /* convert flash writing code into a buffer in target endianness */
629 for (i
= 0; i
< (sizeof(cortex_m3_crc_code
)/sizeof(u16
)); i
++)
630 target_write_u16(target
, crc_algorithm
->address
+ i
*sizeof(u16
), cortex_m3_crc_code
[i
]);
632 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
633 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
634 armv7m_info
.core_state
= ARMV7M_STATE_THUMB
;
636 init_reg_param(®_params
[0], "r0", 32, PARAM_IN_OUT
);
637 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
639 buf_set_u32(reg_params
[0].value
, 0, 32, address
);
640 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
642 if ((retval
= target
->type
->run_algorithm(target
, 0, NULL
, 2, reg_params
,
643 crc_algorithm
->address
, crc_algorithm
->address
+ (sizeof(cortex_m3_crc_code
)-6), 20000, &armv7m_info
)) != ERROR_OK
)
645 LOG_ERROR("error executing cortex_m3 crc algorithm");
646 destroy_reg_param(®_params
[0]);
647 destroy_reg_param(®_params
[1]);
648 target_free_working_area(target
, crc_algorithm
);
652 *checksum
= buf_get_u32(reg_params
[0].value
, 0, 32);
654 destroy_reg_param(®_params
[0]);
655 destroy_reg_param(®_params
[1]);
657 target_free_working_area(target
, crc_algorithm
);
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)