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

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)