All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Henrique Barboza <danielhb413@gmail.com>
To: qemu-devel@nongnu.org
Cc: qemu-ppc@nongnu.org, danielhb413@gmail.com,
	peter.maydell@linaro.org, richard.henderson@linaro.org,
	Leandro Lupori <leandro.lupori@eldorado.org.br>
Subject: [PULL 15/30] target/ppc: Implement ISA 3.00 tlbie[l]
Date: Mon, 18 Jul 2022 14:21:53 -0300	[thread overview]
Message-ID: <20220718172208.1247624-16-danielhb413@gmail.com> (raw)
In-Reply-To: <20220718172208.1247624-1-danielhb413@gmail.com>

From: Leandro Lupori <leandro.lupori@eldorado.org.br>

This initial version supports the invalidation of one or all
TLB entries. Flush by PID/LPID, or based in process/partition
scope is not supported, because it would make using the
generic QEMU TLB implementation hard. In these cases, all
entries are flushed.

Signed-off-by: Leandro Lupori <leandro.lupori@eldorado.org.br>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Message-Id: <20220712193741.59134-3-leandro.lupori@eldorado.org.br>
[danielhb: moved 'set' declaration to TLBIE_RIC_PWC block]
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
---
 target/ppc/helper.h                          |   2 +
 target/ppc/mmu-book3s-v3.h                   |  15 ++
 target/ppc/mmu_helper.c                      | 154 +++++++++++++++++++
 target/ppc/translate/storage-ctrl-impl.c.inc |  17 ++
 4 files changed, 188 insertions(+)

diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 2f112b7de0..294ef1396b 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -674,6 +674,8 @@ DEF_HELPER_FLAGS_1(tlbia, TCG_CALL_NO_RWG, void, env)
 DEF_HELPER_FLAGS_2(tlbie, TCG_CALL_NO_RWG, void, env, tl)
 DEF_HELPER_FLAGS_2(tlbiva, TCG_CALL_NO_RWG, void, env, tl)
 #if defined(TARGET_PPC64)
+DEF_HELPER_FLAGS_4(tlbie_isa300, TCG_CALL_NO_WG, void, \
+        env, tl, tl, i32)
 DEF_HELPER_FLAGS_3(store_slb, TCG_CALL_NO_RWG, void, env, tl, tl)
 DEF_HELPER_2(load_slb_esid, tl, env, tl)
 DEF_HELPER_2(load_slb_vsid, tl, env, tl)
