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

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)