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

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)