On Tue, Aug 23, 2011 at 12:00:00PM -0500, Jason Wessel wrote: > On 08/22/2011 11:55 PM, Alexander Graf wrote: > > When I bumped into Jason on Linuxcon, we tried out to run the e500 target > > on his Windriver build that used SPE and immediately ran into emulation > > issues. Fortunately there weren't too many, so here are the patches to get > > a guest using SPE instructions working just fine. > > > > The patch set looks good to me. I tried it out this morning. > > I have a patch that implements enough of the the dbcr0, dbsr, and msr DE bit > in > order to single step, but I am seeing random fatal mmu faults. Before we go
Hi Jason, We did something with PetaLogix to get the gdbserver working on a ppc440 linux a while ago. It was done a bit in a hurry and I've been meaning to get back to it for rebase/cleanup and contribution, but it just hasnt happened yet, sorry. ATM I dont recall the details, but IIRC it worked quite OK at the time. Maybe useful to compare notes at least. Cheers commit 3c905e20ca654e019db045749b4e1abeb46704ae Author: Edgar E. Iglesias <edgar.igles...@petalogix.com> Date: Wed Nov 24 22:15:53 2010 +0100 ppc: Implement parts of the BookE debug features Signed-off-by: Edgar E. Iglesias <edgar.igles...@petalogix.com> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 74526a2..2264bc1 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1349,6 +1349,26 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) #define SPR_604_HID15 (0x3FF) #define SPR_E500_SVR (0x3FF) +/* DBCR0 Definitions. */ +#define DBCR0_EDM 31 +#define DBCR0_IDM 30 +#define DBCR0_ICMP 27 +#define DBCR0_IAC1 23 +#define DBCR0_IAC2 22 +#define DBCR0_IAC3 21 +#define DBCR0_IAC4 20 +#define DBCR0_DAC1R 19 +#define DBCR0_DAC1W 18 +#define DBCR0_DAC2R 17 +#define DBCR0_DAC2W 16 + +/* DBSR Definitions. */ +#define DBSR_ICMP 27 +#define DBSR_IAC1 23 +#define DBSR_IAC2 22 +#define DBSR_IAC3 21 +#define DBSR_IAC4 20 + /*****************************************************************************/ /* PowerPC Instructions types definitions */ enum { diff --git a/target-ppc/helper.c b/target-ppc/helper.c index 3bc8a34..22b148e 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -2281,7 +2281,6 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp) break; } /* XXX: TODO */ - cpu_abort(env, "Debug exception is not implemented yet !\n"); goto store_next; case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable */ goto store_current; diff --git a/target-ppc/helper.h b/target-ppc/helper.h index c4e72b1..f1a0093 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -400,6 +400,9 @@ DEF_HELPER_2(store_dbatl, void, i32, tl) DEF_HELPER_2(store_dbatu, void, i32, tl) DEF_HELPER_2(store_601_batl, void, i32, tl) DEF_HELPER_2(store_601_batu, void, i32, tl) + +DEF_HELPER_1(embdebug_issue, void, i32) +DEF_HELPER_2(embdebug_icmp, void, i32, i32) #endif #include "def-helper.h" diff --git a/target-ppc/helper_regs.h b/target-ppc/helper_regs.h index 3c98850..265d544 100644 --- a/target-ppc/helper_regs.h +++ b/target-ppc/helper_regs.h @@ -56,7 +56,7 @@ static inline void hreg_compute_hflags(CPUPPCState *env) /* We 'forget' FE0 & FE1: we'll never generate imprecise exceptions */ hflags_mask = (1 << MSR_VR) | (1 << MSR_AP) | (1 << MSR_SA) | (1 << MSR_PR) | (1 << MSR_FP) | (1 << MSR_SE) | (1 << MSR_BE) | - (1 << MSR_LE); + (1 << MSR_LE) | (1 << MSR_DE); hflags_mask |= (1ULL << MSR_CM) | (1ULL << MSR_SF) | MSR_HVB; hreg_compute_mem_idx(env); env->hflags = env->msr & hflags_mask; diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index c050b04..e4b2d79 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -4171,4 +4171,57 @@ target_ulong helper_440_tlbsx (target_ulong address) return ppcemb_tlb_search(env, address, env->spr[SPR_440_MMUCR] & 0xFF); } +/* DEBUG helpers. */ +void helper_embdebug_issue(target_ulong pc) +{ + if (!env->spr[SPR_BOOKE_DBCR0] & (1 << DBCR0_EDM)) { + return; + } + + if (env->spr[SPR_BOOKE_DBCR0] & (1 << DBCR0_IAC1) + && pc == env->spr[SPR_BOOKE_IAC1]) { + /* Assert the ICMP bit in the debug status reg. */ + env->spr[SPR_BOOKE_DBSR] |= 1 << DBSR_IAC1; + /* And raise the debug exception. */ + helper_raise_exception(POWERPC_EXCP_DEBUG); + } + + if (env->spr[SPR_BOOKE_DBCR0] & (1 << DBCR0_IAC2) + && pc == env->spr[SPR_BOOKE_IAC2]) { + /* Assert the ICMP bit in the debug status reg. */ + env->spr[SPR_BOOKE_DBSR] |= 1 << DBSR_IAC2; + /* And raise the debug exception. */ + helper_raise_exception(POWERPC_EXCP_DEBUG); + } + + if (env->spr[SPR_BOOKE_DBCR0] & (1 << DBCR0_IAC3) + && pc == env->spr[SPR_BOOKE_IAC3]) { + /* Assert the ICMP bit in the debug status reg. */ + env->spr[SPR_BOOKE_DBSR] |= 1 << DBSR_IAC3; + /* And raise the debug exception. */ + helper_raise_exception(POWERPC_EXCP_DEBUG); + } + + if (env->spr[SPR_BOOKE_DBCR0] & (1 << DBCR0_IAC4) + && pc == env->spr[SPR_BOOKE_IAC4]) { + /* Assert the ICMP bit in the debug status reg. */ + env->spr[SPR_BOOKE_DBSR] |= 1 << DBSR_IAC4; + /* And raise the debug exception. */ + helper_raise_exception(POWERPC_EXCP_DEBUG); + } +} + +void helper_embdebug_icmp(target_ulong pc, target_ulong branch) +{ + if (!env->spr[SPR_BOOKE_DBCR0] & (1 << DBCR0_IDM)) { + return; + } + if (env->spr[SPR_BOOKE_DBCR0] & (1 << DBCR0_ICMP)) { + /* Assert the ICMP bit in the debug status reg. */ + env->spr[SPR_BOOKE_DBSR] |= 1 << DBSR_ICMP; + /* And raise the debug exception. */ + helper_raise_exception(POWERPC_EXCP_DEBUG); + } +} + #endif /* !CONFIG_USER_ONLY */ diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 09f22a3..f5c3c21 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -9032,6 +9032,14 @@ static inline void gen_intermediate_code_internal(CPUState *env, ctx.nip, ctx.mem_idx, (int)msr_ir); if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) gen_io_start(); + +#if !defined(CONFIG_USER_ONLY) + if (env->mmu_model == POWERPC_MMU_BOOKE + && env->hflags & (1 << MSR_DE)) { + gen_helper_embdebug_issue(tcg_const_tl(ctx.nip)); + } +#endif + if (unlikely(ctx.le_mode)) { ctx.opcode = bswap32(ldl_code(ctx.nip)); } else { @@ -9079,6 +9087,21 @@ static inline void gen_intermediate_code_internal(CPUState *env, #if defined(DO_PPC_STATISTICS) handler->count++; #endif + +#if !defined(CONFIG_USER_ONLY) + if (env->mmu_model == POWERPC_MMU_BOOKE + && env->hflags & (1 << MSR_DE)) { + target_ulong branch = 0; + if (ctx.exception == POWERPC_EXCP_BRANCH) { + branch = 1; + } else + gen_update_nip(&ctx, ctx.nip); + + gen_helper_embdebug_icmp(tcg_const_tl(ctx.nip), + tcg_const_tl(branch)); + } +#endif + /* Check trace mode exceptions */ if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP && (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&