David Brownell <david-b@pacbell.net>: This patch adds annotations to
[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 u8 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 u8 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, u8 *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 u32 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.8x pc: 0x%8.8x",
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, 128 - output_len, "%8s: %8.8x ", ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).name,
343 buf_get_u32(ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).value, 0, 32));
344 }
345 command_print(cmd_ctx, "%s", output);
346 }
347 command_print(cmd_ctx, " cpsr: %8.8x spsr_fiq: %8.8x spsr_irq: %8.8x spsr_svc: %8.8x spsr_abt: %8.8x spsr_und: %8.8x",
348 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
349 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_FIQ].value, 0, 32),
350 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_IRQ].value, 0, 32),
351 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_SVC].value, 0, 32),
352 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_ABT].value, 0, 32),
353 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_UND].value, 0, 32));
354
355 return ERROR_OK;
356 }
357
358 int handle_armv4_5_core_state_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
359 {
360 target_t *target = get_current_target(cmd_ctx);
361 armv4_5_common_t *armv4_5 = target->arch_info;
362
363 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
364 {
365 command_print(cmd_ctx, "current target isn't an ARMV4/5 target");
366 return ERROR_OK;
367 }
368
369 if (argc > 0)
370 {
371 if (strcmp(args[0], "arm") == 0)
372 {
373 armv4_5->core_state = ARMV4_5_STATE_ARM;
374 }
375 if (strcmp(args[0], "thumb") == 0)
376 {
377 armv4_5->core_state = ARMV4_5_STATE_THUMB;
378 }
379 }
380
381 command_print(cmd_ctx, "core state: %s", armv4_5_state_strings[armv4_5->core_state]);
382
383 return ERROR_OK;
384 }
385
386 int handle_armv4_5_disassemble_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
387 {
388 int retval = ERROR_OK;
389 target_t *target = get_current_target(cmd_ctx);
390 armv4_5_common_t *armv4_5 = target->arch_info;
391 u32 address;
392 int count;
393 int i;
394 arm_instruction_t cur_instruction;
395 u32 opcode;
396 u16 thumb_opcode;
397 int thumb = 0;
398
399 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
400 {
401 command_print(cmd_ctx, "current target isn't an ARMV4/5 target");
402 return ERROR_OK;
403 }
404
405 if (argc < 2)
406 {
407 command_print(cmd_ctx, "usage: armv4_5 disassemble <address> <count> ['thumb']");
408 return ERROR_OK;
409 }
410
411 address = strtoul(args[0], NULL, 0);
412 count = strtoul(args[1], NULL, 0);
413
414 if (argc >= 3)
415 if (strcmp(args[2], "thumb") == 0)
416 thumb = 1;
417
418 for (i = 0; i < count; i++)
419 {
420 if (thumb)
421 {
422 if ((retval = target_read_u16(target, address, &thumb_opcode)) != ERROR_OK)
423 {
424 return retval;
425 }
426 if ((retval = thumb_evaluate_opcode(thumb_opcode, address, &cur_instruction)) != ERROR_OK)
427 {
428 return retval;
429 }
430 }
431 else {
432 if ((retval = target_read_u32(target, address, &opcode)) != ERROR_OK)
433 {
434 return retval;
435 }
436 if ((retval = arm_evaluate_opcode(opcode, address, &cur_instruction)) != ERROR_OK)
437 {
438 return retval;
439 }
440 }
441 command_print(cmd_ctx, "%s", cur_instruction.text);
442 address += (thumb) ? 2 : 4;
443 }
444
445 return ERROR_OK;
446 }
447
448 int armv4_5_register_commands(struct command_context_s *cmd_ctx)
449 {
450 command_t *armv4_5_cmd;
451
452 armv4_5_cmd = register_command(cmd_ctx, NULL, "armv4_5", NULL, COMMAND_ANY, "armv4/5 specific commands");
453
454 register_command(cmd_ctx, armv4_5_cmd, "reg", handle_armv4_5_reg_command, COMMAND_EXEC, "display ARM core registers");
455 register_command(cmd_ctx, armv4_5_cmd, "core_state", handle_armv4_5_core_state_command, COMMAND_EXEC, "display/change ARM core state <arm|thumb>");
456
457 register_command(cmd_ctx, armv4_5_cmd, "disassemble", handle_armv4_5_disassemble_command, COMMAND_EXEC, "disassemble instructions <address> <count> ['thumb']");
458 return ERROR_OK;
459 }
460
461 int armv4_5_get_gdb_reg_list(target_t *target, reg_t **reg_list[], int *reg_list_size)
462 {
463 armv4_5_common_t *armv4_5 = target->arch_info;
464 int i;
465
466 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
467 return ERROR_FAIL;
468
469 *reg_list_size = 26;
470 *reg_list = malloc(sizeof(reg_t*) * (*reg_list_size));
471
472 for (i = 0; i < 16; i++)
473 {
474 (*reg_list)[i] = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i);
475 }
476
477 for (i = 16; i < 24; i++)
478 {
479 (*reg_list)[i] = &armv4_5_gdb_dummy_fp_reg;
480 }
481
482 (*reg_list)[24] = &armv4_5_gdb_dummy_fps_reg;
483 (*reg_list)[25] = &armv4_5->core_cache->reg_list[ARMV4_5_CPSR];
484
485 return ERROR_OK;
486 }
487
488 /* wait for execution to complete and check exit point */
489 static int armv4_5_run_algorithm_completion(struct target_s *target, u32 exit_point, int timeout_ms, void *arch_info)
490 {
491 int retval;
492 armv4_5_common_t *armv4_5 = target->arch_info;
493
494 if ((retval = target_wait_state(target, TARGET_HALTED, timeout_ms)) != ERROR_OK)
495 {
496 return retval;
497 }
498 if (target->state != TARGET_HALTED)
499 {
500 if ((retval=target_halt(target))!=ERROR_OK)
501 return retval;
502 if ((retval=target_wait_state(target, TARGET_HALTED, 500))!=ERROR_OK)
503 {
504 return retval;
505 }
506 return ERROR_TARGET_TIMEOUT;
507 }
508 if (buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) != exit_point)
509 {
510 LOG_WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4x",
511 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
512 return ERROR_TARGET_TIMEOUT;
513 }
514
515 return ERROR_OK;
516 }
517
518 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, u32 entry_point, u32 exit_point, int timeout_ms, void *arch_info, int (*run_it)(struct target_s *target, u32 exit_point, int timeout_ms, void *arch_info))
519 {
520 armv4_5_common_t *armv4_5 = target->arch_info;
521 armv4_5_algorithm_t *armv4_5_algorithm_info = arch_info;
522 enum armv4_5_state core_state = armv4_5->core_state;
523 enum armv4_5_mode core_mode = armv4_5->core_mode;
524 u32 context[17];
525 u32 cpsr;
526 int exit_breakpoint_size = 0;
527 int i;
528 int retval = ERROR_OK;
529 LOG_DEBUG("Running algorithm");
530
531 if (armv4_5_algorithm_info->common_magic != ARMV4_5_COMMON_MAGIC)
532 {
533 LOG_ERROR("current target isn't an ARMV4/5 target");
534 return ERROR_TARGET_INVALID;
535 }
536
537 if (target->state != TARGET_HALTED)
538 {
539 LOG_WARNING("target not halted");
540 return ERROR_TARGET_NOT_HALTED;
541 }
542
543 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
544 return ERROR_FAIL;
545
546 for (i = 0; i <= 16; i++)
547 {
548 if (!ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid)
549 armv4_5->read_core_reg(target, i, armv4_5_algorithm_info->core_mode);
550 context[i] = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32);
551 }
552 cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32);
553
554 for (i = 0; i < num_mem_params; i++)
555 {
556 if ((retval = target_write_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK)
557 {
558 return retval;
559 }
560 }
561
562 for (i = 0; i < num_reg_params; i++)
563 {
564 reg_t *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
565 if (!reg)
566 {
567 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
568 exit(-1);
569 }
570
571 if (reg->size != reg_params[i].size)
572 {
573 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
574 exit(-1);
575 }
576
577 if ((retval = armv4_5_set_core_reg(reg, reg_params[i].value)) != ERROR_OK)
578 {
579 return retval;
580 }
581 }
582
583 armv4_5->core_state = armv4_5_algorithm_info->core_state;
584 if (armv4_5->core_state == ARMV4_5_STATE_ARM)
585 exit_breakpoint_size = 4;
586 else if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
587 exit_breakpoint_size = 2;
588 else
589 {
590 LOG_ERROR("BUG: can't execute algorithms when not in ARM or Thumb state");
591 exit(-1);
592 }
593
594 if (armv4_5_algorithm_info->core_mode != ARMV4_5_MODE_ANY)
595 {
596 LOG_DEBUG("setting core_mode: 0x%2.2x", armv4_5_algorithm_info->core_mode);
597 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 5, armv4_5_algorithm_info->core_mode);
598 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
599 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
600 }
601
602 if ((retval = breakpoint_add(target, exit_point, exit_breakpoint_size, BKPT_HARD)) != ERROR_OK)
603 {
604 LOG_ERROR("can't add breakpoint to finish algorithm execution");
605 return ERROR_TARGET_FAILURE;
606 }
607
608 if ((retval = target_resume(target, 0, entry_point, 1, 1)) != ERROR_OK)
609 {
610 return retval;
611 }
612 int retvaltemp;
613 retval=run_it(target, exit_point, timeout_ms, arch_info);
614
615 breakpoint_remove(target, exit_point);
616
617 if (retval!=ERROR_OK)
618 return retval;
619
620 for (i = 0; i < num_mem_params; i++)
621 {
622 if (mem_params[i].direction != PARAM_OUT)
623 if ((retvaltemp = target_read_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK)
624 {
625 retval = retvaltemp;
626 }
627 }
628
629 for (i = 0; i < num_reg_params; i++)
630 {
631 if (reg_params[i].direction != PARAM_OUT)
632 {
633
634 reg_t *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
635 if (!reg)
636 {
637 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
638 exit(-1);
639 }
640
641 if (reg->size != reg_params[i].size)
642 {
643 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
644 exit(-1);
645 }
646
647 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
648 }
649 }
650
651 for (i = 0; i <= 16; i++)
652 {
653 u32 regvalue;
654 regvalue = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32);
655 if (regvalue != context[i])
656 {
657 LOG_DEBUG("restoring register %s with value 0x%8.8x", ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).name, context[i]);
658 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32, context[i]);
659 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid = 1;
660 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).dirty = 1;
661 }
662 }
663 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32, cpsr);
664 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
665 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
666
667 armv4_5->core_state = core_state;
668 armv4_5->core_mode = core_mode;
669
670 return retval;
671 }
672
673 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, u32 entry_point, u32 exit_point, int timeout_ms, void *arch_info)
674 {
675 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);
676 }
677
678 int armv4_5_init_arch_info(target_t *target, armv4_5_common_t *armv4_5)
679 {
680 target->arch_info = armv4_5;
681
682 armv4_5->common_magic = ARMV4_5_COMMON_MAGIC;
683 armv4_5->core_state = ARMV4_5_STATE_ARM;
684 armv4_5->core_mode = ARMV4_5_MODE_USR;
685
686 return ERROR_OK;
687 }

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)