From nobody Tue Feb 10 20:47:42 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1517182755419917.4311866601303; Sun, 28 Jan 2018 15:39:15 -0800 (PST) Received: from localhost ([::1]:45056 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1efwXa-0003Ry-FJ for importer@patchew.org; Sun, 28 Jan 2018 18:39:14 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52173) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1efwBD-0002tA-D1 for qemu-devel@nongnu.org; Sun, 28 Jan 2018 18:16:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1efwBB-000059-Nh for qemu-devel@nongnu.org; Sun, 28 Jan 2018 18:16:07 -0500 Received: from mail-pf0-x244.google.com ([2607:f8b0:400e:c00::244]:39395) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1efwBB-0008WD-En for qemu-devel@nongnu.org; Sun, 28 Jan 2018 18:16:05 -0500 Received: by mail-pf0-x244.google.com with SMTP id e11so3257964pff.6 for ; Sun, 28 Jan 2018 15:16:05 -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 r27sm26949344pfj.75.2018.01.28.15.16.02 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 28 Jan 2018 15:16:03 -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=A4LkY+HD8YP2w0ouXr8w+4csXWsNMSUCJDLYAt6sfi4=; b=Vwgjti9+yDKhEBZqmjuUumNjUvUMpg3KpTxOJqcHMLODn79V/394OBknNPANOswNPx Qc+xXh+6XzsA6RFhzcGmPnZNOE7LKkG10iDfdH4RnnmG7QCM5UUx7PysvohBa0Yc6G1M fT7FMpoX2M4VDN9ajOL8xb1mrnGlCZ8S0pwVs= 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=A4LkY+HD8YP2w0ouXr8w+4csXWsNMSUCJDLYAt6sfi4=; b=leMlsNjUSDUGPKUI5v3Qi3xSOHYI88slvHAggxa/+VCayRNorc0YetNKSYQ+E9gYhf 2iCiohSH/pKT2uqPMIM8J2NjV9ynCNgwpK4p2qHCBv3w4pQF4Nop4rZnfqS2tEPx6NHB OzkYIsA7YGg8E839fBO+QS3VjKkzeeJ2KWMc0x+jENfBJyMmoIyptFiH+ZfJET7fI5yP 6d4KroZYVClIRzUULaSF6+V4NLztkSy7hCc001z4rBktCYGE3v5nTHE0QZTYNinkBiRy SnRIpscd1boEkOk58y9VtFUUartqFqJh0IxlzpbgyYGsRltO1LeiLGhQdPcQgZwEowp0 fZBA== X-Gm-Message-State: AKwxytfYLV0nyPYBY9rhalYWnjVfu0ger/RF5ta04PTrtNW7lg0OO6BK wwoysSmBNOBFUjab/sU/V/VOFXmb+JY= X-Google-Smtp-Source: AH8x225dLPKWjmRzy4uyhs8DZj7fd5FX68Xcx/ZB7IlbRfN9Og5p0H/T2fuwzNuawEH+ta562y3t4g== X-Received: by 10.98.57.142 with SMTP id u14mr25095116pfj.237.1517181364167; Sun, 28 Jan 2018 15:16:04 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sun, 28 Jan 2018 15:15:06 -0800 Message-Id: <20180128231528.22719-22-richard.henderson@linaro.org> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180128231528.22719-1-richard.henderson@linaro.org> References: <20180128231528.22719-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] [PULL v4 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+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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(-) 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 67c57d9a41..47f630d268 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) =20 for (i =3D 0; i < ARRAY_SIZE(env->tlb); ++i) { hppa_tlb_entry *ent =3D &env->tlb[i]; - if (ent->va_b <=3D addr && addr <=3D ent->va_e && ent->entry_valid= ) { + if (ent->va_b <=3D addr && addr <=3D ent->va_e) { return ent; } } return NULL; } =20 +static void hppa_flush_tlb_ent(CPUHPPAState *env, hppa_tlb_entry *ent) +{ + CPUState *cs =3D CPU(hppa_env_get_cpu(env)); + unsigned i, n =3D 1 << (2 * ent->page_size); + uint64_t addr =3D ent->va_b; + + for (i =3D 0; i < n; ++i, addr +=3D 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 =3D -1; +} + +static hppa_tlb_entry *hppa_alloc_tlb_ent(CPUHPPAState *env) +{ + hppa_tlb_entry *ent; + uint32_t i =3D env->tlb_last; + + env->tlb_last =3D (i =3D=3D ARRAY_SIZE(env->tlb) - 1 ? 0 : i + 1); + ent =3D &env->tlb[i]; + + hppa_flush_tlb_ent(env, ent); + return ent; +} + int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx, int type, hwaddr *pphys, int *pprot) { @@ -66,7 +93,7 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr ad= dr, int mmu_idx, =20 /* Find a valid tlb entry that matches the virtual address. */ ent =3D hppa_find_tlb(env, addr); - if (ent =3D=3D NULL) { + if (ent =3D=3D NULL || !ent->entry_valid) { phys =3D 0; prot =3D 0; ret =3D (type & PAGE_EXEC ? EXCP_ITLB_MISS : EXCP_DTLB_MISS); @@ -201,4 +228,53 @@ void tlb_fill(CPUState *cs, target_ulong addr, int siz= e, 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 =3D NULL; + int i; + + /* Zap any old entries covering ADDR; notice empty entries on the way.= */ + for (i =3D 0; i < ARRAY_SIZE(env->tlb); ++i) { + hppa_tlb_entry *ent =3D &env->tlb[i]; + if (!ent->entry_valid) { + empty =3D ent; + } else if (ent->va_b <=3D addr && addr <=3D ent->va_e) { + hppa_flush_tlb_ent(env, ent); + empty =3D ent; + } + } + + /* If we didn't see an empty entry, evict one. */ + if (empty =3D=3D NULL) { + empty =3D hppa_alloc_tlb_ent(env); + } + + /* Note that empty->entry_valid =3D=3D 0 already. */ + empty->va_b =3D addr & TARGET_PAGE_MASK; + empty->va_e =3D empty->va_b + TARGET_PAGE_SIZE - 1; + empty->pa =3D 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 =3D hppa_find_tlb(env, addr); + + if (unlikely(ent =3D=3D NULL || ent->entry_valid)) { + qemu_log_mask(LOG_GUEST_ERROR, "ITLBP not following ITLBA\n"); + return; + } + + ent->access_id =3D extract32(reg, 1, 18); + ent->u =3D extract32(reg, 19, 1); + ent->ar_pl2 =3D extract32(reg, 20, 2); + ent->ar_pl1 =3D extract32(reg, 22, 2); + ent->ar_type =3D extract32(reg, 24, 3); + ent->b =3D extract32(reg, 27, 1); + ent->d =3D extract32(reg, 28, 1); + ent->t =3D extract32(reg, 29, 1); + ent->entry_valid =3D 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, unsi= gned rt, TCGv_reg in1, } =20 #ifndef CONFIG_USER_ONLY -/* Top 2 bits of the base register select sp[4-7]. */ +/* The "normal" usage is SP >=3D 0, wherein SP =3D=3D 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; =20 if (sp !=3D 0) { - return cpu_sr[sp]; + if (sp < 0) { + sp =3D ~sp; + } + spc =3D get_temp_tl(ctx); + load_spr(ctx, spc, sp); + return spc; } =20 ptr =3D tcg_temp_new_ptr(); @@ -2355,6 +2363,42 @@ static DisasJumpType trans_probe(DisasContext *ctx, = uint32_t insn, return nullify_end(ctx, DISAS_NEXT); } =20 +#ifndef CONFIG_USER_ONLY +static DisasJumpType trans_ixtlbx(DisasContext *ctx, uint32_t insn, + const DisasInsn *di) +{ + unsigned sp; + unsigned rr =3D extract32(insn, 16, 5); + unsigned rb =3D extract32(insn, 21, 5); + unsigned is_data =3D insn & 0x1000; + unsigned is_addr =3D insn & 0x40; + TCGv_tl addr; + TCGv_reg ofs, reg; + + if (is_data) { + sp =3D extract32(insn, 14, 2); + } else { + sp =3D ~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 =3D 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[] =3D { { 0x04003280u, 0xfc003fffu, trans_nop }, /* fdc, disp */ { 0x04001280u, 0xfc003fffu, trans_nop }, /* fdc, index */ @@ -2371,6 +2415,12 @@ static const DisasInsn table_mem_mgmt[] =3D { { 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 }; =20 static DisasJumpType trans_add(DisasContext *ctx, uint32_t insn, --=20 2.14.3