From patchwork Wed Mar 16 04:56:41 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 87164 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 41ECCB700D for ; Wed, 16 Mar 2011 16:35:24 +1100 (EST) Received: from localhost ([127.0.0.1]:58976 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Pzj4A-0006vr-9x for incoming@patchwork.ozlabs.org; Wed, 16 Mar 2011 01:14:38 -0400 Received: from [140.186.70.92] (port=56042 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PzinX-0002n5-6I for qemu-devel@nongnu.org; Wed, 16 Mar 2011 00:57:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PzinW-0001do-06 for qemu-devel@nongnu.org; Wed, 16 Mar 2011 00:57:27 -0400 Received: from ozlabs.org ([203.10.76.45]:54321) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PzinV-0001d9-F6 for qemu-devel@nongnu.org; Wed, 16 Mar 2011 00:57:25 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 5CDDAB7015; Wed, 16 Mar 2011 15:57:18 +1100 (EST) From: David Gibson To: agraf@suse.de, qemu-devel@nongnu.org Date: Wed, 16 Mar 2011 15:56:41 +1100 Message-Id: <1300251423-6715-5-git-send-email-david@gibson.dropbear.id.au> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1300251423-6715-1-git-send-email-david@gibson.dropbear.id.au> References: <1300251423-6715-1-git-send-email-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 203.10.76.45 Cc: paulus@samba.org, anton@samba.org Subject: [Qemu-devel] [PATCH 04/26] Implement PowerPC slbmfee and slbmfev instructions X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: David Gibson 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 --- 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); + } + return rt; +} + +target_ulong helper_load_slb_vsid (target_ulong rb) +{ + target_ulong rt; + + if (ppc_load_slb_vsid(env, rb, &rt) < 0) { + helper_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL); + } + return rt; +} + void helper_slbia (void) { ppc_slb_invalidate_all(env); diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 89413c5..2b1a851 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -4227,6 +4227,31 @@ static void gen_slbmte(DisasContext *ctx) #endif } +static void gen_slbmfee(DisasContext *ctx) +{ +#if defined(CONFIG_USER_ONLY) + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); +#else + if (unlikely(!ctx->mem_idx)) { + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); + return; + } + gen_helper_load_slb_esid(cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); +#endif +} + +static void gen_slbmfev(DisasContext *ctx) +{ +#if defined(CONFIG_USER_ONLY) + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); +#else + if (unlikely(!ctx->mem_idx)) { + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); + return; + } + gen_helper_load_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); +#endif +} #endif /* defined(TARGET_PPC64) */ /*** Lookaside buffer management ***/ @@ -8110,7 +8135,9 @@ GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001, GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B), GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT_64B), -GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x00000000, PPC_SEGMENT_64B), +GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x001F0001, PPC_SEGMENT_64B), +GEN_HANDLER2(slbmfee, "slbmfee", 0x1F, 0x13, 0x1C, 0x001F0001, PPC_SEGMENT_64B), +GEN_HANDLER2(slbmfev, "slbmfev", 0x1F, 0x13, 0x1A, 0x001F0001, PPC_SEGMENT_64B), #endif GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA), GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x03FF0001, PPC_MEM_TLBIE),