- remove target specific variant and use target->variant member
[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 int armv4_5_get_core_reg(reg_t *reg)
182 {
183 int retval;
184 armv4_5_core_reg_t *armv4_5 = reg->arch_info;
185 target_t *target = armv4_5->target;
186
187 if (target->state != TARGET_HALTED)
188 {
189 LOG_ERROR("Target not halted");
190 return ERROR_TARGET_NOT_HALTED;
191 }
192
193 /* retval = armv4_5->armv4_5_common->full_context(target); */
194 retval = armv4_5->armv4_5_common->read_core_reg(target, armv4_5->num, armv4_5->mode);
195
196 return retval;
197 }
198
199 int armv4_5_set_core_reg(reg_t *reg, u8 *buf)
200 {
201 armv4_5_core_reg_t *armv4_5 = reg->arch_info;
202 target_t *target = armv4_5->target;
203 armv4_5_common_t *armv4_5_target = target->arch_info;
204 u32 value = buf_get_u32(buf, 0, 32);
205
206 if (target->state != TARGET_HALTED)
207 {
208 return ERROR_TARGET_NOT_HALTED;
209 }
210
211 if (reg == &armv4_5_target->core_cache->reg_list[ARMV4_5_CPSR])
212 {
213 if (value & 0x20)
214 {
215 /* T bit should be set */
216 if (armv4_5_target->core_state == ARMV4_5_STATE_ARM)
217 {
218 /* change state to Thumb */
219 LOG_DEBUG("changing to Thumb state");
220 armv4_5_target->core_state = ARMV4_5_STATE_THUMB;
221 }
222 }
223 else
224 {
225 /* T bit should be cleared */
226 if (armv4_5_target->core_state == ARMV4_5_STATE_THUMB)
227 {
228 /* change state to ARM */
229 LOG_DEBUG("changing to ARM state");
230 armv4_5_target->core_state = ARMV4_5_STATE_ARM;
231 }
232 }
233
234 if (armv4_5_target->core_mode != (value & 0x1f))
235 {
236 LOG_DEBUG("changing ARM core mode to '%s'", armv4_5_mode_strings[armv4_5_mode_to_number(value & 0x1f)]);
237 armv4_5_target->core_mode = value & 0x1f;
238 armv4_5_target->write_core_reg(target, 16, ARMV4_5_MODE_ANY, value);
239 }
240 }
241
242 buf_set_u32(reg->value, 0, 32, value);
243 reg->dirty = 1;
244 reg->valid = 1;
245
246 return ERROR_OK;
247 }
248
249 int armv4_5_invalidate_core_regs(target_t *target)
250 {
251 armv4_5_common_t *armv4_5 = target->arch_info;
252 int i;
253
254 for (i = 0; i < 37; i++)
255 {
256 armv4_5->core_cache->reg_list[i].valid = 0;
257 armv4_5->core_cache->reg_list[i].dirty = 0;
258 }
259
260 return ERROR_OK;
261 }
262
263 reg_cache_t* armv4_5_build_reg_cache(target_t *target, armv4_5_common_t *armv4_5_common)
264 {
265 int num_regs = 37;
266 reg_cache_t *cache = malloc(sizeof(reg_cache_t));
267 reg_t *reg_list = malloc(sizeof(reg_t) * num_regs);
268 armv4_5_core_reg_t *arch_info = malloc(sizeof(armv4_5_core_reg_t) * num_regs);
269 int i;
270
271 cache->name = "arm v4/5 registers";
272 cache->next = NULL;
273 cache->reg_list = reg_list;
274 cache->num_regs = num_regs;
275
276 if (armv4_5_core_reg_arch_type == -1)
277 armv4_5_core_reg_arch_type = register_reg_arch_type(armv4_5_get_core_reg, armv4_5_set_core_reg);
278
279 register_init_dummy(&armv4_5_gdb_dummy_fp_reg);
280 register_init_dummy(&armv4_5_gdb_dummy_fps_reg);
281
282 for (i = 0; i < 37; i++)
283 {
284 arch_info[i] = armv4_5_core_reg_list_arch_info[i];
285 arch_info[i].target = target;
286 arch_info[i].armv4_5_common = armv4_5_common;
287 reg_list[i].name = armv4_5_core_reg_list[i];
288 reg_list[i].size = 32;
289 reg_list[i].value = calloc(1, 4);
290 reg_list[i].dirty = 0;
291 reg_list[i].valid = 0;
292 reg_list[i].bitfield_desc = NULL;
293 reg_list[i].num_bitfields = 0;
294 reg_list[i].arch_type = armv4_5_core_reg_arch_type;
295 reg_list[i].arch_info = &arch_info[i];
296 }
297
298 return cache;
299 }
300
301 int armv4_5_arch_state(struct target_s *target)
302 {
303 armv4_5_common_t *armv4_5 = target->arch_info;
304
305 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
306 {
307 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
308 exit(-1);
309 }
310
311 LOG_USER("target halted in %s state due to %s, current mode: %s\ncpsr: 0x%8.8x pc: 0x%8.8x",
312 armv4_5_state_strings[armv4_5->core_state],
313 Jim_Nvp_value2name_simple( nvp_target_debug_reason, target->debug_reason )->name,
314 armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
315 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
316 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
317
318 return ERROR_OK;
319 }
320
321 int handle_armv4_5_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
322 {
323 char output[128];
324 int output_len;
325 int mode, num;
326 target_t *target = get_current_target(cmd_ctx);
327 armv4_5_common_t *armv4_5 = target->arch_info;
328
329 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
330 {
331 command_print(cmd_ctx, "current target isn't an ARMV4/5 target");
332 return ERROR_OK;
333 }
334
335 if (target->state != TARGET_HALTED)
336 {
337 command_print(cmd_ctx, "error: target must be halted for register accesses");
338 return ERROR_OK;
339 }
340
341 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
342 return ERROR_FAIL;
343
344 for (num = 0; num <= 15; num++)
345 {
346 output_len = 0;
347 for (mode = 0; mode < 6; mode++)
348 {
349 if (!ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).valid)
350 {
351 armv4_5->full_context(target);
352 }
353 output_len += snprintf(output + output_len, 128 - output_len, "%8s: %8.8x ", ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).name,
354 buf_get_u32(ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).value, 0, 32));
355 }
356 command_print(cmd_ctx, output);
357 }
358 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",
359 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
360 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_FIQ].value, 0, 32),
361 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_IRQ].value, 0, 32),
362 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_SVC].value, 0, 32),
363 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_ABT].value, 0, 32),
364 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_UND].value, 0, 32));
365
366 return ERROR_OK;
367 }
368
369 int handle_armv4_5_core_state_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
370 {
371 target_t *target = get_current_target(cmd_ctx);
372 armv4_5_common_t *armv4_5 = target->arch_info;
373
374 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
375 {
376 command_print(cmd_ctx, "current target isn't an ARMV4/5 target");
377 return ERROR_OK;
378 }
379
380 if (argc > 0)
381 {
382 if (strcmp(args[0], "arm") == 0)
383 {
384 armv4_5->core_state = ARMV4_5_STATE_ARM;
385 }
386 if (strcmp(args[0], "thumb") == 0)
387 {
388 armv4_5->core_state = ARMV4_5_STATE_THUMB;
389 }
390 }
391
392 command_print(cmd_ctx, "core state: %s", armv4_5_state_strings[armv4_5->core_state]);
393
394 return ERROR_OK;
395 }
396
397 int handle_armv4_5_disassemble_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
398 {
399 int retval = ERROR_OK;
400 target_t *target = get_current_target(cmd_ctx);
401 armv4_5_common_t *armv4_5 = target->arch_info;
402 u32 address;
403 int count;
404 int i;
405 arm_instruction_t cur_instruction;
406 u32 opcode;
407 int thumb = 0;
408
409 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
410 {
411 command_print(cmd_ctx, "current target isn't an ARMV4/5 target");
412 return ERROR_OK;
413 }
414
415 if (argc < 2)
416 {
417 command_print(cmd_ctx, "usage: armv4_5 disassemble <address> <count> ['thumb']");
418 return ERROR_OK;
419 }
420
421 address = strtoul(args[0], NULL, 0);
422 count = strtoul(args[1], NULL, 0);
423
424 if (argc >= 3)
425 if (strcmp(args[2], "thumb") == 0)
426 thumb = 1;
427
428 for (i = 0; i < count; i++)
429 {
430 if((retval = target_read_u32(target, address, &opcode)) != ERROR_OK)
431 {
432 return retval;
433 }
434 if((retval = arm_evaluate_opcode(opcode, address, &cur_instruction)) != ERROR_OK)
435 {
436 return retval;
437 }
438 command_print(cmd_ctx, "%s", cur_instruction.text);
439 address += (thumb) ? 2 : 4;
440 }
441
442 return ERROR_OK;
443 }
444
445 int armv4_5_register_commands(struct command_context_s *cmd_ctx)
446 {
447 command_t *armv4_5_cmd;
448
449 armv4_5_cmd = register_command(cmd_ctx, NULL, "armv4_5", NULL, COMMAND_ANY, "armv4/5 specific commands");
450
451 register_command(cmd_ctx, armv4_5_cmd, "reg", handle_armv4_5_reg_command, COMMAND_EXEC, "display ARM core registers");
452 register_command(cmd_ctx, armv4_5_cmd, "core_state", handle_armv4_5_core_state_command, COMMAND_EXEC, "display/change ARM core state <arm|thumb>");
453
454 register_command(cmd_ctx, armv4_5_cmd, "disassemble", handle_armv4_5_disassemble_command, COMMAND_EXEC, "disassemble instructions <address> <count> ['thumb']");
455 return ERROR_OK;
456 }
457
458 int armv4_5_get_gdb_reg_list(target_t *target, reg_t **reg_list[], int *reg_list_size)
459 {
460 armv4_5_common_t *armv4_5 = target->arch_info;
461 int i;
462
463 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
464 return ERROR_FAIL;
465
466 *reg_list_size = 26;
467 *reg_list = malloc(sizeof(reg_t*) * (*reg_list_size));
468
469 for (i = 0; i < 16; i++)
470 {
471 (*reg_list)[i] = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i);
472 }
473
474 for (i = 16; i < 24; i++)
475 {
476 (*reg_list)[i] = &armv4_5_gdb_dummy_fp_reg;
477 }
478
479 (*reg_list)[24] = &armv4_5_gdb_dummy_fps_reg;
480 (*reg_list)[25] = &armv4_5->core_cache->reg_list[ARMV4_5_CPSR];
481
482 return ERROR_OK;
483 }
484
485 /* wait for execution to complete and check exit point */
486 static int armv4_5_run_algorithm_completion(struct target_s *target, u32 exit_point, int timeout_ms, void *arch_info)
487 {
488 int retval;
489 armv4_5_common_t *armv4_5 = target->arch_info;
490
491 if((retval = target_wait_state(target, TARGET_HALTED, timeout_ms)) != ERROR_OK)
492 {
493 return retval;
494 }
495 if (target->state != TARGET_HALTED)
496 {
497 if ((retval=target_halt(target))!=ERROR_OK)
498 return retval;
499 if ((retval=target_wait_state(target, TARGET_HALTED, 500))!=ERROR_OK)
500 {
501 return retval;
502 }
503 return ERROR_TARGET_TIMEOUT;
504 }
505 if (buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) != exit_point)
506 {
507 LOG_WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4x",
508 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
509 return ERROR_TARGET_TIMEOUT;
510 }
511
512 return ERROR_OK;
513 }
514
515 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))
516 {
517 armv4_5_common_t *armv4_5 = target->arch_info;
518 armv4_5_algorithm_t *armv4_5_algorithm_info = arch_info;
519 enum armv4_5_state core_state = armv4_5->core_state;
520 enum armv4_5_mode core_mode = armv4_5->core_mode;
521 u32 context[17];
522 u32 cpsr;
523 int exit_breakpoint_size = 0;
524 int i;
525 int retval = ERROR_OK;
526 LOG_DEBUG("Running algorithm");
527
528 if (armv4_5_algorithm_info->common_magic != ARMV4_5_COMMON_MAGIC)
529 {
530 LOG_ERROR("current target isn't an ARMV4/5 target");
531 return ERROR_TARGET_INVALID;
532 }
533
534 if (target->state != TARGET_HALTED)
535 {
536 LOG_WARNING("target not halted");
537 return ERROR_TARGET_NOT_HALTED;
538 }
539
540 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
541 return ERROR_FAIL;
542
543 for (i = 0; i <= 16; i++)
544 {
545 if (!ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid)
546 armv4_5->read_core_reg(target, i, armv4_5_algorithm_info->core_mode);
547 context[i] = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32);
548 }
549 cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32);
550
551 for (i = 0; i < num_mem_params; i++)
552 {
553 if((retval = target_write_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK)
554 {
555 return retval;
556 }
557 }
558
559 for (i = 0; i < num_reg_params; i++)
560 {
561 reg_t *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
562 if (!reg)
563 {
564 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
565 exit(-1);
566 }
567
568 if (reg->size != reg_params[i].size)
569 {
570 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
571 exit(-1);
572 }
573
574 if((retval = armv4_5_set_core_reg(reg, reg_params[i].value)) != ERROR_OK)
575 {
576 return retval;
577 }
578 }
579
580 armv4_5->core_state = armv4_5_algorithm_info->core_state;
581 if (armv4_5->core_state == ARMV4_5_STATE_ARM)
582 exit_breakpoint_size = 4;
583 else if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
584 exit_breakpoint_size = 2;
585 else
586 {
587 LOG_ERROR("BUG: can't execute algorithms when not in ARM or Thumb state");
588 exit(-1);
589 }
590
591 if (armv4_5_algorithm_info->core_mode != ARMV4_5_MODE_ANY)
592 {
593 LOG_DEBUG("setting core_mode: 0x%2.2x", armv4_5_algorithm_info->core_mode);
594 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 5, armv4_5_algorithm_info->core_mode);
595 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
596 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
597 }
598
599 if ((retval = breakpoint_add(target, exit_point, exit_breakpoint_size, BKPT_HARD)) != ERROR_OK)
600 {
601 LOG_ERROR("can't add breakpoint to finish algorithm execution");
602 return ERROR_TARGET_FAILURE;
603 }
604
605 if((retval = target_resume(target, 0, entry_point, 1, 1)) != ERROR_OK)
606 {
607 return retval;
608 }
609 int retvaltemp;
610 retval=run_it(target, exit_point, timeout_ms, arch_info);
611
612 breakpoint_remove(target, exit_point);
613
614 if (retval!=ERROR_OK)
615 return retval;
616
617 for (i = 0; i < num_mem_params; i++)
618 {
619 if (mem_params[i].direction != PARAM_OUT)
620 if((retvaltemp = target_read_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK)
621 {
622 retval = retvaltemp;
623 }
624 }
625
626 for (i = 0; i < num_reg_params; i++)
627 {
628 if (reg_params[i].direction != PARAM_OUT)
629 {
630
631 reg_t *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
632 if (!reg)
633 {
634 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
635 exit(-1);
636 }
637
638 if (reg->size != reg_params[i].size)
639 {
640 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
641 exit(-1);
642 }
643
644 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
645 }
646 }
647
648 for (i = 0; i <= 16; i++)
649 {
650 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]);
651 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32, context[i]);
652 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid = 1;
653 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).dirty = 1;
654 }
655 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32, cpsr);
656 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
657 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
658
659 armv4_5->core_state = core_state;
660 armv4_5->core_mode = core_mode;
661
662 return retval;
663 }
664
665 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)
666 {
667 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);
668 }
669
670 int armv4_5_init_arch_info(target_t *target, armv4_5_common_t *armv4_5)
671 {
672 target->arch_info = armv4_5;
673
674 armv4_5->common_magic = ARMV4_5_COMMON_MAGIC;
675 armv4_5->core_state = ARMV4_5_STATE_ARM;
676 armv4_5->core_mode = ARMV4_5_MODE_USR;
677
678 return ERROR_OK;
679 }

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)