From 4071f20ce2f71f76af6fd0d5e24a65616c5b4a32 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 15 Feb 2018 10:22:48 -0500 Subject: [PATCH] target-arm: Implement AArch64 TLBI operations on IPAs Implement the AArch64 TLBI operations which take an intermediate physical address and invalidate stage 2 translations. Backports commit cea66e91212164e02ad1d245c2371f7e8eb59e7f from qemu --- qemu/target-arm/helper.c | 53 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/qemu/target-arm/helper.c b/qemu/target-arm/helper.c index f1229802..d2e66450 100644 --- a/qemu/target-arm/helper.c +++ b/qemu/target-arm/helper.c @@ -2409,6 +2409,47 @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri, */ } +static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + /* Invalidate by IPA. This has to invalidate any structures that + * contain only stage 2 translation information, but does not need + * to apply to structures that contain combined stage 1 and stage 2 + * translation information. + * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero. + */ + ARMCPU *cpu = arm_env_get_cpu(env); + CPUState *cs = CPU(cpu); + uint64_t pageaddr; + + if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) { + return; + } + + pageaddr = sextract64(value << 12, 0, 48); + + tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdx_S2NS, -1); +} + +static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ +/* UNICORN: TODO: issue #642 + CPUState *other_cs; + uint64_t pageaddr; + + if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) { + return; + } + + pageaddr = sextract64(value << 12, 0, 48); + + CPU_FOREACH(other_cs) { + tlb_flush_page_by_mmuidx(other_cs, pageaddr, ARMMMUIdx_S2NS, -1); + } +*/ +} + static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri) { /* We don't implement EL2, so the only control on DC ZVA is the @@ -2563,9 +2604,21 @@ static const ARMCPRegInfo v8_cp_reginfo[] = { { "TLBI_VMALLS12E1IS", 0,8,3, 1,4,6, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, PL2_W, 0, NULL, 0, 0, {0, 0}, NULL, NULL, tlbi_aa64_alle1is_write }, + { "TLBI_IPAS2E1IS", 0,8,0, 1,4,1, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, + PL2_W, 0, NULL, 0, 0, {0, 0}, + NULL, NULL, tlbi_aa64_ipas2e1is_write }, + { "TLBI_IPAS2LE1IS", 0,8,0, 1,4,5, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, + PL2_W, 0, NULL, 0, 0, {0, 0}, + NULL, NULL, tlbi_aa64_ipas2e1is_write }, { "TLBI_ALLE1IS", 0,8,3, 1,4,4, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, PL2_W, 0, NULL, 0, 0, {0, 0}, NULL, NULL, tlbi_aa64_alle1is_write }, + { "TLBI_IPAS2E1", 0,8,4, 1,4,1, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, + PL2_W, 0, NULL, 0, 0, {0, 0}, + NULL, NULL, tlbi_aa64_ipas2e1_write }, + { "TLBI_IPAS2LE1", 0,8,4, 1,4,5, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, + PL2_W, 0, NULL, 0, 0, {0, 0}, + NULL, NULL, tlbi_aa64_ipas2e1_write }, { "TLBI_ALLE1", 0,8,7, 1,4,4, ARM_CP_STATE_AA64, ARM_CP_NO_RAW, PL2_W, 0, NULL, 0, 0, {0, 0}, NULL, NULL, tlbi_aa64_alle1_write },