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

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)