eedbc702d6750792f7cb252e900252ee1524238a
[openocd.git] / src / target / armv4_5.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
7 * *
8 * Copyright (C) 2008 by Oyvind Harboe *
9 * oyvind.harboe@zylin.com *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
20 * *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 ***************************************************************************/
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "armv4_5.h"
31 #include "arm_disassembler.h"
32 #include "binarybuffer.h"
33
34
35 bitfield_desc_t armv4_5_psr_bitfield_desc[] =
36 {
37 {"M[4:0]", 5},
38 {"T", 1},
39 {"F", 1},
40 {"I", 1},
41 {"reserved", 16},
42 {"J", 1},
43 {"reserved", 2},
44 {"Q", 1},
45 {"V", 1},
46 {"C", 1},
47 {"Z", 1},
48 {"N", 1},
49 };
50
51 char* armv4_5_core_reg_list[] =
52 {
53 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13_usr", "lr_usr", "pc",
54
55 "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "r13_fiq", "lr_fiq",
56
57 "r13_irq", "lr_irq",
58
59 "r13_svc", "lr_svc",
60
61 "r13_abt", "lr_abt",
62
63 "r13_und", "lr_und",
64
65 "cpsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_abt", "spsr_und"
66 };
67
68 char * armv4_5_mode_strings_list[] =
69 {
70 "Illegal mode value", "User", "FIQ", "IRQ", "Supervisor", "Abort", "Undefined", "System"
71 };
72
73 /* Hack! Yuk! allow -1 index, which simplifies codepaths elsewhere in the code */
74 char** armv4_5_mode_strings = armv4_5_mode_strings_list + 1;
75
76 char* armv4_5_state_strings[] =
77 {
78 "ARM", "Thumb", "Jazelle"
79 };
80
81 int armv4_5_core_reg_arch_type = -1;
82
83 armv4_5_core_reg_t armv4_5_core_reg_list_arch_info[] =
84 {
85 {0, ARMV4_5_MODE_ANY, NULL, NULL},
86 {1, ARMV4_5_MODE_ANY, NULL, NULL},
87 {2, ARMV4_5_MODE_ANY, NULL, NULL},
88 {3, ARMV4_5_MODE_ANY, NULL, NULL},
89 {4, ARMV4_5_MODE_ANY, NULL, NULL},
90 {5, ARMV4_5_MODE_ANY, NULL, NULL},
91 {6, ARMV4_5_MODE_ANY, NULL, NULL},
92 {7, ARMV4_5_MODE_ANY, NULL, NULL},
93 {8, ARMV4_5_MODE_ANY, NULL, NULL},
94 {9, ARMV4_5_MODE_ANY, NULL, NULL},
95 {10, ARMV4_5_MODE_ANY, NULL, NULL},
96 {11, ARMV4_5_MODE_ANY, NULL, NULL},
97 {12, ARMV4_5_MODE_ANY, NULL, NULL},
98 {13, ARMV4_5_MODE_USR, NULL, NULL},
99 {14, ARMV4_5_MODE_USR, NULL, NULL},
100 {15, ARMV4_5_MODE_ANY, NULL, NULL},
101
102 {8, ARMV4_5_MODE_FIQ, NULL, NULL},
103 {9, ARMV4_5_MODE_FIQ, NULL, NULL},
104 {10, ARMV4_5_MODE_FIQ, NULL, NULL},
105 {11, ARMV4_5_MODE_FIQ, NULL, NULL},
106 {12, ARMV4_5_MODE_FIQ, NULL, NULL},
107 {13, ARMV4_5_MODE_FIQ, NULL, NULL},
108 {14, ARMV4_5_MODE_FIQ, NULL, NULL},
109
110 {13, ARMV4_5_MODE_IRQ, NULL, NULL},
111 {14, ARMV4_5_MODE_IRQ, NULL, NULL},
112
113 {13, ARMV4_5_MODE_SVC, NULL, NULL},
114 {14, ARMV4_5_MODE_SVC, NULL, NULL},
115
116 {13, ARMV4_5_MODE_ABT, NULL, NULL},
117 {14, ARMV4_5_MODE_ABT, NULL, NULL},
118
119 {13, ARMV4_5_MODE_UND, NULL, NULL},
120 {14, ARMV4_5_MODE_UND, NULL, NULL},
121
122 {16, ARMV4_5_MODE_ANY, NULL, NULL},
123 {16, ARMV4_5_MODE_FIQ, NULL, NULL},
124 {16, ARMV4_5_MODE_IRQ, NULL, NULL},
125 {16, ARMV4_5_MODE_SVC, NULL, NULL},
126 {16, ARMV4_5_MODE_ABT, NULL, NULL},
127 {16, ARMV4_5_MODE_UND, NULL, NULL}
128 };
129
130 /* map core mode (USR, FIQ, ...) and register number to indizes into the register cache */
131 int armv4_5_core_reg_map[7][17] =
132 {
133 { /* USR */
134 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
135 },
136 { /* FIQ */
137 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 15, 32
138 },
139 { /* IRQ */
140 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 23, 24, 15, 33
141 },
142 { /* SVC */
143 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 25, 26, 15, 34
144 },
145 { /* ABT */
146 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 27, 28, 15, 35
147 },
148 { /* UND */
149 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 30, 15, 36
150 },
151 { /* SYS */
152 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
153 }
154 };
155
156 uint8_t armv4_5_gdb_dummy_fp_value[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
157
158 reg_t armv4_5_gdb_dummy_fp_reg =
159 {
160 "GDB dummy floating-point register", armv4_5_gdb_dummy_fp_value, 0, 1, 96, NULL, 0, NULL, 0
161 };
162
163 uint8_t armv4_5_gdb_dummy_fps_value[] = {0, 0, 0, 0};
164
165 reg_t armv4_5_gdb_dummy_fps_reg =
166 {
167 "GDB dummy floating-point status register", armv4_5_gdb_dummy_fps_value, 0, 1, 32, NULL, 0, NULL, 0
168 };
169
170 int armv4_5_get_core_reg(reg_t *reg)
171 {
172 int retval;
173 armv4_5_core_reg_t *armv4_5 = reg->arch_info;
174 target_t *target = armv4_5->target;
175
176 if (target->state != TARGET_HALTED)
177 {
178 LOG_ERROR("Target not halted");
179 return ERROR_TARGET_NOT_HALTED;
180 }
181
182 /* retval = armv4_5->armv4_5_common->full_context(target); */
183 retval = armv4_5->armv4_5_common->read_core_reg(target, armv4_5->num, armv4_5->mode);
184
185 return retval;
186 }
187
188 int armv4_5_set_core_reg(reg_t *reg, uint8_t *buf)
189 {
190 armv4_5_core_reg_t *armv4_5 = reg->arch_info;
191 target_t *target = armv4_5->target;
192 armv4_5_common_t *armv4_5_target = target->arch_info;
193 uint32_t value = buf_get_u32(buf, 0, 32);
194
195 if (target->state != TARGET_HALTED)
196 {
197 return ERROR_TARGET_NOT_HALTED;
198 }
199
200 if (reg == &armv4_5_target->core_cache->reg_list[ARMV4_5_CPSR])
201 {
202 if (value & 0x20)
203 {
204 /* T bit should be set */
205 if (armv4_5_target->core_state == ARMV4_5_STATE_ARM)
206 {
207 /* change state to Thumb */
208 LOG_DEBUG("changing to Thumb state");
209 armv4_5_target->core_state = ARMV4_5_STATE_THUMB;
210 }
211 }
212 else
213 {
214 /* T bit should be cleared */
215 if (armv4_5_target->core_state == ARMV4_5_STATE_THUMB)
216 {
217 /* change state to ARM */
218 LOG_DEBUG("changing to ARM state");
219 armv4_5_target->core_state = ARMV4_5_STATE_ARM;
220 }
221 }
222
223 if (armv4_5_target->core_mode != (enum armv4_5_mode)(value & 0x1f))
224 {
225 LOG_DEBUG("changing ARM core mode to '%s'", armv4_5_mode_strings[armv4_5_mode_to_number(value & 0x1f)]);
226 armv4_5_target->core_mode = value & 0x1f;
227 armv4_5_target->write_core_reg(target, 16, ARMV4_5_MODE_ANY, value);
228 }
229 }
230
231 buf_set_u32(reg->value, 0, 32, value);
232 reg->dirty = 1;
233 reg->valid = 1;
234
235 return ERROR_OK;
236 }
237
238 int armv4_5_invalidate_core_regs(target_t *target)
239 {
240 armv4_5_common_t *armv4_5 = target->arch_info;
241 int i;
242
243 for (i = 0; i < 37; i++)
244 {
245 armv4_5->core_cache->reg_list[i].valid = 0;
246 armv4_5->core_cache->reg_list[i].dirty = 0;
247 }
248
249 return ERROR_OK;
250 }
251
252 reg_cache_t* armv4_5_build_reg_cache(target_t *target, armv4_5_common_t *armv4_5_common)
253 {
254 int num_regs = 37;
255 reg_cache_t *cache = malloc(sizeof(reg_cache_t));
256 reg_t *reg_list = malloc(sizeof(reg_t) * num_regs);
257 armv4_5_core_reg_t *arch_info = malloc(sizeof(armv4_5_core_reg_t) * num_regs);
258 int i;
259
260 cache->name = "arm v4/5 registers";
261 cache->next = NULL;
262 cache->reg_list = reg_list;
263 cache->num_regs = num_regs;
264
265 if (armv4_5_core_reg_arch_type == -1)
266 armv4_5_core_reg_arch_type = register_reg_arch_type(armv4_5_get_core_reg, armv4_5_set_core_reg);
267
268 register_init_dummy(&armv4_5_gdb_dummy_fp_reg);
269 register_init_dummy(&armv4_5_gdb_dummy_fps_reg);
270
271 for (i = 0; i < 37; i++)
272 {
273 arch_info[i] = armv4_5_core_reg_list_arch_info[i];
274 arch_info[i].target = target;
275 arch_info[i].armv4_5_common = armv4_5_common;
276 reg_list[i].name = armv4_5_core_reg_list[i];
277 reg_list[i].size = 32;
278 reg_list[i].value = calloc(1, 4);
279 reg_list[i].dirty = 0;
280 reg_list[i].valid = 0;
281 reg_list[i].bitfield_desc = NULL;
282 reg_list[i].num_bitfields = 0;
283 reg_list[i].arch_type = armv4_5_core_reg_arch_type;
284 reg_list[i].arch_info = &arch_info[i];
285 }
286
287 return cache;
288 }
289
290 int armv4_5_arch_state(struct target_s *target)
291 {
292 armv4_5_common_t *armv4_5 = target->arch_info;
293
294 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
295 {
296 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
297 exit(-1);
298 }
299
300 LOG_USER("target halted in %s state due to %s, current mode: %s\ncpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "",
301 armv4_5_state_strings[armv4_5->core_state],
302 Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name,
303 armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
304 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
305 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
306
307 return ERROR_OK;
308 }
309
310 int handle_armv4_5_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
311 {
312 char output[128];
313 int output_len;
314 int mode, num;
315 target_t *target = get_current_target(cmd_ctx);
316 armv4_5_common_t *armv4_5 = target->arch_info;
317
318 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
319 {
320 command_print(cmd_ctx, "current target isn't an ARMV4/5 target");
321 return ERROR_OK;
322 }
323
324 if (target->state != TARGET_HALTED)
325 {
326 command_print(cmd_ctx, "error: target must be halted for register accesses");
327 return ERROR_OK;
328 }
329
330 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
331 return ERROR_FAIL;
332
333 for (num = 0; num <= 15; num++)
334 {
335 output_len = 0;
336 for (mode = 0; mode < 6; mode++)
337 {
338 if (!ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).valid)
339 {
340 armv4_5->full_context(target);
341 }
342 output_len += snprintf(output + output_len,
343 128 - output_len,
344 "%8s: %8.8" PRIx32 " ",
345 ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).name,
346 buf_get_u32(ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).value, 0, 32));
347 }
348 command_print(cmd_ctx, "%s", output);
349 }
350 command_print(cmd_ctx,
351 " cpsr: %8.8" PRIx32 " spsr_fiq: %8.8" PRIx32 " spsr_irq: %8.8" PRIx32 " spsr_svc: %8.8" PRIx32 " spsr_abt: %8.8" PRIx32 " spsr_und: %8.8" PRIx32 "",
352 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
353 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_FIQ].value, 0, 32),
354 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_IRQ].value, 0, 32),
355 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_SVC].value, 0, 32),
356 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_ABT].value, 0, 32),
357 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_UND].value, 0, 32));
358
359 return ERROR_OK;
360 }
361
362 int handle_armv4_5_core_state_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
363 {
364 target_t *target = get_current_target(cmd_ctx);
365 armv4_5_common_t *armv4_5 = target->arch_info;
366
367 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
368 {
369 command_print(cmd_ctx, "current target isn't an ARMV4/5 target");
370 return ERROR_OK;
371 }
372
373 if (argc > 0)
374 {
375 if (strcmp(args[0], "arm") == 0)
376 {
377 armv4_5->core_state = ARMV4_5_STATE_ARM;
378 }
379 if (strcmp(args[0], "thumb") == 0)
380 {
381 armv4_5->core_state = ARMV4_5_STATE_THUMB;
382 }
383 }
384
385 command_print(cmd_ctx, "core state: %s", armv4_5_state_strings[armv4_5->core_state]);
386
387 return ERROR_OK;
388 }
389
390 static int
391 handle_armv4_5_disassemble_command(struct command_context_s *cmd_ctx,
392 char *cmd, char **args, int argc)
393 {
394 int retval = ERROR_OK;
395 target_t *target = get_current_target(cmd_ctx);
396 armv4_5_common_t *armv4_5 = target->arch_info;
397 uint32_t address;
398 int count = 1;
399 int i;
400 arm_instruction_t cur_instruction;
401 uint32_t opcode;
402 uint16_t thumb_opcode;
403 int thumb = 0;
404
405 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
406 {
407 command_print(cmd_ctx, "current target isn't an ARMV4/5 target");
408 return ERROR_OK;
409 }
410
411 switch (argc) {
412 case 3:
413 if (strcmp(args[2], "thumb") != 0)
414 goto usage;
415 thumb = 1;
416 /* FALL THROUGH */
417 case 2:
418 count = strtoul(args[1], NULL, 0);
419 /* FALL THROUGH */
420 case 1:
421 address = strtoul(args[0], NULL, 0);
422 if (address & 0x01) {
423 if (!thumb) {
424 command_print(cmd_ctx, "Disassemble as Thumb");
425 thumb = 1;
426 }
427 address &= ~1;
428 }
429 break;
430 default:
431 usage:
432 command_print(cmd_ctx,
433 "usage: armv4_5 disassemble <address> [<count> ['thumb']]");
434 return ERROR_OK;
435 }
436
437 for (i = 0; i < count; i++)
438 {
439 if (thumb)
440 {
441 if ((retval = target_read_u16(target, address, &thumb_opcode)) != ERROR_OK)
442 {
443 return retval;
444 }
445 if ((retval = thumb_evaluate_opcode(thumb_opcode, address, &cur_instruction)) != ERROR_OK)
446 {
447 return retval;
448 }
449 }
450 else {
451 if ((retval = target_read_u32(target, address, &opcode)) != ERROR_OK)
452 {
453 return retval;
454 }
455 if ((retval = arm_evaluate_opcode(opcode, address, &cur_instruction)) != ERROR_OK)
456 {
457 return retval;
458 }
459 }
460 command_print(cmd_ctx, "%s", cur_instruction.text);
461 address += (thumb) ? 2 : 4;
462 }
463
464 return ERROR_OK;
465 }
466
467 int armv4_5_register_commands(struct command_context_s *cmd_ctx)
468 {
469 command_t *armv4_5_cmd;
470
471 armv4_5_cmd = register_command(cmd_ctx, NULL, "armv4_5",
472 NULL, COMMAND_ANY,
473 "armv4/5 specific commands");
474
475 register_command(cmd_ctx, armv4_5_cmd, "reg",
476 handle_armv4_5_reg_command, COMMAND_EXEC,
477 "display ARM core registers");
478 register_command(cmd_ctx, armv4_5_cmd, "core_state",
479 handle_armv4_5_core_state_command, COMMAND_EXEC,
480 "display/change ARM core state <arm | thumb>");
481 register_command(cmd_ctx, armv4_5_cmd, "disassemble",
482 handle_armv4_5_disassemble_command, COMMAND_EXEC,
483 "disassemble instructions <address> [<count> ['thumb']]");
484
485 return ERROR_OK;
486 }
487
488 int armv4_5_get_gdb_reg_list(target_t *target, reg_t **reg_list[], int *reg_list_size)
489 {
490 armv4_5_common_t *armv4_5 = target->arch_info;
491 int i;
492
493 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
494 return ERROR_FAIL;
495
496 *reg_list_size = 26;
497 *reg_list = malloc(sizeof(reg_t*) * (*reg_list_size));
498
499 for (i = 0; i < 16; i++)
500 {
501 (*reg_list)[i] = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i);
502 }
503
504 for (i = 16; i < 24; i++)
505 {
506 (*reg_list)[i] = &armv4_5_gdb_dummy_fp_reg;
507 }
508
509 (*reg_list)[24] = &armv4_5_gdb_dummy_fps_reg;
510 (*reg_list)[25] = &armv4_5->core_cache->reg_list[ARMV4_5_CPSR];
511
512 return ERROR_OK;
513 }
514
515 /* wait for execution to complete and check exit point */
516 static int armv4_5_run_algorithm_completion(struct target_s *target, uint32_t exit_point, int timeout_ms, void *arch_info)
517 {
518 int retval;
519 armv4_5_common_t *armv4_5 = target->arch_info;
520
521 if ((retval = target_wait_state(target, TARGET_HALTED, timeout_ms)) != ERROR_OK)
522 {
523 return retval;
524 }
525 if (target->state != TARGET_HALTED)
526 {
527 if ((retval = target_halt(target)) != ERROR_OK)
528 return retval;
529 if ((retval = target_wait_state(target, TARGET_HALTED, 500)) != ERROR_OK)
530 {
531 return retval;
532 }
533 return ERROR_TARGET_TIMEOUT;
534 }
535
536 /* fast exit: ARMv5+ code can use BKPT */
537 if (exit_point && buf_get_u32(armv4_5->core_cache->reg_list[15].value,
538 0, 32) != exit_point)
539 {
540 LOG_WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4" PRIx32 "",
541 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
542 return ERROR_TARGET_TIMEOUT;
543 }
544
545 return ERROR_OK;
546 }
547
548 int armv4_5_run_algorithm_inner(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, int (*run_it)(struct target_s *target, uint32_t exit_point, int timeout_ms, void *arch_info))
549 {
550 armv4_5_common_t *armv4_5 = target->arch_info;
551 armv4_5_algorithm_t *armv4_5_algorithm_info = arch_info;
552 enum armv4_5_state core_state = armv4_5->core_state;
553 enum armv4_5_mode core_mode = armv4_5->core_mode;
554 uint32_t context[17];
555 uint32_t cpsr;
556 int exit_breakpoint_size = 0;
557 int i;
558 int retval = ERROR_OK;
559 LOG_DEBUG("Running algorithm");
560
561 if (armv4_5_algorithm_info->common_magic != ARMV4_5_COMMON_MAGIC)
562 {
563 LOG_ERROR("current target isn't an ARMV4/5 target");
564 return ERROR_TARGET_INVALID;
565 }
566
567 if (target->state != TARGET_HALTED)
568 {
569 LOG_WARNING("target not halted");
570 return ERROR_TARGET_NOT_HALTED;
571 }
572
573 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
574 return ERROR_FAIL;
575
576 /* armv5 and later can terminate with BKPT instruction; less overhead */
577 if (!exit_point && armv4_5->is_armv4)
578 {
579 LOG_ERROR("ARMv4 target needs HW breakpoint location");
580 return ERROR_FAIL;
581 }
582
583 for (i = 0; i <= 16; i++)
584 {
585 if (!ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid)
586 armv4_5->read_core_reg(target, i, armv4_5_algorithm_info->core_mode);
587 context[i] = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32);
588 }
589 cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32);
590
591 for (i = 0; i < num_mem_params; i++)
592 {
593 if ((retval = target_write_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK)
594 {
595 return retval;
596 }
597 }
598
599 for (i = 0; i < num_reg_params; i++)
600 {
601 reg_t *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
602 if (!reg)
603 {
604 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
605 exit(-1);
606 }
607
608 if (reg->size != reg_params[i].size)
609 {
610 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
611 exit(-1);
612 }
613
614 if ((retval = armv4_5_set_core_reg(reg, reg_params[i].value)) != ERROR_OK)
615 {
616 return retval;
617 }
618 }
619
620 armv4_5->core_state = armv4_5_algorithm_info->core_state;
621 if (armv4_5->core_state == ARMV4_5_STATE_ARM)
622 exit_breakpoint_size = 4;
623 else if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
624 exit_breakpoint_size = 2;
625 else
626 {
627 LOG_ERROR("BUG: can't execute algorithms when not in ARM or Thumb state");
628 exit(-1);
629 }
630
631 if (armv4_5_algorithm_info->core_mode != ARMV4_5_MODE_ANY)
632 {
633 LOG_DEBUG("setting core_mode: 0x%2.2x", armv4_5_algorithm_info->core_mode);
634 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 5, armv4_5_algorithm_info->core_mode);
635 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
636 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
637 }
638
639 /* terminate using a hardware or (ARMv5+) software breakpoint */
640 if (exit_point && (retval = breakpoint_add(target, exit_point,
641 exit_breakpoint_size, BKPT_HARD)) != ERROR_OK)
642 {
643 LOG_ERROR("can't add HW breakpoint to terminate algorithm");
644 return ERROR_TARGET_FAILURE;
645 }
646
647 if ((retval = target_resume(target, 0, entry_point, 1, 1)) != ERROR_OK)
648 {
649 return retval;
650 }
651 int retvaltemp;
652 retval = run_it(target, exit_point, timeout_ms, arch_info);
653
654 if (exit_point)
655 breakpoint_remove(target, exit_point);
656
657 if (retval != ERROR_OK)
658 return retval;
659
660 for (i = 0; i < num_mem_params; i++)
661 {
662 if (mem_params[i].direction != PARAM_OUT)
663 if ((retvaltemp = target_read_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK)
664 {
665 retval = retvaltemp;
666 }
667 }
668
669 for (i = 0; i < num_reg_params; i++)
670 {
671 if (reg_params[i].direction != PARAM_OUT)
672 {
673
674 reg_t *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
675 if (!reg)
676 {
677 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
678 exit(-1);
679 }
680
681 if (reg->size != reg_params[i].size)
682 {
683 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
684 exit(-1);
685 }
686
687 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
688 }
689 }
690
691 for (i = 0; i <= 16; i++)
692 {
693 uint32_t regvalue;
694 regvalue = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32);
695 if (regvalue != context[i])
696 {
697 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32 "", ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).name, context[i]);
698 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32, context[i]);
699 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid = 1;
700 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).dirty = 1;
701 }
702 }
703 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32, cpsr);
704 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
705 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
706
707 armv4_5->core_state = core_state;
708 armv4_5->core_mode = core_mode;
709
710 return retval;
711 }
712
713 int armv4_5_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)
714 {
715 return armv4_5_run_algorithm_inner(target, num_mem_params, mem_params, num_reg_params, reg_params, entry_point, exit_point, timeout_ms, arch_info, armv4_5_run_algorithm_completion);
716 }
717
718 int armv4_5_init_arch_info(target_t *target, armv4_5_common_t *armv4_5)
719 {
720 target->arch_info = armv4_5;
721
722 armv4_5->common_magic = ARMV4_5_COMMON_MAGIC;
723 armv4_5->core_state = ARMV4_5_STATE_ARM;
724 armv4_5->core_mode = ARMV4_5_MODE_USR;
725
726 return ERROR_OK;
727 }

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)