jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / target / arm_simulator.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Copyright (C) 2006 by Dominic Rath *
5 * Dominic.Rath@gmx.de *
6 * *
7 * Copyright (C) 2008 by Hongtao Zheng *
8 * hontor@126.com *
9 ***************************************************************************/
10
11 #ifdef HAVE_CONFIG_H
12 #include "config.h"
13 #endif
14
15 #include "arm.h"
16 #include "armv4_5.h"
17 #include "arm_disassembler.h"
18 #include "arm_simulator.h"
19 #include <helper/binarybuffer.h>
20 #include "register.h"
21 #include <helper/log.h>
22
23 static uint32_t arm_shift(uint8_t shift, uint32_t rm,
24 uint32_t shift_amount, uint8_t *carry)
25 {
26 uint32_t return_value = 0;
27 shift_amount &= 0xff;
28
29 if (shift == 0x0) { /* LSL */
30 if ((shift_amount > 0) && (shift_amount <= 32)) {
31 return_value = rm << shift_amount;
32 *carry = rm >> (32 - shift_amount);
33 } else if (shift_amount > 32) {
34 return_value = 0x0;
35 *carry = 0x0;
36 } else /* (shift_amount == 0) */
37 return_value = rm;
38 } else if (shift == 0x1) { /* LSR */
39 if ((shift_amount > 0) && (shift_amount <= 32)) {
40 return_value = rm >> shift_amount;
41 *carry = (rm >> (shift_amount - 1)) & 1;
42 } else if (shift_amount > 32) {
43 return_value = 0x0;
44 *carry = 0x0;
45 } else /* (shift_amount == 0) */
46 return_value = rm;
47 } else if (shift == 0x2) { /* ASR */
48 if ((shift_amount > 0) && (shift_amount <= 32)) {
49 /* C right shifts of unsigned values are guaranteed to
50 * be logical (shift in zeroes); simulate an arithmetic
51 * shift (shift in signed-bit) by adding the sign bit
52 * manually
53 */
54 return_value = rm >> shift_amount;
55 if (rm & 0x80000000)
56 return_value |= 0xffffffff << (32 - shift_amount);
57 } else if (shift_amount > 32) {
58 if (rm & 0x80000000) {
59 return_value = 0xffffffff;
60 *carry = 0x1;
61 } else {
62 return_value = 0x0;
63 *carry = 0x0;
64 }
65 } else /* (shift_amount == 0) */
66 return_value = rm;
67 } else if (shift == 0x3) { /* ROR */
68 if (shift_amount == 0)
69 return_value = rm;
70 else {
71 shift_amount = shift_amount % 32;
72 return_value = (rm >> shift_amount) | (rm << (32 - shift_amount));
73 *carry = (return_value >> 31) & 0x1;
74 }
75 } else if (shift == 0x4) { /* RRX */
76 return_value = rm >> 1;
77 if (*carry)
78 rm |= 0x80000000;
79 *carry = rm & 0x1;
80 }
81
82 return return_value;
83 }
84
85
86 static uint32_t arm_shifter_operand(struct arm_sim_interface *sim,
87 int variant, union arm_shifter_operand shifter_operand,
88 uint8_t *shifter_carry_out)
89 {
90 uint32_t return_value;
91 int instruction_size;
92
93 if (sim->get_state(sim) == ARM_STATE_ARM)
94 instruction_size = 4;
95 else
96 instruction_size = 2;
97
98 *shifter_carry_out = sim->get_cpsr(sim, 29, 1);
99
100 if (variant == 0) /* 32-bit immediate */
101 return_value = shifter_operand.immediate.immediate;
102 else if (variant == 1) {/* immediate shift */
103 uint32_t rm = sim->get_reg_mode(sim, shifter_operand.immediate_shift.rm);
104
105 /* adjust RM in case the PC is being read */
106 if (shifter_operand.immediate_shift.rm == 15)
107 rm += 2 * instruction_size;
108
109 return_value = arm_shift(shifter_operand.immediate_shift.shift,
110 rm, shifter_operand.immediate_shift.shift_imm,
111 shifter_carry_out);
112 } else if (variant == 2) { /* register shift */
113 uint32_t rm = sim->get_reg_mode(sim, shifter_operand.register_shift.rm);
114 uint32_t rs = sim->get_reg_mode(sim, shifter_operand.register_shift.rs);
115
116 /* adjust RM in case the PC is being read */
117 if (shifter_operand.register_shift.rm == 15)
118 rm += 2 * instruction_size;
119
120 return_value = arm_shift(shifter_operand.immediate_shift.shift,
121 rm, rs, shifter_carry_out);
122 } else {
123 LOG_ERROR("BUG: shifter_operand.variant not 0, 1 or 2");
124 return_value = 0xffffffff;
125 }
126
127 return return_value;
128 }
129
130 static int pass_condition(uint32_t cpsr, uint32_t opcode)
131 {
132 switch ((opcode & 0xf0000000) >> 28) {
133 case 0x0: /* EQ */
134 if (cpsr & 0x40000000)
135 return 1;
136 else
137 return 0;
138 case 0x1: /* NE */
139 if (!(cpsr & 0x40000000))
140 return 1;
141 else
142 return 0;
143 case 0x2: /* CS */
144 if (cpsr & 0x20000000)
145 return 1;
146 else
147 return 0;
148 case 0x3: /* CC */
149 if (!(cpsr & 0x20000000))
150 return 1;
151 else
152 return 0;
153 case 0x4: /* MI */
154 if (cpsr & 0x80000000)
155 return 1;
156 else
157 return 0;
158 case 0x5: /* PL */
159 if (!(cpsr & 0x80000000))
160 return 1;
161 else
162 return 0;
163 case 0x6: /* VS */
164 if (cpsr & 0x10000000)
165 return 1;
166 else
167 return 0;
168 case 0x7: /* VC */
169 if (!(cpsr & 0x10000000))
170 return 1;
171 else
172 return 0;
173 case 0x8: /* HI */
174 if ((cpsr & 0x20000000) && !(cpsr & 0x40000000))
175 return 1;
176 else
177 return 0;
178 case 0x9: /* LS */
179 if (!(cpsr & 0x20000000) || (cpsr & 0x40000000))
180 return 1;
181 else
182 return 0;
183 case 0xa: /* GE */
184 if (((cpsr & 0x80000000) && (cpsr & 0x10000000))
185 || (!(cpsr & 0x80000000) && !(cpsr & 0x10000000)))
186 return 1;
187 else
188 return 0;
189 case 0xb: /* LT */
190 if (((cpsr & 0x80000000) && !(cpsr & 0x10000000))
191 || (!(cpsr & 0x80000000) && (cpsr & 0x10000000)))
192 return 1;
193 else
194 return 0;
195 case 0xc: /* GT */
196 if (!(cpsr & 0x40000000) &&
197 (((cpsr & 0x80000000) && (cpsr & 0x10000000))
198 || (!(cpsr & 0x80000000) && !(cpsr & 0x10000000))))
199 return 1;
200 else
201 return 0;
202 case 0xd: /* LE */
203 if ((cpsr & 0x40000000) ||
204 ((cpsr & 0x80000000) && !(cpsr & 0x10000000))
205 || (!(cpsr & 0x80000000) && (cpsr & 0x10000000)))
206 return 1;
207 else
208 return 0;
209 case 0xe:
210 case 0xf:
211 return 1;
212
213 }
214
215 LOG_ERROR("BUG: should never get here");
216 return 0;
217 }
218
219 static int thumb_pass_branch_condition(uint32_t cpsr, uint16_t opcode)
220 {
221 return pass_condition(cpsr, (opcode & 0x0f00) << 20);
222 }
223
224 /* simulate a single step (if possible)
225 * if the dry_run_pc argument is provided, no state is changed,
226 * but the new pc is stored in the variable pointed at by the argument
227 */
228 static int arm_simulate_step_core(struct target *target,
229 uint32_t *dry_run_pc, struct arm_sim_interface *sim)
230 {
231 uint32_t current_pc = sim->get_reg(sim, 15);
232 struct arm_instruction instruction;
233 int instruction_size;
234 int retval = ERROR_OK;
235
236 if (sim->get_state(sim) == ARM_STATE_ARM) {
237 uint32_t opcode;
238
239 /* get current instruction, and identify it */
240 retval = target_read_u32(target, current_pc, &opcode);
241 if (retval != ERROR_OK)
242 return retval;
243 retval = arm_evaluate_opcode(opcode, current_pc, &instruction);
244 if (retval != ERROR_OK)
245 return retval;
246 instruction_size = 4;
247
248 /* check condition code (for all instructions) */
249 if (!pass_condition(sim->get_cpsr(sim, 0, 32), opcode)) {
250 if (dry_run_pc)
251 *dry_run_pc = current_pc + instruction_size;
252 else
253 sim->set_reg(sim, 15, current_pc + instruction_size);
254
255 return ERROR_OK;
256 }
257 } else {
258 uint16_t opcode;
259
260 retval = target_read_u16(target, current_pc, &opcode);
261 if (retval != ERROR_OK)
262 return retval;
263 retval = thumb_evaluate_opcode(opcode, current_pc, &instruction);
264 if (retval != ERROR_OK)
265 return retval;
266 instruction_size = 2;
267
268 /* check condition code (only for branch (1) instructions) */
269 if ((opcode & 0xf000) == 0xd000
270 && !thumb_pass_branch_condition(
271 sim->get_cpsr(sim, 0, 32), opcode)) {
272 if (dry_run_pc)
273 *dry_run_pc = current_pc + instruction_size;
274 else
275 sim->set_reg(sim, 15, current_pc + instruction_size);
276
277 return ERROR_OK;
278 }
279
280 /* Deal with 32-bit BL/BLX */
281 if ((opcode & 0xf800) == 0xf000) {
282 uint32_t high = instruction.info.b_bl_bx_blx.target_address;
283 retval = target_read_u16(target, current_pc+2, &opcode);
284 if (retval != ERROR_OK)
285 return retval;
286 retval = thumb_evaluate_opcode(opcode, current_pc, &instruction);
287 if (retval != ERROR_OK)
288 return retval;
289 instruction.info.b_bl_bx_blx.target_address += high;
290 }
291 }
292
293 /* examine instruction type */
294
295 /* branch instructions */
296 if ((instruction.type >= ARM_B) && (instruction.type <= ARM_BLX)) {
297 uint32_t target_address;
298
299 if (instruction.info.b_bl_bx_blx.reg_operand == -1)
300 target_address = instruction.info.b_bl_bx_blx.target_address;
301 else {
302 target_address = sim->get_reg_mode(sim,
303 instruction.info.b_bl_bx_blx.reg_operand);
304 if (instruction.info.b_bl_bx_blx.reg_operand == 15)
305 target_address += 2 * instruction_size;
306 }
307
308 if (dry_run_pc) {
309 *dry_run_pc = target_address & ~1;
310 return ERROR_OK;
311 } else {
312 if (instruction.type == ARM_B)
313 sim->set_reg(sim, 15, target_address);
314 else if (instruction.type == ARM_BL) {
315 uint32_t old_pc = sim->get_reg(sim, 15);
316 int t = (sim->get_state(sim) == ARM_STATE_THUMB);
317 sim->set_reg_mode(sim, 14, old_pc + 4 + t);
318 sim->set_reg(sim, 15, target_address);
319 } else if (instruction.type == ARM_BX) {
320 if (target_address & 0x1)
321 sim->set_state(sim, ARM_STATE_THUMB);
322 else
323 sim->set_state(sim, ARM_STATE_ARM);
324 sim->set_reg(sim, 15, target_address & 0xfffffffe);
325 } else if (instruction.type == ARM_BLX) {
326 uint32_t old_pc = sim->get_reg(sim, 15);
327 int t = (sim->get_state(sim) == ARM_STATE_THUMB);
328 sim->set_reg_mode(sim, 14, old_pc + 4 + t);
329
330 if (target_address & 0x1)
331 sim->set_state(sim, ARM_STATE_THUMB);
332 else
333 sim->set_state(sim, ARM_STATE_ARM);
334 sim->set_reg(sim, 15, target_address & 0xfffffffe);
335 }
336
337 return ERROR_OK;
338 }
339 }
340 /* data processing instructions, except compare instructions (CMP, CMN, TST, TEQ) */
341 else if (((instruction.type >= ARM_AND) && (instruction.type <= ARM_RSC))
342 || ((instruction.type >= ARM_ORR) && (instruction.type <= ARM_MVN))) {
343 uint32_t rd, rn, shifter_operand;
344 uint8_t c = sim->get_cpsr(sim, 29, 1);
345 uint8_t carry_out;
346
347 rd = 0x0;
348 /* ARM_MOV and ARM_MVN does not use Rn */
349 if ((instruction.type != ARM_MOV) && (instruction.type != ARM_MVN))
350 rn = sim->get_reg_mode(sim, instruction.info.data_proc.rn);
351 else
352 rn = 0;
353
354 shifter_operand = arm_shifter_operand(sim,
355 instruction.info.data_proc.variant,
356 instruction.info.data_proc.shifter_operand,
357 &carry_out);
358
359 /* adjust Rn in case the PC is being read */
360 if (instruction.info.data_proc.rn == 15)
361 rn += 2 * instruction_size;
362
363 if (instruction.type == ARM_AND)
364 rd = rn & shifter_operand;
365 else if (instruction.type == ARM_EOR)
366 rd = rn ^ shifter_operand;
367 else if (instruction.type == ARM_SUB)
368 rd = rn - shifter_operand;
369 else if (instruction.type == ARM_RSB)
370 rd = shifter_operand - rn;
371 else if (instruction.type == ARM_ADD)
372 rd = rn + shifter_operand;
373 else if (instruction.type == ARM_ADC)
374 rd = rn + shifter_operand + (c & 1);
375 else if (instruction.type == ARM_SBC)
376 rd = rn - shifter_operand - (c & 1) ? 0 : 1;
377 else if (instruction.type == ARM_RSC)
378 rd = shifter_operand - rn - (c & 1) ? 0 : 1;
379 else if (instruction.type == ARM_ORR)
380 rd = rn | shifter_operand;
381 else if (instruction.type == ARM_BIC)
382 rd = rn & ~(shifter_operand);
383 else if (instruction.type == ARM_MOV)
384 rd = shifter_operand;
385 else if (instruction.type == ARM_MVN)
386 rd = ~shifter_operand;
387 else
388 LOG_WARNING("unhandled instruction type");
389
390 if (dry_run_pc) {
391 if (instruction.info.data_proc.rd == 15)
392 *dry_run_pc = rd & ~1;
393 else
394 *dry_run_pc = current_pc + instruction_size;
395
396 return ERROR_OK;
397 } else {
398 if (instruction.info.data_proc.rd == 15) {
399 sim->set_reg_mode(sim, 15, rd & ~1);
400 if (rd & 1)
401 sim->set_state(sim, ARM_STATE_THUMB);
402 else
403 sim->set_state(sim, ARM_STATE_ARM);
404 return ERROR_OK;
405 }
406 sim->set_reg_mode(sim, instruction.info.data_proc.rd, rd);
407 LOG_WARNING("no updating of flags yet");
408 }
409 }
410 /* compare instructions (CMP, CMN, TST, TEQ) */
411 else if ((instruction.type >= ARM_TST) && (instruction.type <= ARM_CMN)) {
412 if (dry_run_pc) {
413 *dry_run_pc = current_pc + instruction_size;
414 return ERROR_OK;
415 } else
416 LOG_WARNING("no updating of flags yet");
417 }
418 /* load register instructions */
419 else if ((instruction.type >= ARM_LDR) && (instruction.type <= ARM_LDRSH)) {
420 uint32_t load_address = 0, modified_address = 0, load_value = 0;
421 uint32_t rn = sim->get_reg_mode(sim, instruction.info.load_store.rn);
422
423 /* adjust Rn in case the PC is being read */
424 if (instruction.info.load_store.rn == 15)
425 rn += 2 * instruction_size;
426
427 if (instruction.info.load_store.offset_mode == 0) {
428 if (instruction.info.load_store.u)
429 modified_address = rn + instruction.info.load_store.offset.offset;
430 else
431 modified_address = rn - instruction.info.load_store.offset.offset;
432 } else if (instruction.info.load_store.offset_mode == 1) {
433 uint32_t offset;
434 uint32_t rm = sim->get_reg_mode(sim,
435 instruction.info.load_store.offset.reg.rm);
436 uint8_t shift = instruction.info.load_store.offset.reg.shift;
437 uint8_t shift_imm = instruction.info.load_store.offset.reg.shift_imm;
438 uint8_t carry = sim->get_cpsr(sim, 29, 1);
439
440 offset = arm_shift(shift, rm, shift_imm, &carry);
441
442 if (instruction.info.load_store.u)
443 modified_address = rn + offset;
444 else
445 modified_address = rn - offset;
446 } else
447 LOG_ERROR("BUG: offset_mode neither 0 (offset) nor 1 (scaled register)");
448
449 if (instruction.info.load_store.index_mode == 0) {
450 /* offset mode
451 * we load from the modified address, but don't change
452 * the base address register
453 */
454 load_address = modified_address;
455 modified_address = rn;
456 } else if (instruction.info.load_store.index_mode == 1) {
457 /* pre-indexed mode
458 * we load from the modified address, and write it
459 * back to the base address register
460 */
461 load_address = modified_address;
462 } else if (instruction.info.load_store.index_mode == 2) {
463 /* post-indexed mode
464 * we load from the unmodified address, and write the
465 * modified address back
466 */
467 load_address = rn;
468 }
469
470 if ((!dry_run_pc) || (instruction.info.load_store.rd == 15)) {
471 retval = target_read_u32(target, load_address, &load_value);
472 if (retval != ERROR_OK)
473 return retval;
474 }
475
476 if (dry_run_pc) {
477 if (instruction.info.load_store.rd == 15)
478 *dry_run_pc = load_value & ~1;
479 else
480 *dry_run_pc = current_pc + instruction_size;
481 return ERROR_OK;
482 } else {
483 if ((instruction.info.load_store.index_mode == 1) ||
484 (instruction.info.load_store.index_mode == 2))
485 sim->set_reg_mode(sim,
486 instruction.info.load_store.rn,
487 modified_address);
488
489 if (instruction.info.load_store.rd == 15) {
490 sim->set_reg_mode(sim, 15, load_value & ~1);
491 if (load_value & 1)
492 sim->set_state(sim, ARM_STATE_THUMB);
493 else
494 sim->set_state(sim, ARM_STATE_ARM);
495 return ERROR_OK;
496 }
497 sim->set_reg_mode(sim, instruction.info.load_store.rd, load_value);
498 }
499 }
500 /* load multiple instruction */
501 else if (instruction.type == ARM_LDM) {
502 int i;
503 uint32_t rn = sim->get_reg_mode(sim, instruction.info.load_store_multiple.rn);
504 uint32_t load_values[16];
505 int bits_set = 0;
506
507 for (i = 0; i < 16; i++) {
508 if (instruction.info.load_store_multiple.register_list & (1 << i))
509 bits_set++;
510 }
511
512 switch (instruction.info.load_store_multiple.addressing_mode) {
513 case 0: /* Increment after */
514 /* rn = rn; */
515 break;
516 case 1: /* Increment before */
517 rn = rn + 4;
518 break;
519 case 2: /* Decrement after */
520 rn = rn - (bits_set * 4) + 4;
521 break;
522 case 3: /* Decrement before */
523 rn = rn - (bits_set * 4);
524 break;
525 }
526
527 for (i = 0; i < 16; i++) {
528 if (instruction.info.load_store_multiple.register_list & (1 << i)) {
529 if ((!dry_run_pc) || (i == 15))
530 target_read_u32(target, rn, &load_values[i]);
531 rn += 4;
532 }
533 }
534
535 if (dry_run_pc) {
536 if (instruction.info.load_store_multiple.register_list & 0x8000) {
537 *dry_run_pc = load_values[15] & ~1;
538 return ERROR_OK;
539 }
540 } else {
541 int update_cpsr = 0;
542
543 if (instruction.info.load_store_multiple.s) {
544 if (instruction.info.load_store_multiple.register_list & 0x8000)
545 update_cpsr = 1;
546 }
547
548 for (i = 0; i < 16; i++) {
549 if (instruction.info.load_store_multiple.register_list & (1 << i)) {
550 if (i == 15) {
551 uint32_t val = load_values[i];
552 sim->set_reg_mode(sim, i, val & ~1);
553 if (val & 1)
554 sim->set_state(sim, ARM_STATE_THUMB);
555 else
556 sim->set_state(sim, ARM_STATE_ARM);
557 } else
558 sim->set_reg_mode(sim, i, load_values[i]);
559 }
560 }
561
562 if (update_cpsr) {
563 uint32_t spsr = sim->get_reg_mode(sim, 16);
564 sim->set_reg(sim, ARMV4_5_CPSR, spsr);
565 }
566
567 /* base register writeback */
568 if (instruction.info.load_store_multiple.w)
569 sim->set_reg_mode(sim, instruction.info.load_store_multiple.rn, rn);
570
571
572 if (instruction.info.load_store_multiple.register_list & 0x8000)
573 return ERROR_OK;
574 }
575 }
576 /* store multiple instruction */
577 else if (instruction.type == ARM_STM) {
578 int i;
579
580 if (dry_run_pc) {
581 /* STM wont affect PC (advance by instruction size */
582 } else {
583 uint32_t rn = sim->get_reg_mode(sim,
584 instruction.info.load_store_multiple.rn);
585 int bits_set = 0;
586
587 for (i = 0; i < 16; i++) {
588 if (instruction.info.load_store_multiple.register_list & (1 << i))
589 bits_set++;
590 }
591
592 switch (instruction.info.load_store_multiple.addressing_mode) {
593 case 0: /* Increment after */
594 /* rn = rn; */
595 break;
596 case 1: /* Increment before */
597 rn = rn + 4;
598 break;
599 case 2: /* Decrement after */
600 rn = rn - (bits_set * 4) + 4;
601 break;
602 case 3: /* Decrement before */
603 rn = rn - (bits_set * 4);
604 break;
605 }
606
607 for (i = 0; i < 16; i++) {
608 if (instruction.info.load_store_multiple.register_list & (1 << i)) {
609 target_write_u32(target, rn, sim->get_reg_mode(sim, i));
610 rn += 4;
611 }
612 }
613
614 /* base register writeback */
615 if (instruction.info.load_store_multiple.w)
616 sim->set_reg_mode(sim,
617 instruction.info.load_store_multiple.rn, rn);
618
619 }
620 } else if (!dry_run_pc) {
621 /* the instruction wasn't handled, but we're supposed to simulate it
622 */
623 LOG_ERROR("Unimplemented instruction, could not simulate it.");
624 return ERROR_FAIL;
625 }
626
627 if (dry_run_pc) {
628 *dry_run_pc = current_pc + instruction_size;
629 return ERROR_OK;
630 } else {
631 sim->set_reg(sim, 15, current_pc + instruction_size);
632 return ERROR_OK;
633 }
634
635 }
636
637 static uint32_t armv4_5_get_reg(struct arm_sim_interface *sim, int reg)
638 {
639 struct arm *arm = (struct arm *)sim->user_data;
640
641 return buf_get_u32(arm->core_cache->reg_list[reg].value, 0, 32);
642 }
643
644 static void armv4_5_set_reg(struct arm_sim_interface *sim, int reg, uint32_t value)
645 {
646 struct arm *arm = (struct arm *)sim->user_data;
647
648 buf_set_u32(arm->core_cache->reg_list[reg].value, 0, 32, value);
649 }
650
651 static uint32_t armv4_5_get_reg_mode(struct arm_sim_interface *sim, int reg)
652 {
653 struct arm *arm = (struct arm *)sim->user_data;
654
655 return buf_get_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache,
656 arm->core_mode, reg).value, 0, 32);
657 }
658
659 static void armv4_5_set_reg_mode(struct arm_sim_interface *sim, int reg, uint32_t value)
660 {
661 struct arm *arm = (struct arm *)sim->user_data;
662
663 buf_set_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache,
664 arm->core_mode, reg).value, 0, 32, value);
665 }
666
667 static uint32_t armv4_5_get_cpsr(struct arm_sim_interface *sim, int pos, int bits)
668 {
669 struct arm *arm = (struct arm *)sim->user_data;
670
671 return buf_get_u32(arm->cpsr->value, pos, bits);
672 }
673
674 static enum arm_state armv4_5_get_state(struct arm_sim_interface *sim)
675 {
676 struct arm *arm = (struct arm *)sim->user_data;
677
678 return arm->core_state;
679 }
680
681 static void armv4_5_set_state(struct arm_sim_interface *sim, enum arm_state mode)
682 {
683 struct arm *arm = (struct arm *)sim->user_data;
684
685 arm->core_state = mode;
686 }
687
688 static enum arm_mode armv4_5_get_mode(struct arm_sim_interface *sim)
689 {
690 struct arm *arm = (struct arm *)sim->user_data;
691
692 return arm->core_mode;
693 }
694
695 int arm_simulate_step(struct target *target, uint32_t *dry_run_pc)
696 {
697 struct arm *arm = target_to_arm(target);
698 struct arm_sim_interface sim;
699
700 sim.user_data = arm;
701 sim.get_reg = &armv4_5_get_reg;
702 sim.set_reg = &armv4_5_set_reg;
703 sim.get_reg_mode = &armv4_5_get_reg_mode;
704 sim.set_reg_mode = &armv4_5_set_reg_mode;
705 sim.get_cpsr = &armv4_5_get_cpsr;
706 sim.get_mode = &armv4_5_get_mode;
707 sim.get_state = &armv4_5_get_state;
708 sim.set_state = &armv4_5_set_state;
709
710 return arm_simulate_step_core(target, dry_run_pc, &sim);
711 }

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)