Commit 06c949e62a098f97bd68a7382eb1953898a11e09
1 parent
0240ded8
Implement Arm BKPT instruction.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1740 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
39 additions
and
5 deletions
linux-user/main.c
| @@ -358,14 +358,27 @@ void cpu_loop(CPUARMState *env) | @@ -358,14 +358,27 @@ void cpu_loop(CPUARMState *env) | ||
| 358 | } | 358 | } |
| 359 | break; | 359 | break; |
| 360 | case EXCP_SWI: | 360 | case EXCP_SWI: |
| 361 | + case EXCP_BKPT: | ||
| 361 | { | 362 | { |
| 362 | /* system call */ | 363 | /* system call */ |
| 363 | - if (env->thumb) { | ||
| 364 | - insn = lduw((void *)(env->regs[15] - 2)); | ||
| 365 | - n = insn & 0xff; | 364 | + if (trapnr == EXCP_BKPT) { |
| 365 | + if (env->thumb) { | ||
| 366 | + insn = lduw((void *)(env->regs[15])); | ||
| 367 | + n = insn & 0xff; | ||
| 368 | + env->regs[15] += 2; | ||
| 369 | + } else { | ||
| 370 | + insn = ldl((void *)(env->regs[15])); | ||
| 371 | + n = (insn & 0xf) | ((insn >> 4) & 0xff0); | ||
| 372 | + env->regs[15] += 4; | ||
| 373 | + } | ||
| 366 | } else { | 374 | } else { |
| 367 | - insn = ldl((void *)(env->regs[15] - 4)); | ||
| 368 | - n = insn & 0xffffff; | 375 | + if (env->thumb) { |
| 376 | + insn = lduw((void *)(env->regs[15] - 2)); | ||
| 377 | + n = insn & 0xff; | ||
| 378 | + } else { | ||
| 379 | + insn = ldl((void *)(env->regs[15] - 4)); | ||
| 380 | + n = insn & 0xffffff; | ||
| 381 | + } | ||
| 369 | } | 382 | } |
| 370 | 383 | ||
| 371 | if (n == ARM_NR_cacheflush) { | 384 | if (n == ARM_NR_cacheflush) { |
target-arm/cpu.h
| @@ -34,6 +34,7 @@ | @@ -34,6 +34,7 @@ | ||
| 34 | #define EXCP_DATA_ABORT 4 | 34 | #define EXCP_DATA_ABORT 4 |
| 35 | #define EXCP_IRQ 5 | 35 | #define EXCP_IRQ 5 |
| 36 | #define EXCP_FIQ 6 | 36 | #define EXCP_FIQ 6 |
| 37 | +#define EXCP_BKPT 7 | ||
| 37 | 38 | ||
| 38 | /* We currently assume float and double are IEEE single and double | 39 | /* We currently assume float and double are IEEE single and double |
| 39 | precision respectively. | 40 | precision respectively. |
target-arm/helper.c
| @@ -127,6 +127,7 @@ void do_interrupt(CPUARMState *env) | @@ -127,6 +127,7 @@ void do_interrupt(CPUARMState *env) | ||
| 127 | offset = 0; | 127 | offset = 0; |
| 128 | break; | 128 | break; |
| 129 | case EXCP_PREFETCH_ABORT: | 129 | case EXCP_PREFETCH_ABORT: |
| 130 | + case EXCP_BKPT: | ||
| 130 | new_mode = ARM_CPU_MODE_ABT; | 131 | new_mode = ARM_CPU_MODE_ABT; |
| 131 | addr = 0x0c; | 132 | addr = 0x0c; |
| 132 | mask = CPSR_A | CPSR_I; | 133 | mask = CPSR_A | CPSR_I; |
target-arm/op.c
| @@ -885,6 +885,12 @@ void OPPROTO op_wfi(void) | @@ -885,6 +885,12 @@ void OPPROTO op_wfi(void) | ||
| 885 | cpu_loop_exit(); | 885 | cpu_loop_exit(); |
| 886 | } | 886 | } |
| 887 | 887 | ||
| 888 | +void OPPROTO op_bkpt(void) | ||
| 889 | +{ | ||
| 890 | + env->exception_index = EXCP_BKPT; | ||
| 891 | + cpu_loop_exit(); | ||
| 892 | +} | ||
| 893 | + | ||
| 888 | /* VFP support. We follow the convention used for VFP instrunctions: | 894 | /* VFP support. We follow the convention used for VFP instrunctions: |
| 889 | Single precition routines have a "s" suffix, double precision a | 895 | Single precition routines have a "s" suffix, double precision a |
| 890 | "d" suffix. */ | 896 | "d" suffix. */ |
target-arm/translate.c
| @@ -1217,6 +1217,12 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | @@ -1217,6 +1217,12 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | ||
| 1217 | gen_op_addl_T0_T1_saturate(); | 1217 | gen_op_addl_T0_T1_saturate(); |
| 1218 | gen_movl_reg_T0(s, rd); | 1218 | gen_movl_reg_T0(s, rd); |
| 1219 | break; | 1219 | break; |
| 1220 | + case 7: /* bkpt */ | ||
| 1221 | + gen_op_movl_T0_im((long)s->pc - 4); | ||
| 1222 | + gen_op_movl_reg_TN[0][15](); | ||
| 1223 | + gen_op_bkpt(); | ||
| 1224 | + s->is_jmp = DISAS_JUMP; | ||
| 1225 | + break; | ||
| 1220 | case 0x8: /* signed multiply */ | 1226 | case 0x8: /* signed multiply */ |
| 1221 | case 0xa: | 1227 | case 0xa: |
| 1222 | case 0xc: | 1228 | case 0xc: |
| @@ -2183,6 +2189,13 @@ static void disas_thumb_insn(DisasContext *s) | @@ -2183,6 +2189,13 @@ static void disas_thumb_insn(DisasContext *s) | ||
| 2183 | gen_bx(s); | 2189 | gen_bx(s); |
| 2184 | break; | 2190 | break; |
| 2185 | 2191 | ||
| 2192 | + case 0xe: /* bkpt */ | ||
| 2193 | + gen_op_movl_T0_im((long)s->pc - 2); | ||
| 2194 | + gen_op_movl_reg_TN[0][15](); | ||
| 2195 | + gen_op_bkpt(); | ||
| 2196 | + s->is_jmp = DISAS_JUMP; | ||
| 2197 | + break; | ||
| 2198 | + | ||
| 2186 | default: | 2199 | default: |
| 2187 | goto undef; | 2200 | goto undef; |
| 2188 | } | 2201 | } |