From patchwork Mon Jan 22 03:41:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 125312 Delivered-To: patch@linaro.org Received: by 10.46.66.141 with SMTP id h13csp948989ljf; Sun, 21 Jan 2018 20:03:20 -0800 (PST) X-Google-Smtp-Source: AH8x226sChNTnMjBNMgY32dKtLbPuh8OTU3Fikyp+sJ3MAnD617N2f398Ef+vW+44ywnMEcnxJ3P X-Received: by 10.37.7.133 with SMTP id 127mr52409ybh.102.1516593800886; Sun, 21 Jan 2018 20:03:20 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516593800; cv=none; d=google.com; s=arc-20160816; b=FcE6OmnjaXBteY7UpLai4N3nuNYwLifa643/GYzH3mm8N1vzy4XctVFPqf08Ln2+aF W1hknY+PvIav09TuNKT8RyINK9neajpRW+m/dbUjU4txG7OImqNZyNAEk5s+Oy2LTFdq tnMfPg2eqzgI9Ov0JyCVzRJDQNwJjtklpnhVm/K8e0buzEmd1q51bovMRL3ARlPi1wHz Ic7J8vR97FUojwEAyJhRx6HwLseS1q2blJf1qjUEYo78cfyta/AjYOniYTyYVGUIM640 ySiRLyNjJo/5sD9st7nU3EqMd7IKzRRfWTzkNxDRiL/58kvbdvzIr2K+JiqZ8bDoaAuC ZDIQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=/2rSKpbk9ETiNQxE5ni0XU0sffBx0JEdyXh/JE/AM6k=; b=eUijci7TyOORZl0CPoNf9eXmsVBNntNPwfys6e4V7sgfEuQgBhJNHvhagMTMCSwXj4 27f4CANadwim3oDZDyoXqD/4bBpvTwUB5q3CiKfydU3HiWJSdGhpEB8+xtCGrcPe0iE5 +uZerKoIzNQ7pqpZN9X1pRmjr75ULcLIxfoOCubrRIKdEfhvwyJHhKnLSE6ism2b7xup Iim19Sd+1EQzieUgEIY7dhqAEV/B4sd2N4uYXZ1MmzBpOksPG5R1kVWk2Vs/QuHQUxpI NDNhL7Bg+gePSgV/0vGZoaQrqcsS6QHKZV6IhoaAhcoW9cSvjSye6r7F+qf9oqlOpmmU Wt1w== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Tm5kjKYX; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id p204si2036925ywg.406.2018.01.21.20.03.20 for (version=TLS1 cipher=AES128-SHA bits=128/128); Sun, 21 Jan 2018 20:03:20 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Tm5kjKYX; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:41754 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1edTKI-000448-2b for patch@linaro.org; Sun, 21 Jan 2018 23:03:18 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60264) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1edT0X-0005dJ-JH for qemu-devel@nongnu.org; Sun, 21 Jan 2018 22:42:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1edT0W-0006ZQ-25 for qemu-devel@nongnu.org; Sun, 21 Jan 2018 22:42:53 -0500 Received: from mail-pg0-x241.google.com ([2607:f8b0:400e:c05::241]:46297) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1edT0V-0006YF-Qp for qemu-devel@nongnu.org; Sun, 21 Jan 2018 22:42:52 -0500 Received: by mail-pg0-x241.google.com with SMTP id s9so6074193pgq.13 for ; Sun, 21 Jan 2018 19:42:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=/2rSKpbk9ETiNQxE5ni0XU0sffBx0JEdyXh/JE/AM6k=; b=Tm5kjKYXH0Qvu99q4sRWbY4OkH7c4UbGHJnTjaeA3X+pf7wxSz0eQANI2rw7pnKpcQ KnMO34mhYY4B83vVg2Mhv/kZM8sbNoF1uHtGQ7hHExheTCi9mQrZhP7FH71Dtq6SsufF VoHdonZls9O2PxrNh++3CAFBBT8d6EVo+kf3o= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=/2rSKpbk9ETiNQxE5ni0XU0sffBx0JEdyXh/JE/AM6k=; b=tOBJhzWTuFxllmUNLtlgTOVhNB8PrApxON2XnbDSNTYvaZlrDNbT2M1SwNHR4Osr4C 0rbxQyGujJyM1ngIx7dlOCtVw6PrEEtj58RWGYUEwUxQ3nGljrbVtCY7QJ7JhY8Q5Vfn 3s6zNE2Na3ZWCpB5JaC8BzRx17XsrD7mWe8CBFNBRFDvBdMCeyinyI0DKZvYiLPRcRTM hxkN3/Nzm0VbHDLjwuPA7oPmNWuyUl6uaEyauM8lrRmPRpuhds87mmyHOC7l+tEVPU93 2aYuyLpvCS+97Ld0UW/NxzZhrmvB9DAVJ5ls21/j6wpxKV+VA6f3Qi5O7lH1KHNgKvIH 6Grg== X-Gm-Message-State: AKwxytfXMW1AW4tDrm5cPVFJs61/3GBshuUaHxFjEhP/Ennkrmc2vms1 CSSwexKFL4kLTJ+8HsEX7l/m0zRBtgE= X-Received: by 10.99.94.193 with SMTP id s184mr6289420pgb.325.1516592570544; Sun, 21 Jan 2018 19:42:50 -0800 (PST) Received: from cloudburst.twiddle.net (174-21-6-47.tukw.qwest.net. [174.21.6.47]) by smtp.gmail.com with ESMTPSA id z125sm182023pfz.27.2018.01.21.19.42.49 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 21 Jan 2018 19:42:49 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sun, 21 Jan 2018 19:41:55 -0800 Message-Id: <20180122034217.19593-22-richard.henderson@linaro.org> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180122034217.19593-1-richard.henderson@linaro.org> References: <20180122034217.19593-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c05::241 Subject: [Qemu-devel] [PULL 21/43] target/hppa: Implement I*TLBA and I*TLBP insns X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" The TLB can now be populated, but it cannot yet be cleared. Signed-off-by: Richard Henderson --- target/hppa/helper.h | 2 ++ target/hppa/mem_helper.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++-- target/hppa/translate.c | 54 ++++++++++++++++++++++++++++++-- 3 files changed, 132 insertions(+), 4 deletions(-) -- 2.14.3 diff --git a/target/hppa/helper.h b/target/hppa/helper.h index 744b11cb66..d412093914 100644 --- a/target/hppa/helper.h +++ b/target/hppa/helper.h @@ -86,4 +86,6 @@ DEF_HELPER_FLAGS_2(write_interval_timer, TCG_CALL_NO_RWG, void, env, tr) DEF_HELPER_FLAGS_2(write_eirr, TCG_CALL_NO_RWG, void, env, tr) DEF_HELPER_FLAGS_2(write_eiem, TCG_CALL_NO_RWG, void, env, tr) DEF_HELPER_FLAGS_2(swap_system_mask, TCG_CALL_NO_RWG, tr, env, tr) +DEF_HELPER_FLAGS_3(itlba, TCG_CALL_NO_RWG, void, env, tl, tr) +DEF_HELPER_FLAGS_3(itlbp, TCG_CALL_NO_RWG, void, env, tl, tr) #endif diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c index 4e92e35957..9d4bf132d6 100644 --- a/target/hppa/mem_helper.c +++ b/target/hppa/mem_helper.c @@ -42,13 +42,40 @@ static hppa_tlb_entry *hppa_find_tlb(CPUHPPAState *env, vaddr addr) for (i = 0; i < ARRAY_SIZE(env->tlb); ++i) { hppa_tlb_entry *ent = &env->tlb[i]; - if (ent->va_b <= addr && addr <= ent->va_e && ent->entry_valid) { + if (ent->va_b <= addr && addr <= ent->va_e) { return ent; } } return NULL; } +static void hppa_flush_tlb_ent(CPUHPPAState *env, hppa_tlb_entry *ent) +{ + CPUState *cs = CPU(hppa_env_get_cpu(env)); + unsigned i, n = 1 << (2 * ent->page_size); + uint64_t addr = ent->va_b; + + for (i = 0; i < n; ++i, addr += TARGET_PAGE_SIZE) { + /* Do not flush MMU_PHYS_IDX. */ + tlb_flush_page_by_mmuidx(cs, addr, 0xf); + } + + memset(ent, 0, sizeof(*ent)); + ent->va_b = -1; +} + +static hppa_tlb_entry *hppa_alloc_tlb_ent(CPUHPPAState *env) +{ + hppa_tlb_entry *ent; + uint32_t i = env->tlb_last; + + env->tlb_last = (i == ARRAY_SIZE(env->tlb) - 1 ? 0 : i + 1); + ent = &env->tlb[i]; + + hppa_flush_tlb_ent(env, ent); + return ent; +} + int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx, MMUAccessType type, hwaddr *pphys, int *pprot) { @@ -67,7 +94,7 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx, /* Find a valid tlb entry that matches the virtual address. */ ent = hppa_find_tlb(env, addr); - if (ent == NULL) { + if (ent == NULL || !ent->entry_valid) { phys = 0; prot = 0; ret = (ifetch ? EXCP_ITLB_MISS : EXCP_DTLB_MISS); @@ -192,4 +219,53 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType type, tlb_set_page(cs, addr & TARGET_PAGE_MASK, phys & TARGET_PAGE_MASK, prot, mmu_idx, TARGET_PAGE_SIZE); } + +/* Insert (Insn/Data) TLB Address. Note this is PA 1.1 only. */ +void HELPER(itlba)(CPUHPPAState *env, target_ulong addr, target_ureg reg) +{ + hppa_tlb_entry *empty = NULL; + int i; + + /* Zap any old entries covering ADDR; notice empty entries on the way. */ + for (i = 0; i < ARRAY_SIZE(env->tlb); ++i) { + hppa_tlb_entry *ent = &env->tlb[i]; + if (!ent->entry_valid) { + empty = ent; + } else if (ent->va_b <= addr && addr <= ent->va_e) { + hppa_flush_tlb_ent(env, ent); + empty = ent; + } + } + + /* If we didn't see an empty entry, evict one. */ + if (empty == NULL) { + empty = hppa_alloc_tlb_ent(env); + } + + /* Note that empty->entry_valid == 0 already. */ + empty->va_b = addr & TARGET_PAGE_MASK; + empty->va_e = empty->va_b + TARGET_PAGE_SIZE - 1; + empty->pa = extract32(reg, 5, 20) << TARGET_PAGE_BITS; +} + +/* Insert (Insn/Data) TLB Protection. Note this is PA 1.1 only. */ +void HELPER(itlbp)(CPUHPPAState *env, target_ulong addr, target_ureg reg) +{ + hppa_tlb_entry *ent = hppa_find_tlb(env, addr); + + if (unlikely(ent == NULL || ent->entry_valid)) { + qemu_log_mask(LOG_GUEST_ERROR, "ITLBP not following ITLBA\n"); + return; + } + + ent->access_id = extract32(reg, 1, 18); + ent->u = extract32(reg, 19, 1); + ent->ar_pl2 = extract32(reg, 20, 2); + ent->ar_pl1 = extract32(reg, 22, 2); + ent->ar_type = extract32(reg, 24, 3); + ent->b = extract32(reg, 27, 1); + ent->d = extract32(reg, 28, 1); + ent->t = extract32(reg, 29, 1); + ent->entry_valid = 1; +} #endif /* CONFIG_USER_ONLY */ diff --git a/target/hppa/translate.c b/target/hppa/translate.c index 7334206b44..af84f4d55f 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -1333,7 +1333,10 @@ static DisasJumpType do_unit(DisasContext *ctx, unsigned rt, TCGv_reg in1, } #ifndef CONFIG_USER_ONLY -/* Top 2 bits of the base register select sp[4-7]. */ +/* The "normal" usage is SP >= 0, wherein SP == 0 selects the space + from the top 2 bits of the base register. There are a few system + instructions that have a 3-bit space specifier, for which SR0 is + not special. To handle this, pass ~SP. */ static TCGv_i64 space_select(DisasContext *ctx, int sp, TCGv_reg base) { TCGv_ptr ptr; @@ -1341,7 +1344,12 @@ static TCGv_i64 space_select(DisasContext *ctx, int sp, TCGv_reg base) TCGv_i64 spc; if (sp != 0) { - return cpu_sr[sp]; + if (sp < 0) { + sp = ~sp; + } + spc = get_temp_tl(ctx); + load_spr(ctx, spc, sp); + return spc; } ptr = tcg_temp_new_ptr(); @@ -2344,6 +2352,42 @@ static DisasJumpType trans_probe(DisasContext *ctx, uint32_t insn, return nullify_end(ctx, DISAS_NEXT); } +#ifndef CONFIG_USER_ONLY +static DisasJumpType trans_ixtlbx(DisasContext *ctx, uint32_t insn, + const DisasInsn *di) +{ + unsigned sp; + unsigned rr = extract32(insn, 16, 5); + unsigned rb = extract32(insn, 21, 5); + unsigned is_data = insn & 0x1000; + unsigned is_addr = insn & 0x40; + TCGv_tl addr; + TCGv_reg ofs, reg; + + if (is_data) { + sp = extract32(insn, 14, 2); + } else { + sp = ~assemble_sr3(insn); + } + + CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR); + nullify_over(ctx); + + form_gva(ctx, &addr, &ofs, rb, 0, 0, 0, sp, 0, false); + reg = load_gpr(ctx, rr); + if (is_addr) { + gen_helper_itlba(cpu_env, addr, reg); + } else { + gen_helper_itlbp(cpu_env, addr, reg); + } + + /* Exit TB for ITLB change if mmu is enabled. This *should* not be + the case, since the OS TLB fill handler runs with mmu disabled. */ + return nullify_end(ctx, !is_data && (ctx->base.tb->flags & PSW_C) + ? DISAS_IAQ_N_STALE : DISAS_NEXT); +} +#endif /* !CONFIG_USER_ONLY */ + static const DisasInsn table_mem_mgmt[] = { { 0x04003280u, 0xfc003fffu, trans_nop }, /* fdc, disp */ { 0x04001280u, 0xfc003fffu, trans_nop }, /* fdc, index */ @@ -2360,6 +2404,12 @@ static const DisasInsn table_mem_mgmt[] = { { 0x04002720u, 0xfc003fffu, trans_base_idx_mod }, /* pdc, base mod */ { 0x04001180u, 0xfc003fa0u, trans_probe }, /* probe */ { 0x04003180u, 0xfc003fa0u, trans_probe }, /* probei */ +#ifndef CONFIG_USER_ONLY + { 0x04000000u, 0xfc001fffu, trans_ixtlbx }, /* iitlbp */ + { 0x04000040u, 0xfc001fffu, trans_ixtlbx }, /* iitlba */ + { 0x04001000u, 0xfc001fffu, trans_ixtlbx }, /* idtlbp */ + { 0x04001040u, 0xfc001fffu, trans_ixtlbx }, /* idtlba */ +#endif }; static DisasJumpType trans_add(DisasContext *ctx, uint32_t insn,