X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Ftarget%2Farm_simulator.c;h=b21ea4a8865cf5b15c210e5a4f03141dd481c2bb;hb=00fd07336e2bf99ad630c6c3a7a337b5f37df638;hp=40ca35671d4ac164cef86bf06d4565aad4073575;hpb=d47e1b8f362379d8a2307f49e2b42115a3f40524;p=openocd diff --git a/src/target/arm_simulator.c b/src/target/arm_simulator.c index 40ca3567..b21ea4a8 100644 --- a/src/target/arm_simulator.c +++ b/src/target/arm_simulator.c @@ -2,6 +2,9 @@ * Copyright (C) 2006 by Dominic Rath * * Dominic.Rath@gmx.de * * * + * Copyright (C) 2008 by Hongtao Zheng * + * hontor@126.com * + * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * @@ -272,14 +275,21 @@ int arm_simulate_step(target_t *target, u32 *dry_run_pc) u32 current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32); arm_instruction_t instruction; int instruction_size; + int retval = ERROR_OK; if (armv4_5->core_state == ARMV4_5_STATE_ARM) { u32 opcode; /* get current instruction, and identify it */ - target_read_u32(target, current_pc, &opcode); - arm_evaluate_opcode(opcode, current_pc, &instruction); + if((retval = target_read_u32(target, current_pc, &opcode)) != ERROR_OK) + { + return retval; + } + if((retval = arm_evaluate_opcode(opcode, current_pc, &instruction)) != ERROR_OK) + { + return retval; + } instruction_size = 4; /* check condition code (for all instructions) */ @@ -301,8 +311,14 @@ int arm_simulate_step(target_t *target, u32 *dry_run_pc) { u16 opcode; - target_read_u16(target, current_pc, &opcode); - thumb_evaluate_opcode(opcode, current_pc, &instruction); + if((retval = target_read_u16(target, current_pc, &opcode)) != ERROR_OK) + { + return retval; + } + if((retval = thumb_evaluate_opcode(opcode, current_pc, &instruction)) != ERROR_OK) + { + return retval; + } instruction_size = 2; /* check condition code (only for branch instructions) */ @@ -336,6 +352,10 @@ int arm_simulate_step(target_t *target, u32 *dry_run_pc) else { target = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.b_bl_bx_blx.reg_operand).value, 0, 32); + if(instruction.info.b_bl_bx_blx.reg_operand == 15) + { + target += 2 * instruction_size; + } } if (dry_run_pc) @@ -395,7 +415,12 @@ int arm_simulate_step(target_t *target, u32 *dry_run_pc) u8 carry_out; Rd = 0x0; - Rn = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.data_proc.Rn).value, 0, 32); + /* ARM_MOV and ARM_MVN does not use Rn */ + if ((instruction.type != ARM_MOV) && (instruction.type != ARM_MVN)) + Rn = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.data_proc.Rn).value, 0, 32); + else + Rn = 0; + shifter_operand = arm_shifter_operand(armv4_5, instruction.info.data_proc.variant, instruction.info.data_proc.shifter_operand, &carry_out); /* adjust Rn in case the PC is being read */ @@ -426,6 +451,8 @@ int arm_simulate_step(target_t *target, u32 *dry_run_pc) Rd = shifter_operand; else if (instruction.type == ARM_MVN) Rd = ~shifter_operand; + else + LOG_WARNING("unhandled instruction type"); if (dry_run_pc) { @@ -520,7 +547,13 @@ int arm_simulate_step(target_t *target, u32 *dry_run_pc) load_address = Rn; } - target_read_u32(target, load_address, &load_value); + if((!dry_run_pc) || (instruction.info.load_store.Rd == 15)) + { + if((retval = target_read_u32(target, load_address, &load_value)) != ERROR_OK) + { + return retval; + } + } if (dry_run_pc) { @@ -583,7 +616,10 @@ int arm_simulate_step(target_t *target, u32 *dry_run_pc) { if (instruction.info.load_store_multiple.register_list & (1 << i)) { - target_read_u32(target, Rn, &load_values[i]); + if((!dry_run_pc) || (i == 15)) + { + target_read_u32(target, Rn, &load_values[i]); + } Rn += 4; } }