diff --git a/target/ppc/mmu-book3s-v3.h b/target/ppc/mmu-book3s-v3.h
index d6d5ed8f8e..674377a19e 100644
--- a/target/ppc/mmu-book3s-v3.h
+++ b/target/ppc/mmu-book3s-v3.h
@@ -50,6 +50,21 @@ struct prtb_entry {
 
 #ifdef TARGET_PPC64
 
+/*
+ * tlbie[l] helper flags
+ *
+ * RIC, PRS, R and local are passed as flags in the last argument.
+ */
+#define TLBIE_F_RIC_SHIFT       0
+#define TLBIE_F_PRS_SHIFT       2
+#define TLBIE_F_R_SHIFT         3
+#define TLBIE_F_LOCAL_SHIFT     4
+
+#define TLBIE_F_RIC_MASK        (3 << TLBIE_F_RIC_SHIFT)
+#define TLBIE_F_PRS             (1 << TLBIE_F_PRS_SHIFT)
+#define TLBIE_F_R               (1 << TLBIE_F_R_SHIFT)
+#define TLBIE_F_LOCAL           (1 << TLBIE_F_LOCAL_SHIFT)
+
 static inline bool ppc64_use_proc_tbl(PowerPCCPU *cpu)
 {
     return !!(cpu->env.spr[SPR_LPCR] & LPCR_UPRT);
diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
index 15239dc95b..2a91f3f46a 100644
--- a/target/ppc/mmu_helper.c
+++ b/target/ppc/mmu_helper.c
@@ -429,6 +429,160 @@ void helper_tlbie(CPUPPCState *env, target_ulong addr)
     ppc_tlb_invalidate_one(env, addr);
 }
 
+#if defined(TARGET_PPC64)
+
+/* Invalidation Selector */
+#define TLBIE_IS_VA         0
+#define TLBIE_IS_PID        1
+#define TLBIE_IS_LPID       2
+#define TLBIE_IS_ALL        3
+
+/* Radix Invalidation Control */
+#define TLBIE_RIC_TLB       0
+#define TLBIE_RIC_PWC       1
+#define TLBIE_RIC_ALL       2
+#define TLBIE_RIC_GRP       3
+
+/* Radix Actual Page sizes */
+#define TLBIE_R_AP_4K       0
+#define TLBIE_R_AP_64K      5
+#define TLBIE_R_AP_2M       1
+#define TLBIE_R_AP_1G       2
+
+/* RB field masks */
+#define TLBIE_RB_EPN_MASK   PPC_BITMASK(0, 51)
+#define TLBIE_RB_IS_MASK    PPC_BITMASK(52, 53)
+#define TLBIE_RB_AP_MASK    PPC_BITMASK(56, 58)
+
+void helper_tlbie_isa300(CPUPPCState *env, target_ulong rb, target_ulong rs,
+                         uint32_t flags)
+{
+    unsigned ric = (flags & TLBIE_F_RIC_MASK) >> TLBIE_F_RIC_SHIFT;
+    /*
+     * With the exception of the checks for invalid instruction forms,
+     * PRS is currently ignored, because we don't know if a given TLB entry
+     * is process or partition scoped.
+     */
+    bool prs = flags & TLBIE_F_PRS;
+    bool r = flags & TLBIE_F_R;
+    bool local = flags & TLBIE_F_LOCAL;
+    bool effR;
+    unsigned is = extract64(rb, PPC_BIT_NR(53), 2);
+    unsigned ap;        /* actual page size */
+    target_ulong addr, pgoffs_mask;
+
+    qemu_log_mask(CPU_LOG_MMU,
+        "%s: local=%d addr=" TARGET_FMT_lx " ric=%u prs=%d r=%d is=%u\n",
+        __func__, local, rb & TARGET_PAGE_MASK, ric, prs, r, is);
+
+    effR = FIELD_EX64(env->msr, MSR, HV) ? r : env->spr[SPR_LPCR] & LPCR_HR;
+
+    /* Partial TLB invalidation is supported for Radix only for now. */
+    if (!effR) {
+        goto inval_all;
+    }
+
+    /* Check for invalid instruction forms (effR=1). */
+    if (unlikely(ric == TLBIE_RIC_GRP ||
+                 ((ric == TLBIE_RIC_PWC || ric == TLBIE_RIC_ALL) &&
+                                           is == TLBIE_IS_VA) ||
+                 (!prs && is == TLBIE_IS_PID))) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+            "%s: invalid instruction form: ric=%u prs=%d r=%d is=%u\n",
+            __func__, ric, prs, r, is);
+        goto invalid;
+    }
+
+    /* We don't cache Page Walks. */
+    if (ric == TLBIE_RIC_PWC) {
+        if (local) {
+            unsigned set = extract64(rb, PPC_BIT_NR(51), 12);
+            if (set != 0) {
+                qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid set: %d\n",
+                              __func__, set);
+                goto invalid;
+            }
+        }
+        return;
+    }
+
+    /*
+     * Invalidation by LPID or PID is not supported, so fallback
+     * to full TLB flush in these cases.
+     */
+    if (is != TLBIE_IS_VA) {
+        goto inval_all;
+    }
+
+    /*
+     * The results of an attempt to invalidate a translation outside of
+     * quadrant 0 for Radix Tree translation (effR=1, RIC=0, PRS=1, IS=0,
+     * and EA 0:1 != 0b00) are boundedly undefined.
+     */
+    if (unlikely(ric == TLBIE_RIC_TLB && prs && is == TLBIE_IS_VA &&
+                 (rb & R_EADDR_QUADRANT) != R_EADDR_QUADRANT0)) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+            "%s: attempt to invalidate a translation outside of quadrant 0\n",
+            __func__);
+        goto inval_all;
+    }
+
+    assert(is == TLBIE_IS_VA);
+    assert(ric == TLBIE_RIC_TLB || ric == TLBIE_RIC_ALL);
+
+    ap = extract64(rb, PPC_BIT_NR(58), 3);
+    switch (ap) {
+    case TLBIE_R_AP_4K:
+        pgoffs_mask = 0xfffull;
+        break;
+
+    case TLBIE_R_AP_64K:
+        pgoffs_mask = 0xffffull;
+        break;
+
+    case TLBIE_R_AP_2M:
+        pgoffs_mask = 0x1fffffull;
+        break;
+
+    case TLBIE_R_AP_1G:
+        pgoffs_mask = 0x3fffffffull;
+        break;
+
+    default:
+        /*
+         * If the value specified in RS 0:31, RS 32:63, RB 54:55, RB 56:58,
+         * RB 44:51, or RB 56:63, when it is needed to perform the specified
+         * operation, is not supported by the implementation, the instruction
+         * is treated as if the instruction form were invalid.
+         */
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid AP: %d\n", __func__, ap);
+        goto invalid;
+    }
+
+    addr = rb & TLBIE_RB_EPN_MASK & ~pgoffs_mask;
+
+    if (local) {
+        tlb_flush_page(env_cpu(env), addr);
+    } else {
+        tlb_flush_page_all_cpus(env_cpu(env), addr);
+    }
+    return;
+
+inval_all:
+    env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH;
+    if (!local) {
+        env->tlb_need_flush |= TLB_NEED_GLOBAL_FLUSH;
+    }
+    return;
+
+invalid:
+    raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
+                           POWERPC_EXCP_INVAL |
+                           POWERPC_EXCP_INVAL_INVAL, GETPC());
+}
+
+#endif
+
 void helper_tlbiva(CPUPPCState *env, target_ulong addr)
 {
     /* tlbiva instruction only exists on BookE */
diff --git a/target/ppc/translate/storage-ctrl-impl.c.inc b/target/ppc/translate/storage-ctrl-impl.c.inc
index 7793297dd4..467c390888 100644
--- a/target/ppc/translate/storage-ctrl-impl.c.inc
+++ b/target/ppc/translate/storage-ctrl-impl.c.inc
@@ -21,6 +21,8 @@
  * Store Control Instructions
  */
 
+#include "mmu-book3s-v3.h"
+
 static bool do_tlbie(DisasContext *ctx, arg_X_tlbie *a, bool local)
 {
 #if defined(CONFIG_USER_ONLY)
@@ -65,6 +67,21 @@ static bool do_tlbie(DisasContext *ctx, arg_X_tlbie *a, bool local)
         tcg_gen_ext32u_tl(t0, cpu_gpr[rb]);
         gen_helper_tlbie(cpu_env, t0);
         tcg_temp_free(t0);
+
+#if defined(TARGET_PPC64)
+    /*
+     * ISA 3.1B says that MSR SF must be 1 when this instruction is executed;
+     * otherwise the results are undefined.
+     */
+    } else if (a->r) {
+        gen_helper_tlbie_isa300(cpu_env, cpu_gpr[rb], cpu_gpr[a->rs],
+                tcg_constant_i32(a->ric << TLBIE_F_RIC_SHIFT |
+                                 a->prs << TLBIE_F_PRS_SHIFT |
+                                 a->r << TLBIE_F_R_SHIFT |
+                                 local << TLBIE_F_LOCAL_SHIFT));
+        return true;
+#endif
+
     } else {
         gen_helper_tlbie(cpu_env, cpu_gpr[rb]);
     }
-- 
2.36.1



  parent reply	other threads:[~2022-07-18 17:42 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-18 17:21 [PULL 00/30] ppc queue Daniel Henrique Barboza
2022-07-18 17:21 ` [PULL 01/30] ppc64: Allocate IRQ lines with qdev_init_gpio_in() Daniel Henrique Barboza
2022-07-18 17:21 ` [PULL 02/30] ppc/40x: " Daniel Henrique Barboza
2022-07-18 17:21 ` [PULL 03/30] ppc/6xx: " Daniel Henrique Barboza
2022-07-18 17:21 ` [PULL 04/30] ppc/e500: " Daniel Henrique Barboza
2022-07-18 17:21 ` [PULL 05/30] ppc: Remove unused irq_inputs Daniel Henrique Barboza
2022-07-18 17:21 ` [PULL 06/30] hw/ppc: pass random seed to fdt Daniel Henrique Barboza
2022-07-18 17:21 ` [PULL 07/30] target/ppc/kvm: Skip current and parent directories in kvmppc_find_cpu_dt Daniel Henrique Barboza
2022-07-18 17:21 ` [PULL 08/30] target/ppc: Fix gen_priv_exception error value in mfspr/mtspr Daniel Henrique Barboza
2022-07-18 17:21 ` [PULL 09/30] target/ppc: fix exception error value in slbfee Daniel Henrique Barboza
2022-07-18 17:21 ` [PULL 10/30] target/ppc: remove mfdcrux and mtdcrux Daniel Henrique Barboza
2022-07-18 17:21 ` [PULL 11/30] target/ppc: fix exception error code in helper_{load, store}_dcr Daniel Henrique Barboza
2022-07-18 17:21 ` [PULL 12/30] target/ppc: fix PMU Group A register read/write exceptions Daniel Henrique Barboza
2022-07-18 17:21 ` [PULL 13/30] target/ppc: fix exception error code in spr_write_excp_vector Daniel Henrique Barboza
2022-07-18 17:21 ` [PULL 14/30] target/ppc: Move tlbie[l] to decode tree Daniel Henrique Barboza
2022-07-18 17:21 ` Daniel Henrique Barboza [this message]
2022-07-18 17:21 ` [PULL 16/30] target/ppc: receive DisasContext explicitly in GEN_PRIV Daniel Henrique Barboza
2022-07-18 17:21 ` [PULL 17/30] target/ppc: add macros to check privilege level Daniel Henrique Barboza
2022-07-18 17:21 ` [PULL 18/30] target/ppc: Move slbie to decodetree Daniel Henrique Barboza
2022-07-18 17:21 ` [PULL 19/30] target/ppc: Move slbieg " Daniel Henrique Barboza
2022-07-18 17:21 ` [PULL 20/30] target/ppc: Move slbia " Daniel Henrique Barboza
2022-07-18 17:21 ` [PULL 21/30] target/ppc: Move slbmte " Daniel Henrique Barboza
2022-07-18 17:22 ` [PULL 22/30] target/ppc: Move slbmfev " Daniel Henrique Barboza
2022-07-18 17:22 ` [PULL 23/30] target/ppc: Move slbmfee " Daniel Henrique Barboza
2022-07-18 17:22 ` [PULL 24/30] target/ppc: Move slbfee " Daniel Henrique Barboza
2022-07-18 17:22 ` [PULL 25/30] target/ppc: Move slbsync " Daniel Henrique Barboza
2022-07-18 17:22 ` [PULL 26/30] target/ppc: Implement slbiag Daniel Henrique Barboza
2022-07-18 17:22 ` [PULL 27/30] target/ppc: check tb_env != 0 before printing TBU/TBL/DECR Daniel Henrique Barboza
2022-07-18 17:22 ` [PULL 28/30] ppc: Check partition and process table alignment Daniel Henrique Barboza
2022-07-18 17:22 ` [PULL 29/30] target/ppc: Improve Radix xlate level validation Daniel Henrique Barboza
2022-07-18 17:22 ` [PULL 30/30] target/ppc: Check page dir/table base alignment Daniel Henrique Barboza
2022-07-19  8:56 ` [PULL 00/30] ppc queue Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220718172208.1247624-16-danielhb413@gmail.com \
    --to=danielhb413@gmail.com \
    --cc=leandro.lupori@eldorado.org.br \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    --cc=richard.henderson@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.