- Improves error handling upon GDB connect
[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 ARMV4_5_MODE_USR: return 0; break;
178 case ARMV4_5_MODE_FIQ: return 1; break;
179 case ARMV4_5_MODE_IRQ: return 2; break;
180 case ARMV4_5_MODE_SVC: return 3; break;
181 case ARMV4_5_MODE_ABT: return 4; break;
182 case ARMV4_5_MODE_UND: return 5; break;
183 case ARMV4_5_MODE_SYS: return 6; break;
184 case ARMV4_5_MODE_ANY: 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 if (armv4_5_target->core_mode != (value & 0x1f))
262 {
263 DEBUG("changing ARM core mode to '%s'", armv4_5_mode_strings[armv4_5_mode_to_number(value & 0x1f)]);
264 armv4_5_target->core_mode = value & 0x1f;
265 armv4_5_target->write_core_reg(target, 16, ARMV4_5_MODE_ANY, value);
266 }
267 }
268
269 buf_set_u32(reg->value, 0, 32, value);
270 reg->dirty = 1;
271 reg->valid = 1;
272
273 return ERROR_OK;
274 }
275
276 int armv4_5_invalidate_core_regs(target_t *target)
277 {
278 armv4_5_common_t *armv4_5 = target->arch_info;
279 int i;
280
281 for (i = 0; i < 37; i++)
282 {
283 armv4_5->core_cache->reg_list[i].valid = 0;
284 armv4_5->core_cache->reg_list[i].dirty = 0;
285 }
286
287 return ERROR_OK;
288 }
289
290 reg_cache_t* armv4_5_build_reg_cache(target_t *target, armv4_5_common_t *armv4_5_common)
291 {
292 int num_regs = 37;
293 reg_cache_t *cache = malloc(sizeof(reg_cache_t));
294 reg_t *reg_list = malloc(sizeof(reg_t) * num_regs);
295 armv4_5_core_reg_t *arch_info = malloc(sizeof(armv4_5_core_reg_t) * num_regs);
296 int i;
297
298 cache->name = "arm v4/5 registers";
299 cache->next = NULL;
300 cache->reg_list = reg_list;
301 cache->num_regs = num_regs;
302
303 if (armv4_5_core_reg_arch_type == -1)
304 armv4_5_core_reg_arch_type = register_reg_arch_type(armv4_5_get_core_reg, armv4_5_set_core_reg);
305
306 for (i = 0; i < 37; i++)
307 {
308 arch_info[i] = armv4_5_core_reg_list_arch_info[i];
309 arch_info[i].target = target;
310 arch_info[i].armv4_5_common = armv4_5_common;
311 reg_list[i].name = armv4_5_core_reg_list[i];
312 reg_list[i].size = 32;
313 reg_list[i].value = calloc(1, 4);
314 reg_list[i].dirty = 0;
315 reg_list[i].valid = 0;
316 reg_list[i].bitfield_desc = NULL;
317 reg_list[i].num_bitfields = 0;
318 reg_list[i].arch_type = armv4_5_core_reg_arch_type;
319 reg_list[i].arch_info = &arch_info[i];
320 }
321
322 return cache;
323 }
324
325 int armv4_5_arch_state(struct target_s *target)
326 {
327 armv4_5_common_t *armv4_5 = target->arch_info;
328
329 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
330 {
331 ERROR("BUG: called for a non-ARMv4/5 target");
332 exit(-1);
333 }
334
335 USER("target halted in %s state due to %s, current mode: %s\ncpsr: 0x%8.8x pc: 0x%8.8x",
336 armv4_5_state_strings[armv4_5->core_state],
337 target_debug_reason_strings[target->debug_reason],
338 armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
339 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
340 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
341
342 return ERROR_OK;
343 }
344
345 int handle_armv4_5_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
346 {
347 char output[128];
348 int output_len;
349 int mode, num;
350 target_t *target = get_current_target(cmd_ctx);
351 armv4_5_common_t *armv4_5 = target->arch_info;
352
353 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
354 {
355 command_print(cmd_ctx, "current target isn't an ARMV4/5 target");
356 return ERROR_OK;
357 }
358
359 if (target->state != TARGET_HALTED)
360 {
361 command_print(cmd_ctx, "error: target must be halted for register accesses");
362 return ERROR_OK;
363 }
364
365 for (num = 0; num <= 15; num++)
366 {
367 output_len = 0;
368 for (mode = 0; mode < 6; mode++)
369 {
370 if (!ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).valid)
371 {
372 armv4_5->full_context(target);
373 }
374 output_len += snprintf(output + output_len, 128 - output_len, "%8s: %8.8x ", ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).name,
375 buf_get_u32(ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).value, 0, 32));
376 }
377 command_print(cmd_ctx, output);
378 }
379 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",
380 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
381 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_FIQ].value, 0, 32),
382 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_IRQ].value, 0, 32),
383 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_SVC].value, 0, 32),
384 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_ABT].value, 0, 32),
385 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_UND].value, 0, 32));
386
387 return ERROR_OK;
388 }
389
390 int handle_armv4_5_core_state_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
391 {
392 target_t *target = get_current_target(cmd_ctx);
393 armv4_5_common_t *armv4_5 = target->arch_info;
394
395 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
396 {
397 command_print(cmd_ctx, "current target isn't an ARMV4/5 target");
398 return ERROR_OK;
399 }
400
401 if (argc > 0)
402 {
403 if (strcmp(args[0], "arm") == 0)
404 {
405 armv4_5->core_state = ARMV4_5_STATE_ARM;
406 }
407 if (strcmp(args[0], "thumb") == 0)
408 {
409 armv4_5->core_state = ARMV4_5_STATE_THUMB;
410 }
411 }
412
413 command_print(cmd_ctx, "core state: %s", armv4_5_state_strings[armv4_5->core_state]);
414
415 return ERROR_OK;
416 }
417
418 int handle_armv4_5_disassemble_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
419 {
420 target_t *target = get_current_target(cmd_ctx);
421 armv4_5_common_t *armv4_5 = target->arch_info;
422 u32 address;
423 int count;
424 int i;
425 arm_instruction_t cur_instruction;
426 u32 opcode;
427 int thumb = 0;
428
429 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
430 {
431 command_print(cmd_ctx, "current target isn't an ARMV4/5 target");
432 return ERROR_OK;
433 }
434
435 if (argc < 2)
436 {
437 command_print(cmd_ctx, "usage: armv4_5 disassemble <address> <count> ['thumb']");
438 return ERROR_OK;
439 }
440
441 address = strtoul(args[0], NULL, 0);
442 count = strtoul(args[1], NULL, 0);
443
444 if (argc >= 3)
445 if (strcmp(args[2], "thumb") == 0)
446 thumb = 1;
447
448 for (i = 0; i < count; i++)
449 {
450 target_read_u32(target, address, &opcode);
451 arm_evaluate_opcode(opcode, address, &cur_instruction);
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 (target->state != TARGET_HALTED)
478 {
479 ERROR("Target not halted");
480 return ERROR_TARGET_NOT_HALTED;
481 }
482
483 *reg_list_size = 26;
484 *reg_list = malloc(sizeof(reg_t*) * (*reg_list_size));
485
486 for (i = 0; i < 16; i++)
487 {
488 (*reg_list)[i] = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i);
489 }
490
491 for (i = 16; i < 24; i++)
492 {
493 (*reg_list)[i] = &armv4_5_gdb_dummy_fp_reg;
494 }
495
496 (*reg_list)[24] = &armv4_5_gdb_dummy_fps_reg;
497 (*reg_list)[25] = &armv4_5->core_cache->reg_list[ARMV4_5_CPSR];
498
499 return ERROR_OK;
500 }
501
502 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)
503 {
504 armv4_5_common_t *armv4_5 = target->arch_info;
505 armv4_5_algorithm_t *armv4_5_algorithm_info = arch_info;
506 enum armv4_5_state core_state = armv4_5->core_state;
507 enum armv4_5_mode core_mode = armv4_5->core_mode;
508 u32 context[17];
509 u32 cpsr;
510 int exit_breakpoint_size = 0;
511 int i;
512 int retval = ERROR_OK;
513
514 if (armv4_5_algorithm_info->common_magic != ARMV4_5_COMMON_MAGIC)
515 {
516 ERROR("current target isn't an ARMV4/5 target");
517 return ERROR_TARGET_INVALID;
518 }
519
520 if (target->state != TARGET_HALTED)
521 {
522 WARNING("target not halted");
523 return ERROR_TARGET_NOT_HALTED;
524 }
525
526 for (i = 0; i <= 16; i++)
527 {
528 if (!ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid)
529 armv4_5->read_core_reg(target, i, armv4_5_algorithm_info->core_mode);
530 context[i] = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32);
531 }
532 cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32);
533
534 for (i = 0; i < num_mem_params; i++)
535 {
536 target_write_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value);
537 }
538
539 for (i = 0; i < num_reg_params; i++)
540 {
541 reg_t *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
542 if (!reg)
543 {
544 ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
545 exit(-1);
546 }
547
548 if (reg->size != reg_params[i].size)
549 {
550 ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
551 exit(-1);
552 }
553
554 armv4_5_set_core_reg(reg, reg_params[i].value);
555 }
556
557 armv4_5->core_state = armv4_5_algorithm_info->core_state;
558 if (armv4_5->core_state == ARMV4_5_STATE_ARM)
559 exit_breakpoint_size = 4;
560 else if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
561 exit_breakpoint_size = 2;
562 else
563 {
564 ERROR("BUG: can't execute algorithms when not in ARM or Thumb state");
565 exit(-1);
566 }
567
568 if (armv4_5_algorithm_info->core_mode != ARMV4_5_MODE_ANY)
569 {
570 DEBUG("setting core_mode: 0x%2.2x", armv4_5_algorithm_info->core_mode);
571 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 5, armv4_5_algorithm_info->core_mode);
572 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
573 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
574 }
575
576 if ((retval = breakpoint_add(target, exit_point, exit_breakpoint_size, BKPT_HARD)) != ERROR_OK)
577 {
578 ERROR("can't add breakpoint to finish algorithm execution");
579 return ERROR_TARGET_FAILURE;
580 }
581
582 target->type->resume(target, 0, entry_point, 1, 1);
583 target->type->poll(target);
584
585 while (target->state != TARGET_HALTED)
586 {
587 usleep(10000);
588 target->type->poll(target);
589 if ((timeout_ms -= 10) <= 0)
590 {
591 ERROR("timeout waiting for algorithm to complete, trying to halt target");
592 target->type->halt(target);
593 timeout_ms = 1000;
594 while (target->state != TARGET_HALTED)
595 {
596 usleep(10000);
597 target->type->poll(target);
598 if ((timeout_ms -= 10) <= 0)
599 {
600 ERROR("target didn't reenter debug state, exiting");
601 exit(-1);
602 }
603 }
604 retval = ERROR_TARGET_TIMEOUT;
605 }
606 }
607
608 if ((retval != ERROR_TARGET_TIMEOUT) &&
609 (buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) != exit_point))
610 {
611 WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4x",
612 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
613 }
614
615 breakpoint_remove(target, exit_point);
616
617 for (i = 0; i < num_mem_params; i++)
618 {
619 if (mem_params[i].direction != PARAM_OUT)
620 target_read_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value);
621 }
622
623 for (i = 0; i < num_reg_params; i++)
624 {
625 if (reg_params[i].direction != PARAM_OUT)
626 {
627
628 reg_t *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
629 if (!reg)
630 {
631 ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
632 exit(-1);
633 }
634
635 if (reg->size != reg_params[i].size)
636 {
637 ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
638 exit(-1);
639 }
640
641 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
642 }
643 }
644
645 for (i = 0; i <= 16; i++)
646 {
647 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]);
648 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32, context[i]);
649 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid = 1;
650 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).dirty = 1;
651 }
652 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32, cpsr);
653 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
654 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
655
656 armv4_5->core_state = core_state;
657 armv4_5->core_mode = core_mode;
658
659 return retval;
660 }
661
662 int armv4_5_init_arch_info(target_t *target, armv4_5_common_t *armv4_5)
663 {
664 target->arch_info = armv4_5;
665
666 armv4_5->common_magic = ARMV4_5_COMMON_MAGIC;
667 armv4_5->core_state = ARMV4_5_STATE_ARM;
668 armv4_5->core_mode = ARMV4_5_MODE_USR;
669
670 return ERROR_OK;
671 }

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)