Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Xpulp related extensions #1

Open
wants to merge 16 commits into
base: corev-mcu-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions target/riscv/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,13 @@ static const struct isa_ext_data isa_edata_arr[] = {
ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval),
ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
ISA_EXT_DATA_ENTRY(xcvalu, true, PRIV_VERSION_1_11_0, ext_xcvalu),
ISA_EXT_DATA_ENTRY(xcvbi, true, PRIV_VERSION_1_11_0, ext_xcvbi),
ISA_EXT_DATA_ENTRY(xcvbitmanip, true, PRIV_VERSION_1_11_0, ext_xcvbitmanip),
ISA_EXT_DATA_ENTRY(xcvhwlp, true, PRIV_VERSION_1_11_0, ext_xcvhwlp),
ISA_EXT_DATA_ENTRY(xcvmac, true, PRIV_VERSION_1_11_0, ext_xcvmac),
ISA_EXT_DATA_ENTRY(xcvmem, true, PRIV_VERSION_1_11_0, ext_xcvmem),
ISA_EXT_DATA_ENTRY(xcvsimd, true, PRIV_VERSION_1_11_0, ext_xcvsimd),
ISA_EXT_DATA_ENTRY(xtheadba, true, PRIV_VERSION_1_11_0, ext_xtheadba),
ISA_EXT_DATA_ENTRY(xtheadbb, true, PRIV_VERSION_1_11_0, ext_xtheadbb),
ISA_EXT_DATA_ENTRY(xtheadbs, true, PRIV_VERSION_1_11_0, ext_xtheadbs),
Expand Down Expand Up @@ -1129,6 +1136,13 @@ static Property riscv_cpu_extensions[] = {
DEFINE_PROP_BOOL("zmmul", RISCVCPU, cfg.ext_zmmul, false),

/* Vendor-specific custom extensions */
DEFINE_PROP_BOOL("xcvalu", RISCVCPU, cfg.ext_xcvalu, false),
DEFINE_PROP_BOOL("xcvbi", RISCVCPU, cfg.ext_xcvbi, false),
DEFINE_PROP_BOOL("xcvbitmanip", RISCVCPU, cfg.ext_xcvbitmanip, false),
DEFINE_PROP_BOOL("xcvhwlp", RISCVCPU, cfg.ext_xcvhwlp, false),
DEFINE_PROP_BOOL("xcvmac", RISCVCPU, cfg.ext_xcvmac, false),
DEFINE_PROP_BOOL("xcvmem", RISCVCPU, cfg.ext_xcvmem, false),
DEFINE_PROP_BOOL("xcvsimd", RISCVCPU, cfg.ext_xcvsimd, false),
DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false),
DEFINE_PROP_BOOL("xtheadbb", RISCVCPU, cfg.ext_xtheadbb, false),
DEFINE_PROP_BOOL("xtheadbs", RISCVCPU, cfg.ext_xtheadbs, false),
Expand Down
29 changes: 29 additions & 0 deletions target/riscv/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,22 @@ typedef struct PMUCTRState {
target_ulong irq_overflow_left;
} PMUCTRState;

struct RISCVHwlp {
target_ulong lpstart;
target_ulong lpend;
target_ulong lpcount;
};

typedef struct RISCVHwlp RISCVHwlp;

enum {
HWLP_TYPE_RVC,
HWLP_TYPE_JUMP_BR,
HWLP_TYPE_MEMORY_ORDER,
HWLP_TYPE_PRIV,
HWLP_TYPE_TARGET_PC,
};

