From patchwork Wed Jan 27 10:13:04 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 8132191 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 091299F818 for ; Wed, 27 Jan 2016 10:17:29 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 49EEF20265 for ; Wed, 27 Jan 2016 10:17:28 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3D7952024C for ; Wed, 27 Jan 2016 10:17:27 +0000 (UTC) Received: from localhost ([::1]:48969 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aONAE-0001pm-Gv for patchwork-qemu-devel@patchwork.kernel.org; Wed, 27 Jan 2016 05:17:26 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59639) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aON5O-0001Hu-2q for qemu-devel@nongnu.org; Wed, 27 Jan 2016 05:12:30 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aON5J-0005Nt-FJ for qemu-devel@nongnu.org; Wed, 27 Jan 2016 05:12:26 -0500 Received: from ozlabs.org ([103.22.144.67]:58120) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aON5I-0005NU-TB; Wed, 27 Jan 2016 05:12:21 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 9E886140BF6; Wed, 27 Jan 2016 21:12:18 +1100 (AEDT) From: David Gibson To: benh@kernel.crashing.org Date: Wed, 27 Jan 2016 21:13:04 +1100 Message-Id: <1453889591-30968-4-git-send-email-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1453889591-30968-1-git-send-email-david@gibson.dropbear.id.au> References: <1453889591-30968-1-git-send-email-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 103.22.144.67 Cc: lvivier@redhat.com, thuth@redhat.com, aik@ozlabs.ru, agraf@suse.de, qemu-devel@nongnu.org, qemu-ppc@nongnu.org, David Gibson Subject: [Qemu-devel] [PATCHv2 03/10] target-ppc: Rework ppc_store_slb X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP ppc_store_slb updates the SLB for PPC cpus with 64-bit hash MMUs. Currently it takes two parameters, which contain values encoded as the register arguments to the slbmte instruction, one register contains the ESID portion of the SLBE and also the slot number, the other contains the VSID portion of the SLBE. We're shortly going to want to do some SLB updates from other code where it is more convenient to supply the slot number and ESID separately, so rework this function and its callers to work this way. As a bonus, this slightly simplifies the emulation of segment registers for when running a 32-bit OS on a 64-bit CPU. Signed-off-by: David Gibson Reviewed-by: Laurent Vivier Acked-by: Benjamin Herrenschmidt --- target-ppc/kvm.c | 2 +- target-ppc/mmu-hash64.c | 24 +++++++++++++----------- target-ppc/mmu-hash64.h | 3 ++- target-ppc/mmu_helper.c | 14 +++++--------- 4 files changed, 21 insertions(+), 22 deletions(-) diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 98d7ba6..0f45380 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -1205,7 +1205,7 @@ int kvm_arch_get_registers(CPUState *cs) * Only restore valid entries */ if (rb & SLB_ESID_V) { - ppc_store_slb(cpu, rb, rs); + ppc_store_slb(cpu, rb & 0xfff, rb & ~0xfffULL, rs); } } #endif diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c index 03e25fd..6e05643 100644 --- a/target-ppc/mmu-hash64.c +++ b/target-ppc/mmu-hash64.c @@ -135,28 +135,30 @@ void helper_slbie(CPUPPCState *env, target_ulong addr) } } -int ppc_store_slb(PowerPCCPU *cpu, target_ulong rb, target_ulong rs) +int ppc_store_slb(PowerPCCPU *cpu, target_ulong slot, + target_ulong esid, target_ulong vsid) { CPUPPCState *env = &cpu->env; - int slot = rb & 0xfff; ppc_slb_t *slb = &env->slb[slot]; - if (rb & (0x1000 - env->slb_nr)) { - return -1; /* Reserved bits set or slot too high */ + if (slot >= env->slb_nr) { + return -1; /* Bad slot number */ + } + if (esid & ~(SLB_ESID_ESID | SLB_ESID_V)) { + return -1; /* Reserved bits set */ } - if (rs & (SLB_VSID_B & ~SLB_VSID_B_1T)) { + if (vsid & (SLB_VSID_B & ~SLB_VSID_B_1T)) { return -1; /* Bad segment size */ } - if ((rs & SLB_VSID_B) && !(env->mmu_model & POWERPC_MMU_1TSEG)) { + if ((vsid & SLB_VSID_B) && !(env->mmu_model & POWERPC_MMU_1TSEG)) { return -1; /* 1T segment on MMU that doesn't support it */ } - /* Mask out the slot number as we store the entry */ - slb->esid = rb & (SLB_ESID_ESID | SLB_ESID_V); - slb->vsid = rs; + slb->esid = esid; + slb->vsid = vsid; LOG_SLB("%s: %d " TARGET_FMT_lx " - " TARGET_FMT_lx " => %016" PRIx64 - " %016" PRIx64 "\n", __func__, slot, rb, rs, + " %016" PRIx64 "\n", __func__, slot, esid, vsid, slb->esid, slb->vsid); return 0; @@ -196,7 +198,7 @@ void helper_store_slb(CPUPPCState *env, target_ulong rb, target_ulong rs) { PowerPCCPU *cpu = ppc_env_get_cpu(env); - if (ppc_store_slb(cpu, rb, rs) < 0) { + if (ppc_store_slb(cpu, rb & 0xfff, rb & ~0xfffULL, rs) < 0) { helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL); } diff --git a/target-ppc/mmu-hash64.h b/target-ppc/mmu-hash64.h index 6e3de7e..24fd2c4 100644 --- a/target-ppc/mmu-hash64.h +++ b/target-ppc/mmu-hash64.h @@ -6,7 +6,8 @@ #ifdef TARGET_PPC64 void ppc_hash64_check_page_sizes(PowerPCCPU *cpu, Error **errp); void dump_slb(FILE *f, fprintf_function cpu_fprintf, PowerPCCPU *cpu); -int ppc_store_slb(PowerPCCPU *cpu, target_ulong rb, target_ulong rs); +int ppc_store_slb(PowerPCCPU *cpu, target_ulong slot, + target_ulong esid, target_ulong vsid); hwaddr ppc_hash64_get_phys_page_debug(PowerPCCPU *cpu, target_ulong addr); int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, target_ulong address, int rw, int mmu_idx); diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c index 0ab73bc..c040b17 100644 --- a/target-ppc/mmu_helper.c +++ b/target-ppc/mmu_helper.c @@ -2088,21 +2088,17 @@ void helper_store_sr(CPUPPCState *env, target_ulong srnum, target_ulong value) (int)srnum, value, env->sr[srnum]); #if defined(TARGET_PPC64) if (env->mmu_model & POWERPC_MMU_64) { - uint64_t rb = 0, rs = 0; + uint64_t esid, vsid; /* ESID = srnum */ - rb |= ((uint32_t)srnum & 0xf) << 28; - /* Set the valid bit */ - rb |= SLB_ESID_V; - /* Index = ESID */ - rb |= (uint32_t)srnum; + esid = ((uint64_t)(srnum & 0xf) << 28) | SLB_ESID_V; /* VSID = VSID */ - rs |= (value & 0xfffffff) << 12; + vsid = (value & 0xfffffff) << 12; /* flags = flags */ - rs |= ((value >> 27) & 0xf) << 8; + vsid |= ((value >> 27) & 0xf) << 8; - ppc_store_slb(cpu, rb, rs); + ppc_store_slb(cpu, srnum, esid, vsid); } else #endif if (env->sr[srnum] != value) {