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

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)