From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50022) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bHQSd-0007Sx-5u for qemu-devel@nongnu.org; Mon, 27 Jun 2016 02:56:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bHQSZ-0005RV-5N for qemu-devel@nongnu.org; Mon, 27 Jun 2016 02:55:59 -0400 Received: from 4.mo177.mail-out.ovh.net ([46.105.37.72]:59407) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bHQSY-0005RM-Rp for qemu-devel@nongnu.org; Mon, 27 Jun 2016 02:55:55 -0400 Received: from player699.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo177.mail-out.ovh.net (Postfix) with ESMTP id 42CACFF97A6 for ; Mon, 27 Jun 2016 08:55:54 +0200 (CEST) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 27 Jun 2016 08:55:16 +0200 Message-Id: <1467010521-6106-4-git-send-email-clg@kaod.org> In-Reply-To: <1467010521-6106-1-git-send-email-clg@kaod.org> References: <1467010521-6106-1-git-send-email-clg@kaod.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PATCH 3/8] ppc: Use a helper to filter writes to LPCR List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-ppc@nongnu.org Cc: David Gibson , Alexander Graf , qemu-devel@nongnu.org, Benjamin Herrenschmidt , Cedric Le Goater From: Benjamin Herrenschmidt This handles filtering bits based on what is implemented by a given architecture version. We also use it to copy to LPCR some of the relevant 970 HID4 bits. Signed-off-by: Benjamin Herrenschmidt [clg: fixed checkpatch.pl errors ] Signed-off-by: C=C3=A9dric Le Goater --- target-ppc/helper.h | 1 + target-ppc/mmu-hash64.c | 57 +++++++++++++++++++++++++++++++++++++++= ++++++ target-ppc/translate_init.c | 56 +++++++++++++++++++++++++++++----------= ----- 3 files changed, 95 insertions(+), 19 deletions(-) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 5056ac209572..c532b44847e4 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -16,6 +16,7 @@ DEF_HELPER_1(rfmci, void, env) DEF_HELPER_2(pminsn, void, env, i32) DEF_HELPER_1(rfid, void, env) DEF_HELPER_1(hrfid, void, env) +DEF_HELPER_2(store_lpcr, void, env, tl) #endif DEF_HELPER_1(check_tlb_flush, void, env) #endif diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c index 5b7b5e9eb10c..6d6f26c92957 100644 --- a/target-ppc/mmu-hash64.c +++ b/target-ppc/mmu-hash64.c @@ -851,3 +851,60 @@ void ppc_hash64_tlb_flush_hpte(PowerPCCPU *cpu, */ tlb_flush(CPU(cpu), 1); } + +void helper_store_lpcr(CPUPPCState *env, target_ulong val) +{ + uint64_t lpcr =3D 0; + + /* Filter out bits */ + switch (env->mmu_model) { + case POWERPC_MMU_64B: /* 970 */ + if (val & 0x40) { + lpcr |=3D LPCR_LPES0; + } + if (val & 0x8000000000000000ull) { + lpcr |=3D LPCR_LPES1; + } + if (val & 0x20) { + lpcr |=3D (0x4ull << LPCR_RMLS_SHIFT); + } + if (val & 0x4000000000000000ull) { + lpcr |=3D (0x2ull << LPCR_RMLS_SHIFT); + } + if (val & 0x2000000000000000ull) { + lpcr |=3D (0x1ull << LPCR_RMLS_SHIFT); + } + env->spr[SPR_RMOR] =3D ((lpcr >> 41) & 0xffffull) << 26; + + /* XXX We could also write LPID from HID4 here + * but since we don't tag any translation on it + * it doesn't actually matter + */ + /* XXX For proper emulation of 970 we also need + * to dig HRMOR out of HID5 + */ + break; + case POWERPC_MMU_2_03: /* P5p */ + lpcr =3D val & (LPCR_RMLS | LPCR_ILE | + LPCR_LPES0 | LPCR_LPES1 | + LPCR_RMI | LPCR_HDICE); + break; + case POWERPC_MMU_2_06: /* P7 */ + lpcr =3D val & (LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_DPFD | + LPCR_VRMASD | LPCR_RMLS | LPCR_ILE | + LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2 | + LPCR_MER | LPCR_TC | + LPCR_LPES0 | LPCR_LPES1 | LPCR_HDICE); + break; + case POWERPC_MMU_2_07: /* P8 */ + lpcr =3D val & (LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV | + LPCR_DPFD | LPCR_VRMASD | LPCR_RMLS | LPCR_ILE | + LPCR_AIL | LPCR_ONL | LPCR_P8_PECE0 | LPCR_P8_PECE= 1 | + LPCR_P8_PECE2 | LPCR_P8_PECE3 | LPCR_P8_PECE4 | + LPCR_MER | LPCR_TC | LPCR_LPES0 | LPCR_HDICE); + break; + default: + ; + } + env->spr[SPR_LPCR] =3D lpcr; +} diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index d32845526e6b..af7a790f449f 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7525,16 +7525,6 @@ static void gen_spr_970_hior(CPUPPCState *env) 0x00000000); } =20 -static void gen_spr_970_lpar(CPUPPCState *env) -{ - /* Logical partitionning */ - /* PPC970: HID4 is effectively the LPCR */ - spr_register(env, SPR_970_HID4, "HID4", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); -} - static void gen_spr_book3s_common(CPUPPCState *env) { spr_register(env, SPR_CTRL, "SPR_CTRL", @@ -7787,15 +7777,6 @@ static void gen_spr_power5p_ear(CPUPPCState *env) 0x00000000); } =20 -static void gen_spr_power5p_lpar(CPUPPCState *env) -{ - /* Logical partitionning */ - spr_register_kvm(env, SPR_LPCR, "LPCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_LPCR, LPCR_LPES0 | LPCR_LPES1); -} - #if !defined(CONFIG_USER_ONLY) static void spr_write_hmer(DisasContext *ctx, int sprn, int gprn) { @@ -7807,7 +7788,44 @@ static void spr_write_hmer(DisasContext *ctx, int = sprn, int gprn) spr_store_dump_spr(sprn); tcg_temp_free(hmer); } + +static void spr_write_lpcr(DisasContext *ctx, int sprn, int gprn) +{ + gen_helper_store_lpcr(cpu_env, cpu_gpr[gprn]); +} + +static void spr_write_970_hid4(DisasContext *ctx, int sprn, int gprn) +{ +#if defined(TARGET_PPC64) + spr_write_generic(ctx, sprn, gprn); + gen_helper_store_lpcr(cpu_env, cpu_gpr[gprn]); +#endif +} + +#endif /* !defined(CONFIG_USER_ONLY) */ + +static void gen_spr_970_lpar(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + /* Logical partitionning */ + /* PPC970: HID4 is effectively the LPCR */ + spr_register(env, SPR_970_HID4, "HID4", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_970_hid4, + 0x00000000); +#endif +} + +static void gen_spr_power5p_lpar(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + /* Logical partitionning */ + spr_register_kvm(env, SPR_LPCR, "LPCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_lpcr, + KVM_REG_PPC_LPCR, LPCR_LPES0 | LPCR_LPES1); #endif +} =20 static void gen_spr_book3s_ids(CPUPPCState *env) { --=20 2.1.4