Cleanup: nuke trailling whitespaces
[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 if ((retval = target_read_u16(target, current_pc, &opcode)) != ERROR_OK)
313 {
314 return retval;
315 }
316 if ((retval = thumb_evaluate_opcode(opcode, current_pc, &instruction)) != ERROR_OK)
317 {
318 return retval;
319 }
320 instruction_size = 2;
321
322 /* check condition code (only for branch instructions) */
323 if ((!thumb_pass_branch_condition(sim->get_cpsr(sim, 0, 32), opcode)) &&
324 (instruction.type == ARM_B))
325 {
326 if (dry_run_pc)
327 {
328 *dry_run_pc = current_pc + instruction_size;
329 }
330 else
331 {
332 sim->set_reg(sim, 15, current_pc + instruction_size);
333 }
334
335 return ERROR_OK;
336 }
337 }
338
339 /* examine instruction type */
340
341 /* branch instructions */
342 if ((instruction.type >= ARM_B) && (instruction.type <= ARM_BLX))
343 {
344 uint32_t target;
345
346 if (instruction.info.b_bl_bx_blx.reg_operand == -1)
347 {
348 target = instruction.info.b_bl_bx_blx.target_address;
349 }
350 else
351 {
352 target = sim->get_reg_mode(sim, instruction.info.b_bl_bx_blx.reg_operand);
353 if (instruction.info.b_bl_bx_blx.reg_operand == 15)
354 {
355 target += 2 * instruction_size;
356 }
357 }
358
359 if (dry_run_pc)
360 {
361 *dry_run_pc = target;
362 return ERROR_OK;
363 }
364 else
365 {
366 if (instruction.type == ARM_B)
367 {
368 sim->set_reg(sim, 15, target);
369 }
370 else if (instruction.type == ARM_BL)
371 {
372 uint32_t old_pc = sim->get_reg(sim, 15);
373 sim->set_reg_mode(sim, 14, old_pc + 4);
374 sim->set_reg(sim, 15, target);
375 }
376 else if (instruction.type == ARM_BX)
377 {
378 if (target & 0x1)
379 {
380 sim->set_state(sim, ARMV4_5_STATE_THUMB);
381 }
382 else
383 {
384 sim->set_state(sim, ARMV4_5_STATE_ARM);
385 }
386 sim->set_reg(sim, 15, target & 0xfffffffe);
387 }
388 else if (instruction.type == ARM_BLX)
389 {
390 uint32_t old_pc = sim->get_reg(sim, 15);
391 sim->set_reg_mode(sim, 14, old_pc + 4);
392
393 if (target & 0x1)
394 {
395 sim->set_state(sim, ARMV4_5_STATE_THUMB);
396 }
397 else
398 {
399 sim->set_state(sim, ARMV4_5_STATE_ARM);
400 }
401 sim->set_reg(sim, 15, target & 0xfffffffe);
402 }
403
404 return ERROR_OK;
405 }
406 }
407 /* data processing instructions, except compare instructions (CMP, CMN, TST, TEQ) */
408 else if (((instruction.type >= ARM_AND) && (instruction.type <= ARM_RSC))
409 || ((instruction.type >= ARM_ORR) && (instruction.type <= ARM_MVN)))
410 {
411 uint32_t Rd, Rn, shifter_operand;
412 uint8_t C = sim->get_cpsr(sim, 29, 1);
413 uint8_t carry_out;
414
415 Rd = 0x0;
416 /* ARM_MOV and ARM_MVN does not use Rn */
417 if ((instruction.type != ARM_MOV) && (instruction.type != ARM_MVN))
418 Rn = sim->get_reg_mode(sim, instruction.info.data_proc.Rn);
419 else
420 Rn = 0;
421
422 shifter_operand = arm_shifter_operand(sim, instruction.info.data_proc.variant, instruction.info.data_proc.shifter_operand, &carry_out);
423
424 /* adjust Rn in case the PC is being read */
425 if (instruction.info.data_proc.Rn == 15)
426 Rn += 2 * instruction_size;
427
428 if (instruction.type == ARM_AND)
429 Rd = Rn & shifter_operand;
430 else if (instruction.type == ARM_EOR)
431 Rd = Rn ^ shifter_operand;
432 else if (instruction.type == ARM_SUB)
433 Rd = Rn - shifter_operand;
434 else if (instruction.type == ARM_RSB)
435 Rd = shifter_operand - Rn;
436 else if (instruction.type == ARM_ADD)
437 Rd = Rn + shifter_operand;
438 else if (instruction.type == ARM_ADC)
439 Rd = Rn + shifter_operand + (C & 1);
440 else if (instruction.type == ARM_SBC)
441 Rd = Rn - shifter_operand - (C & 1) ? 0 : 1;
442 else if (instruction.type == ARM_RSC)
443 Rd = shifter_operand - Rn - (C & 1) ? 0 : 1;
444 else if (instruction.type == ARM_ORR)
445 Rd = Rn | shifter_operand;
446 else if (instruction.type == ARM_BIC)
447 Rd = Rn & ~(shifter_operand);
448 else if (instruction.type == ARM_MOV)
449 Rd = shifter_operand;
450 else if (instruction.type == ARM_MVN)
451 Rd = ~shifter_operand;
452 else
453 LOG_WARNING("unhandled instruction type");
454
455 if (dry_run_pc)
456 {
457 if (instruction.info.data_proc.Rd == 15)
458 {
459 *dry_run_pc = Rd;
460 return ERROR_OK;
461 }
462 else
463 {
464 *dry_run_pc = current_pc + instruction_size;
465 }
466
467 return ERROR_OK;
468 }
469 else
470 {
471 sim->set_reg_mode(sim, instruction.info.data_proc.Rd, Rd);
472 LOG_WARNING("no updating of flags yet");
473
474 if (instruction.info.data_proc.Rd == 15)
475 return ERROR_OK;
476 }
477 }
478 /* compare instructions (CMP, CMN, TST, TEQ) */
479 else if ((instruction.type >= ARM_TST) && (instruction.type <= ARM_CMN))
480 {
481 if (dry_run_pc)
482 {
483 *dry_run_pc = current_pc + instruction_size;
484 return ERROR_OK;
485 }
486 else
487 {
488 LOG_WARNING("no updating of flags yet");
489 }
490 }
491 /* load register instructions */
492 else if ((instruction.type >= ARM_LDR) && (instruction.type <= ARM_LDRSH))
493 {
494 uint32_t load_address = 0, modified_address = 0, load_value;
495 uint32_t Rn = sim->get_reg_mode(sim, instruction.info.load_store.Rn);
496
497 /* adjust Rn in case the PC is being read */
498 if (instruction.info.load_store.Rn == 15)
499 Rn += 2 * instruction_size;
500
501 if (instruction.info.load_store.offset_mode == 0)
502 {
503 if (instruction.info.load_store.U)
504 modified_address = Rn + instruction.info.load_store.offset.offset;
505 else
506 modified_address = Rn - instruction.info.load_store.offset.offset;
507 }
508 else if (instruction.info.load_store.offset_mode == 1)
509 {
510 uint32_t offset;
511 uint32_t Rm = sim->get_reg_mode(sim, instruction.info.load_store.offset.reg.Rm);
512 uint8_t shift = instruction.info.load_store.offset.reg.shift;
513 uint8_t shift_imm = instruction.info.load_store.offset.reg.shift_imm;
514 uint8_t carry = sim->get_cpsr(sim, 29, 1);
515
516 offset = arm_shift(shift, Rm, shift_imm, &carry);
517
518 if (instruction.info.load_store.U)
519 modified_address = Rn + offset;
520 else
521 modified_address = Rn - offset;
522 }
523 else
524 {
525 LOG_ERROR("BUG: offset_mode neither 0 (offset) nor 1 (scaled register)");
526 }
527
528 if (instruction.info.load_store.index_mode == 0)
529 {
530 /* offset mode
531 * we load from the modified address, but don't change the base address register */
532 load_address = modified_address;
533 modified_address = Rn;
534 }
535 else if (instruction.info.load_store.index_mode == 1)
536 {
537 /* pre-indexed mode
538 * we load from the modified address, and write it back to the base address register */
539 load_address = modified_address;
540 }
541 else if (instruction.info.load_store.index_mode == 2)
542 {
543 /* post-indexed mode
544 * we load from the unmodified address, and write the modified address back */
545 load_address = Rn;
546 }
547
548 if ((!dry_run_pc) || (instruction.info.load_store.Rd == 15))
549 {
550 if ((retval = target_read_u32(target, load_address, &load_value)) != ERROR_OK)
551 {
552 return retval;
553 }
554 }
555
556 if (dry_run_pc)
557 {
558 if (instruction.info.load_store.Rd == 15)
559 {
560 *dry_run_pc = load_value;
561 return ERROR_OK;
562 }
563 else
564 {
565 *dry_run_pc = current_pc + instruction_size;
566 }
567
568 return ERROR_OK;
569 }
570 else
571 {
572 if ((instruction.info.load_store.index_mode == 1) ||
573 (instruction.info.load_store.index_mode == 2))
574 {
575 sim->set_reg_mode(sim, instruction.info.load_store.Rn, modified_address);
576 }
577 sim->set_reg_mode(sim, instruction.info.load_store.Rd, load_value);
578
579 if (instruction.info.load_store.Rd == 15)
580 return ERROR_OK;
581 }
582 }
583 /* load multiple instruction */
584 else if (instruction.type == ARM_LDM)
585 {
586 int i;
587 uint32_t Rn = sim->get_reg_mode(sim, instruction.info.load_store_multiple.Rn);
588 uint32_t load_values[16];
589 int bits_set = 0;
590
591 for (i = 0; i < 16; i++)
592 {
593 if (instruction.info.load_store_multiple.register_list & (1 << i))
594 bits_set++;
595 }
596
597 switch (instruction.info.load_store_multiple.addressing_mode)
598 {
599 case 0: /* Increment after */
600 Rn = Rn;
601 break;
602 case 1: /* Increment before */
603 Rn = Rn + 4;
604 break;
605 case 2: /* Decrement after */
606 Rn = Rn - (bits_set * 4) + 4;
607 break;
608 case 3: /* Decrement before */
609 Rn = Rn - (bits_set * 4);
610 break;
611 }
612
613 for (i = 0; i < 16; i++)
614 {
615 if (instruction.info.load_store_multiple.register_list & (1 << i))
616 {
617 if ((!dry_run_pc) || (i == 15))
618 {
619 target_read_u32(target, Rn, &load_values[i]);
620 }
621 Rn += 4;
622 }
623 }
624
625 if (dry_run_pc)
626 {
627 if (instruction.info.load_store_multiple.register_list & 0x8000)
628 {
629 *dry_run_pc = load_values[15];
630 return ERROR_OK;
631 }
632 }
633 else
634 {
635 enum armv4_5_mode mode = sim->get_mode(sim);
636 int update_cpsr = 0;
637
638 if (instruction.info.load_store_multiple.S)
639 {
640 if (instruction.info.load_store_multiple.register_list & 0x8000)
641 update_cpsr = 1;
642 else
643 mode = ARMV4_5_MODE_USR;
644 }
645
646 for (i = 0; i < 16; i++)
647 {
648 if (instruction.info.load_store_multiple.register_list & (1 << i))
649 {
650 sim->set_reg_mode(sim, i, load_values[i]);
651 }
652 }
653
654 if (update_cpsr)
655 {
656 uint32_t spsr = sim->get_reg_mode(sim, 16);
657 sim->set_reg(sim, ARMV4_5_CPSR, spsr);
658 }
659
660 /* base register writeback */
661 if (instruction.info.load_store_multiple.W)
662 sim->set_reg_mode(sim, instruction.info.load_store_multiple.Rn, Rn);
663
664 if (instruction.info.load_store_multiple.register_list & 0x8000)
665 return ERROR_OK;
666 }
667 }
668 /* store multiple instruction */
669 else if (instruction.type == ARM_STM)
670 {
671 int i;
672
673 if (dry_run_pc)
674 {
675 /* STM wont affect PC (advance by instruction size */
676 }
677 else
678 {
679 uint32_t Rn = sim->get_reg_mode(sim, instruction.info.load_store_multiple.Rn);
680 int bits_set = 0;
681 enum armv4_5_mode mode = sim->get_mode(sim);
682
683 for (i = 0; i < 16; i++)
684 {
685 if (instruction.info.load_store_multiple.register_list & (1 << i))
686 bits_set++;
687 }
688
689 if (instruction.info.load_store_multiple.S)
690 {
691 mode = ARMV4_5_MODE_USR;
692 }
693
694 switch (instruction.info.load_store_multiple.addressing_mode)
695 {
696 case 0: /* Increment after */
697 Rn = Rn;
698 break;
699 case 1: /* Increment before */
700 Rn = Rn + 4;
701 break;
702 case 2: /* Decrement after */
703 Rn = Rn - (bits_set * 4) + 4;
704 break;
705 case 3: /* Decrement before */
706 Rn = Rn - (bits_set * 4);
707 break;
708 }
709
710 for (i = 0; i < 16; i++)
711 {
712 if (instruction.info.load_store_multiple.register_list & (1 << i))
713 {
714 target_write_u32(target, Rn, sim->get_reg_mode(sim, i));
715 Rn += 4;
716 }
717 }
718
719 /* base register writeback */
720 if (instruction.info.load_store_multiple.W)
721 sim->set_reg_mode(sim, instruction.info.load_store_multiple.Rn, Rn);
722
723 }
724 }
725 else if (!dry_run_pc)
726 {
727 /* the instruction wasn't handled, but we're supposed to simulate it
728 */
729 LOG_ERROR("Unimplemented instruction, could not simulate it.");
730 return ERROR_FAIL;
731 }
732
733 if (dry_run_pc)
734 {
735 *dry_run_pc = current_pc + instruction_size;
736 return ERROR_OK;
737 }
738 else
739 {
740 sim->set_reg(sim, 15, current_pc + instruction_size);
741 return ERROR_OK;
742 }
743
744 }
745
746 static uint32_t armv4_5_get_reg(struct arm_sim_interface *sim, int reg)
747 {
748 armv4_5_common_t *armv4_5 = (armv4_5_common_t *)sim->user_data;
749
750 return buf_get_u32(armv4_5->core_cache->reg_list[reg].value, 0, 32);
751 }
752
753 static void armv4_5_set_reg(struct arm_sim_interface *sim, int reg, uint32_t value)
754 {
755 armv4_5_common_t *armv4_5 = (armv4_5_common_t *)sim->user_data;
756
757 buf_set_u32(armv4_5->core_cache->reg_list[reg].value, 0, 32, value);
758 }
759
760 static uint32_t armv4_5_get_reg_mode(struct arm_sim_interface *sim, int reg)
761 {
762 armv4_5_common_t *armv4_5 = (armv4_5_common_t *)sim->user_data;
763
764 return buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, reg).value, 0, 32);
765 }
766
767 static void armv4_5_set_reg_mode(struct arm_sim_interface *sim, int reg, uint32_t value)
768 {
769 armv4_5_common_t *armv4_5 = (armv4_5_common_t *)sim->user_data;
770
771 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, reg).value, 0, 32, value);
772 }
773
774 static uint32_t armv4_5_get_cpsr(struct arm_sim_interface *sim, int pos, int bits)
775 {
776 armv4_5_common_t *armv4_5 = (armv4_5_common_t *)sim->user_data;
777
778 return buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, pos, bits);
779 }
780
781 static enum armv4_5_state armv4_5_get_state(struct arm_sim_interface *sim)
782 {
783 armv4_5_common_t *armv4_5 = (armv4_5_common_t *)sim->user_data;
784
785 return armv4_5->core_state;
786 }
787
788 static void armv4_5_set_state(struct arm_sim_interface *sim, enum armv4_5_state mode)
789 {
790 armv4_5_common_t *armv4_5 = (armv4_5_common_t *)sim->user_data;
791
792 armv4_5->core_state = mode;
793 }
794
795
796 static enum armv4_5_mode armv4_5_get_mode(struct arm_sim_interface *sim)
797 {
798 armv4_5_common_t *armv4_5 = (armv4_5_common_t *)sim->user_data;
799
800 return armv4_5->core_mode;
801 }
802
803
804
805 int arm_simulate_step(target_t *target, uint32_t *dry_run_pc)
806 {
807 armv4_5_common_t *armv4_5 = target->arch_info;
808
809 struct arm_sim_interface sim;
810
811 sim.user_data=armv4_5;
812 sim.get_reg=&armv4_5_get_reg;
813 sim.set_reg=&armv4_5_set_reg;
814 sim.get_reg_mode=&armv4_5_get_reg_mode;
815 sim.set_reg_mode=&armv4_5_set_reg_mode;
816 sim.get_cpsr=&armv4_5_get_cpsr;
817 sim.get_mode=&armv4_5_get_mode;
818 sim.get_state=&armv4_5_get_state;
819 sim.set_state=&armv4_5_set_state;
820
821 return arm_simulate_step_core(target, dry_run_pc, &sim);
822
823 }
824

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)