struct CPUArchState {
target_ulong gpr[32];
target_ulong gprh[32]; /* 64 top bits of the 128-bit registers */
Expand Down Expand Up @@ -376,6 +392,9 @@ struct CPUArchState {
target_ulong senvcfg;
uint64_t henvcfg;
#endif

RISCVHwlp hwlp[2];

target_ulong cur_pmmask;
target_ulong cur_pmbase;

Expand Down Expand Up @@ -474,6 +493,13 @@ struct RISCVCPUConfig {
uint64_t mimpid;

/* Vendor-specific custom extensions */
bool ext_xcvalu;
bool ext_xcvbi;
bool ext_xcvbitmanip;
bool ext_xcvhwlp;
bool ext_xcvmac;
bool ext_xcvmem;
bool ext_xcvsimd;
bool ext_xtheadba;
bool ext_xtheadbb;
bool ext_xtheadbs;
Expand Down Expand Up @@ -644,6 +670,9 @@ FIELD(TB_FLAGS, VMA, 25, 1)
/* Native debug itrigger */
FIELD(TB_FLAGS, ITRIGGER, 26, 1)

FIELD(TB_FLAGS, HWLP_ENABLED0, 27, 1)
FIELD(TB_FLAGS, HWLP_ENABLED1, 28, 1)

#ifdef TARGET_RISCV32
#define riscv_cpu_mxl(env) ((void)(env), MXL_RV32)
#else
Expand Down
11 changes: 11 additions & 0 deletions target/riscv/cpu_bits.h
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,17 @@
/* Crypto Extension */
#define CSR_SEED 0x015

/*
* Hardware Loop registers
* User Custom CSRs
*/
#define CSR_LPSTART0 0xCC0
#define CSR_LPEND0 0xCC1
#define CSR_LPCOUNT0 0xCC2
#define CSR_LPSTART1 0xCC4
#define CSR_LPEND1 0xCC5
#define CSR_LPCOUNT1 0xCC6

/* mstatus CSR bits */
#define MSTATUS_UIE 0x00000001
#define MSTATUS_SIE 0x00000002
Expand Down
17 changes: 17 additions & 0 deletions target/riscv/cpu_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
#endif
}

inline bool is_same_page(target_ulong addr1, target_ulong addr2)
{
return (addr1 & TARGET_PAGE_MASK) == (addr2 & TARGET_PAGE_MASK);
}

void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
target_ulong *cs_base, uint32_t *pflags)
{
Expand Down Expand Up @@ -118,6 +123,18 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
flags = FIELD_DP32(flags, TB_FLAGS, PM_BASE_ENABLED, 1);
}

if (cpu->cfg.ext_xcvhwlp) {
if (env->hwlp[0].lpcount > 1 &&
is_same_page(*pc, env->hwlp[0].lpend)) {
flags = FIELD_DP32(flags, TB_FLAGS, HWLP_ENABLED0, 1);
}

if (env->hwlp[1].lpcount > 1 &&
is_same_page(*pc, env->hwlp[1].lpend)) {
flags = FIELD_DP32(flags, TB_FLAGS, HWLP_ENABLED1, 1);
}
}

*pflags = flags;
}

Expand Down
151 changes: 151 additions & 0 deletions target/riscv/csr.c
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,15 @@ static RISCVException seed(CPURISCVState *env, int csrno)
#endif
}

static RISCVException hwlp(CPURISCVState *env, int csrno)
{
if (env_archcpu(env)->cfg.ext_xcvhwlp) {
return RISCV_EXCP_NONE;
}

return RISCV_EXCP_ILLEGAL_INST;
}

/* User Floating-Point CSRs */
static RISCVException read_fflags(CPURISCVState *env, int csrno,
target_ulong *val)
Expand Down Expand Up @@ -3757,7 +3766,141 @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno,
if (ret_value) {
*ret_value = rval;
}
return RISCV_EXCP_NONE;
}

static inline void check_hwlp_valid(CPURISCVState *env)
{
int i = 0;
for (int i = 0; i < 2; i++) {
if (env->hwlp[i].lpcount > 1) {
if (env->hwlp[i].lpend & 0x3 || env->hwlp[i].lpstart & 0x3) {
qemu_log_mask(LOG_GUEST_ERROR,
"HWLoop%d: Start and End addresses of an HWLoop "
"must be 32-bit aligned.", i);
}
if (env->hwlp[i].lpend <= env->hwlp[i].lpstart) {
qemu_log_mask(LOG_GUEST_ERROR,
"HWLoop%d: End Address must be strictly greater "
"than Start Address.", i);
}
if (env->hwlp[i].lpend - env->hwlp[i].lpstart < 12) {
qemu_log_mask(LOG_GUEST_ERROR,
"HWLoop%d: HWLoop body must contain at least 3 "
"instructions.", i);
}
}
}

if (env->hwlp[0].lpcount > 1 && env->hwlp[1].lpcount > 1 &&
(env->hwlp[1].lpend - env->hwlp[i].lpend < 8)) {
qemu_log_mask(LOG_GUEST_ERROR,
"When both loops are nested, the End address of the "
"outermost HWLoop (must be #1) must be at least 2 "
"instructions further than the End address of the "
"innermost HWLoop (must be #0).");
}
}

