* [Qemu-devel] [PATCH 0/3] PPC: E500: Support SPE guest @ 2011-08-23 4:55 Alexander Graf 2011-08-23 4:55 ` [Qemu-devel] [PATCH 1/3] PPC: E500: Add ESR bit definitions Alexander Graf 2011-08-23 17:00 ` [Qemu-devel] [PATCH 0/3] PPC: E500: Support SPE guest Jason Wessel 0 siblings, 2 replies; 7+ messages in thread From: Alexander Graf @ 2011-08-23 4:55 UTC (permalink / raw) To: qemu-devel; +Cc: scottwood 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. Thanks a lot for the debugging session Jason! It really helps when 2 pairs of eyes look at code :) Alex Alexander Graf (3): PPC: E500: Add ESR bit definitions PPC: E500: Inject SPE exception on invalid SPE access PPC: E500: Set ESR values target-ppc/cpu.h | 17 ++++++++++- target-ppc/helper.c | 10 +++++- target-ppc/translate.c | 78 ++++++++++++++++++++++++------------------------ 3 files changed, 63 insertions(+), 42 deletions(-) ^ permalink raw reply [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 1/3] PPC: E500: Add ESR bit definitions 2011-08-23 4:55 [Qemu-devel] [PATCH 0/3] PPC: E500: Support SPE guest Alexander Graf @ 2011-08-23 4:55 ` Alexander Graf 2011-08-23 4:55 ` [Qemu-devel] [PATCH 2/3] PPC: E500: Inject SPE exception on invalid SPE access Alexander Graf 2011-08-23 17:00 ` [Qemu-devel] [PATCH 0/3] PPC: E500: Support SPE guest Jason Wessel 1 sibling, 1 reply; 7+ messages in thread From: Alexander Graf @ 2011-08-23 4:55 UTC (permalink / raw) To: qemu-devel; +Cc: scottwood The BookE spec specifies a number of ESR bits. Add defines for them so we can use them later on. Reported-by: Jason Wessel <jason.wessel@windriver.com> Signed-off-by: Alexander Graf <agraf@suse.de> --- target-ppc/cpu.h | 17 ++++++++++++++++- target-ppc/helper.c | 4 ++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 024eb6f..b8d42e0 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -516,7 +516,22 @@ struct ppc_slb_t { #endif /* Exception state register bits definition */ -#define ESR_ST 23 /* Exception was caused by a store type access. */ +#define ESR_PIL (1 << (63 - 36)) /* Illegal Instruction */ +#define ESR_PPR (1 << (63 - 37)) /* Privileged Instruction */ +#define ESR_PTR (1 << (63 - 38)) /* Trap */ +#define ESR_FP (1 << (63 - 39)) /* Floating-Point Operation */ +#define ESR_ST (1 << (63 - 40)) /* Store Operation */ +#define ESR_AP (1 << (63 - 44)) /* Auxiliary Processor Operation */ +#define ESR_PUO (1 << (63 - 45)) /* Unimplemented Operation */ +#define ESR_BO (1 << (63 - 46)) /* Byte Ordering */ +#define ESR_PIE (1 << (63 - 47)) /* Imprecise exception */ +#define ESR_DATA (1 << (63 - 53)) /* Data Access (Embedded page table) */ +#define ESR_TLBI (1 << (63 - 54)) /* TLB Ineligible (Embedded page table) */ +#define ESR_PT (1 << (63 - 55)) /* Page Table (Embedded page table) */ +#define ESR_SPV (1 << (63 - 56)) /* SPE/VMX operation */ +#define ESR_EPID (1 << (63 - 57)) /* External Process ID operation */ +#define ESR_VLEMI (1 << (63 - 58)) /* VLE operation */ +#define ESR_MIF (1 << (63 - 62)) /* Misaligned instruction (VLE) */ enum { POWERPC_FLAG_NONE = 0x00000000, diff --git a/target-ppc/helper.c b/target-ppc/helper.c index 3abab1a..c23d4a4 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -1837,7 +1837,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, env->exception_index = POWERPC_EXCP_DTLB; env->error_code = 0; env->spr[SPR_BOOKE_DEAR] = address; - env->spr[SPR_BOOKE_ESR] = rw ? 1 << ESR_ST : 0; + env->spr[SPR_BOOKE_ESR] = rw ? ESR_ST : 0; return -1; case POWERPC_MMU_REAL: cpu_abort(env, "PowerPC in real mode should never raise " @@ -1861,7 +1861,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, } else if ((env->mmu_model == POWERPC_MMU_BOOKE) || (env->mmu_model == POWERPC_MMU_BOOKE206)) { env->spr[SPR_BOOKE_DEAR] = address; - env->spr[SPR_BOOKE_ESR] = rw ? 1 << ESR_ST : 0; + env->spr[SPR_BOOKE_ESR] = rw ? ESR_ST : 0; } else { env->spr[SPR_DAR] = address; if (rw == 1) { -- 1.6.0.2 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 2/3] PPC: E500: Inject SPE exception on invalid SPE access 2011-08-23 4:55 ` [Qemu-devel] [PATCH 1/3] PPC: E500: Add ESR bit definitions Alexander Graf @ 2011-08-23 4:55 ` Alexander Graf 2011-08-23 4:55 ` [Qemu-devel] [PATCH 3/3] PPC: E500: Set ESR values Alexander Graf 2011-08-23 20:34 ` [Qemu-devel] [PATCH 2/3] PPC: E500: Inject SPE exception on invalid SPE access Edgar E. Iglesias 0 siblings, 2 replies; 7+ messages in thread From: Alexander Graf @ 2011-08-23 4:55 UTC (permalink / raw) To: qemu-devel; +Cc: scottwood When accessing an SPE instruction despite it being not available, throw an SPE exception instead of an APU exception. That way the guest knows what's going on and actually uses SPE. Reported-by: Jason Wessel <jason.wessel@windriver.com> Signed-off-by: Alexander Graf <agraf@suse.de> --- target-ppc/translate.c | 78 ++++++++++++++++++++++++------------------------ 1 files changed, 39 insertions(+), 39 deletions(-) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index fd7c208..f36363a 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -6622,7 +6622,7 @@ static inline void gen_evmra(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } @@ -6693,7 +6693,7 @@ static inline void gen_speundef(DisasContext *ctx) static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \ @@ -6704,7 +6704,7 @@ static inline void gen_##name(DisasContext *ctx) \ static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \ @@ -6729,7 +6729,7 @@ GEN_SPEOP_LOGIC2(evnand, tcg_gen_nand_tl); static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ TCGv_i32 t0 = tcg_temp_local_new_i32(); \ @@ -6750,7 +6750,7 @@ static inline void gen_##name(DisasContext *ctx) \ static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ tcg_opi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \ @@ -6770,7 +6770,7 @@ GEN_SPEOP_TCG_LOGIC_IMM2(evrlwi, tcg_gen_rotli_i32); static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ TCGv_i32 t0 = tcg_temp_local_new_i32(); \ @@ -6791,7 +6791,7 @@ static inline void gen_##name(DisasContext *ctx) \ static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); \ @@ -6829,7 +6829,7 @@ GEN_SPEOP_ARITH1(evcntlzw, gen_helper_cntlzw32); static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ TCGv_i32 t0 = tcg_temp_local_new_i32(); \ @@ -6855,7 +6855,7 @@ static inline void gen_##name(DisasContext *ctx) \ static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \ @@ -6933,7 +6933,7 @@ GEN_SPEOP_ARITH2(evrlw, gen_op_evrlw); static inline void gen_evmergehi(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } #if defined(TARGET_PPC64) @@ -6962,7 +6962,7 @@ GEN_SPEOP_ARITH2(evsubfw, gen_op_evsubf); static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ TCGv_i32 t0 = tcg_temp_local_new_i32(); \ @@ -6983,7 +6983,7 @@ static inline void gen_##name(DisasContext *ctx) \ static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \ @@ -7001,7 +7001,7 @@ GEN_SPEOP_ARITH_IMM2(evsubifw, tcg_gen_subi_i32); static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ int l1 = gen_new_label(); \ @@ -7041,7 +7041,7 @@ static inline void gen_##name(DisasContext *ctx) \ static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ int l1 = gen_new_label(); \ @@ -7084,7 +7084,7 @@ static inline void gen_brinc(DisasContext *ctx) static inline void gen_evmergelo(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } #if defined(TARGET_PPC64) @@ -7103,7 +7103,7 @@ static inline void gen_evmergelo(DisasContext *ctx) static inline void gen_evmergehilo(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } #if defined(TARGET_PPC64) @@ -7122,7 +7122,7 @@ static inline void gen_evmergehilo(DisasContext *ctx) static inline void gen_evmergelohi(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } #if defined(TARGET_PPC64) @@ -7245,7 +7245,7 @@ static inline void gen_evmwumi(DisasContext *ctx) TCGv_i64 t0, t1; if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } @@ -7274,7 +7274,7 @@ static inline void gen_evmwumia(DisasContext *ctx) TCGv_i64 tmp; if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } @@ -7294,7 +7294,7 @@ static inline void gen_evmwumiaa(DisasContext *ctx) TCGv_i64 tmp; if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } @@ -7327,7 +7327,7 @@ static inline void gen_evmwsmi(DisasContext *ctx) TCGv_i64 t0, t1; if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } @@ -7746,7 +7746,7 @@ static void glue(gen_, name)(DisasContext *ctx) { \ TCGv t0; \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ gen_set_access_type(ctx, ACCESS_INT); \ @@ -7904,7 +7904,7 @@ static inline void gen_##name(DisasContext *ctx) \ TCGv_i32 t0, t1; \ TCGv_i64 t2; \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ t0 = tcg_temp_new_i32(); \ @@ -7925,7 +7925,7 @@ static inline void gen_##name(DisasContext *ctx) \ static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \ @@ -7936,7 +7936,7 @@ static inline void gen_##name(DisasContext *ctx) \ { \ TCGv_i32 t0, t1; \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ t0 = tcg_temp_new_i32(); \ @@ -7951,7 +7951,7 @@ static inline void gen_##name(DisasContext *ctx) \ static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \ @@ -7992,7 +7992,7 @@ static inline void gen_##name(DisasContext *ctx) \ static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ gen_helper_##name(cpu_gpr[rD(ctx->opcode)], \ @@ -8003,7 +8003,7 @@ static inline void gen_##name(DisasContext *ctx) \ { \ TCGv_i64 t0, t1; \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ t0 = tcg_temp_new_i64(); \ @@ -8019,7 +8019,7 @@ static inline void gen_##name(DisasContext *ctx) \ static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \ @@ -8030,7 +8030,7 @@ static inline void gen_##name(DisasContext *ctx) \ { \ TCGv_i64 t0, t1; \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ t0 = tcg_temp_new_i64(); \ @@ -8052,7 +8052,7 @@ GEN_SPEFPUOP_ARITH2_64_64(evfsdiv); static inline void gen_evfsabs(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } #if defined(TARGET_PPC64) @@ -8065,7 +8065,7 @@ static inline void gen_evfsabs(DisasContext *ctx) static inline void gen_evfsnabs(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } #if defined(TARGET_PPC64) @@ -8078,7 +8078,7 @@ static inline void gen_evfsnabs(DisasContext *ctx) static inline void gen_evfsneg(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } #if defined(TARGET_PPC64) @@ -8134,7 +8134,7 @@ GEN_SPEFPUOP_ARITH2_32_32(efsdiv); static inline void gen_efsabs(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], (target_long)~0x80000000LL); @@ -8142,7 +8142,7 @@ static inline void gen_efsabs(DisasContext *ctx) static inline void gen_efsnabs(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000); @@ -8150,7 +8150,7 @@ static inline void gen_efsnabs(DisasContext *ctx) static inline void gen_efsneg(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000); @@ -8202,7 +8202,7 @@ GEN_SPEFPUOP_ARITH2_64_64(efddiv); static inline void gen_efdabs(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } #if defined(TARGET_PPC64) @@ -8215,7 +8215,7 @@ static inline void gen_efdabs(DisasContext *ctx) static inline void gen_efdnabs(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } #if defined(TARGET_PPC64) @@ -8228,7 +8228,7 @@ static inline void gen_efdnabs(DisasContext *ctx) static inline void gen_efdneg(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } #if defined(TARGET_PPC64) -- 1.6.0.2 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 3/3] PPC: E500: Set ESR values 2011-08-23 4:55 ` [Qemu-devel] [PATCH 2/3] PPC: E500: Inject SPE exception on invalid SPE access Alexander Graf @ 2011-08-23 4:55 ` Alexander Graf 2011-08-23 20:34 ` [Qemu-devel] [PATCH 2/3] PPC: E500: Inject SPE exception on invalid SPE access Edgar E. Iglesias 1 sibling, 0 replies; 7+ messages in thread From: Alexander Graf @ 2011-08-23 4:55 UTC (permalink / raw) To: qemu-devel; +Cc: scottwood When an exception occurs on BookE, we need to set ESR bits to expose to the guest information on what exactly happened. Add the obvious ones. Reported-by: Jason Wessel <jason.wessel@windriver.com> Signed-off-by: Alexander Graf <agraf@suse.de> --- target-ppc/helper.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/target-ppc/helper.c b/target-ppc/helper.c index c23d4a4..5ec83f2 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -2484,16 +2484,19 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp) if (lpes1 == 0) new_msr |= (target_ulong)MSR_HVB; msr |= 0x00080000; + env->spr[SPR_BOOKE_ESR] = ESR_PIL; break; case POWERPC_EXCP_PRIV: if (lpes1 == 0) new_msr |= (target_ulong)MSR_HVB; msr |= 0x00040000; + env->spr[SPR_BOOKE_ESR] = ESR_PPR; break; case POWERPC_EXCP_TRAP: if (lpes1 == 0) new_msr |= (target_ulong)MSR_HVB; msr |= 0x00020000; + env->spr[SPR_BOOKE_ESR] = ESR_PTR; break; default: /* Should never occur */ @@ -2556,16 +2559,19 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp) cpu_abort(env, "Debug exception is not implemented yet !\n"); goto store_next; case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable */ + env->spr[SPR_BOOKE_ESR] = ESR_SPV; goto store_current; case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */ /* XXX: TODO */ cpu_abort(env, "Embedded floating point data exception " "is not implemented yet !\n"); + env->spr[SPR_BOOKE_ESR] = ESR_SPV; goto store_next; case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */ /* XXX: TODO */ cpu_abort(env, "Embedded floating point round exception " "is not implemented yet !\n"); + env->spr[SPR_BOOKE_ESR] = ESR_SPV; goto store_next; case POWERPC_EXCP_EPERFM: /* Embedded performance monitor interrupt */ /* XXX: TODO */ -- 1.6.0.2 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH 2/3] PPC: E500: Inject SPE exception on invalid SPE access 2011-08-23 4:55 ` [Qemu-devel] [PATCH 2/3] PPC: E500: Inject SPE exception on invalid SPE access Alexander Graf 2011-08-23 4:55 ` [Qemu-devel] [PATCH 3/3] PPC: E500: Set ESR values Alexander Graf @ 2011-08-23 20:34 ` Edgar E. Iglesias 1 sibling, 0 replies; 7+ messages in thread From: Edgar E. Iglesias @ 2011-08-23 20:34 UTC (permalink / raw) To: Alexander Graf; +Cc: scottwood, qemu-devel On Tue, Aug 23, 2011 at 06:55:43AM +0200, Alexander Graf wrote: > When accessing an SPE instruction despite it being not available, > throw an SPE exception instead of an APU exception. That way the > guest knows what's going on and actually uses SPE. > > Reported-by: Jason Wessel <jason.wessel@windriver.com> > Signed-off-by: Alexander Graf <agraf@suse.de> > --- > target-ppc/translate.c | 78 ++++++++++++++++++++++++------------------------ > 1 files changed, 39 insertions(+), 39 deletions(-) > > diff --git a/target-ppc/translate.c b/target-ppc/translate.c > index fd7c208..f36363a 100644 > --- a/target-ppc/translate.c > +++ b/target-ppc/translate.c > @@ -6622,7 +6622,7 @@ static inline void gen_evmra(DisasContext *ctx) > { > > if (unlikely(!ctx->spe_enabled)) { > - gen_exception(ctx, POWERPC_EXCP_APU); > + gen_exception(ctx, POWERPC_EXCP_SPEU); > return; > } > > @@ -6693,7 +6693,7 @@ static inline void gen_speundef(DisasContext *ctx) > static inline void gen_##name(DisasContext *ctx) \ > { \ > if (unlikely(!ctx->spe_enabled)) { \ > - gen_exception(ctx, POWERPC_EXCP_APU); \ > + gen_exception(ctx, POWERPC_EXCP_SPEU); \ ^^ I've applied this (with a minor whitespace change), thanks Alex. Cheers ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH 0/3] PPC: E500: Support SPE guest 2011-08-23 4:55 [Qemu-devel] [PATCH 0/3] PPC: E500: Support SPE guest Alexander Graf 2011-08-23 4:55 ` [Qemu-devel] [PATCH 1/3] PPC: E500: Add ESR bit definitions Alexander Graf @ 2011-08-23 17:00 ` Jason Wessel 2011-08-23 20:10 ` Edgar E. Iglesias 1 sibling, 1 reply; 7+ messages in thread From: Jason Wessel @ 2011-08-23 17:00 UTC (permalink / raw) To: Alexander Graf; +Cc: scottwood, qemu-devel [-- Attachment #1: Type: text/plain, Size: 1471 bytes --] 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 down the route of implementing more pieces, I am interested to know if you see the same behavior, or if you had any ideas around how to further debug it. Using just your patch series + the QEMU HEAD + the SPE enabled rootfs + qemu NFS mounting the rootfs, here is the "litmus test" to see if you experience the fatal mmu faults to user space. ulimit -c unlimited while [ 1 ] ; do echo 3 > /proc/sys/vm/drop_caches (echo quit ; sleep 2) | gdb /bin/ls || break done I find that this runs between 1-15 times and crashes with a core file. Looking at the core file it is usually in a malloc or free operation in the user space, and always in the page fault handler in the kernel. This really amounts to running a medium sized app through the startup, which does a whole bunch of malloc and free because it maps in the elf debug info for /bin/ls , and gdb is not really getting used for anything to ptrace. Jason. [-- Attachment #2: Type: text/html, Size: 2092 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH 0/3] PPC: E500: Support SPE guest 2011-08-23 17:00 ` [Qemu-devel] [PATCH 0/3] PPC: E500: Support SPE guest Jason Wessel @ 2011-08-23 20:10 ` Edgar E. Iglesias 0 siblings, 0 replies; 7+ messages in thread From: Edgar E. Iglesias @ 2011-08-23 20:10 UTC (permalink / raw) To: Jason Wessel; +Cc: scottwood, Alexander Graf, qemu-devel 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.iglesias@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.iglesias@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) && ^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2011-08-23 20:34 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-08-23 4:55 [Qemu-devel] [PATCH 0/3] PPC: E500: Support SPE guest Alexander Graf 2011-08-23 4:55 ` [Qemu-devel] [PATCH 1/3] PPC: E500: Add ESR bit definitions Alexander Graf 2011-08-23 4:55 ` [Qemu-devel] [PATCH 2/3] PPC: E500: Inject SPE exception on invalid SPE access Alexander Graf 2011-08-23 4:55 ` [Qemu-devel] [PATCH 3/3] PPC: E500: Set ESR values Alexander Graf 2011-08-23 20:34 ` [Qemu-devel] [PATCH 2/3] PPC: E500: Inject SPE exception on invalid SPE access Edgar E. Iglesias 2011-08-23 17:00 ` [Qemu-devel] [PATCH 0/3] PPC: E500: Support SPE guest Jason Wessel 2011-08-23 20:10 ` Edgar E. Iglesias
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).