target/riscv: add support for Zcmt extension
Add encode, trans* functions and helper functions support for Zcmt instrutions. Add support for jvt csr. Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-Id: <20230307081403.61950-8-liweiwei@iscas.ac.cn> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
193eb522e4
commit
ce3af0bbbc
@ -176,6 +176,8 @@ struct CPUArchState {
|
|||||||
/* 128-bit helpers upper part return value */
|
/* 128-bit helpers upper part return value */
|
||||||
target_ulong retxh;
|
target_ulong retxh;
|
||||||
|
|
||||||
|
target_ulong jvt;
|
||||||
|
|
||||||
#ifdef CONFIG_USER_ONLY
|
#ifdef CONFIG_USER_ONLY
|
||||||
uint32_t elf_flags;
|
uint32_t elf_flags;
|
||||||
#endif
|
#endif
|
||||||
@ -620,6 +622,8 @@ void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, uint32_t priv,
|
|||||||
target_ulong new_val,
|
target_ulong new_val,
|
||||||
target_ulong write_mask),
|
target_ulong write_mask),
|
||||||
void *rmw_fn_arg);
|
void *rmw_fn_arg);
|
||||||
|
|
||||||
|
RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit);
|
||||||
#endif
|
#endif
|
||||||
void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv);
|
void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv);
|
||||||
|
|
||||||
|
@ -319,6 +319,7 @@
|
|||||||
#define SMSTATEEN_MAX_COUNT 4
|
#define SMSTATEEN_MAX_COUNT 4
|
||||||
#define SMSTATEEN0_CS (1ULL << 0)
|
#define SMSTATEEN0_CS (1ULL << 0)
|
||||||
#define SMSTATEEN0_FCSR (1ULL << 1)
|
#define SMSTATEEN0_FCSR (1ULL << 1)
|
||||||
|
#define SMSTATEEN0_JVT (1ULL << 2)
|
||||||
#define SMSTATEEN0_HSCONTXT (1ULL << 57)
|
#define SMSTATEEN0_HSCONTXT (1ULL << 57)
|
||||||
#define SMSTATEEN0_IMSIC (1ULL << 58)
|
#define SMSTATEEN0_IMSIC (1ULL << 58)
|
||||||
#define SMSTATEEN0_AIA (1ULL << 59)
|
#define SMSTATEEN0_AIA (1ULL << 59)
|
||||||
@ -523,6 +524,9 @@
|
|||||||
/* Crypto Extension */
|
/* Crypto Extension */
|
||||||
#define CSR_SEED 0x015
|
#define CSR_SEED 0x015
|
||||||
|
|
||||||
|
/* Zcmt Extension */
|
||||||
|
#define CSR_JVT 0x017
|
||||||
|
|
||||||
/* mstatus CSR bits */
|
/* mstatus CSR bits */
|
||||||
#define MSTATUS_UIE 0x00000001
|
#define MSTATUS_UIE 0x00000001
|
||||||
#define MSTATUS_SIE 0x00000002
|
#define MSTATUS_SIE 0x00000002
|
||||||
@ -898,4 +902,7 @@ typedef enum RISCVException {
|
|||||||
#define MHPMEVENT_IDX_MASK 0xFFFFF
|
#define MHPMEVENT_IDX_MASK 0xFFFFF
|
||||||
#define MHPMEVENT_SSCOF_RESVD 16
|
#define MHPMEVENT_SSCOF_RESVD 16
|
||||||
|
|
||||||
|
/* JVT CSR bits */
|
||||||
|
#define JVT_MODE 0x3F
|
||||||
|
#define JVT_BASE (~0x3F)
|
||||||
#endif
|
#endif
|
||||||
|
@ -43,8 +43,7 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
|
|||||||
|
|
||||||
/* Predicates */
|
/* Predicates */
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
static RISCVException smstateen_acc_ok(CPURISCVState *env, int index,
|
RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit)
|
||||||
uint64_t bit)
|
|
||||||
{
|
{
|
||||||
bool virt = riscv_cpu_virt_enabled(env);
|
bool virt = riscv_cpu_virt_enabled(env);
|
||||||
|
|
||||||
@ -161,6 +160,22 @@ static RISCVException ctr32(CPURISCVState *env, int csrno)
|
|||||||
return ctr(env, csrno);
|
return ctr(env, csrno);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static RISCVException zcmt(CPURISCVState *env, int csrno)
|
||||||
|
{
|
||||||
|
if (!riscv_cpu_cfg(env)->ext_zcmt) {
|
||||||
|
return RISCV_EXCP_ILLEGAL_INST;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
|
RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_JVT);
|
||||||
|
if (ret != RISCV_EXCP_NONE) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return RISCV_EXCP_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
static RISCVException mctr(CPURISCVState *env, int csrno)
|
static RISCVException mctr(CPURISCVState *env, int csrno)
|
||||||
{
|
{
|
||||||
@ -3958,6 +3973,20 @@ RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static RISCVException read_jvt(CPURISCVState *env, int csrno,
|
||||||
|
target_ulong *val)
|
||||||
|
{
|
||||||
|
*val = env->jvt;
|
||||||
|
return RISCV_EXCP_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static RISCVException write_jvt(CPURISCVState *env, int csrno,
|
||||||
|
target_ulong val)
|
||||||
|
{
|
||||||
|
env->jvt = val;
|
||||||
|
return RISCV_EXCP_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Control and Status Register function table */
|
/* Control and Status Register function table */
|
||||||
riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
|
riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
|
||||||
/* User Floating-Point CSRs */
|
/* User Floating-Point CSRs */
|
||||||
@ -3988,6 +4017,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
|
|||||||
/* Crypto Extension */
|
/* Crypto Extension */
|
||||||
[CSR_SEED] = { "seed", seed, NULL, NULL, rmw_seed },
|
[CSR_SEED] = { "seed", seed, NULL, NULL, rmw_seed },
|
||||||
|
|
||||||
|
/* Zcmt Extension */
|
||||||
|
[CSR_JVT] = {"jvt", zcmt, read_jvt, write_jvt},
|
||||||
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
/* Machine Timers and Counters */
|
/* Machine Timers and Counters */
|
||||||
[CSR_MCYCLE] = { "mcycle", any, read_hpmcounter,
|
[CSR_MCYCLE] = { "mcycle", any, read_hpmcounter,
|
||||||
|
@ -1142,3 +1142,6 @@ DEF_HELPER_FLAGS_1(aes64im, TCG_CALL_NO_RWG_SE, tl, tl)
|
|||||||
|
|
||||||
DEF_HELPER_FLAGS_3(sm4ed, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
|
DEF_HELPER_FLAGS_3(sm4ed, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
|
||||||
DEF_HELPER_FLAGS_3(sm4ks, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
|
DEF_HELPER_FLAGS_3(sm4ks, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
|
||||||
|
|
||||||
|
/* Zce helper */
|
||||||
|
DEF_HELPER_FLAGS_2(cm_jalt, TCG_CALL_NO_WG, tl, env, i32)
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
%uimm_cl_h 5:1 !function=ex_shift_1
|
%uimm_cl_h 5:1 !function=ex_shift_1
|
||||||
%spimm 2:2 !function=ex_shift_4
|
%spimm 2:2 !function=ex_shift_4
|
||||||
%urlist 4:4
|
%urlist 4:4
|
||||||
|
%index 2:8
|
||||||
|
|
||||||
# Argument sets imported from insn32.decode:
|
# Argument sets imported from insn32.decode:
|
||||||
&empty !extern
|
&empty !extern
|
||||||
@ -63,6 +64,7 @@
|
|||||||
&r2_s rs1 rs2 !extern
|
&r2_s rs1 rs2 !extern
|
||||||
|
|
||||||
&cmpp urlist spimm
|
&cmpp urlist spimm
|
||||||
|
&cmjt index
|
||||||
|
|
||||||
# Formats 16:
|
# Formats 16:
|
||||||
@cr .... ..... ..... .. &r rs2=%rs2_5 rs1=%rd %rd
|
@cr .... ..... ..... .. &r rs2=%rs2_5 rs1=%rd %rd
|
||||||
@ -105,6 +107,7 @@
|
|||||||
@cs_h ... . .. ... .. ... .. &s imm=%uimm_cl_h rs1=%rs1_3 rs2=%rs2_3
|
@cs_h ... . .. ... .. ... .. &s imm=%uimm_cl_h rs1=%rs1_3 rs2=%rs2_3
|
||||||
@cm_pp ... ... ........ .. &cmpp %urlist %spimm
|
@cm_pp ... ... ........ .. &cmpp %urlist %spimm
|
||||||
@cm_mv ... ... ... .. ... .. &r2_s rs2=%r2s rs1=%r1s
|
@cm_mv ... ... ... .. ... .. &r2_s rs2=%r2s rs1=%r1s
|
||||||
|
@cm_jt ... ... ........ .. &cmjt %index
|
||||||
|
|
||||||
# *** RV32/64C Standard Extension (Quadrant 0) ***
|
# *** RV32/64C Standard Extension (Quadrant 0) ***
|
||||||
{
|
{
|
||||||
@ -185,7 +188,7 @@ slli 000 . ..... ..... 10 @c_shift2
|
|||||||
sq 101 ... ... .. ... 10 @c_sqsp
|
sq 101 ... ... .. ... 10 @c_sqsp
|
||||||
c_fsd 101 ...... ..... 10 @c_sdsp
|
c_fsd 101 ...... ..... 10 @c_sdsp
|
||||||
|
|
||||||
# *** RV64 and RV32 Zcmp Extension ***
|
# *** RV64 and RV32 Zcmp/Zcmt Extension ***
|
||||||
[
|
[
|
||||||
cm_push 101 11000 .... .. 10 @cm_pp
|
cm_push 101 11000 .... .. 10 @cm_pp
|
||||||
cm_pop 101 11010 .... .. 10 @cm_pp
|
cm_pop 101 11010 .... .. 10 @cm_pp
|
||||||
@ -193,6 +196,8 @@ slli 000 . ..... ..... 10 @c_shift2
|
|||||||
cm_popretz 101 11100 .... .. 10 @cm_pp
|
cm_popretz 101 11100 .... .. 10 @cm_pp
|
||||||
cm_mva01s 101 011 ... 11 ... 10 @cm_mv
|
cm_mva01s 101 011 ... 11 ... 10 @cm_mv
|
||||||
cm_mvsa01 101 011 ... 01 ... 10 @cm_mv
|
cm_mvsa01 101 011 ... 01 ... 10 @cm_mv
|
||||||
|
|
||||||
|
cm_jalt 101 000 ........ 10 @cm_jt
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
sw 110 . ..... ..... 10 @c_swsp
|
sw 110 . ..... ..... 10 @c_swsp
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* RISC-V translation routines for the Zc[b,mp] Standard Extensions.
|
* RISC-V translation routines for the Zc[b,mp,mt] Standard Extensions.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2021-2022 PLCT Lab
|
* Copyright (c) 2021-2022 PLCT Lab
|
||||||
*
|
*
|
||||||
@ -26,6 +26,11 @@
|
|||||||
return false; \
|
return false; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define REQUIRE_ZCMT(ctx) do { \
|
||||||
|
if (!ctx->cfg_ptr->ext_zcmt) \
|
||||||
|
return false; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
static bool trans_c_zext_b(DisasContext *ctx, arg_c_zext_b *a)
|
static bool trans_c_zext_b(DisasContext *ctx, arg_c_zext_b *a)
|
||||||
{
|
{
|
||||||
REQUIRE_ZCB(ctx);
|
REQUIRE_ZCB(ctx);
|
||||||
@ -283,3 +288,24 @@ static bool trans_cm_mvsa01(DisasContext *ctx, arg_cm_mvsa01 *a)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool trans_cm_jalt(DisasContext *ctx, arg_cm_jalt *a)
|
||||||
|
{
|
||||||
|
REQUIRE_ZCMT(ctx);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update pc to current for the non-unwinding exception
|
||||||
|
* that might come from cpu_ld*_code() in the helper.
|
||||||
|
*/
|
||||||
|
tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
|
||||||
|
gen_helper_cm_jalt(cpu_pc, cpu_env, tcg_constant_i32(a->index));
|
||||||
|
|
||||||
|
/* c.jt vs c.jalt depends on the index. */
|
||||||
|
if (a->index >= 32) {
|
||||||
|
gen_set_gpri(ctx, xRA, ctx->pc_succ_insn);
|
||||||
|
}
|
||||||
|
|
||||||
|
tcg_gen_lookup_and_goto_ptr();
|
||||||
|
ctx->base.is_jmp = DISAS_NORETURN;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -329,6 +329,24 @@ static const VMStateDescription vmstate_pmu_ctr_state = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool jvt_needed(void *opaque)
|
||||||
|
{
|
||||||
|
RISCVCPU *cpu = opaque;
|
||||||
|
|
||||||
|
return cpu->cfg.ext_zcmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const VMStateDescription vmstate_jvt = {
|
||||||
|
.name = "cpu/jvt",
|
||||||
|
.version_id = 1,
|
||||||
|
.minimum_version_id = 1,
|
||||||
|
.needed = jvt_needed,
|
||||||
|
.fields = (VMStateField[]) {
|
||||||
|
VMSTATE_UINTTL(env.jvt, RISCVCPU),
|
||||||
|
VMSTATE_END_OF_LIST()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const VMStateDescription vmstate_riscv_cpu = {
|
const VMStateDescription vmstate_riscv_cpu = {
|
||||||
.name = "cpu",
|
.name = "cpu",
|
||||||
.version_id = 7,
|
.version_id = 7,
|
||||||
@ -395,6 +413,7 @@ const VMStateDescription vmstate_riscv_cpu = {
|
|||||||
&vmstate_envcfg,
|
&vmstate_envcfg,
|
||||||
&vmstate_debug,
|
&vmstate_debug,
|
||||||
&vmstate_smstateen,
|
&vmstate_smstateen,
|
||||||
|
&vmstate_jvt,
|
||||||
NULL
|
NULL
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -19,7 +19,8 @@ riscv_ss.add(files(
|
|||||||
'bitmanip_helper.c',
|
'bitmanip_helper.c',
|
||||||
'translate.c',
|
'translate.c',
|
||||||
'm128_helper.c',
|
'm128_helper.c',
|
||||||
'crypto_helper.c'
|
'crypto_helper.c',
|
||||||
|
'zce_helper.c'
|
||||||
))
|
))
|
||||||
riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: files('kvm-stub.c'))
|
riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: files('kvm-stub.c'))
|
||||||
|
|
||||||
|
55
target/riscv/zce_helper.c
Normal file
55
target/riscv/zce_helper.c
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* RISC-V Zcmt Extension Helper for QEMU.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021-2022 PLCT Lab
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2 or later, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qemu/osdep.h"
|
||||||
|
#include "cpu.h"
|
||||||
|
#include "exec/exec-all.h"
|
||||||
|
#include "exec/helper-proto.h"
|
||||||
|
#include "exec/cpu_ldst.h"
|
||||||
|
|
||||||
|
target_ulong HELPER(cm_jalt)(CPURISCVState *env, uint32_t index)
|
||||||
|
{
|
||||||
|
|
||||||
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
|
RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_JVT);
|
||||||
|
if (ret != RISCV_EXCP_NONE) {
|
||||||
|
riscv_raise_exception(env, ret, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
target_ulong target;
|
||||||
|
target_ulong val = env->jvt;
|
||||||
|
int xlen = riscv_cpu_xlen(env);
|
||||||
|
uint8_t mode = get_field(val, JVT_MODE);
|
||||||
|
target_ulong base = val & JVT_BASE;
|
||||||
|
target_ulong t0;
|
||||||
|
|
||||||
|
if (mode != 0) {
|
||||||
|
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xlen == 32) {
|
||||||
|
t0 = base + (index << 2);
|
||||||
|
target = cpu_ldl_code(env, t0);
|
||||||
|
} else {
|
||||||
|
t0 = base + (index << 3);
|
||||||
|
target = cpu_ldq_code(env, t0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return target & ~0x1;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user