fixed crash in dummy register handling
[openocd.git] / src / target / armv7m.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2006 by Magnus Lundin *
6 * lundin@mlu.mine.nu *
7 * *
8 * Copyright (C) 2008 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
10 * *
11 * Copyright (C) 2007,2008 Øyvind Harboe *
12 * oyvind.harboe@zylin.com *
13 * *
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. *
18 * *
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. *
23 * *
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. *
28 ***************************************************************************/
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include "replacements.h"
34
35 #include "armv7m.h"
36 #include "register.h"
37 #include "target.h"
38 #include "log.h"
39 #include "jtag.h"
40 #include "arm_jtag.h"
41
42 #include <stdlib.h>
43 #include <string.h>
44
45 #if 0
46 #define _DEBUG_INSTRUCTION_EXECUTION_
47 #endif
48
49 char* armv7m_mode_strings[] =
50 {
51 "Thread", "Thread (User)", "Handler",
52 };
53
54 char* armv7m_exception_strings[] =
55 {
56 "", "Reset", "NMI", "HardFault", "MemManage", "BusFault", "UsageFault", "RESERVED", "RESERVED", "RESERVED", "RESERVED",
57 "SVCall", "DebugMonitor", "RESERVED", "PendSV", "SysTick"
58 };
59
60 char* armv7m_core_reg_list[] =
61 {
62 /* Registers accessed through core debug */
63 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12",
64 "sp", "lr", "pc",
65 "xPSR", "msp", "psp",
66 /* Registers accessed through special reg 20 */
67 "primask", "basepri", "faultmask", "control"
68 };
69
70 u8 armv7m_gdb_dummy_fp_value[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
71
72 reg_t armv7m_gdb_dummy_fp_reg =
73 {
74 "GDB dummy floating-point register", armv7m_gdb_dummy_fp_value, 0, 1, 96, NULL, 0, NULL, 0
75 };
76
77 u8 armv7m_gdb_dummy_fps_value[] = {0, 0, 0, 0};
78
79 reg_t armv7m_gdb_dummy_fps_reg =
80 {
81 "GDB dummy floating-point status register", armv7m_gdb_dummy_fps_value, 0, 1, 32, NULL, 0, NULL, 0
82 };
83
84 #ifdef ARMV7_GDB_HACKS
85 u8 armv7m_gdb_dummy_cpsr_value[] = {0, 0, 0, 0};
86
87 reg_t armv7m_gdb_dummy_cpsr_reg =
88 {
89 "GDB dummy cpsr register", armv7m_gdb_dummy_cpsr_value, 0, 1, 32, NULL, 0, NULL, 0
90 };
91 #endif
92
93 armv7m_core_reg_t armv7m_core_reg_list_arch_info[] =
94 {
95 /* CORE_GP are accesible using the core debug registers */
96 {0, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
97 {1, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
98 {2, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
99 {3, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
100 {4, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
101 {5, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
102 {6, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
103 {7, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
104 {8, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
105 {9, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
106 {10, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
107 {11, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
108 {12, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
109 {13, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
110 {14, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
111 {15, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL},
112
113 {16, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL}, /* xPSR */
114 {17, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL}, /* MSP */
115 {18, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL}, /* PSP */
116
117 /* CORE_SP are accesible using coreregister 20 */
118 {19, ARMV7M_REGISTER_CORE_SP, ARMV7M_MODE_ANY, NULL, NULL}, /* PRIMASK */
119 {20, ARMV7M_REGISTER_CORE_SP, ARMV7M_MODE_ANY, NULL, NULL}, /* BASEPRI */
120 {21, ARMV7M_REGISTER_CORE_SP, ARMV7M_MODE_ANY, NULL, NULL}, /* FAULTMASK */
121 {22, ARMV7M_REGISTER_CORE_SP, ARMV7M_MODE_ANY, NULL, NULL} /* CONTROL */
122 };
123
124 int armv7m_core_reg_arch_type = -1;
125 int armv7m_dummy_core_reg_arch_type = -1;
126
127 int armv7m_restore_context(target_t *target)
128 {
129 int i;
130
131 /* get pointers to arch-specific information */
132 armv7m_common_t *armv7m = target->arch_info;
133
134 LOG_DEBUG(" ");
135
136 if (armv7m->pre_restore_context)
137 armv7m->pre_restore_context(target);
138
139 for (i = ARMV7NUMCOREREGS-1; i >= 0; i--)
140 {
141 if (armv7m->core_cache->reg_list[i].dirty)
142 {
143 armv7m->write_core_reg(target, i);
144 }
145 }
146
147 if (armv7m->post_restore_context)
148 armv7m->post_restore_context(target);
149
150 return ERROR_OK;
151 }
152
153 /* Core state functions */
154 char *armv7m_exception_string(int number)
155 {
156 static char enamebuf[32];
157
158 if ((number < 0) | (number > 511))
159 return "Invalid exception";
160 if (number < 16)
161 return armv7m_exception_strings[number];
162 sprintf(enamebuf, "External Interrupt(%i)", number - 16);
163 return enamebuf;
164 }
165
166 int armv7m_get_core_reg(reg_t *reg)
167 {
168 int retval;
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;
172
173 if (target->state != TARGET_HALTED)
174 {
175 return ERROR_TARGET_NOT_HALTED;
176 }
177
178 retval = armv7m_target->read_core_reg(target, armv7m_reg->num);
179
180 return retval;
181 }
182
183 int armv7m_set_core_reg(reg_t *reg, u8 *buf)
184 {
185 armv7m_core_reg_t *armv7m_reg = reg->arch_info;
186 target_t *target = armv7m_reg->target;
187 u32 value = buf_get_u32(buf, 0, 32);
188
189 if (target->state != TARGET_HALTED)
190 {
191 return ERROR_TARGET_NOT_HALTED;
192 }
193
194 buf_set_u32(reg->value, 0, 32, value);
195 reg->dirty = 1;
196 reg->valid = 1;
197
198 return ERROR_OK;
199 }
200
201 int armv7m_get_dummy_core_reg(reg_t *reg)
202 {
203 return ERROR_OK;
204 }
205
206 int armv7m_set_dummy_core_reg(reg_t *reg, u8 *buf)
207 {
208 u32 value = buf_get_u32(buf, 0, 32);
209 buf_set_u32(reg->value, 0, 32, value);
210 reg->dirty = 1;
211 reg->valid = 1;
212
213 return ERROR_OK;
214 }
215
216 int armv7m_read_core_reg(struct target_s *target, int num)
217 {
218 u32 reg_value;
219 int retval;
220 armv7m_core_reg_t * armv7m_core_reg;
221
222 /* get pointers to arch-specific information */
223 armv7m_common_t *armv7m = target->arch_info;
224
225 if ((num < 0) || (num >= ARMV7NUMCOREREGS))
226 return ERROR_INVALID_ARGUMENTS;
227
228 armv7m_core_reg = armv7m->core_cache->reg_list[num].arch_info;
229 retval = armv7m->load_core_reg_u32(target, armv7m_core_reg->type, armv7m_core_reg->num, &reg_value);
230 buf_set_u32(armv7m->core_cache->reg_list[num].value, 0, 32, reg_value);
231 armv7m->core_cache->reg_list[num].valid = 1;
232 armv7m->core_cache->reg_list[num].dirty = 0;
233
234 return ERROR_OK;
235 }
236
237 int armv7m_write_core_reg(struct target_s *target, int num)
238 {
239 int retval;
240 u32 reg_value;
241 armv7m_core_reg_t *armv7m_core_reg;
242
243 /* get pointers to arch-specific information */
244 armv7m_common_t *armv7m = target->arch_info;
245
246 if ((num < 0) || (num >= ARMV7NUMCOREREGS))
247 return ERROR_INVALID_ARGUMENTS;
248
249 reg_value = buf_get_u32(armv7m->core_cache->reg_list[num].value, 0, 32);
250 armv7m_core_reg = armv7m->core_cache->reg_list[num].arch_info;
251 retval = armv7m->store_core_reg_u32(target, armv7m_core_reg->type, armv7m_core_reg->num, reg_value);
252 if (retval != ERROR_OK)
253 {
254 LOG_ERROR("JTAG failure");
255 armv7m->core_cache->reg_list[num].dirty = armv7m->core_cache->reg_list[num].valid;
256 return ERROR_JTAG_DEVICE_ERROR;
257 }
258 LOG_DEBUG("write core reg %i value 0x%x", num , reg_value);
259 armv7m->core_cache->reg_list[num].valid = 1;
260 armv7m->core_cache->reg_list[num].dirty = 0;
261
262 return ERROR_OK;
263 }
264
265 int armv7m_invalidate_core_regs(target_t *target)
266 {
267 /* get pointers to arch-specific information */
268 armv7m_common_t *armv7m = target->arch_info;
269 int i;
270
271 for (i = 0; i < armv7m->core_cache->num_regs; i++)
272 {
273 armv7m->core_cache->reg_list[i].valid = 0;
274 armv7m->core_cache->reg_list[i].dirty = 0;
275 }
276
277 return ERROR_OK;
278 }
279
280 int armv7m_get_gdb_reg_list(target_t *target, reg_t **reg_list[], int *reg_list_size)
281 {
282 /* get pointers to arch-specific information */
283 armv7m_common_t *armv7m = target->arch_info;
284 int i;
285
286 *reg_list_size = 26;
287 *reg_list = malloc(sizeof(reg_t*) * (*reg_list_size));
288
289 for (i = 0; i < 16; i++)
290 {
291 (*reg_list)[i] = &armv7m->core_cache->reg_list[i];
292 }
293
294 for (i = 16; i < 24; i++)
295 {
296 (*reg_list)[i] = &armv7m_gdb_dummy_fp_reg;
297 }
298
299 (*reg_list)[24] = &armv7m_gdb_dummy_fps_reg;
300
301 #ifdef ARMV7_GDB_HACKS
302 /* use dummy cpsr reg otherwise gdb may try and set the thumb bit */
303 (*reg_list)[25] = &armv7m_gdb_dummy_cpsr_reg;
304
305 /* ARMV7M is always in thumb mode, try to make GDB understand this
306 * if it does not support this arch */
307 armv7m->core_cache->reg_list[15].value[0] |= 1;
308 #else
309 (*reg_list)[25] = &armv7m->core_cache->reg_list[ARMV7M_xPSR];
310 #endif
311
312 return ERROR_OK;
313 }
314
315 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)
316 {
317 /* get pointers to arch-specific information */
318 armv7m_common_t *armv7m = target->arch_info;
319 armv7m_algorithm_t *armv7m_algorithm_info = arch_info;
320 enum armv7m_mode core_mode = armv7m->core_mode;
321 int retval = ERROR_OK;
322 u32 pc;
323 int i;
324 u32 context[ARMV7NUMCOREREGS];
325
326 if (armv7m_algorithm_info->common_magic != ARMV7M_COMMON_MAGIC)
327 {
328 LOG_ERROR("current target isn't an ARMV7M target");
329 return ERROR_TARGET_INVALID;
330 }
331
332 if (target->state != TARGET_HALTED)
333 {
334 LOG_WARNING("target not halted");
335 return ERROR_TARGET_NOT_HALTED;
336 }
337
338 /* refresh core register cache */
339 /* Not needed if core register cache is always consistent with target process state */
340 for (i = 0; i < ARMV7NUMCOREREGS; i++)
341 {
342 if (!armv7m->core_cache->reg_list[i].valid)
343 armv7m->read_core_reg(target, i);
344 context[i] = buf_get_u32(armv7m->core_cache->reg_list[i].value, 0, 32);
345 }
346
347 for (i = 0; i < num_mem_params; i++)
348 {
349 target_write_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value);
350 }
351
352 for (i = 0; i < num_reg_params; i++)
353 {
354 reg_t *reg = register_get_by_name(armv7m->core_cache, reg_params[i].reg_name, 0);
355 u32 regvalue;
356
357 if (!reg)
358 {
359 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
360 exit(-1);
361 }
362
363 if (reg->size != reg_params[i].size)
364 {
365 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
366 exit(-1);
367 }
368
369 regvalue = buf_get_u32(reg_params[i].value, 0, 32);
370 armv7m_set_core_reg(reg, reg_params[i].value);
371 }
372
373 if (armv7m_algorithm_info->core_mode != ARMV7M_MODE_ANY)
374 {
375 LOG_DEBUG("setting core_mode: 0x%2.2x", armv7m_algorithm_info->core_mode);
376 buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_CONTROL].value, 0, 1, armv7m_algorithm_info->core_mode);
377 armv7m->core_cache->reg_list[ARMV7M_CONTROL].dirty = 1;
378 armv7m->core_cache->reg_list[ARMV7M_CONTROL].valid = 1;
379 }
380
381 /* ARMV7M always runs in Thumb state */
382 if ((retval = breakpoint_add(target, exit_point, 2, BKPT_SOFT)) != ERROR_OK)
383 {
384 LOG_ERROR("can't add breakpoint to finish algorithm execution");
385 return ERROR_TARGET_FAILURE;
386 }
387
388 /* This code relies on the target specific resume() and poll()->debug_entry()
389 sequence to write register values to the processor and the read them back */
390 target_resume(target, 0, entry_point, 1, 1);
391 target_poll(target);
392
393 target_wait_state(target, TARGET_HALTED, timeout_ms);
394 if (target->state != TARGET_HALTED)
395 {
396 if ((retval=target_halt(target))!=ERROR_OK)
397 return retval;
398 if ((retval=target_wait_state(target, TARGET_HALTED, 500))!=ERROR_OK)
399 {
400 return retval;
401 }
402 return ERROR_TARGET_TIMEOUT;
403 }
404
405
406 armv7m->load_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 15, &pc);
407 if (pc != exit_point)
408 {
409 LOG_DEBUG("failed algoritm halted at 0x%x ", pc);
410 return ERROR_TARGET_TIMEOUT;
411 }
412
413 breakpoint_remove(target, exit_point);
414
415 /* Read memory values to mem_params[] */
416 for (i = 0; i < num_mem_params; i++)
417 {
418 if (mem_params[i].direction != PARAM_OUT)
419 target_read_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value);
420 }
421
422 /* Copy core register values to reg_params[] */
423 for (i = 0; i < num_reg_params; i++)
424 {
425 if (reg_params[i].direction != PARAM_OUT)
426 {
427 reg_t *reg = register_get_by_name(armv7m->core_cache, reg_params[i].reg_name, 0);
428
429 if (!reg)
430 {
431 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
432 exit(-1);
433 }
434
435 if (reg->size != reg_params[i].size)
436 {
437 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
438 exit(-1);
439 }
440
441 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
442 }
443 }
444
445 for (i = ARMV7NUMCOREREGS-1; i >= 0; i--)
446 {
447 LOG_DEBUG("restoring register %s with value 0x%8.8x", armv7m->core_cache->reg_list[i].name, context[i]);
448 buf_set_u32(armv7m->core_cache->reg_list[i].value, 0, 32, context[i]);
449 armv7m->core_cache->reg_list[i].valid = 1;
450 armv7m->core_cache->reg_list[i].dirty = 1;
451 }
452
453 armv7m->core_mode = core_mode;
454
455 return retval;
456 }
457
458 int armv7m_arch_state(struct target_s *target)
459 {
460 /* get pointers to arch-specific information */
461 armv7m_common_t *armv7m = target->arch_info;
462
463 LOG_USER("target halted due to %s, current mode: %s %s\nxPSR: 0x%8.8x pc: 0x%8.8x",
464 Jim_Nvp_value2name_simple( nvp_target_debug_reason,target->debug_reason)->name,
465 armv7m_mode_strings[armv7m->core_mode],
466 armv7m_exception_string(armv7m->exception_number),
467 buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32),
468 buf_get_u32(armv7m->core_cache->reg_list[15].value, 0, 32));
469
470 return ERROR_OK;
471 }
472
473 reg_cache_t *armv7m_build_reg_cache(target_t *target)
474 {
475 /* get pointers to arch-specific information */
476 armv7m_common_t *armv7m = target->arch_info;
477
478 int num_regs = ARMV7NUMCOREREGS;
479 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
480 reg_cache_t *cache = malloc(sizeof(reg_cache_t));
481 reg_t *reg_list = malloc(sizeof(reg_t) * num_regs);
482 armv7m_core_reg_t *arch_info = malloc(sizeof(armv7m_core_reg_t) * num_regs);
483 int i;
484
485 if (armv7m_core_reg_arch_type == -1)
486 {
487 armv7m_core_reg_arch_type = register_reg_arch_type(armv7m_get_core_reg, armv7m_set_core_reg);
488 armv7m_dummy_core_reg_arch_type = register_reg_arch_type(armv7m_get_dummy_core_reg, armv7m_set_dummy_core_reg);
489
490 armv7m_gdb_dummy_fp_reg.arch_type=armv7m_dummy_core_reg_arch_type;
491 armv7m_gdb_dummy_fps_reg.arch_type=armv7m_dummy_core_reg_arch_type;
492 armv7m_gdb_dummy_cpsr_reg.arch_type=armv7m_dummy_core_reg_arch_type;
493 }
494
495 /* Build the process context cache */
496 cache->name = "arm v7m registers";
497 cache->next = NULL;
498 cache->reg_list = reg_list;
499 cache->num_regs = num_regs;
500 (*cache_p) = cache;
501 armv7m->core_cache = cache;
502
503 for (i = 0; i < num_regs; i++)
504 {
505 arch_info[i] = armv7m_core_reg_list_arch_info[i];
506 arch_info[i].target = target;
507 arch_info[i].armv7m_common = armv7m;
508 reg_list[i].name = armv7m_core_reg_list[i];
509 reg_list[i].size = 32;
510 reg_list[i].value = calloc(1, 4);
511 reg_list[i].dirty = 0;
512 reg_list[i].valid = 0;
513 reg_list[i].bitfield_desc = NULL;
514 reg_list[i].num_bitfields = 0;
515 reg_list[i].arch_type = armv7m_core_reg_arch_type;
516 reg_list[i].arch_info = &arch_info[i];
517 }
518
519 return cache;
520 }
521
522 int armv7m_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
523 {
524 armv7m_build_reg_cache(target);
525
526 return ERROR_OK;
527 }
528
529 int armv7m_init_arch_info(target_t *target, armv7m_common_t *armv7m)
530 {
531 /* register arch-specific functions */
532
533 target->arch_info = armv7m;
534 armv7m->read_core_reg = armv7m_read_core_reg;
535 armv7m->write_core_reg = armv7m_write_core_reg;
536
537 return ERROR_OK;
538 }
539
540 int armv7m_register_commands(struct command_context_s *cmd_ctx)
541 {
542 return ERROR_OK;
543 }
544
545 int armv7m_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum)
546 {
547 working_area_t *crc_algorithm;
548 armv7m_algorithm_t armv7m_info;
549 reg_param_t reg_params[2];
550 int retval;
551
552 u16 cortex_m3_crc_code[] = {
553 0x4602, /* mov r2, r0 */
554 0xF04F, 0x30FF, /* mov r0, #0xffffffff */
555 0x460B, /* mov r3, r1 */
556 0xF04F, 0x0400, /* mov r4, #0 */
557 0xE013, /* b ncomp */
558 /* nbyte: */
559 0x5D11, /* ldrb r1, [r2, r4] */
560 0xF8DF, 0x7028, /* ldr r7, CRC32XOR */
561 0xEA80, 0x6001, /* eor r0, r0, r1, asl #24 */
562
563 0xF04F, 0x0500, /* mov r5, #0 */
564 /* loop: */
565 0x2800, /* cmp r0, #0 */
566 0xEA4F, 0x0640, /* mov r6, r0, asl #1 */
567 0xF105, 0x0501, /* add r5, r5, #1 */
568 0x4630, /* mov r0, r6 */
569 0xBFB8, /* it lt */
570 0xEA86, 0x0007, /* eor r0, r6, r7 */
571 0x2D08, /* cmp r5, #8 */
572 0xD1F4, /* bne loop */
573
574 0xF104, 0x0401, /* add r4, r4, #1 */
575 /* ncomp: */
576 0x429C, /* cmp r4, r3 */
577 0xD1E9, /* bne nbyte */
578 /* end: */
579 0xE7FE, /* b end */
580 0x1DB7, 0x04C1 /* CRC32XOR: .word 0x04C11DB7 */
581 };
582
583 int i;
584
585 if (target_alloc_working_area(target, sizeof(cortex_m3_crc_code), &crc_algorithm) != ERROR_OK)
586 {
587 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
588 }
589
590 /* convert flash writing code into a buffer in target endianness */
591 for (i = 0; i < (sizeof(cortex_m3_crc_code)/sizeof(u16)); i++)
592 target_write_u16(target, crc_algorithm->address + i*sizeof(u16), cortex_m3_crc_code[i]);
593
594 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
595 armv7m_info.core_mode = ARMV7M_MODE_ANY;
596
597 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
598 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
599
600 buf_set_u32(reg_params[0].value, 0, 32, address);
601 buf_set_u32(reg_params[1].value, 0, 32, count);
602
603 if ((retval = target->type->run_algorithm(target, 0, NULL, 2, reg_params,
604 crc_algorithm->address, crc_algorithm->address + (sizeof(cortex_m3_crc_code)-6), 20000, &armv7m_info)) != ERROR_OK)
605 {
606 LOG_ERROR("error executing cortex_m3 crc algorithm");
607 destroy_reg_param(&reg_params[0]);
608 destroy_reg_param(&reg_params[1]);
609 target_free_working_area(target, crc_algorithm);
610 return retval;
611 }
612
613 *checksum = buf_get_u32(reg_params[0].value, 0, 32);
614
615 destroy_reg_param(&reg_params[0]);
616 destroy_reg_param(&reg_params[1]);
617
618 target_free_working_area(target, crc_algorithm);
619
620 return ERROR_OK;
621 }
622
623 int armv7m_blank_check_memory(struct target_s *target, u32 address, u32 count, u32* blank)
624 {
625 working_area_t *erase_check_algorithm;
626 reg_param_t reg_params[3];
627 armv7m_algorithm_t armv7m_info;
628 int retval;
629 int i;
630
631 u16 erase_check_code[] =
632 {
633 /* loop: */
634 0xF810, 0x3B01, /* ldrb r3, [r0], #1 */
635 0xEA02, 0x0203, /* and r2, r2, r3 */
636 0x3901, /* subs r1, r1, #1 */
637 0xD1F9, /* bne loop */
638 /* end: */
639 0xE7FE, /* b end */
640 };
641
642 /* make sure we have a working area */
643 if (target_alloc_working_area(target, sizeof(erase_check_code), &erase_check_algorithm) != ERROR_OK)
644 {
645 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
646 }
647
648 /* convert flash writing code into a buffer in target endianness */
649 for (i = 0; i < (sizeof(erase_check_code)/sizeof(u16)); i++)
650 target_write_u16(target, erase_check_algorithm->address + i*sizeof(u16), erase_check_code[i]);
651
652 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
653 armv7m_info.core_mode = ARMV7M_MODE_ANY;
654
655 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
656 buf_set_u32(reg_params[0].value, 0, 32, address);
657
658 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
659 buf_set_u32(reg_params[1].value, 0, 32, count);
660
661 init_reg_param(&reg_params[2], "r2", 32, PARAM_IN_OUT);
662 buf_set_u32(reg_params[2].value, 0, 32, 0xff);
663
664 if ((retval = target->type->run_algorithm(target, 0, NULL, 3, reg_params,
665 erase_check_algorithm->address, erase_check_algorithm->address + (sizeof(erase_check_code)-2), 10000, &armv7m_info)) != ERROR_OK)
666 {
667 destroy_reg_param(&reg_params[0]);
668 destroy_reg_param(&reg_params[1]);
669 destroy_reg_param(&reg_params[2]);
670 target_free_working_area(target, erase_check_algorithm);
671 return 0;
672 }
673
674 *blank = buf_get_u32(reg_params[2].value, 0, 32);
675
676 destroy_reg_param(&reg_params[0]);
677 destroy_reg_param(&reg_params[1]);
678 destroy_reg_param(&reg_params[2]);
679
680 target_free_working_area(target, erase_check_algorithm);
681
682 return ERROR_OK;
683 }

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)