From patchwork Sun Jan 28 23:15:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 126113 Delivered-To: patch@linaro.org Received: by 10.46.84.92 with SMTP id y28csp1984331ljd; Sun, 28 Jan 2018 15:37:38 -0800 (PST) X-Google-Smtp-Source: AH8x224romNBh42bocFhzp9M3oQAZxcw0f48YCWA4ZXzBoJ35GaajqVWjfw8JItrmUdCyGkxwJcK X-Received: by 10.129.62.11 with SMTP id l11mr15612340ywa.244.1517182657911; Sun, 28 Jan 2018 15:37:37 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517182657; cv=none; d=google.com; s=arc-20160816; b=hTaRC9ZQOGuDdY1ZlZlEyrHTS7Gi5y65+khilfXA0HxWqYvrDndImBP3+Fya4J4bm7 a5U1t9cV0y9nszYYB9UV/bBKbg1p214mGPIqRLNNUOoVuIUnfEo2X2d623hB9he0qZeI STTdVbN9ZKSswOKxRQCTBN8RGfA0NI7QM9XOsgdERRrKIHA2UtNkogm0f33GM8B7NWlZ J6AMmbkguRZaibDa9WRoqqJMnHwiIDJwtnwZ1r5nN0aN0iCGEAT6Vdr1tQqzxhILN99B Zx57dYt7SptfDDKf6reQbm/XZaiFKKWwYmUII3ieYHGFzcpnASov5/KmuoV9Rq5/ePjq SMlQ== 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=A4LkY+HD8YP2w0ouXr8w+4csXWsNMSUCJDLYAt6sfi4=; b=yaQ6vU6HxTDI7ltG7BFmMxOZsqe0+JPkVuFjFDOwaJj8gN0CP7Ccub0pP5CisbjhrZ ghgbMB/q3D/ch4wnri/0Y0R1FYScHs/FCb+EUpqxDwtY5hJbV/NWs35zq9vuNgWYWqMt FO+Y/UEdgaNg2vk/+htnvhcisVhPi/Pk1g9+AtRoDPVcAGfywSWmjMoKDOUFjvxU9uoS PJzv1ae2h8dqMeGa10ORQwv1UWPAFnSPB8nMvsm/BYbc3qZar3RePjQFwzD50HP3qu8H 6zRbipYMXBKLN0OMiHeaqSuDHrJCuzXglSXbgPw5IWYMrW5hcQ04PkJE44aR3TYYgk54 HFmw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Vwgjti9+; 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 b67si4521965ybc.215.2018.01.28.15.37.37 for (version=TLS1 cipher=AES128-SHA bits=128/128); Sun, 28 Jan 2018 15:37:37 -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=Vwgjti9+; 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]:45046 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1efwW1-0002G6-7C for patch@linaro.org; Sun, 28 Jan 2018 18:37:37 -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) 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-Received: by 10.98.57.142 with SMTP id u14mr25095116pfj.237.1517181364167; Sun, 28 Jan 2018 15:16:04 -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) 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+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 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) 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, int type, hwaddr *pphys, int *pprot) { @@ -66,7 +93,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 = (type & PAGE_EXEC ? EXCP_ITLB_MISS : EXCP_DTLB_MISS); @@ -201,4 +228,53 @@ void tlb_fill(CPUState *cs, target_ulong addr, int size, 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,