On 12.02.2011, at 15:54, David Gibson wrote: > From: David Gibson <d...@au1.ibm.com> > > For a 64-bit PowerPC target, qemu correctly implements translation > through the segment lookaside buffer. Likewise it supports the > slbmte instruction which is used to load entries into the SLB. > > However, it does not emulate the slbmfee and slbmfev instructions > which read SLB entries back into registers. Because these are > only occasionally used in guests (mostly for debugging) we get > away with it. > > However, given the recent SLB cleanups, it becomes quite easy to > implement these, and thereby allow, amongst other things, a guest > Linux to use xmon's command to dump the SLB. > > Signed-off-by: David Gibson <d...@au1.ibm.com> > --- > target-ppc/cpu.h | 2 ++ > target-ppc/helper.c | 26 ++++++++++++++++++++++++++ > target-ppc/helper.h | 2 ++ > target-ppc/op_helper.c | 20 ++++++++++++++++++++ > target-ppc/translate.c | 29 ++++++++++++++++++++++++++++- > 5 files changed, 78 insertions(+), 1 deletions(-) > > diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h > index eaddc27..9a7495a 100644 > --- a/target-ppc/cpu.h > +++ b/target-ppc/cpu.h > @@ -781,6 +781,8 @@ void ppc_store_asr (CPUPPCState *env, target_ulong value); > target_ulong ppc_load_slb (CPUPPCState *env, int slb_nr); > target_ulong ppc_load_sr (CPUPPCState *env, int sr_nr); > int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs); > +int ppc_load_slb_esid (CPUPPCState *env, target_ulong rb, target_ulong *rt); > +int ppc_load_slb_vsid (CPUPPCState *env, target_ulong rb, target_ulong *rt); > #endif /* defined(TARGET_PPC64) */ > void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value); > #endif /* !defined(CONFIG_USER_ONLY) */ > diff --git a/target-ppc/helper.c b/target-ppc/helper.c > index 19aa067..4830981 100644 > --- a/target-ppc/helper.c > +++ b/target-ppc/helper.c > @@ -770,6 +770,32 @@ int ppc_store_slb (CPUPPCState *env, target_ulong rb, > target_ulong rs) > > return 0; > } > + > +int ppc_load_slb_esid (CPUPPCState *env, target_ulong rb, target_ulong *rt) > +{ > + int slot = rb & 0xfff; > + ppc_slb_t *slb = &env->slb[slot]; > + > + if (slot >= env->slb_nr) { > + return -1; > + } > + > + *rt = slb->esid; > + return 0; > +} > + > +int ppc_load_slb_vsid (CPUPPCState *env, target_ulong rb, target_ulong *rt) > +{ > + int slot = rb & 0xfff; > + ppc_slb_t *slb = &env->slb[slot]; > + > + if (slot >= env->slb_nr) { > + return -1; > + } > + > + *rt = slb->vsid; > + return 0; > +} > #endif /* defined(TARGET_PPC64) */ > > /* Perform segment based translation */ > diff --git a/target-ppc/helper.h b/target-ppc/helper.h > index d512cb0..1a69cf8 100644 > --- a/target-ppc/helper.h > +++ b/target-ppc/helper.h > @@ -341,6 +341,8 @@ DEF_HELPER_FLAGS_0(tlbia, TCG_CALL_CONST, void) > DEF_HELPER_FLAGS_1(tlbie, TCG_CALL_CONST, void, tl) > #if defined(TARGET_PPC64) > DEF_HELPER_FLAGS_2(store_slb, TCG_CALL_CONST, void, tl, tl) > +DEF_HELPER_1(load_slb_esid, tl, tl) > +DEF_HELPER_1(load_slb_vsid, tl, tl) > DEF_HELPER_FLAGS_0(slbia, TCG_CALL_CONST, void) > DEF_HELPER_FLAGS_1(slbie, TCG_CALL_CONST, void, tl) > #endif > diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c > index bf41627..bdb1f17 100644 > --- a/target-ppc/op_helper.c > +++ b/target-ppc/op_helper.c > @@ -3753,6 +3753,26 @@ void helper_store_slb (target_ulong rb, target_ulong > rs) > } > } > > +target_ulong helper_load_slb_esid (target_ulong rb) > +{ > + target_ulong rt; > + > + if (ppc_load_slb_esid(env, rb, &rt) < 0) { > + helper_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL);
The spec doesn't say what to do in this case. Have you checked what real hardware does? Alex