static inline void check_write_hwlp(CPURISCVState *env, int i)
{
if (env->hwlp[i].lpcount > 1 && env->pc >= env->hwlp[i].lpstart &&
env->pc < env->hwlp[i].lpend) {
qemu_log_mask(LOG_GUEST_ERROR,
"HWLoop %d: No HWLoop #0 (resp. #1) CSR should be "
"modified inside the HWLoop #0 (resp. #1) body.", i);
}
}

static RISCVException read_lpstart0(CPURISCVState *env, int csrno,
target_ulong *val)
{
*val = env->hwlp[0].lpstart;
return RISCV_EXCP_NONE;
}

static RISCVException write_lpstart0(CPURISCVState *env, int csrno,
target_ulong val)
{
check_write_hwlp(env, 0);
env->hwlp[0].lpstart = val & (~0x3);
return RISCV_EXCP_NONE;
}

static RISCVException read_lpend0(CPURISCVState *env, int csrno,
target_ulong *val)
{
*val = env->hwlp[0].lpend;
return RISCV_EXCP_NONE;
}

static RISCVException write_lpend0(CPURISCVState *env, int csrno,
target_ulong val)
{
check_write_hwlp(env, 0);
env->hwlp[0].lpend = val & (~0x3);
return RISCV_EXCP_NONE;
}

static RISCVException read_lpcount0(CPURISCVState *env, int csrno,
target_ulong *val)
{
*val = env->hwlp[0].lpcount;
return RISCV_EXCP_NONE;
}

static RISCVException write_lpcount0(CPURISCVState *env, int csrno,
target_ulong val)
{
check_write_hwlp(env, 0);
env->hwlp[0].lpcount = val;
check_hwlp_valid(env);
return RISCV_EXCP_NONE;
}

static RISCVException read_lpstart1(CPURISCVState *env, int csrno,
target_ulong *val)
{
*val = env->hwlp[1].lpstart;
return RISCV_EXCP_NONE;
}

static RISCVException write_lpstart1(CPURISCVState *env, int csrno,
target_ulong val)
{
check_write_hwlp(env, 1);
env->hwlp[1].lpstart = val & (~0x3);
return RISCV_EXCP_NONE;
}

static RISCVException read_lpend1(CPURISCVState *env, int csrno,
target_ulong *val)
{
*val = env->hwlp[1].lpend;
return RISCV_EXCP_NONE;
}

static RISCVException write_lpend1(CPURISCVState *env, int csrno,
target_ulong val)
{
check_write_hwlp(env, 1);
env->hwlp[1].lpend = val & (~0x3);
return RISCV_EXCP_NONE;
}

static RISCVException read_lpcount1(CPURISCVState *env, int csrno,
target_ulong *val)
{
*val = env->hwlp[1].lpcount;
return RISCV_EXCP_NONE;
}

static RISCVException write_lpcount1(CPURISCVState *env, int csrno,
target_ulong val)
{
check_write_hwlp(env, 1);
env->hwlp[1].lpcount = val;
check_hwlp_valid(env);
return RISCV_EXCP_NONE;
}

Expand Down Expand Up @@ -4657,4 +4800,12 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
.min_priv_ver = PRIV_VERSION_1_12_0 },

#endif /* !CONFIG_USER_ONLY */

