qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

target/riscv: add vector configure instruction

vsetvl and vsetvli are two configure instructions for vl, vtype. TB flags
should update after configure instructions. The (ill, lmul, sew ) of vtype
and the bit of (VSTART == 0 && VL == VLMAX) will be placed within tb_flags.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20200701152549.1218-5-zhiwei_liu@c-sky.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

authored by

LIU Zhiwei and committed by
Alistair Francis
2b7168fc 8e3a1f18

+210 -12
+1 -1
target/riscv/Makefile.objs
··· 1 - obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.o fpu_helper.o gdbstub.o 1 + obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.o fpu_helper.o vector_helper.o gdbstub.o 2 2 obj-$(CONFIG_SOFTMMU) += pmp.o 3 3 4 4 ifeq ($(CONFIG_SOFTMMU),y)
+54 -9
target/riscv/cpu.h
··· 21 21 #define RISCV_CPU_H 22 22 23 23 #include "hw/core/cpu.h" 24 + #include "hw/registerfields.h" 24 25 #include "exec/cpu-defs.h" 25 26 #include "fpu/softfloat-types.h" 26 27 ··· 92 93 #include "pmp.h" 93 94 94 95 #define RV_VLEN_MAX 512 96 + 97 + FIELD(VTYPE, VLMUL, 0, 2) 98 + FIELD(VTYPE, VSEW, 2, 3) 99 + FIELD(VTYPE, VEDIV, 5, 2) 100 + FIELD(VTYPE, RESERVED, 7, sizeof(target_ulong) * 8 - 9) 101 + FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 2, 1) 95 102 96 103 struct CPURISCVState { 97 104 target_ulong gpr[32]; ··· 352 359 #define TB_FLAGS_MMU_MASK 3 353 360 #define TB_FLAGS_MSTATUS_FS MSTATUS_FS 354 361 362 + typedef CPURISCVState CPUArchState; 363 + typedef RISCVCPU ArchCPU; 364 + #include "exec/cpu-all.h" 365 + 366 + FIELD(TB_FLAGS, VL_EQ_VLMAX, 2, 1) 367 + FIELD(TB_FLAGS, LMUL, 3, 2) 368 + FIELD(TB_FLAGS, SEW, 5, 3) 369 + FIELD(TB_FLAGS, VILL, 8, 1) 370 + 371 + /* 372 + * A simplification for VLMAX 373 + * = (1 << LMUL) * VLEN / (8 * (1 << SEW)) 374 + * = (VLEN << LMUL) / (8 << SEW) 375 + * = (VLEN << LMUL) >> (SEW + 3) 376 + * = VLEN >> (SEW + 3 - LMUL) 377 + */ 378 + static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype) 379 + { 380 + uint8_t sew, lmul; 381 + 382 + sew = FIELD_EX64(vtype, VTYPE, VSEW); 383 + lmul = FIELD_EX64(vtype, VTYPE, VLMUL); 384 + return cpu->cfg.vlen >> (sew + 3 - lmul); 385 + } 386 + 355 387 static inline void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc, 356 - target_ulong *cs_base, uint32_t *flags) 388 + target_ulong *cs_base, uint32_t *pflags) 357 389 { 390 + uint32_t flags = 0; 391 + 358 392 *pc = env->pc; 359 393 *cs_base = 0; 394 + 395 + if (riscv_has_ext(env, RVV)) { 396 + uint32_t vlmax = vext_get_vlmax(env_archcpu(env), env->vtype); 397 + bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl); 398 + flags = FIELD_DP32(flags, TB_FLAGS, VILL, 399 + FIELD_EX64(env->vtype, VTYPE, VILL)); 400 + flags = FIELD_DP32(flags, TB_FLAGS, SEW, 401 + FIELD_EX64(env->vtype, VTYPE, VSEW)); 402 + flags = FIELD_DP32(flags, TB_FLAGS, LMUL, 403 + FIELD_EX64(env->vtype, VTYPE, VLMUL)); 404 + flags = FIELD_DP32(flags, TB_FLAGS, VL_EQ_VLMAX, vl_eq_vlmax); 405 + } else { 406 + flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1); 407 + } 408 + 360 409 #ifdef CONFIG_USER_ONLY 361 - *flags = TB_FLAGS_MSTATUS_FS; 410 + flags |= TB_FLAGS_MSTATUS_FS; 362 411 #else 363 - *flags = cpu_mmu_index(env, 0); 412 + flags |= cpu_mmu_index(env, 0); 364 413 if (riscv_cpu_fp_enabled(env)) { 365 - *flags |= env->mstatus & MSTATUS_FS; 414 + flags |= env->mstatus & MSTATUS_FS; 366 415 } 367 416 #endif 417 + *pflags = flags; 368 418 } 369 419 370 420 int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, ··· 404 454 void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops); 405 455 406 456 void riscv_cpu_register_gdb_regs_for_features(CPUState *cs); 407 - 408 - typedef CPURISCVState CPUArchState; 409 - typedef RISCVCPU ArchCPU; 410 - 411 - #include "exec/cpu-all.h" 412 457 413 458 #endif /* RISCV_CPU_H */
+3
target/riscv/helper.h
··· 81 81 #ifndef CONFIG_USER_ONLY 82 82 DEF_HELPER_1(hyp_tlb_flush, void, env) 83 83 #endif 84 + 85 + /* Vector functions */ 86 + DEF_HELPER_3(vsetvl, tl, env, tl, tl)
+5
target/riscv/insn32.decode
··· 62 62 @r_rm ....... ..... ..... ... ..... ....... %rs2 %rs1 %rm %rd 63 63 @r2_rm ....... ..... ..... ... ..... ....... %rs1 %rm %rd 64 64 @r2 ....... ..... ..... ... ..... ....... %rs1 %rd 65 + @r2_zimm . zimm:11 ..... ... ..... ....... %rs1 %rd 65 66 66 67 @hfence_gvma ....... ..... ..... ... ..... ....... %rs2 %rs1 67 68 @hfence_vvma ....... ..... ..... ... ..... ....... %rs2 %rs1 ··· 209 210 # *** RV32H Base Instruction Set *** 210 211 hfence_gvma 0110001 ..... ..... 000 00000 1110011 @hfence_gvma 211 212 hfence_vvma 0010001 ..... ..... 000 00000 1110011 @hfence_vvma 213 + 214 + # *** RV32V Extension *** 215 + vsetvli 0 ........... ..... 111 ..... 1010111 @r2_zimm 216 + vsetvl 1000000 ..... ..... 111 ..... 1010111 @r
+79
target/riscv/insn_trans/trans_rvv.inc.c
··· 1 + /* 2 + * RISC-V translation routines for the RVV Standard Extension. 3 + * 4 + * Copyright (c) 2020 T-Head Semiconductor Co., Ltd. All rights reserved. 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 + static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a) 20 + { 21 + TCGv s1, s2, dst; 22 + 23 + if (!has_ext(ctx, RVV)) { 24 + return false; 25 + } 26 + 27 + s2 = tcg_temp_new(); 28 + dst = tcg_temp_new(); 29 + 30 + /* Using x0 as the rs1 register specifier, encodes an infinite AVL */ 31 + if (a->rs1 == 0) { 32 + /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */ 33 + s1 = tcg_const_tl(RV_VLEN_MAX); 34 + } else { 35 + s1 = tcg_temp_new(); 36 + gen_get_gpr(s1, a->rs1); 37 + } 38 + gen_get_gpr(s2, a->rs2); 39 + gen_helper_vsetvl(dst, cpu_env, s1, s2); 40 + gen_set_gpr(a->rd, dst); 41 + tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn); 42 + lookup_and_goto_ptr(ctx); 43 + ctx->base.is_jmp = DISAS_NORETURN; 44 + 45 + tcg_temp_free(s1); 46 + tcg_temp_free(s2); 47 + tcg_temp_free(dst); 48 + return true; 49 + } 50 + 51 + static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a) 52 + { 53 + TCGv s1, s2, dst; 54 + 55 + if (!has_ext(ctx, RVV)) { 56 + return false; 57 + } 58 + 59 + s2 = tcg_const_tl(a->zimm); 60 + dst = tcg_temp_new(); 61 + 62 + /* Using x0 as the rs1 register specifier, encodes an infinite AVL */ 63 + if (a->rs1 == 0) { 64 + /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */ 65 + s1 = tcg_const_tl(RV_VLEN_MAX); 66 + } else { 67 + s1 = tcg_temp_new(); 68 + gen_get_gpr(s1, a->rs1); 69 + } 70 + gen_helper_vsetvl(dst, cpu_env, s1, s2); 71 + gen_set_gpr(a->rd, dst); 72 + gen_goto_tb(ctx, 0, ctx->pc_succ_insn); 73 + ctx->base.is_jmp = DISAS_NORETURN; 74 + 75 + tcg_temp_free(s1); 76 + tcg_temp_free(s2); 77 + tcg_temp_free(dst); 78 + return true; 79 + }
+15 -2
target/riscv/translate.c
··· 56 56 to reset this known value. */ 57 57 int frm; 58 58 bool ext_ifencei; 59 + /* vector extension */ 60 + bool vill; 61 + uint8_t lmul; 62 + uint8_t sew; 63 + uint16_t vlen; 64 + bool vl_eq_vlmax; 59 65 } DisasContext; 60 66 61 67 #ifdef TARGET_RISCV64 ··· 712 718 #include "insn_trans/trans_rvf.inc.c" 713 719 #include "insn_trans/trans_rvd.inc.c" 714 720 #include "insn_trans/trans_rvh.inc.c" 721 + #include "insn_trans/trans_rvv.inc.c" 715 722 #include "insn_trans/trans_privileged.inc.c" 716 723 717 724 /* Include the auto-generated decoder for 16 bit insn */ ··· 746 753 DisasContext *ctx = container_of(dcbase, DisasContext, base); 747 754 CPURISCVState *env = cs->env_ptr; 748 755 RISCVCPU *cpu = RISCV_CPU(cs); 756 + uint32_t tb_flags = ctx->base.tb->flags; 749 757 750 758 ctx->pc_succ_insn = ctx->base.pc_first; 751 - ctx->mem_idx = ctx->base.tb->flags & TB_FLAGS_MMU_MASK; 752 - ctx->mstatus_fs = ctx->base.tb->flags & TB_FLAGS_MSTATUS_FS; 759 + ctx->mem_idx = tb_flags & TB_FLAGS_MMU_MASK; 760 + ctx->mstatus_fs = tb_flags & TB_FLAGS_MSTATUS_FS; 753 761 ctx->priv_ver = env->priv_ver; 754 762 #if !defined(CONFIG_USER_ONLY) 755 763 if (riscv_has_ext(env, RVH)) { ··· 773 781 ctx->misa = env->misa; 774 782 ctx->frm = -1; /* unknown rounding mode */ 775 783 ctx->ext_ifencei = cpu->cfg.ext_ifencei; 784 + ctx->vlen = cpu->cfg.vlen; 785 + ctx->vill = FIELD_EX32(tb_flags, TB_FLAGS, VILL); 786 + ctx->sew = FIELD_EX32(tb_flags, TB_FLAGS, SEW); 787 + ctx->lmul = FIELD_EX32(tb_flags, TB_FLAGS, LMUL); 788 + ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX); 776 789 } 777 790 778 791 static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
+53
target/riscv/vector_helper.c
··· 1 + /* 2 + * RISC-V Vector Extension Helpers for QEMU. 3 + * 4 + * Copyright (c) 2020 T-Head Semiconductor Co., Ltd. All rights reserved. 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 + #include "qemu/osdep.h" 20 + #include "cpu.h" 21 + #include "exec/exec-all.h" 22 + #include "exec/helper-proto.h" 23 + #include <math.h> 24 + 25 + target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1, 26 + target_ulong s2) 27 + { 28 + int vlmax, vl; 29 + RISCVCPU *cpu = env_archcpu(env); 30 + uint16_t sew = 8 << FIELD_EX64(s2, VTYPE, VSEW); 31 + uint8_t ediv = FIELD_EX64(s2, VTYPE, VEDIV); 32 + bool vill = FIELD_EX64(s2, VTYPE, VILL); 33 + target_ulong reserved = FIELD_EX64(s2, VTYPE, RESERVED); 34 + 35 + if ((sew > cpu->cfg.elen) || vill || (ediv != 0) || (reserved != 0)) { 36 + /* only set vill bit. */ 37 + env->vtype = FIELD_DP64(0, VTYPE, VILL, 1); 38 + env->vl = 0; 39 + env->vstart = 0; 40 + return 0; 41 + } 42 + 43 + vlmax = vext_get_vlmax(cpu, s2); 44 + if (s1 <= vlmax) { 45 + vl = s1; 46 + } else { 47 + vl = vlmax; 48 + } 49 + env->vl = vl; 50 + env->vtype = s2; 51 + env->vstart = 0; 52 + return vl; 53 + }