Commit ea4e754f5a3c44d82ae7a09daad97e67c4b956a0
1 parent
cae41b10
PPC Breakpoints for gdb-stub (Jason Wessel)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1933 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
26 additions
and
2 deletions
target-ppc/op.c
| @@ -204,6 +204,11 @@ PPC_OP(update_nip) | @@ -204,6 +204,11 @@ PPC_OP(update_nip) | ||
| 204 | env->nip = PARAM(1); | 204 | env->nip = PARAM(1); |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | +PPC_OP(debug) | ||
| 208 | +{ | ||
| 209 | + do_raise_exception(EXCP_DEBUG); | ||
| 210 | +} | ||
| 211 | + | ||
| 207 | /* Segment registers load and store with immediate index */ | 212 | /* Segment registers load and store with immediate index */ |
| 208 | PPC_OP(load_srin) | 213 | PPC_OP(load_srin) |
| 209 | { | 214 | { |
target-ppc/translate.c
| @@ -148,6 +148,7 @@ typedef struct DisasContext { | @@ -148,6 +148,7 @@ typedef struct DisasContext { | ||
| 148 | #endif | 148 | #endif |
| 149 | int fpu_enabled; | 149 | int fpu_enabled; |
| 150 | ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */ | 150 | ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */ |
| 151 | + int singlestep_enabled; | ||
| 151 | } DisasContext; | 152 | } DisasContext; |
| 152 | 153 | ||
| 153 | struct opc_handler_t { | 154 | struct opc_handler_t { |
| @@ -1738,10 +1739,14 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) | @@ -1738,10 +1739,14 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) | ||
| 1738 | gen_op_set_T1(dest); | 1739 | gen_op_set_T1(dest); |
| 1739 | gen_op_b_T1(); | 1740 | gen_op_b_T1(); |
| 1740 | gen_op_set_T0((long)tb + n); | 1741 | gen_op_set_T0((long)tb + n); |
| 1742 | + if (ctx->singlestep_enabled) | ||
| 1743 | + gen_op_debug(); | ||
| 1741 | gen_op_exit_tb(); | 1744 | gen_op_exit_tb(); |
| 1742 | } else { | 1745 | } else { |
| 1743 | gen_op_set_T1(dest); | 1746 | gen_op_set_T1(dest); |
| 1744 | gen_op_b_T1(); | 1747 | gen_op_b_T1(); |
| 1748 | + if (ctx->singlestep_enabled) | ||
| 1749 | + gen_op_debug(); | ||
| 1745 | gen_op_set_T0(0); | 1750 | gen_op_set_T0(0); |
| 1746 | gen_op_exit_tb(); | 1751 | gen_op_exit_tb(); |
| 1747 | } | 1752 | } |
| @@ -2520,12 +2525,22 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | @@ -2520,12 +2525,22 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | ||
| 2520 | ctx.mem_idx = ((1 - msr_pr) << 1) | msr_le; | 2525 | ctx.mem_idx = ((1 - msr_pr) << 1) | msr_le; |
| 2521 | #endif | 2526 | #endif |
| 2522 | ctx.fpu_enabled = msr_fp; | 2527 | ctx.fpu_enabled = msr_fp; |
| 2528 | + ctx.singlestep_enabled = env->singlestep_enabled; | ||
| 2523 | #if defined (DO_SINGLE_STEP) && 0 | 2529 | #if defined (DO_SINGLE_STEP) && 0 |
| 2524 | /* Single step trace mode */ | 2530 | /* Single step trace mode */ |
| 2525 | msr_se = 1; | 2531 | msr_se = 1; |
| 2526 | #endif | 2532 | #endif |
| 2527 | /* Set env in case of segfault during code fetch */ | 2533 | /* Set env in case of segfault during code fetch */ |
| 2528 | while (ctx.exception == EXCP_NONE && gen_opc_ptr < gen_opc_end) { | 2534 | while (ctx.exception == EXCP_NONE && gen_opc_ptr < gen_opc_end) { |
| 2535 | + if (env->nb_breakpoints > 0) { | ||
| 2536 | + for(j = 0; j < env->nb_breakpoints; j++) { | ||
| 2537 | + if (env->breakpoints[j] == ctx.nip) { | ||
| 2538 | + gen_op_update_nip(ctx.nip); | ||
| 2539 | + gen_op_debug(); | ||
| 2540 | + break; | ||
| 2541 | + } | ||
| 2542 | + } | ||
| 2543 | + } | ||
| 2529 | if (search_pc) { | 2544 | if (search_pc) { |
| 2530 | j = gen_opc_ptr - gen_opc_buf; | 2545 | j = gen_opc_ptr - gen_opc_buf; |
| 2531 | if (lj < j) { | 2546 | if (lj < j) { |
| @@ -2616,8 +2631,12 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | @@ -2616,8 +2631,12 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | ||
| 2616 | ctx.exception != EXCP_TRAP)) { | 2631 | ctx.exception != EXCP_TRAP)) { |
| 2617 | RET_EXCP(ctxp, EXCP_TRACE, 0); | 2632 | RET_EXCP(ctxp, EXCP_TRACE, 0); |
| 2618 | } | 2633 | } |
| 2619 | - /* if we reach a page boundary, stop generation */ | ||
| 2620 | - if ((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) { | 2634 | + |
| 2635 | + /* if we reach a page boundary or are single stepping, stop | ||
| 2636 | + * generation | ||
| 2637 | + */ | ||
| 2638 | + if (((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) || | ||
| 2639 | + (env->singlestep_enabled)) { | ||
| 2621 | break; | 2640 | break; |
| 2622 | } | 2641 | } |
| 2623 | #if defined (DO_SINGLE_STEP) | 2642 | #if defined (DO_SINGLE_STEP) |