From patchwork Thu Feb 2 01:49:33 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 139061 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 324A21007D1 for ; Thu, 2 Feb 2012 13:49:23 +1100 (EST) Received: from localhost ([::1]:50155 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Rsloz-0005MF-To for incoming@patchwork.ozlabs.org; Wed, 01 Feb 2012 20:50:45 -0500 Received: from eggs.gnu.org ([140.186.70.92]:48578) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RsloC-0004km-Qq for qemu-devel@nongnu.org; Wed, 01 Feb 2012 20:50:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Rslo3-0005Tr-Hi for qemu-devel@nongnu.org; Wed, 01 Feb 2012 20:49:56 -0500 Received: from cantor2.suse.de ([195.135.220.15]:49101 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Rslo3-0005Si-6G; Wed, 01 Feb 2012 20:49:47 -0500 Received: from relay2.suse.de (unknown [195.135.220.254]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id 7549C90F2E; Thu, 2 Feb 2012 02:49:45 +0100 (CET) From: Alexander Graf To: qemu-ppc@nongnu.org Date: Thu, 2 Feb 2012 02:49:33 +0100 Message-Id: <1328147384-10387-11-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.7.3.4 In-Reply-To: <1328147384-10387-1-git-send-email-agraf@suse.de> References: <1328147384-10387-1-git-send-email-agraf@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4-2.6 X-Received-From: 195.135.220.15 Cc: Blue Swirl , qemu-devel Developers , Aurelien Jarno Subject: [Qemu-devel] [PATCH 10/21] PPC: booke206: Implement tlbilx 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+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org The PowerPC 2.06 BookE ISA defines an opcode called "tlbilx" which is used to flush TLB entries. It's the recommended way of flushing in virtualized environments. So far we got away without implementing it, but Linux for e500mc uses this instruction, so we better add it :). Signed-off-by: Alexander Graf --- target-ppc/helper.h | 3 ++ target-ppc/op_helper.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ target-ppc/translate.c | 35 ++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 0 deletions(-) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 470e42f..4798fd5 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -336,6 +336,9 @@ DEF_HELPER_0(booke206_tlbre, void) DEF_HELPER_0(booke206_tlbwe, void) DEF_HELPER_1(booke206_tlbsx, void, tl) DEF_HELPER_1(booke206_tlbivax, void, tl) +DEF_HELPER_1(booke206_tlbilx0, void, tl) +DEF_HELPER_1(booke206_tlbilx1, void, tl) +DEF_HELPER_1(booke206_tlbilx3, void, tl) DEF_HELPER_1(booke206_tlbflush, void, i32) DEF_HELPER_2(booke_setpid, void, i32, tl) DEF_HELPER_1(6xx_tlbd, void, tl) diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index 3b197f2..1f1fa09 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -4406,6 +4406,70 @@ void helper_booke206_tlbivax(target_ulong address) } } +void helper_booke206_tlbilx0(target_ulong address) +{ + /* XXX missing LPID handling */ + booke206_flush_tlb(env, -1, 1); +} + +void helper_booke206_tlbilx1(target_ulong address) +{ + int i, j; + int tid = (env->spr[SPR_BOOKE_MAS6] & MAS6_SPID); + ppcmas_tlb_t *tlb = env->tlb.tlbm; + int tlb_size; + + /* XXX missing LPID handling */ + for (i = 0; i < BOOKE206_MAX_TLBN; i++) { + tlb_size = booke206_tlb_size(env, i); + for (j = 0; j < tlb_size; j++) { + if (!(tlb[j].mas1 & MAS1_IPROT) && + ((tlb[j].mas1 & MAS1_TID_MASK) == tid)) { + tlb[j].mas1 &= ~MAS1_VALID; + } + } + tlb += booke206_tlb_size(env, i); + } + tlb_flush(env, 1); +} + +void helper_booke206_tlbilx3(target_ulong address) +{ + int i, j; + ppcmas_tlb_t *tlb; + int tid = (env->spr[SPR_BOOKE_MAS6] & MAS6_SPID); + int pid = tid >> MAS6_SPID_SHIFT; + int sgs = env->spr[SPR_BOOKE_MAS5] & MAS5_SGS; + int ind = (env->spr[SPR_BOOKE_MAS6] & MAS6_SIND) ? MAS1_IND : 0; + /* XXX check for unsupported isize and raise an invalid opcode then */ + int size = env->spr[SPR_BOOKE_MAS6] & MAS6_ISIZE_MASK; + /* XXX implement MAV2 handling */ + bool mav2 = false; + + /* XXX missing LPID handling */ + /* flush by pid and ea */ + for (i = 0; i < BOOKE206_MAX_TLBN; i++) { + int ways = booke206_tlb_ways(env, i); + + for (j = 0; j < ways; j++) { + tlb = booke206_get_tlbm(env, i, address, j); + if ((ppcmas_tlb_check(env, tlb, NULL, address, pid) != 0) || + (tlb->mas1 & MAS1_IPROT) || + ((tlb->mas1 & MAS1_IND) != ind) || + ((tlb->mas8 & MAS8_TGS) != sgs)) { + continue; + } + if (mav2 && ((tlb->mas1 & MAS1_TSIZE_MASK) != size)) { + /* XXX only check when MMUCFG[TWC] || TLBnCFG[HES] */ + continue; + } + /* XXX e500mc doesn't match SAS, but other cores might */ + tlb->mas1 &= ~MAS1_VALID; + } + } + tlb_flush(env, 1); +} + void helper_booke206_tlbflush(uint32_t type) { int flags = 0; diff --git a/target-ppc/translate.c b/target-ppc/translate.c index adde65b..d8ef719 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -6110,6 +6110,39 @@ static void gen_tlbivax_booke206(DisasContext *ctx) #endif } +static void gen_tlbilx_booke206(DisasContext *ctx) +{ +#if defined(CONFIG_USER_ONLY) + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); +#else + TCGv t0; + if (unlikely(!ctx->mem_idx)) { + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); + return; + } + + t0 = tcg_temp_new(); + gen_addr_reg_index(ctx, t0); + + switch((ctx->opcode >> 21) & 0x3) { + case 0: + gen_helper_booke206_tlbilx0(t0); + break; + case 1: + gen_helper_booke206_tlbilx1(t0); + break; + case 3: + gen_helper_booke206_tlbilx3(t0); + break; + default: + gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); + break; + } + + tcg_temp_free(t0); +#endif +} + /* wrtee */ static void gen_wrtee(DisasContext *ctx) @@ -8574,6 +8607,8 @@ GEN_HANDLER2_E(tlbwe_booke206, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_NONE, PPC2_BOOKE206), GEN_HANDLER2_E(tlbivax_booke206, "tlbivax", 0x1F, 0x12, 0x18, 0x00000001, PPC_NONE, PPC2_BOOKE206), +GEN_HANDLER2_E(tlbilx_booke206, "tlbilx", 0x1F, 0x12, 0x00, 0x03800001, + PPC_NONE, PPC2_BOOKE206), GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE), GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE), GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC),