Zach Welch <zw@superlucidity.net> fix -Werror warnings
[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 != (enum armv4_5_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 u16 thumb_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(thumb)
432 {
433 if((retval = target_read_u16(target, address, &thumb_opcode)) != ERROR_OK)
434 {
435 return retval;
436 }
437 if((retval = thumb_evaluate_opcode(thumb_opcode, address, &cur_instruction)) != ERROR_OK)
438 {
439 return retval;
440 }
441 }
442 else {
443 if((retval = target_read_u32(target, address, &opcode)) != ERROR_OK)
444 {
445 return retval;
446 }
447 if((retval = arm_evaluate_opcode(opcode, address, &cur_instruction)) != ERROR_OK)
448 {
449 return retval;
450 }
451 }
452 command_print(cmd_ctx, "%s", cur_instruction.text);
453 address += (thumb) ? 2 : 4;
454 }
455
456 return ERROR_OK;
457 }
458
459 int armv4_5_register_commands(struct command_context_s *cmd_ctx)
460 {
461 command_t *armv4_5_cmd;
462
463 armv4_5_cmd = register_command(cmd_ctx, NULL, "armv4_5", NULL, COMMAND_ANY, "armv4/5 specific commands");
464
465 register_command(cmd_ctx, armv4_5_cmd, "reg", handle_armv4_5_reg_command, COMMAND_EXEC, "display ARM core registers");
466 register_command(cmd_ctx, armv4_5_cmd, "core_state", handle_armv4_5_core_state_command, COMMAND_EXEC, "display/change ARM core state <arm|thumb>");
467
468 register_command(cmd_ctx, armv4_5_cmd, "disassemble", handle_armv4_5_disassemble_command, COMMAND_EXEC, "disassemble instructions <address> <count> ['thumb']");
469 return ERROR_OK;
470 }
471
472 int armv4_5_get_gdb_reg_list(target_t *target, reg_t **reg_list[], int *reg_list_size)
473 {
474 armv4_5_common_t *armv4_5 = target->arch_info;
475 int i;
476
477 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
478 return ERROR_FAIL;
479
480 *reg_list_size = 26;
481 *reg_list = malloc(sizeof(reg_t*) * (*reg_list_size));
482
483 for (i = 0; i < 16; i++)
484 {
485 (*reg_list)[i] = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i);
486 }
487
488 for (i = 16; i < 24; i++)
489 {
490 (*reg_list)[i] = &armv4_5_gdb_dummy_fp_reg;
491 }
492
493 (*reg_list)[24] = &armv4_5_gdb_dummy_fps_reg;
494 (*reg_list)[25] = &armv4_5->core_cache->reg_list[ARMV4_5_CPSR];
495
496 return ERROR_OK;
497 }
498
499 /* wait for execution to complete and check exit point */
500 static int armv4_5_run_algorithm_completion(struct target_s *target, u32 exit_point, int timeout_ms, void *arch_info)
501 {
502 int retval;
503 armv4_5_common_t *armv4_5 = target->arch_info;
504
505 if((retval = target_wait_state(target, TARGET_HALTED, timeout_ms)) != ERROR_OK)
506 {
507 return retval;
508 }
509 if (target->state != TARGET_HALTED)
510 {
511 if ((retval=target_halt(target))!=ERROR_OK)
512 return retval;
513 if ((retval=target_wait_state(target, TARGET_HALTED, 500))!=ERROR_OK)
514 {
515 return retval;
516 }
517 return ERROR_TARGET_TIMEOUT;
518 }
519 if (buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) != exit_point)
520 {
521 LOG_WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4x",
522 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
523 return ERROR_TARGET_TIMEOUT;
524 }
525
526 return ERROR_OK;
527 }
528
529 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))
530 {
531 armv4_5_common_t *armv4_5 = target->arch_info;
532 armv4_5_algorithm_t *armv4_5_algorithm_info = arch_info;
533 enum armv4_5_state core_state = armv4_5->core_state;
534 enum armv4_5_mode core_mode = armv4_5->core_mode;
535 u32 context[17];
536 u32 cpsr;
537 int exit_breakpoint_size = 0;
538 int i;
539 int retval = ERROR_OK;
540 LOG_DEBUG("Running algorithm");
541
542 if (armv4_5_algorithm_info->common_magic != ARMV4_5_COMMON_MAGIC)
543 {
544 LOG_ERROR("current target isn't an ARMV4/5 target");
545 return ERROR_TARGET_INVALID;
546 }
547
548 if (target->state != TARGET_HALTED)
549 {
550 LOG_WARNING("target not halted");
551 return ERROR_TARGET_NOT_HALTED;
552 }
553
554 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
555 return ERROR_FAIL;
556
557 for (i = 0; i <= 16; i++)
558 {
559 if (!ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid)
560 armv4_5->read_core_reg(target, i, armv4_5_algorithm_info->core_mode);
561 context[i] = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32);
562 }
563 cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32);
564
565 for (i = 0; i < num_mem_params; i++)
566 {
567 if((retval = target_write_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK)
568 {
569 return retval;
570 }
571 }
572
573 for (i = 0; i < num_reg_params; i++)
574 {
575 reg_t *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
576 if (!reg)
577 {
578 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
579 exit(-1);
580 }
581
582 if (reg->size != reg_params[i].size)
583 {
584 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
585 exit(-1);
586 }
587
588 if((retval = armv4_5_set_core_reg(reg, reg_params[i].value)) != ERROR_OK)
589 {
590 return retval;
591 }
592 }
593
594 armv4_5->core_state = armv4_5_algorithm_info->core_state;
595 if (armv4_5->core_state == ARMV4_5_STATE_ARM)
596 exit_breakpoint_size = 4;
597 else if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
598 exit_breakpoint_size = 2;
599 else
600 {
601 LOG_ERROR("BUG: can't execute algorithms when not in ARM or Thumb state");
602 exit(-1);
603 }
604
605 if (armv4_5_algorithm_info->core_mode != ARMV4_5_MODE_ANY)
606 {
607 LOG_DEBUG("setting core_mode: 0x%2.2x", armv4_5_algorithm_info->core_mode);
608 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 5, armv4_5_algorithm_info->core_mode);
609 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
610 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
611 }
612
613 if ((retval = breakpoint_add(target, exit_point, exit_breakpoint_size, BKPT_HARD)) != ERROR_OK)
614 {
615 LOG_ERROR("can't add breakpoint to finish algorithm execution");
616 return ERROR_TARGET_FAILURE;
617 }
618
619 if((retval = target_resume(target, 0, entry_point, 1, 1)) != ERROR_OK)
620 {
621 return retval;
622 }
623 int retvaltemp;
624 retval=run_it(target, exit_point, timeout_ms, arch_info);
625
626 breakpoint_remove(target, exit_point);
627
628 if (retval!=ERROR_OK)
629 return retval;
630
631 for (i = 0; i < num_mem_params; i++)
632 {
633 if (mem_params[i].direction != PARAM_OUT)
634 if((retvaltemp = target_read_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK)
635 {
636 retval = retvaltemp;
637 }
638 }
639
640 for (i = 0; i < num_reg_params; i++)
641 {
642 if (reg_params[i].direction != PARAM_OUT)
643 {
644
645 reg_t *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
646 if (!reg)
647 {
648 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
649 exit(-1);
650 }
651
652 if (reg->size != reg_params[i].size)
653 {
654 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
655 exit(-1);
656 }
657
658 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
659 }
660 }
661
662 for (i = 0; i <= 16; i++)
663 {
664 u32 regvalue;
665 regvalue = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32);
666 if (regvalue != context[i])
667 {
668 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]);
669 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32, context[i]);
670 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid = 1;
671 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).dirty = 1;
672 }
673 }
674 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32, cpsr);
675 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
676 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
677
678 armv4_5->core_state = core_state;
679 armv4_5->core_mode = core_mode;
680
681 return retval;
682 }
683
684 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)
685 {
686 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);
687 }
688
689 int armv4_5_init_arch_info(target_t *target, armv4_5_common_t *armv4_5)
690 {
691 target->arch_info = armv4_5;
692
693 armv4_5->common_magic = ARMV4_5_COMMON_MAGIC;
694 armv4_5->core_state = ARMV4_5_STATE_ARM;
695 armv4_5->core_mode = ARMV4_5_MODE_USR;
696
697 return ERROR_OK;
698 }

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)