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


Reply via email to