From patchwork Sat May 22 10:52:35 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Igor V. Kovalenko" X-Patchwork-Id: 53267 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 12FBBB7D2D for ; Sat, 22 May 2010 20:57:41 +1000 (EST) Received: from localhost ([127.0.0.1]:46154 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OFmOg-0005EH-5L for incoming@patchwork.ozlabs.org; Sat, 22 May 2010 06:57:38 -0400 Received: from [140.186.70.92] (port=53498 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OFmJs-0003O4-F1 for qemu-devel@nongnu.org; Sat, 22 May 2010 06:52:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OFmJp-0004PY-7Y for qemu-devel@nongnu.org; Sat, 22 May 2010 06:52:40 -0400 Received: from mail-fx0-f45.google.com ([209.85.161.45]:45113) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OFmJp-0004M6-1c for qemu-devel@nongnu.org; Sat, 22 May 2010 06:52:37 -0400 Received: by mail-fx0-f45.google.com with SMTP id 14so550821fxm.4 for ; Sat, 22 May 2010 03:52:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:received:subject:to:from:date :message-id:in-reply-to:references:user-agent:mime-version :content-type:content-transfer-encoding; bh=qDn8e/HYgYRIBp+WDQAVSHHKsgZXxmIf4PNGiGR1d8A=; b=Bpt067XQHcIitWkt6m3uVUS2OZS0WnMegnlRlSLuyjbuusa5asGZ/QtbSSRyDv4ifu V1T9q8Pbn7BZvzZGL3HKIZWcdxPF2fi9ylmWba/9O2OEuoHOBeAY6Xk3YnHVEY4Liefl E0z6bGxO4QB++maoHLGeldHdbXMonHOiUzapI= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=subject:to:from:date:message-id:in-reply-to:references:user-agent :mime-version:content-type:content-transfer-encoding; b=PQrKHAAabZ/B/2kWR5vCnDL3oHLL6BgDW/03do3npQVSX7n1QaAgfub0rfovvjo9On QlNCljO+sJMKv2b8BTpuG4IXj1a3d+mcQDb9o9Y0jONYIANE6jhRoi/1d2o8qujItahO lmoVFvCYOYJDHAcx6Vhdz/6Zg4LyXtU3NWbnE= Received: by 10.223.99.78 with SMTP id t14mr2540455fan.85.1274525556535; Sat, 22 May 2010 03:52:36 -0700 (PDT) Received: from skyserv ([87.255.14.75]) by mx.google.com with ESMTPS id r12sm9041387fah.20.2010.05.22.03.52.35 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sat, 22 May 2010 03:52:36 -0700 (PDT) Received: from localhost ([127.0.0.1] helo=[192.168.1.2]) by skyserv with esmtp (Exim 4.71) (envelope-from ) id 1OFmJn-0004oj-19 for qemu-devel@nongnu.org; Sat, 22 May 2010 14:52:35 +0400 To: qemu-devel@nongnu.org From: "Igor V. Kovalenko" Date: Sat, 22 May 2010 14:52:35 +0400 Message-ID: <20100522105234.18257.53650.stgit@skyserv> In-Reply-To: <20100522104440.18257.92813.stgit@skyserv> References: <20100522104440.18257.92813.stgit@skyserv> User-Agent: StGit/0.15 MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) Subject: [Qemu-devel] [PATCH 4/5] sparc64: fix mmu context at trap levels above zero 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: Igor V. Kovalenko - cpu_mmu_index return MMU_NUCLEUS_IDX if trap level is not zero - cpu_get_tb_cpu_state: store trap level and primary context in flags this allows to restart code translation when address translation is changed - stop translation block after writing to pstate and tl registers - stop translation block after writing to alternate space this can be optimized to stop only if address translation can be changed by write operation (e.g. by comparing with MMU ASI values) Signed-off-by: Igor V. Kovalenko --- target-sparc/cpu.h | 14 ++++++++++---- target-sparc/helper.c | 19 ++++++++++++++++++- target-sparc/translate.c | 10 +++++++--- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index 4fd58e9..8f0484b 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -556,7 +556,9 @@ static inline int cpu_mmu_index(CPUState *env1) #elif !defined(TARGET_SPARC64) return env1->psrs; #else - if (cpu_hypervisor_mode(env1)) { + if (env1->tl > 0) { + return MMU_NUCLEUS_IDX; + } else if (cpu_hypervisor_mode(env1)) { return MMU_HYPV_IDX; } else if (cpu_supervisor_mode(env1)) { return MMU_KERNEL_IDX; @@ -636,9 +638,13 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, *cs_base = env->npc; #ifdef TARGET_SPARC64 // AM . Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled - *flags = ((env->pstate & PS_AM) << 2) - | (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2)) - | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2); + *flags = ((env->pstate & PS_AM) << 2) /* 5 */ + | (((env->pstate & PS_PEF) >> 1) /* 3 */ + | ((env->fprs & FPRS_FEF) << 2)) /* 4 */ + | (env->pstate & PS_PRIV) /* 2 */ + | ((env->lsu & (DMMU_E | IMMU_E)) >> 2) /* 1, 0 */ + | ((env->tl & 0xff) << 8) + | (env->dmmu.mmu_primary_context << 16); /* 16... */ #else // FPU enable . Supervisor *flags = (env->psref << 4) | env->psrs; diff --git a/target-sparc/helper.c b/target-sparc/helper.c index 1045c31..96a22f3 100644 --- a/target-sparc/helper.c +++ b/target-sparc/helper.c @@ -572,6 +572,23 @@ static int get_physical_address(CPUState *env, target_phys_addr_t *physical, /* ??? We treat everything as a small page, then explicitly flush everything when an entry is evicted. */ *page_size = TARGET_PAGE_SIZE; + +#if defined (DEBUG_MMU) + /* safety net to catch wrong softmmu index use from dynamic code */ + if (env->tl > 0 && mmu_idx != MMU_NUCLEUS_IDX) { + DPRINTF_MMU("get_physical_address %s tl=%d mmu_idx=%d" + " primary context=%" PRIx64 + " secondary context=%" PRIx64 + " address=%" PRIx64 + "\n", + (rw == 2 ? "CODE" : "DATA"), + env->tl, mmu_idx, + env->dmmu.mmu_primary_context, + env->dmmu.mmu_secondary_context, + address); + } +#endif + if (rw == 2) return get_physical_address_code(env, physical, prot, address, mmu_idx); @@ -718,7 +735,7 @@ target_phys_addr_t cpu_get_phys_page_nofault(CPUState *env, target_ulong addr, target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) { - return cpu_get_phys_page_nofault(env, addr, MMU_KERNEL_IDX); + return cpu_get_phys_page_nofault(env, addr, cpu_mmu_index(env)); } #endif diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 86096d2..72ca0b4 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -3484,14 +3484,14 @@ static void disas_sparc_insn(DisasContext * dc) case 6: // pstate save_state(dc, cpu_cond); gen_helper_wrpstate(cpu_tmp0); - gen_op_next_insn(); - tcg_gen_exit_tb(0); - dc->is_br = 1; + dc->npc = DYNAMIC_PC; break; case 7: // tl + save_state(dc, cpu_cond); tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0); tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, tl)); + dc->npc = DYNAMIC_PC; break; case 8: // pil gen_helper_wrpil(cpu_tmp0); @@ -4550,6 +4550,7 @@ static void disas_sparc_insn(DisasContext * dc) #endif save_state(dc, cpu_cond); gen_st_asi(cpu_val, cpu_addr, insn, 4); + dc->npc = DYNAMIC_PC; break; case 0x15: /* stba, store byte alternate */ #ifndef TARGET_SPARC64 @@ -4560,6 +4561,7 @@ static void disas_sparc_insn(DisasContext * dc) #endif save_state(dc, cpu_cond); gen_st_asi(cpu_val, cpu_addr, insn, 1); + dc->npc = DYNAMIC_PC; break; case 0x16: /* stha, store halfword alternate */ #ifndef TARGET_SPARC64 @@ -4570,6 +4572,7 @@ static void disas_sparc_insn(DisasContext * dc) #endif save_state(dc, cpu_cond); gen_st_asi(cpu_val, cpu_addr, insn, 2); + dc->npc = DYNAMIC_PC; break; case 0x17: /* stda, store double word alternate */ #ifndef TARGET_SPARC64 @@ -4594,6 +4597,7 @@ static void disas_sparc_insn(DisasContext * dc) case 0x1e: /* V9 stxa */ save_state(dc, cpu_cond); gen_st_asi(cpu_val, cpu_addr, insn, 8); + dc->npc = DYNAMIC_PC; break; #endif default: