You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

835 lines
21 KiB

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