/* Custom CSRs */
[CSR_LPSTART0] = { "lpstart0", hwlp, read_lpstart0, write_lpstart0 },
[CSR_LPEND0] = { "lpend0", hwlp, read_lpend0, write_lpend0 },
[CSR_LPCOUNT0] = { "lpcount0", hwlp, read_lpcount0, write_lpcount0 },
[CSR_LPSTART1] = { "lpstart1", hwlp, read_lpstart1, write_lpstart1 },
[CSR_LPEND1] = { "lpend1", hwlp, read_lpend1, write_lpend1 },
[CSR_LPCOUNT1] = { "lpcount1", hwlp, read_lpcount1, write_lpcount1 },
};
86 changes: 86 additions & 0 deletions target/riscv/helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -1137,3 +1137,89 @@ 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(sm4ks, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)

/* Hardware Loop Function */
DEF_HELPER_FLAGS_3(check_hwlp_body, TCG_CALL_NO_RWG, void, env, tl, tl)

/* XPulp SIMD operation */
DEF_HELPER_FLAGS_2(min_h, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(min_b, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(max_h, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(max_b, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(minu_h, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(minu_b, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(maxu_h, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(maxu_b, TCG_CALL_NO_RWG_SE, tl, tl, tl)

DEF_HELPER_FLAGS_2(shr_h, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(shr_b, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(sra_h, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(sra_b, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(shl_h, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(shl_b, TCG_CALL_NO_RWG_SE, tl, tl, tl)

/* XPulp SIMD Dot Product Instructions */
DEF_HELPER_FLAGS_2(dotup_h, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(dotup_b, TCG_CALL_NO_RWG_SE, tl, tl, tl)

DEF_HELPER_FLAGS_2(dotusp_h, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(dotusp_b, TCG_CALL_NO_RWG_SE, tl, tl, tl)

DEF_HELPER_FLAGS_2(dotsp_h, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(dotsp_b, TCG_CALL_NO_RWG_SE, tl, tl, tl)

DEF_HELPER_FLAGS_2(shuffle_h, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(shuffle_sc_h, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(shuffle_b, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_3(shuffle_sc_b, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
DEF_HELPER_FLAGS_3(shuffle2_h, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
DEF_HELPER_FLAGS_3(shuffle2_b, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)

DEF_HELPER_FLAGS_2(cmpeq_h, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(cmpeq_b, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(cmpne_h, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(cmpne_b, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(cmpgt_h, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(cmpgt_b, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(cmpge_h, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(cmpge_b, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(cmplt_h, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(cmplt_b, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(cmple_h, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(cmple_b, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(cmpgtu_h, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(cmpgtu_b, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(cmpgeu_h, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(cmpgeu_b, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(cmpltu_h, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(cmpltu_b, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(cmpleu_h, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(cmpleu_b, TCG_CALL_NO_RWG_SE, tl, tl, tl)

DEF_HELPER_FLAGS_3(subrotmj, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
DEF_HELPER_FLAGS_4(cplxmul_r, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl, tl)
DEF_HELPER_FLAGS_4(cplxmul_i, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl, tl)

DEF_HELPER_FLAGS_4(muluN, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl, tl)
DEF_HELPER_FLAGS_4(mulsN, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl, tl)
DEF_HELPER_FLAGS_4(muluRN, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl, tl)
DEF_HELPER_FLAGS_4(mulsRN, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl, tl)
DEF_HELPER_FLAGS_5(macuN, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl, tl, tl)
DEF_HELPER_FLAGS_5(macsN, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl, tl, tl)
DEF_HELPER_FLAGS_5(macuRN, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl, tl, tl)
DEF_HELPER_FLAGS_5(macsRN, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl, tl, tl)

DEF_HELPER_FLAGS_2(extract, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(extractu, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_3(insert, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
DEF_HELPER_FLAGS_2(bclr, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(bset, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(bitrev, TCG_CALL_NO_RWG_SE, tl, tl, tl)

DEF_HELPER_FLAGS_1(fl1, TCG_CALL_NO_RWG_SE, tl, tl)
DEF_HELPER_FLAGS_1(clb, TCG_CALL_NO_RWG_SE, tl, tl)

DEF_HELPER_FLAGS_2(clip, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(clipr, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(clipu, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(clipur, TCG_CALL_NO_RWG_SE, tl, tl, tl)
Loading