1/*
2 * RISC-V translation routines for the T-Head vendor extensions (xthead*).
3 *
4 * Copyright (c) 2022 VRULL GmbH.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2 or later, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#define REQUIRE_XTHEADCMO(ctx) do {              \
20    if (!ctx->cfg_ptr->ext_xtheadcmo) {          \
21        return false;                            \
22    }                                            \
23} while (0)
24
25/* XTheadCmo */
26
27static inline int priv_level(DisasContext *ctx)
28{
29#ifdef CONFIG_USER_ONLY
30    return PRV_U;
31#else
32     /* Priv level is part of mem_idx. */
33    return ctx->mem_idx & TB_FLAGS_PRIV_MMU_MASK;
34#endif
35}
36
37/* Test if priv level is M, S, or U (cannot fail). */
38#define REQUIRE_PRIV_MSU(ctx)
39
40/* Test if priv level is M or S. */
41#define REQUIRE_PRIV_MS(ctx)                                    \
42do {                                                            \
43    int priv = priv_level(ctx);                                 \
44    if (!(priv == PRV_M ||                                      \
45          priv == PRV_S)) {                                     \
46        return false;                                           \
47    }                                                           \
48} while (0)
49
50#define NOP_PRIVCHECK(insn, extcheck, privcheck)                \
51static bool trans_ ## insn(DisasContext *ctx, arg_ ## insn * a) \
52{                                                               \
53    (void) a;                                                   \
54    extcheck(ctx);                                              \
55    privcheck(ctx);                                             \
56    return true;                                                \
57}
58
59NOP_PRIVCHECK(th_dcache_call, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
60NOP_PRIVCHECK(th_dcache_ciall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
61NOP_PRIVCHECK(th_dcache_iall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
62NOP_PRIVCHECK(th_dcache_cpa, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
63NOP_PRIVCHECK(th_dcache_cipa, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
64NOP_PRIVCHECK(th_dcache_ipa, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
65NOP_PRIVCHECK(th_dcache_cva, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MSU)
66NOP_PRIVCHECK(th_dcache_civa, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MSU)
67NOP_PRIVCHECK(th_dcache_iva, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MSU)
68NOP_PRIVCHECK(th_dcache_csw, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
69NOP_PRIVCHECK(th_dcache_cisw, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
70NOP_PRIVCHECK(th_dcache_isw, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
71NOP_PRIVCHECK(th_dcache_cpal1, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
72NOP_PRIVCHECK(th_dcache_cval1, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
73
74NOP_PRIVCHECK(th_icache_iall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
75NOP_PRIVCHECK(th_icache_ialls, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
76NOP_PRIVCHECK(th_icache_ipa, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
77NOP_PRIVCHECK(th_icache_iva, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MSU)
78
79NOP_PRIVCHECK(th_l2cache_call, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
80NOP_PRIVCHECK(th_l2cache_ciall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
81NOP_PRIVCHECK(th_l2cache_iall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
82