cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

trans_rvh.c.inc (4523B)


      1/*
      2 * RISC-V translation routines for the RVXI Base Integer Instruction Set.
      3 *
      4 * Copyright (c) 2020 Western Digital
      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#ifndef CONFIG_USER_ONLY
     20static bool check_access(DisasContext *ctx)
     21{
     22    if (!ctx->hlsx) {
     23        if (ctx->virt_enabled) {
     24            generate_exception(ctx, RISCV_EXCP_VIRT_INSTRUCTION_FAULT);
     25        } else {
     26            generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
     27        }
     28        return false;
     29    }
     30    return true;
     31}
     32#endif
     33
     34static bool do_hlv(DisasContext *ctx, arg_r2 *a, MemOp mop)
     35{
     36#ifdef CONFIG_USER_ONLY
     37    return false;
     38#else
     39    if (check_access(ctx)) {
     40        TCGv dest = dest_gpr(ctx, a->rd);
     41        TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
     42        int mem_idx = ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
     43        tcg_gen_qemu_ld_tl(dest, addr, mem_idx, mop);
     44        gen_set_gpr(ctx, a->rd, dest);
     45    }
     46    return true;
     47#endif
     48}
     49
     50static bool trans_hlv_b(DisasContext *ctx, arg_hlv_b *a)
     51{
     52    REQUIRE_EXT(ctx, RVH);
     53    return do_hlv(ctx, a, MO_SB);
     54}
     55
     56static bool trans_hlv_h(DisasContext *ctx, arg_hlv_h *a)
     57{
     58    REQUIRE_EXT(ctx, RVH);
     59    return do_hlv(ctx, a, MO_TESW);
     60}
     61
     62static bool trans_hlv_w(DisasContext *ctx, arg_hlv_w *a)
     63{
     64    REQUIRE_EXT(ctx, RVH);
     65    return do_hlv(ctx, a, MO_TESL);
     66}
     67
     68static bool trans_hlv_bu(DisasContext *ctx, arg_hlv_bu *a)
     69{
     70    REQUIRE_EXT(ctx, RVH);
     71    return do_hlv(ctx, a, MO_UB);
     72}
     73
     74static bool trans_hlv_hu(DisasContext *ctx, arg_hlv_hu *a)
     75{
     76    REQUIRE_EXT(ctx, RVH);
     77    return do_hlv(ctx, a, MO_TEUW);
     78}
     79
     80static bool do_hsv(DisasContext *ctx, arg_r2_s *a, MemOp mop)
     81{
     82#ifdef CONFIG_USER_ONLY
     83    return false;
     84#else
     85    if (check_access(ctx)) {
     86        TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
     87        TCGv data = get_gpr(ctx, a->rs2, EXT_NONE);
     88        int mem_idx = ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
     89        tcg_gen_qemu_st_tl(data, addr, mem_idx, mop);
     90    }
     91    return true;
     92#endif
     93}
     94
     95static bool trans_hsv_b(DisasContext *ctx, arg_hsv_b *a)
     96{
     97    REQUIRE_EXT(ctx, RVH);
     98    return do_hsv(ctx, a, MO_SB);
     99}
    100
    101static bool trans_hsv_h(DisasContext *ctx, arg_hsv_h *a)
    102{
    103    REQUIRE_EXT(ctx, RVH);
    104    return do_hsv(ctx, a, MO_TESW);
    105}
    106
    107static bool trans_hsv_w(DisasContext *ctx, arg_hsv_w *a)
    108{
    109    REQUIRE_EXT(ctx, RVH);
    110    return do_hsv(ctx, a, MO_TESL);
    111}
    112
    113static bool trans_hlv_wu(DisasContext *ctx, arg_hlv_wu *a)
    114{
    115    REQUIRE_64BIT(ctx);
    116    REQUIRE_EXT(ctx, RVH);
    117    return do_hlv(ctx, a, MO_TEUL);
    118}
    119
    120static bool trans_hlv_d(DisasContext *ctx, arg_hlv_d *a)
    121{
    122    REQUIRE_64BIT(ctx);
    123    REQUIRE_EXT(ctx, RVH);
    124    return do_hlv(ctx, a, MO_TEQ);
    125}
    126
    127static bool trans_hsv_d(DisasContext *ctx, arg_hsv_d *a)
    128{
    129    REQUIRE_64BIT(ctx);
    130    REQUIRE_EXT(ctx, RVH);
    131    return do_hsv(ctx, a, MO_TEQ);
    132}
    133
    134#ifndef CONFIG_USER_ONLY
    135static bool do_hlvx(DisasContext *ctx, arg_r2 *a,
    136                    void (*func)(TCGv, TCGv_env, TCGv))
    137{
    138    if (check_access(ctx)) {
    139        TCGv dest = dest_gpr(ctx, a->rd);
    140        TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
    141        func(dest, cpu_env, addr);
    142        gen_set_gpr(ctx, a->rd, dest);
    143    }
    144    return true;
    145}
    146#endif
    147
    148static bool trans_hlvx_hu(DisasContext *ctx, arg_hlvx_hu *a)
    149{
    150    REQUIRE_EXT(ctx, RVH);
    151#ifndef CONFIG_USER_ONLY
    152    return do_hlvx(ctx, a, gen_helper_hyp_hlvx_hu);
    153#else
    154    return false;
    155#endif
    156}
    157
    158static bool trans_hlvx_wu(DisasContext *ctx, arg_hlvx_wu *a)
    159{
    160    REQUIRE_EXT(ctx, RVH);
    161#ifndef CONFIG_USER_ONLY
    162    return do_hlvx(ctx, a, gen_helper_hyp_hlvx_wu);
    163#else
    164    return false;
    165#endif
    166}
    167
    168static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
    169{
    170    REQUIRE_EXT(ctx, RVH);
    171#ifndef CONFIG_USER_ONLY
    172    gen_helper_hyp_gvma_tlb_flush(cpu_env);
    173    return true;
    174#endif
    175    return false;
    176}
    177
    178static bool trans_hfence_vvma(DisasContext *ctx, arg_sfence_vma *a)
    179{
    180    REQUIRE_EXT(ctx, RVH);
    181#ifndef CONFIG_USER_ONLY
    182    gen_helper_hyp_tlb_flush(cpu_env);
    183    return true;
    184#endif
    185    return false;
    186}