summaryrefslogtreecommitdiff
path: root/target-ppc
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2006-05-22 21:50:20 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2006-05-22 21:50:20 +0000
commitea4e754f5a3c44d82ae7a09daad97e67c4b956a0 (patch)
tree4e10a777f4232b248200e990e94e0a99ad20a156 /target-ppc
parentcae41b10a4c7bd76e582bd9ed7fc9480b72c9709 (diff)
downloadqemu-ea4e754f5a3c44d82ae7a09daad97e67c4b956a0.tar.gz
PPC Breakpoints for gdb-stub (Jason Wessel)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1933 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-ppc')
-rw-r--r--target-ppc/op.c5
-rw-r--r--target-ppc/translate.c23
2 files changed, 26 insertions, 2 deletions
diff --git a/target-ppc/op.c b/target-ppc/op.c
index 4b0af5587c..ca1dbc5eb4 100644
--- a/target-ppc/op.c
+++ b/target-ppc/op.c
@@ -204,6 +204,11 @@ PPC_OP(update_nip)
env->nip = PARAM(1);
}
+PPC_OP(debug)
+{
+ do_raise_exception(EXCP_DEBUG);
+}
+
/* Segment registers load and store with immediate index */
PPC_OP(load_srin)
{
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 3bc6aa376e..9eb3e6197a 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -148,6 +148,7 @@ typedef struct DisasContext {
#endif
int fpu_enabled;
ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
+ int singlestep_enabled;
} DisasContext;
struct opc_handler_t {
@@ -1738,10 +1739,14 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
gen_op_set_T1(dest);
gen_op_b_T1();
gen_op_set_T0((long)tb + n);
+ if (ctx->singlestep_enabled)
+ gen_op_debug();
gen_op_exit_tb();
} else {
gen_op_set_T1(dest);
gen_op_b_T1();
+ if (ctx->singlestep_enabled)
+ gen_op_debug();
gen_op_set_T0(0);
gen_op_exit_tb();
}
@@ -2520,12 +2525,22 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
ctx.mem_idx = ((1 - msr_pr) << 1) | msr_le;
#endif
ctx.fpu_enabled = msr_fp;
+ ctx.singlestep_enabled = env->singlestep_enabled;
#if defined (DO_SINGLE_STEP) && 0
/* Single step trace mode */
msr_se = 1;
#endif
/* Set env in case of segfault during code fetch */
while (ctx.exception == EXCP_NONE && gen_opc_ptr < gen_opc_end) {
+ if (env->nb_breakpoints > 0) {
+ for(j = 0; j < env->nb_breakpoints; j++) {
+ if (env->breakpoints[j] == ctx.nip) {
+ gen_op_update_nip(ctx.nip);
+ gen_op_debug();
+ break;
+ }
+ }
+ }
if (search_pc) {
j = gen_opc_ptr - gen_opc_buf;
if (lj < j) {
@@ -2616,8 +2631,12 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
ctx.exception != EXCP_TRAP)) {
RET_EXCP(ctxp, EXCP_TRACE, 0);
}
- /* if we reach a page boundary, stop generation */
- if ((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) {
+
+ /* if we reach a page boundary or are single stepping, stop
+ * generation
+ */
+ if (((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
+ (env->singlestep_enabled)) {
break;
}
#if defined (DO_SINGLE_STEP)