From patchwork Wed Jan 24 23:26:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 125752 Delivered-To: patch@linaro.org Received: by 10.46.66.141 with SMTP id h13csp742892ljf; Wed, 24 Jan 2018 15:55:02 -0800 (PST) X-Google-Smtp-Source: AH8x225OPN7SugOrSFzqSUzg/caxSgp8y3XC8yTC8TKUGc08Y1M+HBOfkutKYmq6IJtY2ORD8Eev X-Received: by 10.37.97.75 with SMTP id v72mr6722187ybb.14.1516838102501; Wed, 24 Jan 2018 15:55:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516838102; cv=none; d=google.com; s=arc-20160816; b=x75FQSl4Q1FgsHPgewmDQG63uORfecaYbWeyyN1PXj+1LSnh7JPNVQgSo4v7O8pgXY U6Q9gDGDRBLU2vickymqChGsMkBPNg33Muw04BiCjyueM/EgfyNoEx6+LCab2IKZJlyC a7dYFkLMQH4kkwwidA+KLeuQVDywg3YPgksrUZSSvJKX0bxPj4CkTcAPMlJLjgTDQRXH FnC71awiIX0kH0rakP+3PgJyVu+QW0M7ddYo7B796QaSi8/UWcjqNQjD2aru/+TbSlP/ 5g1npSMWr2oj/9D6CCDhXY6OAgw7TFEeQHJ2p9HrHH20R3EDyzyvZaf6SuBn470EvD35 PYDQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to: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=35pGJnCLY/5W72jYPTV6lM+5a5u4ZQxV/aLV82wAQ+M=; b=kfcScxYR7AH9nIayV2eoya0SJEuC9Zg64Z6CSVBtAzkacAz72ruzg27LdjcpqP/6bY On5KjhJ+jkBmB1cSKMBqSNOxhzmtY0Lh7aCFUSw0ugNitRObsijFm9Evyi/IDwhDhevV W5Wra8IsXs7BriOH9n5Fe01c+ESV4XdNfPTZbW24fT018eSDJASHZINpwP5+T6Dswdtt lVtp3WeXPAQ83LaRl8EY8Pm21aBPYf+cCaYNORbt/BCBDPuSGBUSe5eIsTBKdiO9gdOZ C7JHM2K17lFcz453pAn4U78unlP+a7jCkmzwC3jAO2BnIob4fKZZhHNuJiUisJCuSzPI rq1w== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Mbnq2Jn0; 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 u135si244630ywu.191.2018.01.24.15.55.02 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 24 Jan 2018 15:55:02 -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=Mbnq2Jn0; 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]:55364 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eeUsf-0002dK-Si for patch@linaro.org; Wed, 24 Jan 2018 18:55:01 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51159) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eeURa-0004l3-Q4 for qemu-devel@nongnu.org; Wed, 24 Jan 2018 18:27:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eeURZ-0001vn-8O for qemu-devel@nongnu.org; Wed, 24 Jan 2018 18:27:02 -0500 Received: from mail-pf0-x244.google.com ([2607:f8b0:400e:c00::244]:42713) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eeURY-0001va-W5 for qemu-devel@nongnu.org; Wed, 24 Jan 2018 18:27:01 -0500 Received: by mail-pf0-x244.google.com with SMTP id b25so4353424pfd.9 for ; Wed, 24 Jan 2018 15:27:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references; bh=35pGJnCLY/5W72jYPTV6lM+5a5u4ZQxV/aLV82wAQ+M=; b=Mbnq2Jn0pNbDE8WfTlfGyZB8d2fPlHjlGzbcibMm1Ja+4XU0m9VBbwVUKiOwmlER8b VrvnwhpLda1/1LdDH4wMjEXckt8GXYWbH+RxkFMVvov0Ku50peHnW9nDgt0VKGXVu45s so27TekwjMd/mjdoEhewxo+fNtJ1A0nSvfRs4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=35pGJnCLY/5W72jYPTV6lM+5a5u4ZQxV/aLV82wAQ+M=; b=e2da6cn3AuMr0iF22yutvKW2lWVaBS2kxhnKf+bnDSHVytdaDIEOlXkkXhLls/DBCC JH2YH2va3kR/YOg2N869Mu6G48aIzgQ8A3apbgA81E33HmBPTePBEwU9MpuEYbXo/zbo Y/LYGL97bDWPEe5RVE83SY8qi6uAG0DMqm64iZOF8NxkhmRUQbIR0IE7WV+GeBHYw4jy bd21aX7TmPdT398ut6uJfaQiTuF0F+BIG+RDz88eC1VRsxqbhDrm9zXTY9213mVPrPje vyLAPIgwyF39IYqZaA9K6x3h4H8r0PV1HYMMOFEG5djfQJM2U6wXcKsccm9eYH94OZOY V7TQ== X-Gm-Message-State: AKwxytfkWKpc6fLh6aVQacE5JvBPbZz+iGof/YO24BK5QiClSSIiMyxY 5WvOQLxrEjERRArMhg7f6KdGU+8s00w= X-Received: by 2002:a17:902:be09:: with SMTP id r9-v6mr9599970pls.234.1516836419453; Wed, 24 Jan 2018 15:26:59 -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 z19sm9760028pfh.185.2018.01.24.15.26.58 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 24 Jan 2018 15:26:58 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Wed, 24 Jan 2018 15:26:01 -0800 Message-Id: <20180124232625.30105-22-richard.henderson@linaro.org> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180124232625.30105-1-richard.henderson@linaro.org> References: <20180124232625.30105-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:c00::244 Subject: [Qemu-devel] [PATCH v3 21/45] 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: , 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 08ab19aacf..7c3c7d1415 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); @@ -194,4 +221,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 6288bb9f67..c02d107041 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -1344,7 +1344,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; @@ -1352,7 +1355,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(); @@ -2355,6 +2363,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 */ @@ -2371,6 +2415,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,