diff options
Diffstat (limited to 'target-arm')
-rw-r--r-- | target-arm/cpu.h | 7 | ||||
-rw-r--r-- | target-arm/op.c | 6 | ||||
-rw-r--r-- | target-arm/translate.c | 14 |
3 files changed, 26 insertions, 1 deletions
diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 1346175134..ef7469d0c3 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -26,6 +26,8 @@ #include "softfloat.h" +#define TARGET_HAS_ICE 1 + #define EXCP_UDEF 1 /* undefined instruction */ #define EXCP_SWI 2 /* software interrupt */ #define EXCP_PREFETCH_ABORT 3 @@ -62,6 +64,11 @@ typedef struct CPUARMState { int user_mode_only; uint32_t address; + /* ICE debug support. */ + target_ulong breakpoints[MAX_BREAKPOINTS]; + int nb_breakpoints; + int singlestep_enabled; + /* in order to avoid passing too many arguments to the memory write helpers, we store some rarely used information in the CPU context) */ diff --git a/target-arm/op.c b/target-arm/op.c index 42ee4f960a..f4cbb6e662 100644 --- a/target-arm/op.c +++ b/target-arm/op.c @@ -858,6 +858,12 @@ void OPPROTO op_undef_insn(void) cpu_loop_exit(); } +void OPPROTO op_debug(void) +{ + env->exception_index = EXCP_DEBUG; + cpu_loop_exit(); +} + /* VFP support. We follow the convention used for VFP instrunctions: Single precition routines have a "s" suffix, double precision a "d" suffix. */ diff --git a/target-arm/translate.c b/target-arm/translate.c index 39c28e754d..280b68c4cb 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -2026,6 +2026,17 @@ static inline int gen_intermediate_code_internal(CPUState *env, dc->pc = pc_start; lj = -1; do { + if (env->nb_breakpoints > 0) { + for(j = 0; j < env->nb_breakpoints; j++) { + if (env->breakpoints[j] == dc->pc) { + gen_op_movl_T0_im((long)dc->pc); + gen_op_movl_reg_TN[0][15](); + gen_op_debug(); + dc->is_jmp = DISAS_JUMP; + break; + } + } + } if (search_pc) { j = gen_opc_ptr - gen_opc_buf; if (lj < j) { @@ -2040,7 +2051,8 @@ static inline int gen_intermediate_code_internal(CPUState *env, disas_thumb_insn(dc); else disas_arm_insn(env, dc); - } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && + } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && + !env->singlestep_enabled && (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32)); switch(dc->is_jmp) { case DISAS_JUMP_NEXT: |