Skip to content
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
9 changes: 9 additions & 0 deletions arch/riscv/arch_exports.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,15 @@ void tlib_allow_additional_feature(uint32_t feature)
case RISCV_FEATURE_ZACAS:
// No dependencies
break;
case RISCV_FEATURE_ZCB:
tlib_allow_feature('C' - 'A'); // Depends on RVC
break;
case RISCV_FEATURE_ZCMP:
tlib_allow_feature('C' - 'A'); // Depends on RVC
break;
case RISCV_FEATURE_ZCMT:
tlib_allow_feature('C' - 'A'); // Depends on RVC
break;
}
cpu->additional_extensions |= 1U << extension;
}
Expand Down
7 changes: 6 additions & 1 deletion arch/riscv/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ struct CPUState {
target_ulong mseccfg;
target_ulong mseccfgh;

target_ulong jvt;

/* Vector shadow state */
target_ulong elen;
target_ulong vlmax;
Expand Down Expand Up @@ -355,8 +357,11 @@ enum riscv_additional_feature {
RISCV_FEATURE_ZVE64D = 13,
RISCV_FEATURE_ZACAS = 14,
RISCV_FEATURE_SSCOFPMF = 15,
RISCV_FEATURE_ZCB = 16,
RISCV_FEATURE_ZCMP = 17,
RISCV_FEATURE_ZCMT = 18,
// Please update the highest additional when adding a new member!
RISCV_FEATURE_HIGHEST_ADDITIONAL = RISCV_FEATURE_SSCOFPMF
RISCV_FEATURE_HIGHEST_ADDITIONAL = RISCV_FEATURE_ZCMT
};

enum privilege_architecture {
Expand Down
1 change: 1 addition & 0 deletions arch/riscv/cpu_bits.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#define CSR_FFLAGS 0x1
#define CSR_FRM 0x2
#define CSR_FCSR 0x3
#define CSR_JVT 0x17 /* Jump Vector Table base - Zcmt extension */
#define CSR_SSTATUS 0x100
#define CSR_SIE 0x104
#define CSR_STVEC 0x105
Expand Down
4 changes: 4 additions & 0 deletions arch/riscv/cpu_registers.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ uint64_t *get_reg_pointer_64(int reg)
return &(cpu->vlenb);
case MSECCFG_64:
return &(cpu->mseccfg);
case JVT_64:
return &(cpu->jvt);
default:
break;
}
Expand Down Expand Up @@ -185,6 +187,8 @@ uint32_t *get_reg_pointer_32(int reg)
return &(cpu->vlenb);
case MSECCFG_32:
return &(cpu->mseccfg);
case JVT_32:
return &(cpu->jvt);
default:
break;
}
Expand Down
2 changes: 2 additions & 0 deletions arch/riscv/cpu_registers.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ typedef enum {
T_6_64 = 31,
X_31_64 = 31,
PC_64 = 32,
JVT_64 = 0x58,
SSTATUS_64 = 0x141,
SIE_64 = 0x145,
STVEC_64 = 0x146,
Expand Down Expand Up @@ -203,6 +204,7 @@ typedef enum {
T_6_32 = 31,
X_31_32 = 31,
PC_32 = 32,
JVT_32 = 0x58,
SSTATUS_32 = 0x141,
SIE_32 = 0x145,
STVEC_32 = 0x146,
Expand Down
16 changes: 16 additions & 0 deletions arch/riscv/instmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -715,3 +715,19 @@ enum {
#define GET_C_RS2(inst) extract32(inst, 2, 5)
#define GET_C_RS1S(inst) (8 + extract32(inst, 7, 3))
#define GET_C_RS2S(inst) (8 + extract32(inst, 2, 3))

/* Zcb decoding macros */
#define GET_C_LBU_IMM(inst) ((extract32(inst, 5, 1) << 1) | extract32(inst, 6, 1))
#define GET_C_LH_IMM(inst) (extract32(inst, 5, 1) << 1)
#define GET_C_LHU_IMM(inst) (extract32(inst, 5, 1) << 1)
#define GET_C_SB_IMM(inst) ((extract32(inst, 5, 1) << 1) | extract32(inst, 6, 1))
#define GET_C_SH_IMM(inst) (extract32(inst, 5, 1) << 1)

/* Zcmp decoding macros */
#define GET_C_PUSHPOP_SPIMM(inst) extract32(inst, 2, 2)
#define GET_C_PUSHPOP_RLIST(inst) extract32(inst, 4, 4)
#define GET_C_MVSA01_R1S(inst) extract32(inst, 7, 3)
#define GET_C_MVSA01_R2S(inst) extract32(inst, 2, 3)

/* Zcmt decoding macros */
#define GET_C_JT_INDEX(inst) extract32(inst, 2, 8)
14 changes: 14 additions & 0 deletions arch/riscv/op_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,14 @@ inline void csr_write_helper(CPUState *env, target_ulong val_to_write, target_ul
helper_raise_illegal_instruction(env);
}
break;
case CSR_JVT:
if(!riscv_has_additional_ext(env, RISCV_FEATURE_ZCMT)) {
tlib_printf(LOG_LEVEL_ERROR, "CSR_JVT can only be accessed when ZCMT extension is enabled");
goto unhandled_csr_write;
}
// Bits [5:0] are reserved and must be 0, jump table base address must be 64-byte aligned.
env->jvt = val_to_write & ~((target_ulong)0x3F);
break;
case CSR_MSTATUS: {
target_ulong mstatus = env->mstatus;
target_ulong mask = MSTATUS_MIE | MSTATUS_MPIE | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_MPP | MSTATUS_MXR | MSTATUS_VS;
Expand Down Expand Up @@ -799,6 +807,12 @@ static inline target_ulong csr_read_helper(CPUState *env, target_ulong csrno)
helper_raise_illegal_instruction(env);
break;
}
case CSR_JVT:
if(!riscv_has_additional_ext(env, RISCV_FEATURE_ZCMT)) {
tlib_printf(LOG_LEVEL_ERROR, "CSR_JVT can only be accessed when ZCMT extension is enabled");
goto unhandled_csr_read;
}
return env->jvt;
case CSR_TIME:
return tlib_get_cpu_time();
case CSR_TIMEH:
Expand Down
Loading