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

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)